{"version":3,"sources":["../src/crypto-runtime.ts","../src/internal.ts","../src/auth-wire.ts","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/errors.js","../../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/algorithm.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/identifiers.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/interfaces/kemInterface.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/kdfs/hkdf.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/utils/misc.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/kems/dhkem.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/interfaces/dhkemPrimitives.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/xCryptoKey.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/xCurve.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/md.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/sha2.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/hash/sha3.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/curve/modular.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/curve/curve.js","../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/curve/montgomery.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+chacha20poly1305@1.8.0/node_modules/@hpke/chacha20poly1305/esm/src/chacha20Poly1305.js","../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/utils/emitNotSupported.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/encryptionContext.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/native.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","../../node_modules/.pnpm/@hpke+dhkem-x25519@1.8.0/node_modules/@hpke/dhkem-x25519/esm/src/primitives/x25519.js","../../node_modules/.pnpm/@hpke+dhkem-x25519@1.8.0/node_modules/@hpke/dhkem-x25519/esm/src/hkdfSha256.js","../../node_modules/.pnpm/@hpke+dhkem-x25519@1.8.0/node_modules/@hpke/dhkem-x25519/esm/src/dhkemX25519.js","../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/utils.ts","../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/_md.ts","../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/_u64.ts","../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/src/sha2.ts","../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/src/utils.ts","../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/src/abstract/modular.ts","../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/src/abstract/curve.ts","../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/src/abstract/edwards.ts","../../node_modules/.pnpm/@noble+curves@1.9.7/node_modules/@noble/curves/src/ed25519.ts","../../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","../src/errors.ts","../src/perf/url-redactor.ts","../src/sse.ts","../src/request.ts","../src/passkey.ts","../src/auth-facade.ts","../src/state.ts","../src/namespaces.ts","../../modules/auth/src/auth-client.ts","../../modules/auth/src/device-client.ts","../../modules/auth/src/oauth.ts","../src/analytics-facade.ts","../src/api-key.ts","../src/calls/facade.ts","../../modules/flags/src/admin-client.ts","../../modules/flags/src/flags-client.ts","../../modules/flags/src/pooled-flags.ts","../src/flags-facade.ts","../src/messaging/deadline-calculator.ts","../src/messaging/delete-fold.ts","../src/messaging/edit-fold.ts","../src/messaging/util.ts","../src/messaging/wire.ts","../src/messaging/keydir.ts","../src/messaging/group-messaging.ts","../src/messaging/mention-ranges.ts","../src/messaging/reaction-fold.ts","../src/messaging/timer-fold.ts","../src/messaging/chat.ts","../src/messaging/delivery-source.ts","../src/messaging/disappearing.ts","../src/messaging/history.ts","../src/messaging/mention-elevation.ts","../src/messaging/wasm/pkg/palbe_mls_bg.js","../src/messaging/wasm/pkg/snippets/mls-rs-core-f99cdecbb456b09c/inline0.js","../src/messaging/wasm/loader.ts","../src/messaging/wasm/bridge.ts","../src/messaging/mls-engine.ts","../src/messaging/registry.ts","../src/messaging/storage.ts","../src/messaging/suppression.ts","../src/messaging/coordinator.ts","../src/messaging/facade.ts","../src/perf/app-start.ts","../src/perf/perf-config-client.ts","../src/perf/fetch-swizzle.ts","../src/perf/offline-queue.ts","../src/perf/perf-state.ts","../src/perf/perf-wire.ts","../src/perf/perf-facade.ts","../src/perf/web-vitals.ts","../src/runtime-metadata.ts","../src/realtime/anon-token.ts","../src/realtime/frames.ts","../src/realtime/connection.ts","../src/realtime/state.ts","../src/realtime/facade.ts","../src/session-coordinator.ts","../src/storage.ts","../src/version.ts","../src/runtime.ts","../src/call.ts","../src/room.ts","../src/upload.ts","../src/pb.ts"],"sourcesContent":["// The web package supports browsers and modern Node/Next runtimes with WebCrypto.\n// HPKE/noble's legacy Node fallbacks must not leave a `crypto` import in browser\n// bundles. Only those dependencies are redirected here by the build plugin.\nexport const webcrypto = globalThis.crypto;\nexport const crypto = globalThis.crypto;\n","import { __resetPermissionDeniedHandlers } from './auth-facade.js';\nimport type { PalbeConfig } from './config.js';\nimport { BackendError } from './errors.js';\nimport { __registerNamespaces, resetNamespaces } from './namespaces.js';\nimport { buildRuntime, type PalbeRuntime } from './runtime.js';\nimport { palbeState } from './state.js';\n\n// Runtime lives in a process-global slot (see state.ts) so every build copy\n// (ESM/CJS, palbe + palbe/internal entries) converges on one singleton.\n// This is the BROWSER path (one runtime per tab). Server-side per-request\n// runtimes arrive with palbe/next (P3); do not sign in from shared server\n// code against this singleton.\n\n/**\n * Called by the generated palbe.gen.ts on import. REPLACES the runtime\n * (re-runs storage hydration) — safe to call repeatedly, e.g. watch-mode\n * regen. The namespace registry intentionally survives re-configure: the\n * gen file re-registers its static descriptors right after.\n */\nexport function __configure(config: PalbeConfig): void {\n  const state = palbeState();\n  // Destroy the old realtime facade if it was constructed — closes the socket\n  // and clears heartbeat timers so they do not outlive the replaced runtime.\n  state.runtime?.destroyRealtime();\n  state.runtime = buildRuntime(config);\n  // Fire after the runtime is in place so listeners that read pb.* immediately\n  // (e.g. useSyncExternalStore getSnapshot) see the new runtime.\n  for (const cb of state.configuredListeners) {\n    try {\n      cb();\n    } catch {\n      // consumer errors must not abort delivery to other listeners\n    }\n  }\n}\n\n/**\n * Register a callback that fires synchronously after every successful\n * `__configure` call (including re-configure / watch-mode regen).\n *\n * Returns an unsubscribe function. Safe to call before the first `__configure`.\n *\n * Consumed by `palbe/react`; not part of the public `palbe` surface — which is\n * what the separate `palbe/internal` ENTRY expresses, and the only thing that\n * may. DO NOT mark this doc comment with the TSDoc internal tag (not even in\n * prose — the compiler matches the token anywhere in the block): `stripInternal`\n * in tsconfig.json reads the whole src tree, so the tag deletes this declaration\n * from the shipped `internal.d.ts` while the JS keeps exporting it, and every\n * honest importer fails typecheck (WEB-9).\n */\nexport function onConfigured(cb: () => void): () => void {\n  const state = palbeState();\n  state.configuredListeners.add(cb);\n  return () => state.configuredListeners.delete(cb);\n}\n\n/** The configured runtime, or a guided `notConfigured` throw. Package-internal\n * (hence the `palbe/internal` entry) but part of THAT entry's shipped surface —\n * carries no TSDoc internal tag, which `stripInternal` would honour by deleting\n * this declaration from `internal.d.ts` (see `onConfigured` above). */\nexport function getRuntime(): PalbeRuntime {\n  const rt = palbeState().runtime;\n  if (!rt) throw BackendError.notConfigured();\n  return rt;\n}\n\n/** Test-only: drop runtime + registered namespaces. */\nexport function __reset(): void {\n  __resetPermissionDeniedHandlers();\n  const state = palbeState();\n  state.runtime?.destroyRealtime();\n  state.runtime = null;\n  state.configuredListeners.clear();\n  resetNamespaces();\n}\n\nexport type { EndpointDescriptor, NamespaceTree } from './namespaces.js';\nexport type { PB } from './pb.js';\nexport { createBoundClient } from './pb.js';\nexport type { PalbeConfig, PalbeRuntime };\n// Server-adapter seams (palbe/next): per-request runtime + bound client.\nexport { __registerNamespaces, buildRuntime };\n","/**\n * palauth AuthResult wire shape + its structural guard — shared by the auth\n * facade (sign-in / verify / code-exchange flows) and the palbe/next OAuth\n * callback handler, so both gate on the SAME shape rules.\n */\n\nexport interface WireUser {\n  id: string;\n  email?: string; // omitted for phone-only users\n  email_verified: boolean;\n  created_at: string;\n  /** Application roles from `auth.user_roles`. Optional on the wire only\n   * because a stack older than the roles surface omits it — a current one\n   * always sends `[]` when the caller holds none. */\n  roles?: string[];\n}\n\n/**\n * GET /auth/me. Distinct from WireUser (GET /auth/user): only this endpoint\n * reports which credentials the account actually has.\n *\n * `providers` is nullable ON PURPOSE and the difference carries meaning —\n * `[]` is \"asked, none linked\", `null` is \"could not determine\" (social login\n * unconfigured on the server, or the identity lookup failed). Collapsing null\n * to [] would report a social-only account as password-only, which is exactly\n * the wrong answer for the form this field exists to choose.\n */\nexport interface WireMe {\n  has_password: boolean;\n  has_mfa: boolean;\n  providers: string[] | null;\n}\n\nexport interface WireAuthResult {\n  access_token: string;\n  refresh_token: string;\n  expires_in: number;\n  user: WireUser;\n}\n\n/**\n * Structural guard for the palauth AuthResult wire shape. Consumers adopt\n * the session (persisting tokens to storage / cookies) BEFORE reading user\n * fields, so the full shape must be proven before adoption — a 200 body with\n * access_token but a missing/malformed user, refresh_token or expires_in\n * would otherwise half-adopt a zombie session (tokens stored, then TypeError\n * on user.id).\n */\nexport function asWireAuthResult(raw: unknown): WireAuthResult | null {\n  if (typeof raw !== 'object' || raw === null) return null;\n  const obj = raw as Record<string, unknown>;\n  if (typeof obj.access_token !== 'string') return null;\n  if (typeof obj.refresh_token !== 'string') return null;\n  if (typeof obj.expires_in !== 'number') return null;\n  const user = obj.user;\n  if (typeof user !== 'object' || user === null) return null;\n  if (typeof (user as Record<string, unknown>).id !== 'string') return null;\n  return raw as WireAuthResult;\n}\n\n/** FR-010: the permission a 403 said it required, or null. Only a string counts —\n * `required` is the cure the server names, and a cure the client cannot name is no cure. */\nexport function requiredPermission(body: unknown): string | null {\n  if (typeof body !== 'object' || body === null) return null;\n  const required = (body as Record<string, unknown>).required;\n  return typeof required === 'string' && required !== '' ? required : null;\n}\n","/**\n * The base error class of hpke-js.\n * @group Errors\n */\nexport class HpkeError extends Error {\n    constructor(e) {\n        let message;\n        if (e instanceof Error) {\n            message = e.message;\n        }\n        else if (typeof e === \"string\") {\n            message = e;\n        }\n        else {\n            message = \"\";\n        }\n        super(message);\n        this.name = this.constructor.name;\n    }\n}\n/**\n * Invalid parameter.\n * @group Errors\n */\nexport class InvalidParamError extends HpkeError {\n}\n/**\n * KEM input or output validation failure.\n * @group Errors\n */\nexport class ValidationError extends HpkeError {\n}\n/**\n * Public or private key serialization failure.\n * @group Errors\n */\nexport class SerializeError extends HpkeError {\n}\n/**\n * Public or private key deserialization failure.\n * @group Errors\n */\nexport class DeserializeError extends HpkeError {\n}\n/**\n * encap() failure.\n * @group Errors\n */\nexport class EncapError extends HpkeError {\n}\n/**\n * decap() failure.\n * @group Errors\n */\nexport class DecapError extends HpkeError {\n}\n/**\n * Secret export failure.\n * @group Errors\n */\nexport class ExportError extends HpkeError {\n}\n/**\n * seal() failure.\n * @group Errors\n */\nexport class SealError extends HpkeError {\n}\n/**\n * open() failure.\n * @group Errors\n */\nexport class OpenError extends HpkeError {\n}\n/**\n * Sequence number overflow on the encryption context.\n * @group Errors\n */\nexport class MessageLimitReachedError extends HpkeError {\n}\n/**\n * Key pair derivation failure.\n * @group Errors\n */\nexport class DeriveKeyPairError extends HpkeError {\n}\n/**\n * Not supported failure.\n * @group Errors\n */\nexport class NotSupportedError extends HpkeError {\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","import * as dntShim from \"../_dnt.shims.js\";\nimport { NotSupportedError } from \"./errors.js\";\nasync function loadSubtleCrypto() {\n    if (dntShim.dntGlobalThis !== undefined && globalThis.crypto !== undefined) {\n        // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc.\n        return globalThis.crypto.subtle;\n    }\n    // Node.js <= v18\n    try {\n        // @ts-ignore: to ignore \"crypto\"\n        const { webcrypto } = await import(\"crypto\"); // node:crypto\n        return webcrypto.subtle;\n    }\n    catch (e) {\n        throw new NotSupportedError(e);\n    }\n}\nexport class NativeAlgorithm {\n    constructor() {\n        Object.defineProperty(this, \"_api\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: undefined\n        });\n    }\n    async _setup() {\n        if (this._api !== undefined) {\n            return;\n        }\n        this._api = await loadSubtleCrypto();\n    }\n}\n","/**\n * The supported HPKE modes.\n */\nexport const Mode = {\n    Base: 0x00,\n    Psk: 0x01,\n    Auth: 0x02,\n    AuthPsk: 0x03,\n};\n/**\n * The supported Key Encapsulation Mechanism (KEM) identifiers.\n */\nexport const KemId = {\n    NotAssigned: 0x0000,\n    DhkemP256HkdfSha256: 0x0010,\n    DhkemP384HkdfSha384: 0x0011,\n    DhkemP521HkdfSha512: 0x0012,\n    DhkemSecp256k1HkdfSha256: 0x0013,\n    DhkemX25519HkdfSha256: 0x0020,\n    DhkemX448HkdfSha512: 0x0021,\n    HybridkemX25519Kyber768: 0x0030,\n    MlKem512: 0x0040,\n    MlKem768: 0x0041,\n    MlKem1024: 0x0042,\n    XWing: 0x647a,\n};\n/**\n * The supported Key Derivation Function (KDF) identifiers.\n */\nexport const KdfId = {\n    HkdfSha256: 0x0001,\n    HkdfSha384: 0x0002,\n    HkdfSha512: 0x0003,\n    Sha3256: 0x0004,\n    Sha3384: 0x0005,\n    Sha3512: 0x0006,\n    Shake128: 0x0010,\n    Shake256: 0x0011,\n    TurboShake128: 0x0012,\n    TurboShake256: 0x0013,\n};\n/**\n * The supported Authenticated Encryption with Associated Data (AEAD) identifiers.\n */\nexport const AeadId = {\n    Aes128Gcm: 0x0001,\n    Aes256Gcm: 0x0002,\n    Chacha20Poly1305: 0x0003,\n    ExportOnly: 0xFFFF,\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","// b\"KEM\"\nexport const SUITE_ID_HEADER_KEM = /* @__PURE__ */ new Uint8Array([\n    75,\n    69,\n    77,\n    0,\n    0,\n]);\n","import { EMPTY } from \"../consts.js\";\nimport { InvalidParamError } from \"../errors.js\";\nimport { KdfId } from \"../identifiers.js\";\nimport { NativeAlgorithm } from \"../algorithm.js\";\n// b\"HPKE-v1\"\nconst HPKE_VERSION = /* @__PURE__ */ new Uint8Array([\n    72,\n    80,\n    75,\n    69,\n    45,\n    118,\n    49,\n]);\nexport function toUint8Array(input) {\n    return new Uint8Array(toArrayBuffer(input));\n}\nexport function toArrayBuffer(input) {\n    if (input instanceof ArrayBuffer) {\n        return input;\n    }\n    if (ArrayBuffer.isView(input)) {\n        return new Uint8Array(input.buffer, input.byteOffset, input.byteLength)\n            .slice().buffer;\n    }\n    return new Uint8Array(input).slice().buffer;\n}\nexport class HkdfNative extends NativeAlgorithm {\n    constructor() {\n        super();\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: KdfId.HkdfSha256\n        });\n        Object.defineProperty(this, \"hashSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"_suiteId\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: EMPTY\n        });\n        Object.defineProperty(this, \"algHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: {\n                name: \"HMAC\",\n                hash: \"SHA-256\",\n                length: 256,\n            }\n        });\n    }\n    init(suiteId) {\n        this._suiteId = suiteId;\n    }\n    buildLabeledIkm(label, ikm) {\n        this._checkInit();\n        const ret = new Uint8Array(7 + this._suiteId.byteLength + label.byteLength + ikm.byteLength);\n        ret.set(HPKE_VERSION, 0);\n        ret.set(this._suiteId, 7);\n        ret.set(label, 7 + this._suiteId.byteLength);\n        ret.set(ikm, 7 + this._suiteId.byteLength + label.byteLength);\n        return ret;\n    }\n    buildLabeledInfo(label, info, len) {\n        this._checkInit();\n        const ret = new Uint8Array(9 + this._suiteId.byteLength + label.byteLength + info.byteLength);\n        ret.set(new Uint8Array([0, len]), 0);\n        ret.set(HPKE_VERSION, 2);\n        ret.set(this._suiteId, 9);\n        ret.set(label, 9 + this._suiteId.byteLength);\n        ret.set(info, 9 + this._suiteId.byteLength + label.byteLength);\n        return ret;\n    }\n    async extract(salt, ikm) {\n        await this._setup();\n        const saltBuf = salt.byteLength === 0\n            ? new ArrayBuffer(this.hashSize)\n            : toArrayBuffer(salt);\n        if (saltBuf.byteLength !== this.hashSize) {\n            throw new InvalidParamError(\"The salt length must be the same as the hashSize\");\n        }\n        const ikmBuf = toArrayBuffer(ikm);\n        const key = await this._api.importKey(\"raw\", saltBuf, this.algHash, false, [\n            \"sign\",\n        ]);\n        return await this._api.sign(\"HMAC\", key, ikmBuf);\n    }\n    async expand(prk, info, len) {\n        await this._setup();\n        const prkBuf = toArrayBuffer(prk);\n        const key = await this._api.importKey(\"raw\", prkBuf, this.algHash, false, [\n            \"sign\",\n        ]);\n        const okm = new ArrayBuffer(len);\n        const okmBytes = new Uint8Array(okm);\n        let prev = EMPTY;\n        const mid = toUint8Array(info);\n        const tail = new Uint8Array(1);\n        if (len > 255 * this.hashSize) {\n            throw new Error(\"Entropy limit reached\");\n        }\n        const tmp = new Uint8Array(this.hashSize + mid.length + 1);\n        for (let i = 1, cur = 0; cur < okmBytes.length; i++) {\n            tail[0] = i;\n            tmp.set(prev, 0);\n            tmp.set(mid, prev.length);\n            tmp.set(tail, prev.length + mid.length);\n            prev = new Uint8Array(await this._api.sign(\"HMAC\", key, tmp.slice(0, prev.length + mid.length + 1)));\n            if (okmBytes.length - cur >= prev.length) {\n                okmBytes.set(prev, cur);\n                cur += prev.length;\n            }\n            else {\n                okmBytes.set(prev.slice(0, okmBytes.length - cur), cur);\n                cur += okmBytes.length - cur;\n            }\n        }\n        return okm;\n    }\n    async extractAndExpand(salt, ikm, info, len) {\n        await this._setup();\n        const ikmBuf = toArrayBuffer(ikm);\n        const baseKey = await this._api.importKey(\"raw\", ikmBuf, \"HKDF\", false, [\"deriveBits\"]);\n        return await this._api.deriveBits({\n            name: \"HKDF\",\n            hash: this.algHash.hash,\n            salt: toArrayBuffer(salt),\n            info: toArrayBuffer(info),\n        }, baseKey, len * 8);\n    }\n    async labeledExtract(salt, label, ikm) {\n        return await this.extract(salt, this.buildLabeledIkm(label, ikm));\n    }\n    async labeledExpand(prk, label, info, len) {\n        return await this.expand(prk, this.buildLabeledInfo(label, info, len), len);\n    }\n    _checkInit() {\n        if (this._suiteId === EMPTY) {\n            throw new Error(\"Not initialized. Call init()\");\n        }\n    }\n}\nexport class HkdfSha256Native extends HkdfNative {\n    constructor() {\n        super(...arguments);\n        /** KdfId.HkdfSha256 (0x0001) */\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: KdfId.HkdfSha256\n        });\n        /** 32 */\n        Object.defineProperty(this, \"hashSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n        /** The parameters for Web Cryptography API */\n        Object.defineProperty(this, \"algHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: {\n                name: \"HMAC\",\n                hash: \"SHA-256\",\n                length: 256,\n            }\n        });\n    }\n}\nexport class HkdfSha384Native extends HkdfNative {\n    constructor() {\n        super(...arguments);\n        /** KdfId.HkdfSha384 (0x0002) */\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: KdfId.HkdfSha384\n        });\n        /** 48 */\n        Object.defineProperty(this, \"hashSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 48\n        });\n        /** The parameters for Web Cryptography API */\n        Object.defineProperty(this, \"algHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: {\n                name: \"HMAC\",\n                hash: \"SHA-384\",\n                length: 384,\n            }\n        });\n    }\n}\nexport class HkdfSha512Native extends HkdfNative {\n    constructor() {\n        super(...arguments);\n        /** KdfId.HkdfSha512 (0x0003) */\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: KdfId.HkdfSha512\n        });\n        /** 64 */\n        Object.defineProperty(this, \"hashSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 64\n        });\n        /** The parameters for Web Cryptography API */\n        Object.defineProperty(this, \"algHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: {\n                name: \"HMAC\",\n                hash: \"SHA-512\",\n                length: 512,\n            }\n        });\n    }\n}\n","import * as dntShim from \"../../_dnt.shims.js\";\nimport { KemId } from \"../identifiers.js\";\nexport const isDenoV1 = () => \n// deno-lint-ignore no-explicit-any\ndntShim.dntGlobalThis.process === undefined;\n/**\n * Checks whether the runtime is Deno or not (Node.js).\n * @returns boolean - true if the runtime is Deno, false Node.js.\n */\nexport function isDeno() {\n    // deno-lint-ignore no-explicit-any\n    if (dntShim.dntGlobalThis.process === undefined) {\n        return true;\n    }\n    // deno-lint-ignore no-explicit-any\n    return dntShim.dntGlobalThis.process?.versions?.deno !== undefined;\n}\n/**\n * Checks whetehr the type of input is CryptoKeyPair or not.\n */\nexport const isCryptoKeyPair = (x) => typeof x === \"object\" &&\n    x !== null &&\n    typeof x.privateKey === \"object\" &&\n    typeof x.publicKey === \"object\";\n/**\n * Converts integer to octet string. I2OSP implementation.\n */\nexport function i2Osp(n, w) {\n    if (w <= 0) {\n        throw new Error(\"i2Osp: too small size\");\n    }\n    if (n >= 256 ** w) {\n        throw new Error(\"i2Osp: too large integer\");\n    }\n    const ret = new Uint8Array(w);\n    for (let i = 0; i < w && n; i++) {\n        ret[w - (i + 1)] = n % 256;\n        n = Math.floor(n / 256);\n    }\n    return ret;\n}\n/**\n * Concatenates two Uint8Arrays.\n * @param a Uint8Array\n * @param b Uint8Array\n * @returns Concatenated Uint8Array\n */\nexport function concat(a, b) {\n    const ret = new Uint8Array(a.length + b.length);\n    ret.set(a, 0);\n    ret.set(b, a.length);\n    return ret;\n}\n/**\n * Decodes Base64Url-encoded data.\n * @param v Base64Url-encoded string\n * @returns Uint8Array\n */\nexport function base64UrlToBytes(v) {\n    const base64 = v.replace(/-/g, \"+\").replace(/_/g, \"/\");\n    const byteString = atob(base64);\n    const ret = new Uint8Array(byteString.length);\n    for (let i = 0; i < byteString.length; i++) {\n        ret[i] = byteString.charCodeAt(i);\n    }\n    return ret;\n}\n/**\n * Encodes Uint8Array to Base64Url.\n * @param v Uint8Array\n * @returns Base64Url-encoded string\n */\nexport function bytesToBase64Url(v) {\n    return btoa(String.fromCharCode(...v))\n        .replace(/\\+/g, \"-\")\n        .replace(/\\//g, \"_\")\n        .replace(/=*$/g, \"\");\n}\n/**\n * Decodes hex string to Uint8Array.\n * @param v Hex string\n * @returns Uint8Array\n * @throws Error if the input is not a hex string.\n */\nexport function hexToBytes(v) {\n    if (v.length === 0) {\n        return new Uint8Array([]);\n    }\n    const res = v.match(/[\\da-f]{2}/gi);\n    if (res == null) {\n        throw new Error(\"Not hex string.\");\n    }\n    return new Uint8Array(res.map(function (h) {\n        return parseInt(h, 16);\n    }));\n}\n/**\n * Encodes Uint8Array to hex string.\n * @param v Uint8Array\n * @returns Hex string\n */\nexport function bytesToHex(v) {\n    return [...v].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n}\n/**\n * Converts KemId to KeyAlgorithm.\n * @param kem KemId\n * @returns KeyAlgorithm\n */\nexport function kemToKeyGenAlgorithm(kem) {\n    switch (kem) {\n        case KemId.DhkemP256HkdfSha256:\n            return {\n                name: \"ECDH\",\n                namedCurve: \"P-256\",\n            };\n        case KemId.DhkemP384HkdfSha384:\n            return {\n                name: \"ECDH\",\n                namedCurve: \"P-384\",\n            };\n        case KemId.DhkemP521HkdfSha512:\n            return {\n                name: \"ECDH\",\n                namedCurve: \"P-521\",\n            };\n        default:\n            // case KemId.DhkemX25519HkdfSha256\n            return {\n                name: \"X25519\",\n            };\n    }\n}\nexport async function loadSubtleCrypto() {\n    if (dntShim.dntGlobalThis !== undefined && globalThis.crypto !== undefined) {\n        // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc.\n        return globalThis.crypto.subtle;\n    }\n    // Node.js <= v18\n    try {\n        // @ts-ignore: to ignore \"crypto\"\n        const { webcrypto } = await import(\"crypto\"); // node:crypto\n        return webcrypto.subtle;\n    }\n    catch (_e) {\n        throw new Error(\"Failed to load SubtleCrypto\");\n    }\n}\nexport async function loadCrypto() {\n    if (typeof dntShim.dntGlobalThis !== \"undefined\" && globalThis.crypto !== undefined) {\n        // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc.\n        return globalThis.crypto;\n    }\n    // Node.js <= v18\n    try {\n        // @ts-ignore: to ignore \"crypto\"\n        const { webcrypto } = await import(\"crypto\"); // node:crypto\n        return webcrypto;\n    }\n    catch (_e) {\n        throw new Error(\"failed to load Crypto\");\n    }\n}\n/**\n * XOR for Uint8Array.\n */\nexport function xor(a, b) {\n    if (a.byteLength !== b.byteLength) {\n        throw new Error(\"xor: different length inputs\");\n    }\n    const buf = new Uint8Array(a.byteLength);\n    for (let i = 0; i < a.byteLength; i++) {\n        buf[i] = a[i] ^ b[i];\n    }\n    return buf;\n}\n","import { EMPTY, INPUT_LENGTH_LIMIT } from \"../consts.js\";\nimport { DecapError, EncapError, InvalidParamError } from \"../errors.js\";\nimport { SUITE_ID_HEADER_KEM } from \"../interfaces/kemInterface.js\";\nimport { toArrayBuffer } from \"../kdfs/hkdf.js\";\nimport { concat, i2Osp, isCryptoKeyPair } from \"../utils/misc.js\";\n// b\"eae_prk\"\nconst LABEL_EAE_PRK = /* @__PURE__ */ new Uint8Array([\n    101,\n    97,\n    101,\n    95,\n    112,\n    114,\n    107,\n]);\n// b\"shared_secret\"\n// deno-fmt-ignore\nconst LABEL_SHARED_SECRET = /* @__PURE__ */ new Uint8Array([\n    115, 104, 97, 114, 101, 100, 95, 115, 101, 99,\n    114, 101, 116,\n]);\nfunction concat3(a, b, c) {\n    const ret = new Uint8Array(a.length + b.length + c.length);\n    ret.set(a, 0);\n    ret.set(b, a.length);\n    ret.set(c, a.length + b.length);\n    return ret;\n}\nexport class Dhkem {\n    constructor(id, prim, kdf) {\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"secretSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"encSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"publicKeySize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"privateKeySize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"_prim\", {\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.id = id;\n        this._prim = prim;\n        this._kdf = kdf;\n        const suiteId = new Uint8Array(SUITE_ID_HEADER_KEM);\n        suiteId.set(i2Osp(this.id, 2), 3);\n        this._kdf.init(suiteId);\n    }\n    async serializePublicKey(key) {\n        return await this._prim.serializePublicKey(key);\n    }\n    async deserializePublicKey(key) {\n        return await this._prim.deserializePublicKey(toArrayBuffer(key));\n    }\n    async serializePrivateKey(key) {\n        return await this._prim.serializePrivateKey(key);\n    }\n    async deserializePrivateKey(key) {\n        return await this._prim.deserializePrivateKey(toArrayBuffer(key));\n    }\n    async importKey(format, key, isPublic = true) {\n        return await this._prim.importKey(format, key, isPublic);\n    }\n    async generateKeyPair() {\n        return await this._prim.generateKeyPair();\n    }\n    async deriveKeyPair(ikm) {\n        const rawIkm = toArrayBuffer(ikm);\n        if (rawIkm.byteLength > INPUT_LENGTH_LIMIT) {\n            throw new InvalidParamError(\"Too long ikm\");\n        }\n        return await this._prim.deriveKeyPair(rawIkm);\n    }\n    async encap(params) {\n        let ke;\n        if (params.ekm === undefined) {\n            ke = await this.generateKeyPair();\n        }\n        else if (isCryptoKeyPair(params.ekm)) {\n            // params.ekm is only used for testing.\n            ke = params.ekm;\n        }\n        else {\n            // params.ekm is only used for testing.\n            ke = await this.deriveKeyPair(params.ekm);\n        }\n        const enc = await this._prim.serializePublicKey(ke.publicKey);\n        const pkrm = await this._prim.serializePublicKey(params.recipientPublicKey);\n        try {\n            let dh;\n            if (params.senderKey === undefined) {\n                dh = new Uint8Array(await this._prim.dh(ke.privateKey, params.recipientPublicKey));\n            }\n            else {\n                const sks = isCryptoKeyPair(params.senderKey)\n                    ? params.senderKey.privateKey\n                    : params.senderKey;\n                const dh1 = new Uint8Array(await this._prim.dh(ke.privateKey, params.recipientPublicKey));\n                const dh2 = new Uint8Array(await this._prim.dh(sks, params.recipientPublicKey));\n                dh = concat(dh1, dh2);\n            }\n            let kemContext;\n            if (params.senderKey === undefined) {\n                kemContext = concat(new Uint8Array(enc), new Uint8Array(pkrm));\n            }\n            else {\n                const pks = isCryptoKeyPair(params.senderKey)\n                    ? params.senderKey.publicKey\n                    : await this._prim.derivePublicKey(params.senderKey);\n                const pksm = await this._prim.serializePublicKey(pks);\n                kemContext = concat3(new Uint8Array(enc), new Uint8Array(pkrm), new Uint8Array(pksm));\n            }\n            const sharedSecret = await this._generateSharedSecret(dh, kemContext);\n            return {\n                enc: enc,\n                sharedSecret: sharedSecret,\n            };\n        }\n        catch (e) {\n            throw new EncapError(e);\n        }\n    }\n    async decap(params) {\n        const enc = toArrayBuffer(params.enc);\n        const pke = await this._prim.deserializePublicKey(enc);\n        const skr = isCryptoKeyPair(params.recipientKey)\n            ? params.recipientKey.privateKey\n            : params.recipientKey;\n        const pkr = isCryptoKeyPair(params.recipientKey)\n            ? params.recipientKey.publicKey\n            : await this._prim.derivePublicKey(params.recipientKey);\n        const pkrm = await this._prim.serializePublicKey(pkr);\n        try {\n            let dh;\n            if (params.senderPublicKey === undefined) {\n                dh = new Uint8Array(await this._prim.dh(skr, pke));\n            }\n            else {\n                const dh1 = new Uint8Array(await this._prim.dh(skr, pke));\n                const dh2 = new Uint8Array(await this._prim.dh(skr, params.senderPublicKey));\n                dh = concat(dh1, dh2);\n            }\n            let kemContext;\n            if (params.senderPublicKey === undefined) {\n                kemContext = concat(new Uint8Array(enc), new Uint8Array(pkrm));\n            }\n            else {\n                const pksm = await this._prim.serializePublicKey(params.senderPublicKey);\n                kemContext = new Uint8Array(enc.byteLength + pkrm.byteLength + pksm.byteLength);\n                kemContext.set(new Uint8Array(enc), 0);\n                kemContext.set(new Uint8Array(pkrm), enc.byteLength);\n                kemContext.set(new Uint8Array(pksm), enc.byteLength + pkrm.byteLength);\n            }\n            return await this._generateSharedSecret(dh, kemContext);\n        }\n        catch (e) {\n            throw new DecapError(e);\n        }\n    }\n    async _generateSharedSecret(dh, kemContext) {\n        const labeledIkm = this._kdf.buildLabeledIkm(LABEL_EAE_PRK, dh);\n        const labeledInfo = this._kdf.buildLabeledInfo(LABEL_SHARED_SECRET, kemContext, this.secretSize);\n        return await this._kdf.extractAndExpand(EMPTY, labeledIkm, labeledInfo, this.secretSize);\n    }\n}\n","// The key usages for KEM.\nexport const KEM_USAGES = [\"deriveBits\"];\n// b\"dkp_prk\"\nexport const LABEL_DKP_PRK = /* @__PURE__ */ new Uint8Array([\n    100,\n    107,\n    112,\n    95,\n    112,\n    114,\n    107,\n]);\n// b\"sk\"\nexport const LABEL_SK = /* @__PURE__ */ new Uint8Array([115, 107]);\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","export class XCryptoKey {\n    constructor(name, key, type, usages = []) {\n        Object.defineProperty(this, \"key\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"type\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"extractable\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: true\n        });\n        Object.defineProperty(this, \"algorithm\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"usages\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this.key = key;\n        this.type = type;\n        this.algorithm = { name: name };\n        this.usages = usages;\n        if (type === \"public\") {\n            this.usages = [];\n        }\n    }\n}\n","import { EMPTY } from \"../../consts.js\";\nimport { DeriveKeyPairError, DeserializeError, NotSupportedError, SerializeError, } from \"../../errors.js\";\nimport { toArrayBuffer } from \"../../kdfs/hkdf.js\";\nimport { KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, } from \"../../interfaces/dhkemPrimitives.js\";\nimport { base64UrlToBytes } from \"../../utils/misc.js\";\nimport { XCryptoKey } from \"../../xCryptoKey.js\";\n/**\n * Base DhkemPrimitives implementation for Montgomery curves (X25519/X448).\n *\n * Subclasses pass curve-specific parameters (algorithm name, key size, curve)\n * and optionally add extra methods (e.g., raw derive for X25519).\n */\nexport class XCurveDhkemPrimitives {\n    constructor(algName, keySize, curve, hkdf) {\n        Object.defineProperty(this, \"_algName\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_curve\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_hkdf\", {\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        this._algName = algName;\n        this._nPk = keySize;\n        this._nSk = keySize;\n        this._curve = curve;\n        this._hkdf = hkdf;\n    }\n    serializePublicKey(key) {\n        try {\n            return Promise.resolve(key.key.buffer);\n        }\n        catch (e) {\n            return Promise.reject(new SerializeError(e));\n        }\n    }\n    async deserializePublicKey(key) {\n        try {\n            return await this._importRawKey(toArrayBuffer(key), true);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    serializePrivateKey(key) {\n        try {\n            return Promise.resolve(key.key.buffer);\n        }\n        catch (e) {\n            return Promise.reject(new SerializeError(e));\n        }\n    }\n    async deserializePrivateKey(key) {\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        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        try {\n            const rawSk = await this._curve.utils.randomSecretKey();\n            const sk = new XCryptoKey(this._algName, rawSk, \"private\", KEM_USAGES);\n            const pk = await this.derivePublicKey(sk);\n            return { publicKey: pk, privateKey: sk };\n        }\n        catch (e) {\n            throw new NotSupportedError(e);\n        }\n    }\n    async deriveKeyPair(ikm) {\n        try {\n            const rawIkm = toArrayBuffer(ikm);\n            const dkpPrk = await this._hkdf.labeledExtract(EMPTY.buffer, LABEL_DKP_PRK, new Uint8Array(rawIkm));\n            const rawSk = await this._hkdf.labeledExpand(dkpPrk, LABEL_SK, EMPTY, this._nSk);\n            const sk = new XCryptoKey(this._algName, new Uint8Array(rawSk), \"private\", KEM_USAGES);\n            return {\n                privateKey: sk,\n                publicKey: await this.derivePublicKey(sk),\n            };\n        }\n        catch (e) {\n            throw new DeriveKeyPairError(e);\n        }\n    }\n    derivePublicKey(key) {\n        try {\n            const pk = this._curve.getPublicKey(key.key);\n            return Promise.resolve(new XCryptoKey(this._algName, pk, \"public\"));\n        }\n        catch (e) {\n            return Promise.reject(new DeserializeError(e));\n        }\n    }\n    dh(sk, pk) {\n        try {\n            return Promise.resolve(this._curve.getSharedSecret(sk.key, pk.key).buffer);\n        }\n        catch (e) {\n            return Promise.reject(new SerializeError(e));\n        }\n    }\n    _importRawKey(key, isPublic) {\n        return new Promise((resolve, reject) => {\n            if (isPublic && key.byteLength !== this._nPk) {\n                reject(new Error(\"Invalid length of the key\"));\n            }\n            if (!isPublic && key.byteLength !== this._nSk) {\n                reject(new Error(\"Invalid length of the key\"));\n            }\n            resolve(new XCryptoKey(this._algName, new Uint8Array(key), isPublic ? \"public\" : \"private\", isPublic ? [] : KEM_USAGES));\n        });\n    }\n    _importJWK(key, isPublic) {\n        return new Promise((resolve, reject) => {\n            if (key.kty !== \"OKP\") {\n                reject(new Error(`Invalid kty: ${key.kty}`));\n            }\n            if (key.crv !== this._algName) {\n                reject(new Error(`Invalid crv: ${key.crv}`));\n            }\n            if (isPublic) {\n                if (typeof key.d !== \"undefined\") {\n                    reject(new Error(\"Invalid key: `d` should not be set\"));\n                }\n                if (typeof key.x !== \"string\") {\n                    reject(new Error(\"Invalid key: `x` not found\"));\n                }\n                resolve(new XCryptoKey(this._algName, base64UrlToBytes(key.x), \"public\"));\n            }\n            else {\n                if (typeof key.d !== \"string\") {\n                    reject(new Error(\"Invalid key: `d` not found\"));\n                }\n                resolve(new XCryptoKey(this._algName, base64UrlToBytes(key.d), \"private\", KEM_USAGES));\n            }\n        });\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","// 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/_md.ts\n */\n/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport { abytes, aexists, aoutput, clean, createView, numberToBigint, } from \"../utils/noble.js\";\n/** Choice: a ? b : c */\nexport function Chi(a, b, c) {\n    return (a & b) ^ (~a & c);\n}\n/** Majority function, true if any two inputs is true. */\nexport function Maj(a, b, c) {\n    return (a & b) ^ (a & c) ^ (b & c);\n}\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n */\nexport class HashMD {\n    constructor(blockLen, outputLen, padOffset, isLE) {\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, \"padOffset\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"isLE\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // For partial updates less than block size\n        Object.defineProperty(this, \"buffer\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"view\", {\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, \"length\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"pos\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"destroyed\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        this.blockLen = blockLen;\n        this.outputLen = outputLen;\n        this.padOffset = padOffset;\n        this.isLE = isLE;\n        this.buffer = new Uint8Array(blockLen);\n        this.view = createView(this.buffer);\n    }\n    update(data) {\n        aexists(this);\n        abytes(data);\n        const { view, 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, cast it to view and process\n            if (take === blockLen) {\n                const dataView = createView(data);\n                for (; blockLen <= len - pos; pos += blockLen) {\n                    this.process(dataView, pos);\n                }\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(view, 0);\n                this.pos = 0;\n            }\n        }\n        this.length += data.length;\n        this.roundClean();\n        return this;\n    }\n    digestInto(out) {\n        aexists(this);\n        aoutput(out, this);\n        this.finished = true;\n        // Padding\n        // We can avoid allocation of buffer for padding completely if it\n        // was previously not allocated here. But it won't change performance.\n        const { buffer, view, blockLen, isLE } = this;\n        let { pos } = this;\n        // append the bit '1' to the message\n        buffer[pos++] = 0b10000000;\n        clean(this.buffer.subarray(pos));\n        // we have less than padOffset left in buffer, so we cannot put length in\n        // current block, need process it and pad again\n        if (this.padOffset > blockLen - pos) {\n            this.process(view, 0);\n            pos = 0;\n        }\n        // Pad until full block byte with zeros\n        for (let i = pos; i < blockLen; i++)\n            buffer[i] = 0;\n        // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n        // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n        // So we just write lowest 64 bits of that value.\n        view.setBigUint64(blockLen - 8, numberToBigint(this.length * 8), isLE);\n        this.process(view, 0);\n        const oview = createView(out);\n        const len = this.outputLen;\n        // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n        if (len % 4)\n            throw new Error(\"_sha2: outputLen must be aligned to 32bit\");\n        const outLen = len / 4;\n        const state = this.get();\n        if (outLen > state.length) {\n            throw new Error(\"_sha2: outputLen bigger than state\");\n        }\n        for (let i = 0; i < outLen; i++)\n            oview.setUint32(4 * i, state[i], isLE);\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    _cloneInto(to) {\n        to ||= new this.constructor();\n        to.set(...this.get());\n        const { blockLen, buffer, length, finished, destroyed, pos } = this;\n        to.destroyed = destroyed;\n        to.finished = finished;\n        to.length = length;\n        to.pos = pos;\n        if (length % blockLen)\n            to.buffer.set(buffer);\n        return to;\n    }\n    clone() {\n        return this._cloneInto();\n    }\n}\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */\nexport const SHA256_IV = /* @__PURE__ */ Uint32Array.from([\n    0x6a09e667,\n    0xbb67ae85,\n    0x3c6ef372,\n    0xa54ff53a,\n    0x510e527f,\n    0x9b05688c,\n    0x1f83d9ab,\n    0x5be0cd19,\n]);\n/** Initial SHA384 state. Bits 0..64 of frac part of sqrt of primes 23..53 */\nexport const SHA384_IV = /* @__PURE__ */ Uint32Array.from([\n    0xcbbb9d5d,\n    0xc1059ed8,\n    0x629a292a,\n    0x367cd507,\n    0x9159015a,\n    0x3070dd17,\n    0x152fecd8,\n    0xf70e5939,\n    0x67332667,\n    0xffc00b31,\n    0x8eb44a87,\n    0x68581511,\n    0xdb0c2e0d,\n    0x64f98fa7,\n    0x47b5481d,\n    0xbefa4fa4,\n]);\n/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */\nexport const SHA512_IV = /* @__PURE__ */ Uint32Array.from([\n    0x6a09e667,\n    0xf3bcc908,\n    0xbb67ae85,\n    0x84caa73b,\n    0x3c6ef372,\n    0xfe94f82b,\n    0xa54ff53a,\n    0x5f1d36f1,\n    0x510e527f,\n    0xade682d1,\n    0x9b05688c,\n    0x2b3e6c1f,\n    0x1f83d9ab,\n    0xfb41bd6b,\n    0x5be0cd19,\n    0x137e2179,\n]);\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/2e0c00e1aa134082ba1380bf3afb8b1641f60fed/src/sha2.ts\n */\n/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out [RFC 4634](https://www.rfc-editor.org/rfc/rfc4634) and\n * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).\n * @module\n */\nimport { Chi, HashMD, Maj, SHA256_IV, SHA384_IV, SHA512_IV } from \"./md.js\";\nimport * as u64 from \"./u64.js\";\nimport { clean, oidNist, rotr } from \"../utils/noble.js\";\nimport { createHasher } from \"./hash.js\";\n/**\n * Round constants:\n * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)\n */\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n    0x428a2f98,\n    0x71374491,\n    0xb5c0fbcf,\n    0xe9b5dba5,\n    0x3956c25b,\n    0x59f111f1,\n    0x923f82a4,\n    0xab1c5ed5,\n    0xd807aa98,\n    0x12835b01,\n    0x243185be,\n    0x550c7dc3,\n    0x72be5d74,\n    0x80deb1fe,\n    0x9bdc06a7,\n    0xc19bf174,\n    0xe49b69c1,\n    0xefbe4786,\n    0x0fc19dc6,\n    0x240ca1cc,\n    0x2de92c6f,\n    0x4a7484aa,\n    0x5cb0a9dc,\n    0x76f988da,\n    0x983e5152,\n    0xa831c66d,\n    0xb00327c8,\n    0xbf597fc7,\n    0xc6e00bf3,\n    0xd5a79147,\n    0x06ca6351,\n    0x14292967,\n    0x27b70a85,\n    0x2e1b2138,\n    0x4d2c6dfc,\n    0x53380d13,\n    0x650a7354,\n    0x766a0abb,\n    0x81c2c92e,\n    0x92722c85,\n    0xa2bfe8a1,\n    0xa81a664b,\n    0xc24b8b70,\n    0xc76c51a3,\n    0xd192e819,\n    0xd6990624,\n    0xf40e3585,\n    0x106aa070,\n    0x19a4c116,\n    0x1e376c08,\n    0x2748774c,\n    0x34b0bcb5,\n    0x391c0cb3,\n    0x4ed8aa4a,\n    0x5b9cca4f,\n    0x682e6ff3,\n    0x748f82ee,\n    0x78a5636f,\n    0x84c87814,\n    0x8cc70208,\n    0x90befffa,\n    0xa4506ceb,\n    0xbef9a3f7,\n    0xc67178f2,\n]);\n/** Reusable temporary buffer. \"W\" comes straight from spec. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n/** Internal 32-byte base SHA2 hash class. */\nclass SHA2_32B extends HashMD {\n    constructor(outputLen) {\n        super(64, outputLen, 8, false);\n    }\n    get() {\n        const { A, B, C, D, E, F, G, H } = this;\n        return [A, B, C, D, E, F, G, H];\n    }\n    set(A, B, C, D, E, F, G, H) {\n        this.A = A | 0;\n        this.B = B | 0;\n        this.C = C | 0;\n        this.D = D | 0;\n        this.E = E | 0;\n        this.F = F | 0;\n        this.G = G | 0;\n        this.H = H | 0;\n    }\n    process(view, offset) {\n        // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n        for (let i = 0; i < 16; i++, offset += 4) {\n            SHA256_W[i] = view.getUint32(offset, false);\n        }\n        for (let i = 16; i < 64; i++) {\n            const W15 = SHA256_W[i - 15];\n            const W2 = SHA256_W[i - 2];\n            const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n            const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n            SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n        }\n        // Compression function main loop, 64 rounds\n        let { A, B, C, D, E, F, G, H } = this;\n        for (let i = 0; i < 64; i++) {\n            const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n            const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n            const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n            const T2 = (sigma0 + Maj(A, B, C)) | 0;\n            H = G;\n            G = F;\n            F = E;\n            E = (D + T1) | 0;\n            D = C;\n            C = B;\n            B = A;\n            A = (T1 + T2) | 0;\n        }\n        // Add the compressed chunk to the current hash value\n        A = (A + this.A) | 0;\n        B = (B + this.B) | 0;\n        C = (C + this.C) | 0;\n        D = (D + this.D) | 0;\n        E = (E + this.E) | 0;\n        F = (F + this.F) | 0;\n        G = (G + this.G) | 0;\n        H = (H + this.H) | 0;\n        this.set(A, B, C, D, E, F, G, H);\n    }\n    roundClean() {\n        clean(SHA256_W);\n    }\n    destroy() {\n        this.set(0, 0, 0, 0, 0, 0, 0, 0);\n        clean(this.buffer);\n    }\n}\n/** Internal SHA2-256 hash class. */\nexport class _SHA256 extends SHA2_32B {\n    constructor() {\n        super(32);\n        // We cannot use array here since array allows indexing by variable\n        // which means optimizer/compiler cannot use registers.\n        Object.defineProperty(this, \"A\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[0] | 0\n        });\n        Object.defineProperty(this, \"B\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[1] | 0\n        });\n        Object.defineProperty(this, \"C\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[2] | 0\n        });\n        Object.defineProperty(this, \"D\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[3] | 0\n        });\n        Object.defineProperty(this, \"E\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[4] | 0\n        });\n        Object.defineProperty(this, \"F\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[5] | 0\n        });\n        Object.defineProperty(this, \"G\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[6] | 0\n        });\n        Object.defineProperty(this, \"H\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA256_IV[7] | 0\n        });\n    }\n}\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n// Round contants\n// First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409\nconst K512 = /* @__PURE__ */ (() => u64.split([\n    0x428a2f98d728ae22n,\n    0x7137449123ef65cdn,\n    0xb5c0fbcfec4d3b2fn,\n    0xe9b5dba58189dbbcn,\n    0x3956c25bf348b538n,\n    0x59f111f1b605d019n,\n    0x923f82a4af194f9bn,\n    0xab1c5ed5da6d8118n,\n    0xd807aa98a3030242n,\n    0x12835b0145706fben,\n    0x243185be4ee4b28cn,\n    0x550c7dc3d5ffb4e2n,\n    0x72be5d74f27b896fn,\n    0x80deb1fe3b1696b1n,\n    0x9bdc06a725c71235n,\n    0xc19bf174cf692694n,\n    0xe49b69c19ef14ad2n,\n    0xefbe4786384f25e3n,\n    0x0fc19dc68b8cd5b5n,\n    0x240ca1cc77ac9c65n,\n    0x2de92c6f592b0275n,\n    0x4a7484aa6ea6e483n,\n    0x5cb0a9dcbd41fbd4n,\n    0x76f988da831153b5n,\n    0x983e5152ee66dfabn,\n    0xa831c66d2db43210n,\n    0xb00327c898fb213fn,\n    0xbf597fc7beef0ee4n,\n    0xc6e00bf33da88fc2n,\n    0xd5a79147930aa725n,\n    0x06ca6351e003826fn,\n    0x142929670a0e6e70n,\n    0x27b70a8546d22ffcn,\n    0x2e1b21385c26c926n,\n    0x4d2c6dfc5ac42aedn,\n    0x53380d139d95b3dfn,\n    0x650a73548baf63den,\n    0x766a0abb3c77b2a8n,\n    0x81c2c92e47edaee6n,\n    0x92722c851482353bn,\n    0xa2bfe8a14cf10364n,\n    0xa81a664bbc423001n,\n    0xc24b8b70d0f89791n,\n    0xc76c51a30654be30n,\n    0xd192e819d6ef5218n,\n    0xd69906245565a910n,\n    0xf40e35855771202an,\n    0x106aa07032bbd1b8n,\n    0x19a4c116b8d2d0c8n,\n    0x1e376c085141ab53n,\n    0x2748774cdf8eeb99n,\n    0x34b0bcb5e19b48a8n,\n    0x391c0cb3c5c95a63n,\n    0x4ed8aa4ae3418acbn,\n    0x5b9cca4f7763e373n,\n    0x682e6ff3d6b2b8a3n,\n    0x748f82ee5defb2fcn,\n    0x78a5636f43172f60n,\n    0x84c87814a1f0ab72n,\n    0x8cc702081a6439ecn,\n    0x90befffa23631e28n,\n    0xa4506cebde82bde9n,\n    0xbef9a3f7b2c67915n,\n    0xc67178f2e372532bn,\n    0xca273eceea26619cn,\n    0xd186b8c721c0c207n,\n    0xeada7dd6cde0eb1en,\n    0xf57d4f7fee6ed178n,\n    0x06f067aa72176fban,\n    0x0a637dc5a2c898a6n,\n    0x113f9804bef90daen,\n    0x1b710b35131c471bn,\n    0x28db77f523047d84n,\n    0x32caab7b40c72493n,\n    0x3c9ebe0a15c9bebcn,\n    0x431d67c49c100d4cn,\n    0x4cc5d4becb3e42b6n,\n    0x597f299cfc657e2an,\n    0x5fcb6fab3ad6faecn,\n    0x6c44198c4a475817n,\n]))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n// Reusable temporary buffers\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n/** Internal 64-byte base SHA2 hash class. */\nclass SHA2_64B extends HashMD {\n    constructor(outputLen) {\n        super(128, outputLen, 16, false);\n    }\n    get() {\n        const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n        return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n    }\n    set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {\n        this.Ah = Ah | 0;\n        this.Al = Al | 0;\n        this.Bh = Bh | 0;\n        this.Bl = Bl | 0;\n        this.Ch = Ch | 0;\n        this.Cl = Cl | 0;\n        this.Dh = Dh | 0;\n        this.Dl = Dl | 0;\n        this.Eh = Eh | 0;\n        this.El = El | 0;\n        this.Fh = Fh | 0;\n        this.Fl = Fl | 0;\n        this.Gh = Gh | 0;\n        this.Gl = Gl | 0;\n        this.Hh = Hh | 0;\n        this.Hl = Hl | 0;\n    }\n    process(view, offset) {\n        // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n        for (let i = 0; i < 16; i++, offset += 4) {\n            SHA512_W_H[i] = view.getUint32(offset);\n            SHA512_W_L[i] = view.getUint32(offset += 4);\n        }\n        for (let i = 16; i < 80; i++) {\n            // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n            const W15h = SHA512_W_H[i - 15] | 0;\n            const W15l = SHA512_W_L[i - 15] | 0;\n            const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^\n                u64.shrSH(W15h, W15l, 7);\n            const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^\n                u64.shrSL(W15h, W15l, 7);\n            // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n            const W2h = SHA512_W_H[i - 2] | 0;\n            const W2l = SHA512_W_L[i - 2] | 0;\n            const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^\n                u64.shrSH(W2h, W2l, 6);\n            const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^\n                u64.shrSL(W2h, W2l, 6);\n            // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];\n            const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n            const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n            SHA512_W_H[i] = SUMh | 0;\n            SHA512_W_L[i] = SUMl | 0;\n        }\n        let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n        // Compression function main loop, 80 rounds\n        for (let i = 0; i < 80; i++) {\n            // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n            const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^\n                u64.rotrBH(Eh, El, 41);\n            const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^\n                u64.rotrBL(Eh, El, 41);\n            //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n            const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n            const CHIl = (El & Fl) ^ (~El & Gl);\n            // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n            const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n            const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n            const T1l = T1ll | 0;\n            // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n            const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^\n                u64.rotrBH(Ah, Al, 39);\n            const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^\n                u64.rotrBL(Ah, Al, 39);\n            const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n            const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n            Hh = Gh | 0;\n            Hl = Gl | 0;\n            Gh = Fh | 0;\n            Gl = Fl | 0;\n            Fh = Eh | 0;\n            Fl = El | 0;\n            ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n            Dh = Ch | 0;\n            Dl = Cl | 0;\n            Ch = Bh | 0;\n            Cl = Bl | 0;\n            Bh = Ah | 0;\n            Bl = Al | 0;\n            const All = u64.add3L(T1l, sigma0l, MAJl);\n            Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n            Al = All | 0;\n        }\n        // Add the compressed chunk to the current hash value\n        ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n        ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n        ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n        ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n        ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n        ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n        ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n        ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n        this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n    }\n    roundClean() {\n        clean(SHA512_W_H, SHA512_W_L);\n    }\n    destroy() {\n        clean(this.buffer);\n        this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n    }\n}\n/** Internal SHA2-512 hash class. */\nexport class _SHA512 extends SHA2_64B {\n    constructor() {\n        super(64);\n        Object.defineProperty(this, \"Ah\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[0] | 0\n        });\n        Object.defineProperty(this, \"Al\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[1] | 0\n        });\n        Object.defineProperty(this, \"Bh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[2] | 0\n        });\n        Object.defineProperty(this, \"Bl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[3] | 0\n        });\n        Object.defineProperty(this, \"Ch\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[4] | 0\n        });\n        Object.defineProperty(this, \"Cl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[5] | 0\n        });\n        Object.defineProperty(this, \"Dh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[6] | 0\n        });\n        Object.defineProperty(this, \"Dl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[7] | 0\n        });\n        Object.defineProperty(this, \"Eh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[8] | 0\n        });\n        Object.defineProperty(this, \"El\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[9] | 0\n        });\n        Object.defineProperty(this, \"Fh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[10] | 0\n        });\n        Object.defineProperty(this, \"Fl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[11] | 0\n        });\n        Object.defineProperty(this, \"Gh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[12] | 0\n        });\n        Object.defineProperty(this, \"Gl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[13] | 0\n        });\n        Object.defineProperty(this, \"Hh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[14] | 0\n        });\n        Object.defineProperty(this, \"Hl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA512_IV[15] | 0\n        });\n    }\n}\nexport class _SHA384 extends SHA2_64B {\n    constructor() {\n        super(48);\n        Object.defineProperty(this, \"Ah\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[0] | 0\n        });\n        Object.defineProperty(this, \"Al\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[1] | 0\n        });\n        Object.defineProperty(this, \"Bh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[2] | 0\n        });\n        Object.defineProperty(this, \"Bl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[3] | 0\n        });\n        Object.defineProperty(this, \"Ch\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[4] | 0\n        });\n        Object.defineProperty(this, \"Cl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[5] | 0\n        });\n        Object.defineProperty(this, \"Dh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[6] | 0\n        });\n        Object.defineProperty(this, \"Dl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[7] | 0\n        });\n        Object.defineProperty(this, \"Eh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[8] | 0\n        });\n        Object.defineProperty(this, \"El\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[9] | 0\n        });\n        Object.defineProperty(this, \"Fh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[10] | 0\n        });\n        Object.defineProperty(this, \"Fl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[11] | 0\n        });\n        Object.defineProperty(this, \"Gh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[12] | 0\n        });\n        Object.defineProperty(this, \"Gl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[13] | 0\n        });\n        Object.defineProperty(this, \"Hh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[14] | 0\n        });\n        Object.defineProperty(this, \"Hl\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: SHA384_IV[15] | 0\n        });\n    }\n}\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n */\nexport const sha256 = /* @__PURE__ */ createHasher(() => new _SHA256(), \n/* @__PURE__ */ oidNist(0x01));\n/** SHA2-512 hash function from RFC 4634. */\nexport const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(), \n/* @__PURE__ */ oidNist(0x03));\n/** SHA2-384 hash function from RFC 4634. */\nexport const sha384 = /* @__PURE__ */ createHasher(() => new _SHA384(), \n/* @__PURE__ */ oidNist(0x02));\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-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/abstract/modular.ts\n */\n/**\n * Utils for modular division and fields.\n * Field over 11 is a finite (Galois) field is integer number operations `mod 11`.\n * There is no division: it is replaced by modular multiplicative inverse.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { N_0 } from \"../consts.js\";\n// Numbers aren't used in x25519 / x448 builds\n// Calculates a modulo b\nexport function mod(a, b) {\n    const result = a % b;\n    return result >= N_0 ? result : b + result;\n}\n/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */\nexport function pow2(x, power, modulo) {\n    let res = x;\n    while (power-- > N_0) {\n        res *= res;\n        res %= modulo;\n    }\n    return res;\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/abstract/curve.ts\n */\nexport function createKeygen(\n// deno-lint-ignore ban-types\nrandomSecretKey, getPublicKey) {\n    return function keygen(seed) {\n        const secretKey = randomSecretKey(seed);\n        return { secretKey, publicKey: getPublicKey(secretKey) };\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/abstract/montgomery.ts\n */\n/**\n * Montgomery curve methods. It's not really whole montgomery curve,\n * just bunch of very specific methods for X25519 / X448 from\n * [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748)\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { abytes, aInRange, bytesToNumberLE, copyBytes, numberToBytesLE, randomBytesAsync, validateObject, } from \"../utils/noble.js\";\nimport { createKeygen } from \"./curve.js\";\nimport { mod } from \"./modular.js\";\nimport { N_0, N_1, N_2 } from \"../consts.js\";\nfunction validateOpts(curve) {\n    validateObject(curve, {\n        adjustScalarBytes: \"function\",\n        powPminus2: \"function\",\n    });\n    return Object.freeze({ ...curve });\n}\nexport function montgomery(curveDef) {\n    const CURVE = validateOpts(curveDef);\n    const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE;\n    const is25519 = type === \"x25519\";\n    if (!is25519 && type !== \"x448\")\n        throw new Error(\"invalid type\");\n    const randomBytes_ = rand || randomBytesAsync;\n    const montgomeryBits = is25519 ? 255n : 448n;\n    const fieldLen = is25519 ? 32 : 56;\n    const Gu = is25519 ? 9n : 5n;\n    // RFC 7748 #5:\n    // The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519 and\n    // (156326 - 2) / 4 = 39081 for curve448/X448\n    // const a = is25519 ? 156326n : 486662n;\n    const a24 = is25519 ? 121665n : 39081n;\n    // RFC: x25519 \"the resulting integer is of the form 2^254 plus\n    // eight times a value between 0 and 2^251 - 1 (inclusive)\"\n    // x448: \"2^447 plus four times a value between 0 and 2^445 - 1 (inclusive)\"\n    const minScalar = is25519 ? N_2 ** 254n : N_2 ** 447n;\n    const maxAdded = is25519 ? 8n * N_2 ** 251n - N_1 : 4n * N_2 ** 445n - N_1;\n    const maxScalar = minScalar + maxAdded + N_1; // (inclusive)\n    const modP = (n) => mod(n, P);\n    const GuBytes = encodeU(Gu);\n    function encodeU(u) {\n        return numberToBytesLE(modP(u), fieldLen);\n    }\n    function decodeU(u) {\n        const _u = copyBytes(abytes(u, fieldLen, \"uCoordinate\"));\n        // RFC: When receiving such an array, implementations of X25519\n        // (but not X448) MUST mask the most significant bit in the final byte.\n        if (is25519)\n            _u[31] &= 127; // 0b0111_1111\n        // RFC: Implementations MUST accept non-canonical values and process them as\n        // if they had been reduced modulo the field prime.  The non-canonical\n        // values are 2^255 - 19 through 2^255 - 1 for X25519 and 2^448 - 2^224\n        // - 1 through 2^448 - 1 for X448.\n        return modP(bytesToNumberLE(_u));\n    }\n    function decodeScalar(scalar) {\n        return bytesToNumberLE(adjustScalarBytes(copyBytes(abytes(scalar, fieldLen, \"scalar\"))));\n    }\n    function scalarMult(scalar, u) {\n        const pu = montgomeryLadder(decodeU(u), decodeScalar(scalar));\n        // Some public keys are useless, of low-order. Curve author doesn't think\n        // it needs to be validated, but we do it nonetheless.\n        // https://cr.yp.to/ecdh.html#validate\n        if (pu === N_0)\n            throw new Error(\"invalid private or public key received\");\n        return encodeU(pu);\n    }\n    // Computes public key from private. By doing scalar multiplication of base point.\n    function scalarMultBase(scalar) {\n        return scalarMult(scalar, GuBytes);\n    }\n    const getPublicKey = scalarMultBase;\n    const getSharedSecret = scalarMult;\n    // cswap from RFC7748 \"example code\"\n    function cswap(swap, x_2, x_3) {\n        // dummy = mask(swap) AND (x_2 XOR x_3)\n        // Where mask(swap) is the all-1 or all-0 word of the same length as x_2\n        // and x_3, computed, e.g., as mask(swap) = 0 - swap.\n        const dummy = modP(swap * (x_2 - x_3));\n        x_2 = modP(x_2 - dummy); // x_2 = x_2 XOR dummy\n        x_3 = modP(x_3 + dummy); // x_3 = x_3 XOR dummy\n        return { x_2, x_3 };\n    }\n    /**\n     * Montgomery x-only multiplication ladder.\n     * @param pointU u coordinate (x) on Montgomery Curve 25519\n     * @param scalar by which the point would be multiplied\n     * @returns new Point on Montgomery curve\n     */\n    function montgomeryLadder(u, scalar) {\n        aInRange(\"u\", u, N_0, P);\n        aInRange(\"scalar\", scalar, minScalar, maxScalar);\n        const k = scalar;\n        const x_1 = u;\n        let x_2 = N_1;\n        let z_2 = N_0;\n        let x_3 = u;\n        let z_3 = N_1;\n        let swap = N_0;\n        for (let t = montgomeryBits - 1n; t >= N_0; t--) {\n            const k_t = (k >> t) & N_1;\n            swap ^= k_t;\n            ({ x_2, x_3 } = cswap(swap, x_2, x_3));\n            ({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3));\n            swap = k_t;\n            const A = x_2 + z_2;\n            const AA = modP(A * A);\n            const B = x_2 - z_2;\n            const BB = modP(B * B);\n            const E = AA - BB;\n            const C = x_3 + z_3;\n            const D = x_3 - z_3;\n            const DA = modP(D * A);\n            const CB = modP(C * B);\n            const dacb = DA + CB;\n            const da_cb = DA - CB;\n            x_3 = modP(dacb * dacb);\n            z_3 = modP(x_1 * modP(da_cb * da_cb));\n            x_2 = modP(AA * BB);\n            z_2 = modP(E * (AA + modP(a24 * E)));\n        }\n        ({ x_2, x_3 } = cswap(swap, x_2, x_3));\n        ({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3));\n        const z2 = powPminus2(z_2); // `Fp.pow(x, P - N_2)` is much slower equivalent\n        return modP(x_2 * z2); // Return x_2 * (z_2^(p - 2))\n    }\n    const lengths = {\n        secretKey: fieldLen,\n        publicKey: fieldLen,\n        seed: fieldLen,\n    };\n    const randomSecretKey = async (seed) => {\n        if (seed === undefined) {\n            seed = await randomBytes_(fieldLen);\n        }\n        abytes(seed, lengths.seed, \"seed\");\n        return seed;\n    };\n    const utils = { randomSecretKey };\n    return Object.freeze({\n        keygen: createKeygen(randomSecretKey, getPublicKey),\n        getSharedSecret,\n        getPublicKey,\n        scalarMult,\n        scalarMultBase,\n        utils,\n        GuBytes: GuBytes.slice(),\n        lengths,\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/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 { chacha20poly1305 } from \"./chacha/chacha.js\";\nimport { AeadId, toArrayBuffer } from \"@hpke/common\";\nexport class Chacha20Poly1305Context {\n    constructor(key) {\n        Object.defineProperty(this, \"_key\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this._key = new Uint8Array(toArrayBuffer(key));\n    }\n    async seal(iv, data, aad) {\n        return await this._seal(toArrayBuffer(iv), toArrayBuffer(data), toArrayBuffer(aad));\n    }\n    async open(iv, data, aad) {\n        return await this._open(toArrayBuffer(iv), toArrayBuffer(data), toArrayBuffer(aad));\n    }\n    _seal(iv, data, aad) {\n        return new Promise((resolve) => {\n            const ret = chacha20poly1305(this._key, new Uint8Array(iv), new Uint8Array(aad)).encrypt(new Uint8Array(data));\n            resolve(ret.buffer);\n        });\n    }\n    _open(iv, data, aad) {\n        return new Promise((resolve) => {\n            const ret = chacha20poly1305(this._key, new Uint8Array(iv), new Uint8Array(aad)).decrypt(new Uint8Array(data));\n            resolve(ret.buffer);\n        });\n    }\n}\n/**\n * The ChaCha20Poly1305 for HPKE AEAD implementing {@link AeadInterface}.\n *\n * When using `@hpke/core`, the instance of this class can be specified\n * to the `aead` parameter of {@link CipherSuiteParams} instead of `AeadId.Chacha20Poly1305`\n * as follows:\n *\n * @example\n *\n * ```ts\n * import {\n *   CipherSuite,\n *   DhkemP256HkdfSha256,\n *   HkdfSha256,\n * } from \"@hpke/core\";\n * import {\n *   Chacha20Poly1305,\n * } from \"@hpke/chacha20poly1305\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP256HkdfSha256(),\n *   kdf: new HkdfSha256(),\n *   aead: new Chacha20Poly1305(),\n * });\n * ```\n *\n * This class is implemented using\n * {@link https://github.com/paulmillr/noble-ciphers | @noble/ciphers}.\n */\nexport class Chacha20Poly1305 {\n    constructor() {\n        /** AeadId.Chacha20Poly1305 (0x0003) */\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: AeadId.Chacha20Poly1305\n        });\n        /** 32 */\n        Object.defineProperty(this, \"keySize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n        /** 12 */\n        Object.defineProperty(this, \"nonceSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 12\n        });\n        /** 16 */\n        Object.defineProperty(this, \"tagSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 16\n        });\n    }\n    createEncryptionContext(key) {\n        return new Chacha20Poly1305Context(key);\n    }\n}\n","import { NotSupportedError } from \"@hpke/common\";\nexport function emitNotSupported() {\n    return new Promise((_resolve, reject) => {\n        reject(new NotSupportedError(\"Not supported\"));\n    });\n}\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","import { i2Osp, MessageLimitReachedError, xor } from \"@hpke/common\";\nimport { ExporterContextImpl } from \"./exporterContext.js\";\nexport class EncryptionContextImpl extends ExporterContextImpl {\n    constructor(api, kdf, params) {\n        super(api, kdf, params.exporterSecret);\n        // AEAD id.\n        Object.defineProperty(this, \"_aead\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // The length in bytes of a key for the algorithm.\n        Object.defineProperty(this, \"_nK\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // The length in bytes of a nonce for the algorithm.\n        Object.defineProperty(this, \"_nN\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // The length in bytes of an authentication tag for the algorithm.\n        Object.defineProperty(this, \"_nT\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // The end-to-end encryption key information.\n        Object.defineProperty(this, \"_ctx\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        if (params.key === undefined || params.baseNonce === undefined ||\n            params.seq === undefined) {\n            throw new Error(\"Required parameters are missing\");\n        }\n        this._aead = params.aead;\n        this._nK = this._aead.keySize;\n        this._nN = this._aead.nonceSize;\n        this._nT = this._aead.tagSize;\n        const key = this._aead.createEncryptionContext(params.key);\n        this._ctx = {\n            key: key,\n            baseNonce: params.baseNonce,\n            seq: params.seq,\n        };\n    }\n    computeNonce(k) {\n        const seqBytes = i2Osp(k.seq, k.baseNonce.byteLength);\n        return xor(k.baseNonce, seqBytes).buffer;\n    }\n    incrementSeq(k) {\n        // if (this.seq >= (1 << (8 * this.baseNonce.byteLength)) - 1) {\n        if (k.seq > Number.MAX_SAFE_INTEGER) {\n            throw new MessageLimitReachedError(\"Message limit reached\");\n        }\n        k.seq += 1;\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 { HkdfSha256Native, HkdfSha384Native, HkdfSha512Native, } from \"@hpke/common\";\nimport { CipherSuiteNative } from \"./cipherSuiteNative.js\";\nimport { DhkemP256HkdfSha256Native, DhkemP384HkdfSha384Native, DhkemP521HkdfSha512Native, } from \"./kems/dhkemNative.js\";\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 class is the same as\n * {@link https://jsr.io/@hpke/core/doc/~/CipherSuiteNative | @hpke/core#CipherSuiteNative} 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(X448, HKDF-SHA512)`\n * - `ChaCha20Poly1305`\n *\n * In addtion, the HKDF functions contained in this `CipherSuiteNative`\n * class can only derive 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 https://jsr.io/@hpke/hpke-js/doc/~/CipherSuite | hpke-js#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 DHKEM(X25519, HKDF-SHA256).\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   DhkemX25519HkdfSha256,\n *   HkdfSha256,\n * } from \"@hpke/core\";\n * const suite = new CipherSuite({\n *   kem: new DhkemX25519HkdfSha256(),\n *   kdf: new HkdfSha256(),\n *   aead: new Aes128Gcm(),\n * });\n * ```\n */\nexport class CipherSuite extends CipherSuiteNative {\n}\n/**\n * The DHKEM(P-256, HKDF-SHA256) for HPKE KEM implementing {@link KemInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KemId.DhkemP256HkdfSha256`\n * as follows:\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   DhkemP256HkdfSha256,\n *   HkdfSha256,\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 */\nexport class DhkemP256HkdfSha256 extends DhkemP256HkdfSha256Native {\n}\n/**\n * The DHKEM(P-384, HKDF-SHA384) for HPKE KEM implementing {@link KemInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KemId.DhkemP384HkdfSha384`\n * as follows:\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   DhkemP384HkdfSha384,\n *   HkdfSha384,\n * } from \"@hpke/core\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP384HkdfSha384(),\n *   kdf: new HkdfSha384(),\n *   aead: new Aes128Gcm(),\n * });\n * ```\n */\nexport class DhkemP384HkdfSha384 extends DhkemP384HkdfSha384Native {\n}\n/**\n * The DHKEM(P-521, HKDF-SHA512) for HPKE KEM implementing {@link KemInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KemId.DhkemP521HkdfSha512`\n * as follows:\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes256Gcm,\n *   CipherSuite,\n *   DhkemP521HkdfSha512,\n *   HkdfSha512,\n * } from \"@hpke/core\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP521HkdfSha512(),\n *   kdf: new HkdfSha512(),\n *   aead: new Aes256Gcm(),\n * });\n * ```\n */\nexport class DhkemP521HkdfSha512 extends DhkemP521HkdfSha512Native {\n}\n/**\n * The HKDF-SHA256 for HPKE KDF implementing {@link KdfInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KdfId.HkdfSha256`.\n *\n * The KDF class can only derive keys of the same length as the `hashSize`.\n * If you want to derive keys longer than the `hashSize`,\n * please use {@link https://jsr.io/@hpke/hpke-js/doc/~/CipherSuite | hpke-js#CipherSuite}.\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   DhkemP256HkdfSha256,\n *   HkdfSha256,\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 */\nexport class HkdfSha256 extends HkdfSha256Native {\n}\n/**\n * The HKDF-SHA384 for HPKE KDF implementing {@link KdfInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KdfId.HkdfSha384`.\n *\n * The KDF class can only derive keys of the same length as the `hashSize`.\n * If you want to derive keys longer than the `hashSize`,\n * please use {@link https://jsr.io/@hpke/hpke-js/doc/~/CipherSuite | hpke-js#CipherSuite}.\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   DhkemP384HkdfSha384,\n *   HkdfSha384,\n * } from \"@hpke/core\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP384HkdfSha384(),\n *   kdf: new HkdfSha384(),\n *   aead: new Aes128Gcm(),\n * });\n * ```\n */\nexport class HkdfSha384 extends HkdfSha384Native {\n}\n/**\n * The HKDF-SHA512 for HPKE KDF implementing {@link KdfInterface}.\n *\n * When using `@hpke/core`, the instance of this class must be specified\n * to the `kem` parameter of {@link CipherSuiteParams} instead of `KdfId.HkdfSha512`.\n *\n * The KDF class can only derive keys of the same length as the `hashSize`.\n * If you want to derive keys longer than the `hashSize`,\n * please use {@link https://jsr.io/@hpke/hpke-js/doc/~/CipherSuite | hpke-js#CipherSuite}.\n *\n * @example\n *\n * ```ts\n * import {\n *   Aes256Gcm,\n *   CipherSuite,\n *   DhkemP521HkdfSha512,\n *   HkdfSha512,\n * } from \"@hpke/core\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP521HkdfSha512(),\n *   kdf: new HkdfSha512(),\n *   aead: new Aes256Gcm(),\n * });\n * ```\n */\nexport class HkdfSha512 extends HkdfSha512Native {\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","/**\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/ed25519.ts\n */\n/**\n * ed25519 Twisted Edwards curve with following addons:\n * - X25519 ECDH\n * - Ristretto cofactor elimination\n * - Elligator hash-to-group / point indistinguishability\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { mod, montgomery, pow2 } from \"@hpke/common\";\nconst _1n = 1n;\nconst _2n = 2n;\nconst _3n = 3n;\nconst _5n = 5n;\n// P = 2n**255n - 19n\nconst ed25519_CURVE_p = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn;\nfunction ed25519_pow_2_252_3(x) {\n    const _10n = 10n;\n    const _20n = 20n;\n    const _40n = 40n;\n    const _80n = 80n;\n    const P = ed25519_CURVE_p;\n    const x2 = (x * x) % P;\n    const b2 = (x2 * x) % P; // x^3, 11\n    const b4 = (pow2(b2, _2n, P) * b2) % P; // x^15, 1111\n    const b5 = (pow2(b4, _1n, P) * x) % P; // x^31\n    const b10 = (pow2(b5, _5n, P) * b5) % P;\n    const b20 = (pow2(b10, _10n, P) * b10) % P;\n    const b40 = (pow2(b20, _20n, P) * b20) % P;\n    const b80 = (pow2(b40, _40n, P) * b40) % P;\n    const b160 = (pow2(b80, _80n, P) * b80) % P;\n    const b240 = (pow2(b160, _80n, P) * b80) % P;\n    const b250 = (pow2(b240, _10n, P) * b10) % P;\n    const pow_p_5_8 = (pow2(b250, _2n, P) * x) % P;\n    // ^ To pow to (p+3)/8, multiply it by x.\n    return { pow_p_5_8, b2 };\n}\nfunction adjustScalarBytes(bytes) {\n    // Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,\n    // set the three least significant bits of the first byte\n    bytes[0] &= 248; // 0b1111_1000\n    // and the most significant bit of the last to zero,\n    bytes[31] &= 127; // 0b0111_1111\n    // set the second most significant bit of the last byte to 1\n    bytes[31] |= 64; // 0b0100_0000\n    return bytes;\n}\nexport const x25519 = /* @__PURE__ */ (() => {\n    const P = ed25519_CURVE_p;\n    return montgomery({\n        P,\n        type: \"x25519\",\n        powPminus2: (x) => {\n            // x^(p-2) aka x^(2^255-21)\n            const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);\n            return mod(pow2(pow_p_5_8, _3n, P) * b2, P);\n        },\n        adjustScalarBytes,\n    });\n})();\n","import { HkdfSha256Native, hmac, sha256, toArrayBuffer } from \"@hpke/common\";\nexport class HkdfSha256 extends HkdfSha256Native {\n    async extract(salt, ikm) {\n        await this._setup();\n        const saltBuf = salt.byteLength === 0\n            ? new ArrayBuffer(this.hashSize)\n            : toArrayBuffer(salt);\n        const ikmBuf = toArrayBuffer(ikm);\n        if (saltBuf.byteLength !== this.hashSize) {\n            return hmac(sha256, new Uint8Array(saltBuf), new Uint8Array(ikmBuf))\n                .buffer;\n        }\n        const key = await this._api.importKey(\"raw\", saltBuf, this.algHash, false, [\n            \"sign\",\n        ]);\n        return await this._api.sign(\"HMAC\", key, ikmBuf);\n    }\n}\n","import { Dhkem, KemId, SerializeError, XCurveDhkemPrimitives, } from \"@hpke/common\";\nimport { x25519 } from \"./primitives/x25519.js\";\nimport { HkdfSha256 } from \"./hkdfSha256.js\";\nexport class X25519 extends XCurveDhkemPrimitives {\n    constructor(hkdf) {\n        super(\"X25519\", 32, x25519, hkdf);\n    }\n    derive(sk, pk) {\n        try {\n            return Promise.resolve(this._curve.getSharedSecret(sk, pk));\n        }\n        catch (e) {\n            return Promise.reject(new SerializeError(e));\n        }\n    }\n}\n/**\n * The DHKEM(X25519, HKDF-SHA256) for HPKE KEM implementing {@link KemInterface}.\n *\n * This class is implemented using\n * {@link https://github.com/paulmillr/noble-curves | @noble/curves}.\n *\n * The instance of this class can be specified to the\n * {@link https://jsr.io/@hpke/core/doc/~/CipherSuiteParams | CipherSuiteParams} as follows:\n *\n * @example Use with `@hpke/core`:\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   CipherSuite,\n *   HkdfSha256,\n * } from \"@hpke/core\";\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 DhkemX25519HkdfSha256 extends Dhkem {\n    constructor() {\n        const kdf = new HkdfSha256();\n        super(KemId.DhkemX25519HkdfSha256, new X25519(kdf), kdf);\n        /** KemId.DhkemX25519HkdfSha256 (0x0020) */\n        Object.defineProperty(this, \"id\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: KemId.DhkemX25519HkdfSha256\n        });\n        /** 32 */\n        Object.defineProperty(this, \"secretSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n        /** 32 */\n        Object.defineProperty(this, \"encSize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n        /** 32 */\n        Object.defineProperty(this, \"publicKeySize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n        /** 32 */\n        Object.defineProperty(this, \"privateKeySize\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 32\n        });\n    }\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n  return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number): void {\n  if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(b: Uint8Array | undefined, ...lengths: number[]): void {\n  if (!isBytes(b)) throw new Error('Uint8Array expected');\n  if (lengths.length > 0 && !lengths.includes(b.length))\n    throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);\n}\n\n/** Asserts something is hash */\nexport function ahash(h: IHash): void {\n  if (typeof h !== 'function' || typeof h.create !== 'function')\n    throw new Error('Hash should be wrapped by utils.createHasher');\n  anumber(h.outputLen);\n  anumber(h.blockLen);\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n  if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n  if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n  abytes(out);\n  const min = instance.outputLen;\n  if (out.length < min) {\n    throw new Error('digestInto() expects output buffer of length at least ' + min);\n  }\n}\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n  Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n  return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n  return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n  for (let i = 0; i < arrays.length; i++) {\n    arrays[i].fill(0);\n  }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n  return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n  return (word << (32 - shift)) | (word >>> shift);\n}\n\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n  return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n  new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/** The byte swap operation for uint32 */\nexport function byteSwap(word: number): number {\n  return (\n    ((word << 24) & 0xff000000) |\n    ((word << 8) & 0xff0000) |\n    ((word >>> 8) & 0xff00) |\n    ((word >>> 24) & 0xff)\n  );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const swap8IfBE: (n: number) => number = isLE\n  ? (n: number) => n\n  : (n: number) => byteSwap(n);\n\n/** @deprecated */\nexport const byteSwapIfBE: typeof swap8IfBE = swap8IfBE;\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): Uint32Array {\n  for (let i = 0; i < arr.length; i++) {\n    arr[i] = byteSwap(arr[i]);\n  }\n  return arr;\n}\n\nexport const swap32IfBE: (u: Uint32Array) => Uint32Array = isLE\n  ? (u: Uint32Array) => u\n  : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n  // @ts-ignore\n  typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n  i.toString(16).padStart(2, '0')\n);\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: Uint8Array): string {\n  abytes(bytes);\n  // @ts-ignore\n  if (hasHexBuiltin) 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\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 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n  if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n  if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n  if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n  return;\n}\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: string): Uint8Array {\n  if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n  // @ts-ignore\n  if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n  const hl = hex.length;\n  const al = hl / 2;\n  if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\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 ' + 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/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n  iters: number,\n  tick: number,\n  cb: (i: number) => void\n): Promise<void> {\n  let ts = Date.now();\n  for (let i = 0; i < iters; i++) {\n    cb(i);\n    // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n    const diff = Date.now() - ts;\n    if (diff >= 0 && diff < tick) continue;\n    await nextTick();\n    ts += diff;\n  }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n  if (typeof str !== 'string') throw new Error('string expected');\n  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes: Uint8Array): string {\n  return new TextDecoder().decode(bytes);\n}\n\n/** Accepted input of hash functions. Strings are converted to byte arrays. */\nexport type Input = string | Uint8Array;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n  if (typeof data === 'string') data = utf8ToBytes(data);\n  abytes(data);\n  return data;\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n/**\n * Helper for KDFs: consumes uint8array or string.\n * When string is passed, does utf8 decoding, using TextDecoder.\n */\nexport function kdfInputToBytes(data: KDFInput): Uint8Array {\n  if (typeof data === 'string') data = utf8ToBytes(data);\n  abytes(data);\n  return data;\n}\n\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\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\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n  defaults: T1,\n  opts?: T2\n): T1 & T2 {\n  if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n    throw new Error('options should be object or undefined');\n  const merged = Object.assign(defaults, opts);\n  return merged as T1 & T2;\n}\n\n/** Hash interface. */\nexport type IHash = {\n  (data: Uint8Array): Uint8Array;\n  blockLen: number;\n  outputLen: number;\n  create: any;\n};\n\n/** For runtime check if class implements interface */\nexport abstract class Hash<T extends Hash<T>> {\n  abstract blockLen: number; // Bytes per block\n  abstract outputLen: number; // Bytes in output\n  abstract update(buf: Input): this;\n  // Writes digest into buf\n  abstract digestInto(buf: Uint8Array): void;\n  abstract digest(): Uint8Array;\n  /**\n   * Resets internal state. Makes Hash instance unusable.\n   * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n   * by user, they will need to manually call `destroy()` when zeroing is necessary.\n   */\n  abstract destroy(): void;\n  /**\n   * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n   * when no options are passed.\n   * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n   * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n   * There are no guarantees for clean-up because it's impossible in JS.\n   */\n  abstract _cloneInto(to?: T): T;\n  // Safe version that clones internal state\n  abstract clone(): T;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n  xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n  xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\n/** Hash function */\nexport type CHash = ReturnType<typeof createHasher>;\n/** Hash function with output */\nexport type CHashO = ReturnType<typeof createOptHasher>;\n/** XOF with output */\nexport type CHashXO = ReturnType<typeof createXOFer>;\n\n/** Wraps hash function, creating an interface on top of it */\nexport function createHasher<T extends Hash<T>>(\n  hashCons: () => Hash<T>\n): {\n  (msg: Input): Uint8Array;\n  outputLen: number;\n  blockLen: number;\n  create(): Hash<T>;\n} {\n  const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n  const tmp = hashCons();\n  hashC.outputLen = tmp.outputLen;\n  hashC.blockLen = tmp.blockLen;\n  hashC.create = () => hashCons();\n  return hashC;\n}\n\nexport function createOptHasher<H extends Hash<H>, T extends Object>(\n  hashCons: (opts?: T) => Hash<H>\n): {\n  (msg: Input, opts?: T): Uint8Array;\n  outputLen: number;\n  blockLen: number;\n  create(opts?: T): Hash<H>;\n} {\n  const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n  const tmp = hashCons({} as T);\n  hashC.outputLen = tmp.outputLen;\n  hashC.blockLen = tmp.blockLen;\n  hashC.create = (opts?: T) => hashCons(opts);\n  return hashC;\n}\n\nexport function createXOFer<H extends HashXOF<H>, T extends Object>(\n  hashCons: (opts?: T) => HashXOF<H>\n): {\n  (msg: Input, opts?: T): Uint8Array;\n  outputLen: number;\n  blockLen: number;\n  create(opts?: T): HashXOF<H>;\n} {\n  const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n  const tmp = hashCons({} as T);\n  hashC.outputLen = tmp.outputLen;\n  hashC.blockLen = tmp.blockLen;\n  hashC.create = (opts?: T) => hashCons(opts);\n  return hashC;\n}\nexport const wrapConstructor: typeof createHasher = createHasher;\nexport const wrapConstructorWithOpts: typeof createOptHasher = createOptHasher;\nexport const wrapXOFConstructorWithOpts: typeof createXOFer = createXOFer;\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n  if (crypto && typeof crypto.getRandomValues === 'function') {\n    return crypto.getRandomValues(new Uint8Array(bytesLength));\n  }\n  // Legacy Node.js compatibility\n  if (crypto && typeof crypto.randomBytes === 'function') {\n    return Uint8Array.from(crypto.randomBytes(bytesLength));\n  }\n  throw new Error('crypto.getRandomValues must be defined');\n}\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport { type Input, Hash, abytes, aexists, aoutput, clean, createView, toBytes } from './utils.ts';\n\n/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */\nexport function setBigUint64(\n  view: DataView,\n  byteOffset: number,\n  value: bigint,\n  isLE: boolean\n): void {\n  if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);\n  const _32n = BigInt(32);\n  const _u32_max = BigInt(0xffffffff);\n  const wh = Number((value >> _32n) & _u32_max);\n  const wl = Number(value & _u32_max);\n  const h = isLE ? 4 : 0;\n  const l = isLE ? 0 : 4;\n  view.setUint32(byteOffset + h, wh, isLE);\n  view.setUint32(byteOffset + l, wl, isLE);\n}\n\n/** Choice: a ? b : c */\nexport function Chi(a: number, b: number, c: number): number {\n  return (a & b) ^ (~a & c);\n}\n\n/** Majority function, true if any two inputs is true. */\nexport function Maj(a: number, b: number, c: number): number {\n  return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n */\nexport abstract class HashMD<T extends HashMD<T>> extends Hash<T> {\n  protected abstract process(buf: DataView, offset: number): void;\n  protected abstract get(): number[];\n  protected abstract set(...args: number[]): void;\n  abstract destroy(): void;\n  protected abstract roundClean(): void;\n\n  readonly blockLen: number;\n  readonly outputLen: number;\n  readonly padOffset: number;\n  readonly isLE: boolean;\n\n  // For partial updates less than block size\n  protected buffer: Uint8Array;\n  protected view: DataView;\n  protected finished = false;\n  protected length = 0;\n  protected pos = 0;\n  protected destroyed = false;\n\n  constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n    super();\n    this.blockLen = blockLen;\n    this.outputLen = outputLen;\n    this.padOffset = padOffset;\n    this.isLE = isLE;\n    this.buffer = new Uint8Array(blockLen);\n    this.view = createView(this.buffer);\n  }\n  update(data: Input): this {\n    aexists(this);\n    data = toBytes(data);\n    abytes(data);\n    const { view, 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, cast it to view and process\n      if (take === blockLen) {\n        const dataView = createView(data);\n        for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, 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(view, 0);\n        this.pos = 0;\n      }\n    }\n    this.length += data.length;\n    this.roundClean();\n    return this;\n  }\n  digestInto(out: Uint8Array): void {\n    aexists(this);\n    aoutput(out, this);\n    this.finished = true;\n    // Padding\n    // We can avoid allocation of buffer for padding completely if it\n    // was previously not allocated here. But it won't change performance.\n    const { buffer, view, blockLen, isLE } = this;\n    let { pos } = this;\n    // append the bit '1' to the message\n    buffer[pos++] = 0b10000000;\n    clean(this.buffer.subarray(pos));\n    // we have less than padOffset left in buffer, so we cannot put length in\n    // current block, need process it and pad again\n    if (this.padOffset > blockLen - pos) {\n      this.process(view, 0);\n      pos = 0;\n    }\n    // Pad until full block byte with zeros\n    for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n    // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n    // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n    // So we just write lowest 64 bits of that value.\n    setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n    this.process(view, 0);\n    const oview = createView(out);\n    const len = this.outputLen;\n    // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n    if (len % 4) throw new Error('_sha2: outputLen should be aligned to 32bit');\n    const outLen = len / 4;\n    const state = this.get();\n    if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n    for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n  }\n  digest(): Uint8Array {\n    const { buffer, outputLen } = this;\n    this.digestInto(buffer);\n    const res = buffer.slice(0, outputLen);\n    this.destroy();\n    return res;\n  }\n  _cloneInto(to?: T): T {\n    to ||= new (this.constructor as any)() as T;\n    to.set(...this.get());\n    const { blockLen, buffer, length, finished, destroyed, pos } = this;\n    to.destroyed = destroyed;\n    to.finished = finished;\n    to.length = length;\n    to.pos = pos;\n    if (length % blockLen) to.buffer.set(buffer);\n    return to;\n  }\n  clone(): T {\n    return this._cloneInto();\n  }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */\nexport const SHA256_IV: Uint32Array = /* @__PURE__ */ Uint32Array.from([\n  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state. Bits 32..64 of frac part of sqrt of primes 23..53 */\nexport const SHA224_IV: Uint32Array = /* @__PURE__ */ Uint32Array.from([\n  0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state. Bits 0..64 of frac part of sqrt of primes 23..53 */\nexport const SHA384_IV: Uint32Array = /* @__PURE__ */ Uint32Array.from([\n  0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n  0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */\nexport const SHA512_IV: Uint32Array = /* @__PURE__ */ Uint32Array.from([\n  0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n  0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\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 = /* @__PURE__ */ BigInt(2 ** 32 - 1);\nconst _32n = /* @__PURE__ */ BigInt(32);\n\nfunction fromBig(\n  n: bigint,\n  le = false\n): {\n  h: number;\n  l: number;\n} {\n  if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n  return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };\n}\n\nfunction split(lst: bigint[], le = false): Uint32Array[] {\n  const len = lst.length;\n  let Ah = new Uint32Array(len);\n  let 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}\n\nconst toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// for Shift in [0, 32)\nconst shrSH = (h: number, _l: number, s: number): number => h >>> s;\nconst shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in [1, 32)\nconst rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s));\nconst rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32));\nconst rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s));\n// Right rotate for shift===32 (just swaps l&h)\nconst rotr32H = (_h: number, l: number): number => l;\nconst rotr32L = (h: number, _l: number): number => h;\n// Left rotate for Shift in [1, 32)\nconst rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s));\nconst rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s));\n// Left rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s));\nconst rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s));\n\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(\n  Ah: number,\n  Al: number,\n  Bh: number,\n  Bl: number\n): {\n  h: number;\n  l: number;\n} {\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: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\nconst add3H = (low: number, Ah: number, Bh: number, Ch: number): number =>\n  (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\nconst add4L = (Al: number, Bl: number, Cl: number, Dl: number): number =>\n  (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\nconst add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number =>\n  (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\nconst add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>\n  (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\nconst add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>\n  (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n\n// prettier-ignore\nexport {\n  add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig\n};\n// prettier-ignore\nconst u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = {\n  fromBig, split, toBig,\n  shrSH, shrSL,\n  rotrSH, rotrSL, rotrBH, rotrBL,\n  rotr32H, rotr32L,\n  rotlSH, rotlSL, rotlBH, rotlBL,\n  add, add3L, add3H, add4L, add4H, add5H, add5L,\n};\nexport default u64;\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and\n * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, rotr } from './utils.ts';\n\n/**\n * Round constants:\n * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable temporary buffer. \"W\" comes straight from spec. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\nexport class SHA256 extends HashMD<SHA256> {\n  // We cannot use array here since array allows indexing by variable\n  // which means optimizer/compiler cannot use registers.\n  protected A: number = SHA256_IV[0] | 0;\n  protected B: number = SHA256_IV[1] | 0;\n  protected C: number = SHA256_IV[2] | 0;\n  protected D: number = SHA256_IV[3] | 0;\n  protected E: number = SHA256_IV[4] | 0;\n  protected F: number = SHA256_IV[5] | 0;\n  protected G: number = SHA256_IV[6] | 0;\n  protected H: number = SHA256_IV[7] | 0;\n\n  constructor(outputLen: number = 32) {\n    super(64, outputLen, 8, false);\n  }\n  protected get(): [number, number, number, number, number, number, number, number] {\n    const { A, B, C, D, E, F, G, H } = this;\n    return [A, B, C, D, E, F, G, H];\n  }\n  // prettier-ignore\n  protected set(\n    A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n  ): void {\n    this.A = A | 0;\n    this.B = B | 0;\n    this.C = C | 0;\n    this.D = D | 0;\n    this.E = E | 0;\n    this.F = F | 0;\n    this.G = G | 0;\n    this.H = H | 0;\n  }\n  protected process(view: DataView, offset: number): void {\n    // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n    for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n    for (let i = 16; i < 64; i++) {\n      const W15 = SHA256_W[i - 15];\n      const W2 = SHA256_W[i - 2];\n      const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n      const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n      SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n    }\n    // Compression function main loop, 64 rounds\n    let { A, B, C, D, E, F, G, H } = this;\n    for (let i = 0; i < 64; i++) {\n      const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n      const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n      const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n      const T2 = (sigma0 + Maj(A, B, C)) | 0;\n      H = G;\n      G = F;\n      F = E;\n      E = (D + T1) | 0;\n      D = C;\n      C = B;\n      B = A;\n      A = (T1 + T2) | 0;\n    }\n    // Add the compressed chunk to the current hash value\n    A = (A + this.A) | 0;\n    B = (B + this.B) | 0;\n    C = (C + this.C) | 0;\n    D = (D + this.D) | 0;\n    E = (E + this.E) | 0;\n    F = (F + this.F) | 0;\n    G = (G + this.G) | 0;\n    H = (H + this.H) | 0;\n    this.set(A, B, C, D, E, F, G, H);\n  }\n  protected roundClean(): void {\n    clean(SHA256_W);\n  }\n  destroy(): void {\n    this.set(0, 0, 0, 0, 0, 0, 0, 0);\n    clean(this.buffer);\n  }\n}\n\nexport class SHA224 extends SHA256 {\n  protected A: number = SHA224_IV[0] | 0;\n  protected B: number = SHA224_IV[1] | 0;\n  protected C: number = SHA224_IV[2] | 0;\n  protected D: number = SHA224_IV[3] | 0;\n  protected E: number = SHA224_IV[4] | 0;\n  protected F: number = SHA224_IV[5] | 0;\n  protected G: number = SHA224_IV[6] | 0;\n  protected H: number = SHA224_IV[7] | 0;\n  constructor() {\n    super(28);\n  }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// Round contants\n// First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n  '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n  '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n  '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n  '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n  '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n  '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n  '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n  '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n  '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n  '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n  '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n  '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n  '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n  '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n  '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n  '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n  '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n  '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n  '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n  '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable temporary buffers\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\nexport class SHA512 extends HashMD<SHA512> {\n  // We cannot use array here since array allows indexing by variable\n  // which means optimizer/compiler cannot use registers.\n  // h -- high 32 bits, l -- low 32 bits\n  protected Ah: number = SHA512_IV[0] | 0;\n  protected Al: number = SHA512_IV[1] | 0;\n  protected Bh: number = SHA512_IV[2] | 0;\n  protected Bl: number = SHA512_IV[3] | 0;\n  protected Ch: number = SHA512_IV[4] | 0;\n  protected Cl: number = SHA512_IV[5] | 0;\n  protected Dh: number = SHA512_IV[6] | 0;\n  protected Dl: number = SHA512_IV[7] | 0;\n  protected Eh: number = SHA512_IV[8] | 0;\n  protected El: number = SHA512_IV[9] | 0;\n  protected Fh: number = SHA512_IV[10] | 0;\n  protected Fl: number = SHA512_IV[11] | 0;\n  protected Gh: number = SHA512_IV[12] | 0;\n  protected Gl: number = SHA512_IV[13] | 0;\n  protected Hh: number = SHA512_IV[14] | 0;\n  protected Hl: number = SHA512_IV[15] | 0;\n\n  constructor(outputLen: number = 64) {\n    super(128, outputLen, 16, false);\n  }\n  // prettier-ignore\n  protected get(): [\n    number, number, number, number, number, number, number, number,\n    number, number, number, number, number, number, number, number\n  ] {\n    const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n    return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n  }\n  // prettier-ignore\n  protected set(\n    Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n    Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n  ): void {\n    this.Ah = Ah | 0;\n    this.Al = Al | 0;\n    this.Bh = Bh | 0;\n    this.Bl = Bl | 0;\n    this.Ch = Ch | 0;\n    this.Cl = Cl | 0;\n    this.Dh = Dh | 0;\n    this.Dl = Dl | 0;\n    this.Eh = Eh | 0;\n    this.El = El | 0;\n    this.Fh = Fh | 0;\n    this.Fl = Fl | 0;\n    this.Gh = Gh | 0;\n    this.Gl = Gl | 0;\n    this.Hh = Hh | 0;\n    this.Hl = Hl | 0;\n  }\n  protected process(view: DataView, offset: number): void {\n    // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n    for (let i = 0; i < 16; i++, offset += 4) {\n      SHA512_W_H[i] = view.getUint32(offset);\n      SHA512_W_L[i] = view.getUint32((offset += 4));\n    }\n    for (let i = 16; i < 80; i++) {\n      // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n      const W15h = SHA512_W_H[i - 15] | 0;\n      const W15l = SHA512_W_L[i - 15] | 0;\n      const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n      const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n      // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n      const W2h = SHA512_W_H[i - 2] | 0;\n      const W2l = SHA512_W_L[i - 2] | 0;\n      const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n      const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n      // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];\n      const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n      const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n      SHA512_W_H[i] = SUMh | 0;\n      SHA512_W_L[i] = SUMl | 0;\n    }\n    let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n    // Compression function main loop, 80 rounds\n    for (let i = 0; i < 80; i++) {\n      // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n      const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n      const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n      //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n      const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n      const CHIl = (El & Fl) ^ (~El & Gl);\n      // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n      // prettier-ignore\n      const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n      const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n      const T1l = T1ll | 0;\n      // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n      const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n      const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n      const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n      const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n      Hh = Gh | 0;\n      Hl = Gl | 0;\n      Gh = Fh | 0;\n      Gl = Fl | 0;\n      Fh = Eh | 0;\n      Fl = El | 0;\n      ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n      Dh = Ch | 0;\n      Dl = Cl | 0;\n      Ch = Bh | 0;\n      Cl = Bl | 0;\n      Bh = Ah | 0;\n      Bl = Al | 0;\n      const All = u64.add3L(T1l, sigma0l, MAJl);\n      Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n      Al = All | 0;\n    }\n    // Add the compressed chunk to the current hash value\n    ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n    ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n    ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n    ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n    ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n    ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n    ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n    ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n    this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n  }\n  protected roundClean(): void {\n    clean(SHA512_W_H, SHA512_W_L);\n  }\n  destroy(): void {\n    clean(this.buffer);\n    this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n  }\n}\n\nexport class SHA384 extends SHA512 {\n  protected Ah: number = SHA384_IV[0] | 0;\n  protected Al: number = SHA384_IV[1] | 0;\n  protected Bh: number = SHA384_IV[2] | 0;\n  protected Bl: number = SHA384_IV[3] | 0;\n  protected Ch: number = SHA384_IV[4] | 0;\n  protected Cl: number = SHA384_IV[5] | 0;\n  protected Dh: number = SHA384_IV[6] | 0;\n  protected Dl: number = SHA384_IV[7] | 0;\n  protected Eh: number = SHA384_IV[8] | 0;\n  protected El: number = SHA384_IV[9] | 0;\n  protected Fh: number = SHA384_IV[10] | 0;\n  protected Fl: number = SHA384_IV[11] | 0;\n  protected Gh: number = SHA384_IV[12] | 0;\n  protected Gl: number = SHA384_IV[13] | 0;\n  protected Hh: number = SHA384_IV[14] | 0;\n  protected Hl: number = SHA384_IV[15] | 0;\n\n  constructor() {\n    super(48);\n  }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See `test/misc/sha2-gen-iv.js`.\n */\n\n/** SHA512/224 IV */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n  0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n  0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA512/256 IV */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n  0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n  0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\nexport class SHA512_224 extends SHA512 {\n  protected Ah: number = T224_IV[0] | 0;\n  protected Al: number = T224_IV[1] | 0;\n  protected Bh: number = T224_IV[2] | 0;\n  protected Bl: number = T224_IV[3] | 0;\n  protected Ch: number = T224_IV[4] | 0;\n  protected Cl: number = T224_IV[5] | 0;\n  protected Dh: number = T224_IV[6] | 0;\n  protected Dl: number = T224_IV[7] | 0;\n  protected Eh: number = T224_IV[8] | 0;\n  protected El: number = T224_IV[9] | 0;\n  protected Fh: number = T224_IV[10] | 0;\n  protected Fl: number = T224_IV[11] | 0;\n  protected Gh: number = T224_IV[12] | 0;\n  protected Gl: number = T224_IV[13] | 0;\n  protected Hh: number = T224_IV[14] | 0;\n  protected Hl: number = T224_IV[15] | 0;\n\n  constructor() {\n    super(28);\n  }\n}\n\nexport class SHA512_256 extends SHA512 {\n  protected Ah: number = T256_IV[0] | 0;\n  protected Al: number = T256_IV[1] | 0;\n  protected Bh: number = T256_IV[2] | 0;\n  protected Bl: number = T256_IV[3] | 0;\n  protected Ch: number = T256_IV[4] | 0;\n  protected Cl: number = T256_IV[5] | 0;\n  protected Dh: number = T256_IV[6] | 0;\n  protected Dl: number = T256_IV[7] | 0;\n  protected Eh: number = T256_IV[8] | 0;\n  protected El: number = T256_IV[9] | 0;\n  protected Fh: number = T256_IV[10] | 0;\n  protected Fl: number = T256_IV[11] | 0;\n  protected Gh: number = T256_IV[12] | 0;\n  protected Gl: number = T256_IV[13] | 0;\n  protected Hh: number = T256_IV[14] | 0;\n  protected Hl: number = T256_IV[15] | 0;\n\n  constructor() {\n    super(32);\n  }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634.\n *\n * It is the fastest JS hash, even faster than Blake3.\n * To break sha256 using birthday attack, attackers need to try 2^128 hashes.\n * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n */\nexport const sha256: CHash = /* @__PURE__ */ createHasher(() => new SHA256());\n/** SHA2-224 hash function from RFC 4634 */\nexport const sha224: CHash = /* @__PURE__ */ createHasher(() => new SHA224());\n\n/** SHA2-512 hash function from RFC 4634. */\nexport const sha512: CHash = /* @__PURE__ */ createHasher(() => new SHA512());\n/** SHA2-384 hash function from RFC 4634. */\nexport const sha384: CHash = /* @__PURE__ */ createHasher(() => new SHA384());\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on [truncated SHA512](https://eprint.iacr.org/2010/548.pdf).\n */\nexport const sha512_256: CHash = /* @__PURE__ */ createHasher(() => new SHA512_256());\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on [truncated SHA512](https://eprint.iacr.org/2010/548.pdf).\n */\nexport const sha512_224: CHash = /* @__PURE__ */ createHasher(() => new SHA512_224());\n","/**\n * Hex, bytes and number utilities.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n  abytes as abytes_,\n  bytesToHex as bytesToHex_,\n  concatBytes as concatBytes_,\n  hexToBytes as hexToBytes_,\n  isBytes as isBytes_,\n} from '@noble/hashes/utils.js';\nexport {\n  abytes,\n  anumber,\n  bytesToHex,\n  bytesToUtf8,\n  concatBytes,\n  hexToBytes,\n  isBytes,\n  randomBytes,\n  utf8ToBytes,\n} from '@noble/hashes/utils.js';\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\nexport type Hex = Uint8Array | string; // hex strings are accepted for simplicity\nexport type PrivKey = Hex | bigint; // bigints are accepted to ease learning curve\nexport type CHash = {\n  (message: Uint8Array | string): Uint8Array;\n  blockLen: number;\n  outputLen: number;\n  create(opts?: { dkLen?: number }): any; // For shake\n};\nexport type FHash = (message: Uint8Array | string) => Uint8Array;\n\nexport function abool(title: string, value: boolean): void {\n  if (typeof value !== 'boolean') throw new Error(title + ' boolean expected, got ' + value);\n}\n\n// tmp name until v2\nexport function _abool2(value: boolean, title: string = ''): boolean {\n  if (typeof value !== 'boolean') {\n    const prefix = title && `\"${title}\"`;\n    throw new Error(prefix + 'expected boolean, got type=' + typeof value);\n  }\n  return value;\n}\n\n// tmp name until v2\n/** Asserts something is Uint8Array. */\nexport function _abytes2(value: Uint8Array, length?: number, title: string = ''): Uint8Array {\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\n// Used in weierstrass, der\nexport function numberToHexUnpadded(num: number | bigint): string {\n  const hex = num.toString(16);\n  return hex.length & 1 ? '0' + hex : hex;\n}\n\nexport function hexToNumber(hex: string): bigint {\n  if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n  return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian\n}\n\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n  return hexToNumber(bytesToHex_(bytes));\n}\nexport function bytesToNumberLE(bytes: Uint8Array): bigint {\n  abytes_(bytes);\n  return hexToNumber(bytesToHex_(Uint8Array.from(bytes).reverse()));\n}\n\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n  return hexToBytes_(n.toString(16).padStart(len * 2, '0'));\n}\nexport function numberToBytesLE(n: number | bigint, len: number): Uint8Array {\n  return numberToBytesBE(n, len).reverse();\n}\n// Unpadded, rarely used\nexport function numberToVarBytesBE(n: number | bigint): Uint8Array {\n  return hexToBytes_(numberToHexUnpadded(n));\n}\n\n/**\n * Takes hex string or Uint8Array, converts to Uint8Array.\n * Validates output length.\n * Will throw error for other types.\n * @param title descriptive title for an error e.g. 'secret key'\n * @param hex hex string or Uint8Array\n * @param expectedLength optional, will compare to result array's length\n * @returns\n */\nexport function ensureBytes(title: string, hex: Hex, expectedLength?: number): Uint8Array {\n  let res: Uint8Array;\n  if (typeof hex === 'string') {\n    try {\n      res = hexToBytes_(hex);\n    } catch (e) {\n      throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);\n    }\n  } else if (isBytes_(hex)) {\n    // Uint8Array.from() instead of hash.slice() because node.js Buffer\n    // is instance of Uint8Array, and its slice() creates **mutable** copy\n    res = Uint8Array.from(hex);\n  } else {\n    throw new Error(title + ' must be hex string or Uint8Array');\n  }\n  const len = res.length;\n  if (typeof expectedLength === 'number' && len !== expectedLength)\n    throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);\n  return res;\n}\n\n// Compares 2 u8a-s in kinda constant time\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n  if (a.length !== b.length) return false;\n  let diff = 0;\n  for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n  return diff === 0;\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: Uint8Array): Uint8Array {\n  return Uint8Array.from(bytes);\n}\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: string): Uint8Array {\n  return Uint8Array.from(ascii, (c, i) => {\n    const charCode = c.charCodeAt(0);\n    if (c.length !== 1 || charCode > 127) {\n      throw new Error(\n        `string contains non-ASCII character \"${ascii[i]}\" with code ${charCode} at position ${i}`\n      );\n    }\n    return charCode;\n  });\n}\n\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\n// export const utf8ToBytes: typeof utf8ToBytes_ = utf8ToBytes_;\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\n// export const bytesToUtf8: typeof bytesToUtf8_ = bytesToUtf8_;\n\n// Is positive bigint\nconst isPosBig = (n: bigint) => typeof n === 'bigint' && _0n <= n;\n\nexport function inRange(n: bigint, min: bigint, max: bigint): boolean {\n  return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;\n}\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: string, n: bigint, min: bigint, max: bigint): void {\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\n// Bit operations\n\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n * TODO: merge with nLength in modular\n */\nexport function bitLen(n: bigint): number {\n  let len;\n  for (len = 0; n > _0n; n >>= _1n, len += 1);\n  return len;\n}\n\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n */\nexport function bitGet(n: bigint, pos: number): bigint {\n  return (n >> BigInt(pos)) & _1n;\n}\n\n/**\n * Sets single bit at position.\n */\nexport function bitSet(n: bigint, pos: number, value: boolean): bigint {\n  return n | ((value ? _1n : _0n) << BigInt(pos));\n}\n\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n */\nexport const bitMask = (n: number): bigint => (_1n << BigInt(n)) - _1n;\n\n// DRBG\n\ntype Pred<T> = (v: Uint8Array) => T | undefined;\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @returns function that will call DRBG until 2nd arg returns something meaningful\n * @example\n *   const drbg = createHmacDRBG<Key>(32, 32, hmac);\n *   drbg(seed, bytesToKey); // bytesToKey must return Key or undefined\n */\nexport function createHmacDrbg<T>(\n  hashLen: number,\n  qByteLen: number,\n  hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array\n): (seed: Uint8Array, predicate: Pred<T>) => T {\n  if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number');\n  if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number');\n  if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function');\n  // Step B, Step C: set hashLen to 8*ceil(hlen/8)\n  const u8n = (len: number) => new Uint8Array(len); // creates Uint8Array\n  const u8of = (byte: number) => Uint8Array.of(byte); // another shortcut\n  let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n  let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same\n  let i = 0; // Iterations counter, will throw when over 1000\n  const reset = () => {\n    v.fill(1);\n    k.fill(0);\n    i = 0;\n  };\n  const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)\n  const reseed = (seed = u8n(0)) => {\n    // HMAC-DRBG reseed() function. Steps D-G\n    k = h(u8of(0x00), seed); // k = hmac(k || v || 0x00 || seed)\n    v = h(); // v = hmac(k || v)\n    if (seed.length === 0) return;\n    k = h(u8of(0x01), seed); // k = hmac(k || v || 0x01 || seed)\n    v = h(); // v = hmac(k || v)\n  };\n  const gen = () => {\n    // HMAC-DRBG generate() function\n    if (i++ >= 1000) throw new Error('drbg: tried 1000 values');\n    let len = 0;\n    const out: Uint8Array[] = [];\n    while (len < qByteLen) {\n      v = h();\n      const sl = v.slice();\n      out.push(sl);\n      len += v.length;\n    }\n    return concatBytes_(...out);\n  };\n  const genUntil = (seed: Uint8Array, pred: Pred<T>): T => {\n    reset();\n    reseed(seed); // Steps D-G\n    let res: T | undefined = undefined; // Step H: grind until k is in [1..n-1]\n    while (!(res = pred(gen()))) reseed();\n    reset();\n    return res;\n  };\n  return genUntil;\n}\n\n// Validating curves and fields\n\nconst validatorFns = {\n  bigint: (val: any): boolean => typeof val === 'bigint',\n  function: (val: any): boolean => typeof val === 'function',\n  boolean: (val: any): boolean => typeof val === 'boolean',\n  string: (val: any): boolean => typeof val === 'string',\n  stringOrUint8Array: (val: any): boolean => typeof val === 'string' || isBytes_(val),\n  isSafeInteger: (val: any): boolean => Number.isSafeInteger(val),\n  array: (val: any): boolean => Array.isArray(val),\n  field: (val: any, object: any): any => (object as any).Fp.isValid(val),\n  hash: (val: any): boolean => typeof val === 'function' && Number.isSafeInteger(val.outputLen),\n} as const;\ntype Validator = keyof typeof validatorFns;\ntype ValMap<T extends Record<string, any>> = { [K in keyof T]?: Validator };\n// type Record<K extends string | number | symbol, T> = { [P in K]: T; }\n\nexport function validateObject<T extends Record<string, any>>(\n  object: T,\n  validators: ValMap<T>,\n  optValidators: ValMap<T> = {}\n): T {\n  const checkField = (fieldName: keyof T, type: Validator, isOptional: boolean) => {\n    const checkVal = validatorFns[type];\n    if (typeof checkVal !== 'function') throw new Error('invalid validator function');\n\n    const val = object[fieldName as keyof typeof object];\n    if (isOptional && val === undefined) return;\n    if (!checkVal(val, object)) {\n      throw new Error(\n        'param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val\n      );\n    }\n  };\n  for (const [fieldName, type] of Object.entries(validators)) checkField(fieldName, type!, false);\n  for (const [fieldName, type] of Object.entries(optValidators)) checkField(fieldName, type!, true);\n  return object;\n}\n// validate type tests\n// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };\n// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!\n// // Should fail type-check\n// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });\n// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });\n// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });\n// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });\n\nexport function isHash(val: CHash): boolean {\n  return typeof val === 'function' && Number.isSafeInteger(val.outputLen);\n}\nexport function _validateObject(\n  object: Record<string, any>,\n  fields: Record<string, string>,\n  optFields: Record<string, string> = {}\n): void {\n  if (!object || typeof object !== 'object') throw new Error('expected valid options object');\n  type Item = keyof typeof object;\n  function checkField(fieldName: Item, expectedType: string, isOpt: boolean) {\n    const val = object[fieldName];\n    if (isOpt && val === undefined) 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  Object.entries(fields).forEach(([k, v]) => checkField(k, v, false));\n  Object.entries(optFields).forEach(([k, v]) => checkField(k, v, true));\n}\n\n/**\n * throws not implemented error\n */\nexport const notImplemented = (): never => {\n  throw new Error('not implemented');\n};\n\n/**\n * Memoizes (caches) computation result.\n * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.\n */\nexport function memoized<T extends object, R, O extends any[]>(\n  fn: (arg: T, ...args: O) => R\n): (arg: T, ...args: O) => R {\n  const map = new WeakMap<T, R>();\n  return (arg: T, ...args: O): R => {\n    const val = map.get(arg);\n    if (val !== undefined) return val;\n    const computed = fn(arg, ...args);\n    map.set(arg, computed);\n    return computed;\n  };\n}\n","/**\n * Utils for modular division and fields.\n * Field over 11 is a finite (Galois) field is integer number operations `mod 11`.\n * There is no division: it is replaced by modular multiplicative inverse.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n  _validateObject,\n  anumber,\n  bitMask,\n  bytesToNumberBE,\n  bytesToNumberLE,\n  ensureBytes,\n  numberToBytesBE,\n  numberToBytesLE,\n} from '../utils.ts';\n\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3);\n// prettier-ignore\nconst _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5), _7n = /* @__PURE__ */ BigInt(7);\n// prettier-ignore\nconst _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9), _16n = /* @__PURE__ */ BigInt(16);\n\n// Calculates a modulo b\nexport function mod(a: bigint, b: bigint): bigint {\n  const result = a % b;\n  return result >= _0n ? result : b + result;\n}\n/**\n * Efficiently raise num to power and do modular division.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * @example\n * pow(2n, 6n, 11n) // 64n % 11n == 9n\n */\nexport function pow(num: bigint, power: bigint, modulo: bigint): bigint {\n  return FpPow(Field(modulo), num, power);\n}\n\n/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */\nexport function pow2(x: bigint, power: bigint, modulo: bigint): bigint {\n  let res = x;\n  while (power-- > _0n) {\n    res *= res;\n    res %= modulo;\n  }\n  return res;\n}\n\n/**\n * Inverses number over modulo.\n * Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).\n */\nexport function invert(number: bigint, modulo: bigint): bigint {\n  if (number === _0n) throw new Error('invert: expected non-zero number');\n  if (modulo <= _0n) throw new Error('invert: expected positive modulus, got ' + modulo);\n  // Fermat's little theorem \"CT-like\" version inv(n) = n^(m-2) mod m is 30x slower.\n  let a = mod(number, modulo);\n  let b = modulo;\n  // prettier-ignore\n  let x = _0n, y = _1n, u = _1n, v = _0n;\n  while (a !== _0n) {\n    // JIT applies optimization if those two lines follow each other\n    const q = b / a;\n    const r = b % a;\n    const m = x - u * q;\n    const n = y - v * q;\n    // prettier-ignore\n    b = a, a = r, x = u, y = v, u = m, v = n;\n  }\n  const gcd = b;\n  if (gcd !== _1n) throw new Error('invert: does not exist');\n  return mod(x, modulo);\n}\n\nfunction assertIsSquare<T>(Fp: IField<T>, root: T, n: T): void {\n  if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');\n}\n\n// Not all roots are possible! Example which will throw:\n// const NUM =\n// n = 72057594037927816n;\n// Fp = Field(BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'));\nfunction sqrt3mod4<T>(Fp: IField<T>, n: T) {\n  const p1div4 = (Fp.ORDER + _1n) / _4n;\n  const root = Fp.pow(n, p1div4);\n  assertIsSquare(Fp, root, n);\n  return root;\n}\n\nfunction sqrt5mod8<T>(Fp: IField<T>, n: T) {\n  const p5div8 = (Fp.ORDER - _5n) / _8n;\n  const n2 = Fp.mul(n, _2n);\n  const v = Fp.pow(n2, p5div8);\n  const nv = Fp.mul(n, v);\n  const i = Fp.mul(Fp.mul(nv, _2n), v);\n  const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));\n  assertIsSquare(Fp, root, n);\n  return root;\n}\n\n// Based on RFC9380, Kong algorithm\n// prettier-ignore\nfunction sqrt9mod16(P: bigint): <T>(Fp: IField<T>, n: T) => T {\n  const Fp_ = Field(P);\n  const tn = tonelliShanks(P);\n  const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));//  1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F\n  const c2 = tn(Fp_, c1);              //  2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F\n  const c3 = tn(Fp_, Fp_.neg(c1));     //  3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F\n  const c4 = (P + _7n) / _16n;         //  4. c4 = (q + 7) / 16        # Integer arithmetic\n  return <T>(Fp: IField<T>, n: T) => {\n    let tv1 = Fp.pow(n, c4);           //  1. tv1 = x^c4\n    let tv2 = Fp.mul(tv1, c1);         //  2. tv2 = c1 * tv1\n    const tv3 = Fp.mul(tv1, c2);       //  3. tv3 = c2 * tv1\n    const tv4 = Fp.mul(tv1, c3);       //  4. tv4 = c3 * tv1\n    const e1 = Fp.eql(Fp.sqr(tv2), n); //  5.  e1 = (tv2^2) == x\n    const e2 = Fp.eql(Fp.sqr(tv3), n); //  6.  e2 = (tv3^2) == x\n    tv1 = Fp.cmov(tv1, tv2, e1);       //  7. tv1 = CMOV(tv1, tv2, e1)  # Select tv2 if (tv2^2) == x\n    tv2 = Fp.cmov(tv4, tv3, e2);       //  8. tv2 = CMOV(tv4, tv3, e2)  # Select tv3 if (tv3^2) == x\n    const e3 = Fp.eql(Fp.sqr(tv2), n); //  9.  e3 = (tv2^2) == x\n    const root = Fp.cmov(tv1, tv2, e3);// 10.  z = CMOV(tv1, tv2, e3)   # Select sqrt from tv1 & tv2\n    assertIsSquare(Fp, root, n);\n    return root;\n  };\n}\n\n/**\n * Tonelli-Shanks square root search algorithm.\n * 1. https://eprint.iacr.org/2012/685.pdf (page 12)\n * 2. Square Roots from 1; 24, 51, 10 to Dan Shanks\n * @param P field order\n * @returns function that takes field Fp (created from P) and number n\n */\nexport function tonelliShanks(P: bigint): <T>(Fp: IField<T>, n: T) => T {\n  // Initialization (precomputation).\n  // Caching initialization could boost perf by 7%.\n  if (P < _3n) throw new Error('sqrt is not defined for small field');\n  // Factor P - 1 = Q * 2^S, where Q is odd\n  let Q = P - _1n;\n  let S = 0;\n  while (Q % _2n === _0n) {\n    Q /= _2n;\n    S++;\n  }\n\n  // Find the first quadratic non-residue Z >= 2\n  let Z = _2n;\n  const _Fp = Field(P);\n  while (FpLegendre(_Fp, Z) === 1) {\n    // Basic primality test for P. After x iterations, chance of\n    // not finding quadratic non-residue is 2^x, so 2^1000.\n    if (Z++ > 1000) throw new Error('Cannot find square root: probably non-prime P');\n  }\n  // Fast-path; usually done before Z, but we do \"primality test\".\n  if (S === 1) return sqrt3mod4;\n\n  // Slow-path\n  // TODO: test on Fp2 and others\n  let cc = _Fp.pow(Z, Q); // c = z^Q\n  const Q1div2 = (Q + _1n) / _2n;\n  return function tonelliSlow<T>(Fp: IField<T>, n: T): T {\n    if (Fp.is0(n)) return n;\n    // Check if n is a quadratic residue using Legendre symbol\n    if (FpLegendre(Fp, n) !== 1) throw new Error('Cannot find square root');\n\n    // Initialize variables for the main loop\n    let M = S;\n    let c = Fp.mul(Fp.ONE, cc); // c = z^Q, move cc from field _Fp into field Fp\n    let t = Fp.pow(n, Q); // t = n^Q, first guess at the fudge factor\n    let R = Fp.pow(n, Q1div2); // R = n^((Q+1)/2), first guess at the square root\n\n    // Main loop\n    // while t != 1\n    while (!Fp.eql(t, Fp.ONE)) {\n      if (Fp.is0(t)) return Fp.ZERO; // if t=0 return R=0\n      let i = 1;\n\n      // Find the smallest i >= 1 such that t^(2^i) ≡ 1 (mod P)\n      let t_tmp = Fp.sqr(t); // t^(2^1)\n      while (!Fp.eql(t_tmp, Fp.ONE)) {\n        i++;\n        t_tmp = Fp.sqr(t_tmp); // t^(2^2)...\n        if (i === M) throw new Error('Cannot find square root');\n      }\n\n      // Calculate the exponent for b: 2^(M - i - 1)\n      const exponent = _1n << BigInt(M - i - 1); // bigint is important\n      const b = Fp.pow(c, exponent); // b = 2^(M - i - 1)\n\n      // Update variables\n      M = i;\n      c = Fp.sqr(b); // c = b^2\n      t = Fp.mul(t, c); // t = (t * b^2)\n      R = Fp.mul(R, b); // R = R*b\n    }\n    return R;\n  };\n}\n\n/**\n * Square root for a finite field. Will try optimized versions first:\n *\n * 1. P ≡ 3 (mod 4)\n * 2. P ≡ 5 (mod 8)\n * 3. P ≡ 9 (mod 16)\n * 4. Tonelli-Shanks algorithm\n *\n * Different algorithms can give different roots, it is up to user to decide which one they want.\n * For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).\n */\nexport function FpSqrt(P: bigint): <T>(Fp: IField<T>, n: T) => T {\n  // P ≡ 3 (mod 4) => √n = n^((P+1)/4)\n  if (P % _4n === _3n) return sqrt3mod4;\n  // P ≡ 5 (mod 8) => Atkin algorithm, page 10 of https://eprint.iacr.org/2012/685.pdf\n  if (P % _8n === _5n) return sqrt5mod8;\n  // P ≡ 9 (mod 16) => Kong algorithm, page 11 of https://eprint.iacr.org/2012/685.pdf (algorithm 4)\n  if (P % _16n === _9n) return sqrt9mod16(P);\n  // Tonelli-Shanks algorithm\n  return tonelliShanks(P);\n}\n\n// Little-endian check for first LE bit (last BE bit);\nexport const isNegativeLE = (num: bigint, modulo: bigint): boolean =>\n  (mod(num, modulo) & _1n) === _1n;\n\n/** Field is not always over prime: for example, Fp2 has ORDER(q)=p^m. */\nexport interface IField<T> {\n  ORDER: bigint;\n  isLE: boolean;\n  BYTES: number;\n  BITS: number;\n  MASK: bigint;\n  ZERO: T;\n  ONE: T;\n  // 1-arg\n  create: (num: T) => T;\n  isValid: (num: T) => boolean;\n  is0: (num: T) => boolean;\n  isValidNot0: (num: T) => boolean;\n  neg(num: T): T;\n  inv(num: T): T;\n  sqrt(num: T): T;\n  sqr(num: T): T;\n  // 2-args\n  eql(lhs: T, rhs: T): boolean;\n  add(lhs: T, rhs: T): T;\n  sub(lhs: T, rhs: T): T;\n  mul(lhs: T, rhs: T | bigint): T;\n  pow(lhs: T, power: bigint): T;\n  div(lhs: T, rhs: T | bigint): T;\n  // N for NonNormalized (for now)\n  addN(lhs: T, rhs: T): T;\n  subN(lhs: T, rhs: T): T;\n  mulN(lhs: T, rhs: T | bigint): T;\n  sqrN(num: T): T;\n\n  // Optional\n  // Should be same as sgn0 function in\n  // [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#section-4.1).\n  // NOTE: sgn0 is 'negative in LE', which is same as odd. And negative in LE is kinda strange definition anyway.\n  isOdd?(num: T): boolean; // Odd instead of even since we have it for Fp2\n  allowedLengths?: number[];\n  // legendre?(num: T): T;\n  invertBatch: (lst: T[]) => T[];\n  toBytes(num: T): Uint8Array;\n  fromBytes(bytes: Uint8Array, skipValidation?: boolean): T;\n  // If c is False, CMOV returns a, otherwise it returns b.\n  cmov(a: T, b: T, c: boolean): T;\n}\n// prettier-ignore\nconst FIELD_FIELDS = [\n  'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',\n  'eql', 'add', 'sub', 'mul', 'pow', 'div',\n  'addN', 'subN', 'mulN', 'sqrN'\n] as const;\nexport function validateField<T>(field: IField<T>): IField<T> {\n  const initial = {\n    ORDER: 'bigint',\n    MASK: 'bigint',\n    BYTES: 'number',\n    BITS: 'number',\n  } as Record<string, string>;\n  const opts = FIELD_FIELDS.reduce((map, val: string) => {\n    map[val] = 'function';\n    return map;\n  }, initial);\n  _validateObject(field, opts);\n  // const max = 16384;\n  // if (field.BYTES < 1 || field.BYTES > max) throw new Error('invalid field');\n  // if (field.BITS < 1 || field.BITS > 8 * max) throw new Error('invalid field');\n  return field;\n}\n\n// Generic field functions\n\n/**\n * Same as `pow` but for Fp: non-constant-time.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n */\nexport function FpPow<T>(Fp: IField<T>, num: T, power: bigint): T {\n  if (power < _0n) throw new Error('invalid exponent, negatives unsupported');\n  if (power === _0n) return Fp.ONE;\n  if (power === _1n) return num;\n  let p = Fp.ONE;\n  let d = num;\n  while (power > _0n) {\n    if (power & _1n) p = Fp.mul(p, d);\n    d = Fp.sqr(d);\n    power >>= _1n;\n  }\n  return p;\n}\n\n/**\n * Efficiently invert an array of Field elements.\n * Exception-free. Will return `undefined` for 0 elements.\n * @param passZero map 0 to 0 (instead of undefined)\n */\nexport function FpInvertBatch<T>(Fp: IField<T>, nums: T[], passZero = false): T[] {\n  const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : undefined);\n  // Walk from first to last, multiply them by each other MOD p\n  const multipliedAcc = nums.reduce((acc, num, i) => {\n    if (Fp.is0(num)) return acc;\n    inverted[i] = acc;\n    return Fp.mul(acc, num);\n  }, Fp.ONE);\n  // Invert last element\n  const invertedAcc = Fp.inv(multipliedAcc);\n  // Walk from last to first, multiply them by inverted each other MOD p\n  nums.reduceRight((acc, num, i) => {\n    if (Fp.is0(num)) return acc;\n    inverted[i] = Fp.mul(acc, inverted[i]);\n    return Fp.mul(acc, num);\n  }, invertedAcc);\n  return inverted;\n}\n\n// TODO: remove\nexport function FpDiv<T>(Fp: IField<T>, lhs: T, rhs: T | bigint): T {\n  return Fp.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, Fp.ORDER) : Fp.inv(rhs));\n}\n\n/**\n * Legendre symbol.\n * Legendre constant is used to calculate Legendre symbol (a | p)\n * which denotes the value of a^((p-1)/2) (mod p).\n *\n * * (a | p) ≡ 1    if a is a square (mod p), quadratic residue\n * * (a | p) ≡ -1   if a is not a square (mod p), quadratic non residue\n * * (a | p) ≡ 0    if a ≡ 0 (mod p)\n */\nexport function FpLegendre<T>(Fp: IField<T>, n: T): -1 | 0 | 1 {\n  // We can use 3rd argument as optional cache of this value\n  // but seems unneeded for now. The operation is very fast.\n  const p1mod2 = (Fp.ORDER - _1n) / _2n;\n  const powered = Fp.pow(n, p1mod2);\n  const yes = Fp.eql(powered, Fp.ONE);\n  const zero = Fp.eql(powered, Fp.ZERO);\n  const no = Fp.eql(powered, Fp.neg(Fp.ONE));\n  if (!yes && !zero && !no) throw new Error('invalid Legendre symbol result');\n  return yes ? 1 : zero ? 0 : -1;\n}\n\n// This function returns True whenever the value x is a square in the field F.\nexport function FpIsSquare<T>(Fp: IField<T>, n: T): boolean {\n  const l = FpLegendre(Fp, n);\n  return l === 1;\n}\n\nexport type NLength = { nByteLength: number; nBitLength: number };\n// CURVE.n lengths\nexport function nLength(n: bigint, nBitLength?: number): NLength {\n  // Bit size, byte size of CURVE.n\n  if (nBitLength !== undefined) anumber(nBitLength);\n  const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;\n  const nByteLength = Math.ceil(_nBitLength / 8);\n  return { nBitLength: _nBitLength, nByteLength };\n}\n\ntype FpField = IField<bigint> & Required<Pick<IField<bigint>, 'isOdd'>>;\ntype SqrtFn = (n: bigint) => bigint;\ntype FieldOpts = Partial<{\n  sqrt: SqrtFn;\n  isLE: boolean;\n  BITS: number;\n  modFromBytes: boolean; // bls12-381 requires mod(n) instead of rejecting keys >= n\n  allowedLengths?: readonly number[]; // for P521 (adds padding for smaller sizes)\n}>;\n/**\n * Creates a finite field. Major performance optimizations:\n * * 1. Denormalized operations like mulN instead of mul.\n * * 2. Identical object shape: never add or remove keys.\n * * 3. `Object.freeze`.\n * Fragile: always run a benchmark on a change.\n * Security note: operations don't check 'isValid' for all elements for performance reasons,\n * it is caller responsibility to check this.\n * This is low-level code, please make sure you know what you're doing.\n *\n * Note about field properties:\n * * CHARACTERISTIC p = prime number, number of elements in main subgroup.\n * * ORDER q = similar to cofactor in curves, may be composite `q = p^m`.\n *\n * @param ORDER field order, probably prime, or could be composite\n * @param bitLen how many bits the field consumes\n * @param isLE (default: false) if encoding / decoding should be in little-endian\n * @param redef optional faster redefinitions of sqrt and other methods\n */\nexport function Field(\n  ORDER: bigint,\n  bitLenOrOpts?: number | FieldOpts, // TODO: use opts only in v2?\n  isLE = false,\n  opts: { sqrt?: SqrtFn } = {}\n): Readonly<FpField> {\n  if (ORDER <= _0n) throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);\n  let _nbitLength: number | undefined = undefined;\n  let _sqrt: SqrtFn | undefined = undefined;\n  let modFromBytes: boolean = false;\n  let allowedLengths: undefined | readonly number[] = undefined;\n  if (typeof bitLenOrOpts === 'object' && bitLenOrOpts != null) {\n    if (opts.sqrt || isLE) throw new Error('cannot specify opts in two arguments');\n    const _opts = bitLenOrOpts;\n    if (_opts.BITS) _nbitLength = _opts.BITS;\n    if (_opts.sqrt) _sqrt = _opts.sqrt;\n    if (typeof _opts.isLE === 'boolean') isLE = _opts.isLE;\n    if (typeof _opts.modFromBytes === 'boolean') modFromBytes = _opts.modFromBytes;\n    allowedLengths = _opts.allowedLengths;\n  } else {\n    if (typeof bitLenOrOpts === 'number') _nbitLength = bitLenOrOpts;\n    if (opts.sqrt) _sqrt = opts.sqrt;\n  }\n  const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, _nbitLength);\n  if (BYTES > 2048) throw new Error('invalid field: expected ORDER of <= 2048 bytes');\n  let sqrtP: ReturnType<typeof FpSqrt>; // cached sqrtP\n  const f: Readonly<FpField> = Object.freeze({\n    ORDER,\n    isLE,\n    BITS,\n    BYTES,\n    MASK: bitMask(BITS),\n    ZERO: _0n,\n    ONE: _1n,\n    allowedLengths: allowedLengths,\n    create: (num) => mod(num, ORDER),\n    isValid: (num) => {\n      if (typeof num !== 'bigint')\n        throw new Error('invalid field element: expected bigint, got ' + typeof num);\n      return _0n <= num && num < ORDER; // 0 is valid element, but it's not invertible\n    },\n    is0: (num) => num === _0n,\n    // is valid and invertible\n    isValidNot0: (num: bigint) => !f.is0(num) && f.isValid(num),\n    isOdd: (num) => (num & _1n) === _1n,\n    neg: (num) => mod(-num, ORDER),\n    eql: (lhs, rhs) => lhs === rhs,\n\n    sqr: (num) => mod(num * num, ORDER),\n    add: (lhs, rhs) => mod(lhs + rhs, ORDER),\n    sub: (lhs, rhs) => mod(lhs - rhs, ORDER),\n    mul: (lhs, rhs) => mod(lhs * rhs, ORDER),\n    pow: (num, power) => FpPow(f, num, power),\n    div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),\n\n    // Same as above, but doesn't normalize\n    sqrN: (num) => num * num,\n    addN: (lhs, rhs) => lhs + rhs,\n    subN: (lhs, rhs) => lhs - rhs,\n    mulN: (lhs, rhs) => lhs * rhs,\n\n    inv: (num) => invert(num, ORDER),\n    sqrt:\n      _sqrt ||\n      ((n) => {\n        if (!sqrtP) sqrtP = FpSqrt(ORDER);\n        return sqrtP(f, n);\n      }),\n    toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),\n    fromBytes: (bytes, skipValidation = true) => {\n      if (allowedLengths) {\n        if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {\n          throw new Error(\n            'Field.fromBytes: expected ' + allowedLengths + ' bytes, got ' + bytes.length\n          );\n        }\n        const padded = new Uint8Array(BYTES);\n        // isLE add 0 to right, !isLE to the left.\n        padded.set(bytes, isLE ? 0 : padded.length - bytes.length);\n        bytes = padded;\n      }\n      if (bytes.length !== BYTES)\n        throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);\n      let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n      if (modFromBytes) scalar = mod(scalar, ORDER);\n      if (!skipValidation)\n        if (!f.isValid(scalar)) throw new Error('invalid field element: outside of range 0..ORDER');\n      // NOTE: we don't validate scalar here, please use isValid. This done such way because some\n      // protocol may allow non-reduced scalar that reduced later or changed some other way.\n      return scalar;\n    },\n    // TODO: we don't need it here, move out to separate fn\n    invertBatch: (lst) => FpInvertBatch(f, lst),\n    // We can't move this out because Fp6, Fp12 implement it\n    // and it's unclear what to return in there.\n    cmov: (a, b, c) => (c ? b : a),\n  } as FpField);\n  return Object.freeze(f);\n}\n\n// Generic random scalar, we can do same for other fields if via Fp2.mul(Fp2.ONE, Fp2.random)?\n// This allows unsafe methods like ignore bias or zero. These unsafe, but often used in different protocols (if deterministic RNG).\n// which mean we cannot force this via opts.\n// Not sure what to do with randomBytes, we can accept it inside opts if wanted.\n// Probably need to export getMinHashLength somewhere?\n// random(bytes?: Uint8Array, unsafeAllowZero = false, unsafeAllowBias = false) {\n//   const LEN = !unsafeAllowBias ? getMinHashLength(ORDER) : BYTES;\n//   if (bytes === undefined) bytes = randomBytes(LEN); // _opts.randomBytes?\n//   const num = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n//   // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n//   const reduced = unsafeAllowZero ? mod(num, ORDER) : mod(num, ORDER - _1n) + _1n;\n//   return reduced;\n// },\n\nexport function FpSqrtOdd<T>(Fp: IField<T>, elm: T): T {\n  if (!Fp.isOdd) throw new Error(\"Field doesn't have isOdd\");\n  const root = Fp.sqrt(elm);\n  return Fp.isOdd(root) ? root : Fp.neg(root);\n}\n\nexport function FpSqrtEven<T>(Fp: IField<T>, elm: T): T {\n  if (!Fp.isOdd) throw new Error(\"Field doesn't have isOdd\");\n  const root = Fp.sqrt(elm);\n  return Fp.isOdd(root) ? Fp.neg(root) : root;\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Same as mapKeyToField, but accepts less bytes (40 instead of 48 for 32-byte field).\n * Which makes it slightly more biased, less secure.\n * @deprecated use `mapKeyToField` instead\n */\nexport function hashToPrivateScalar(\n  hash: string | Uint8Array,\n  groupOrder: bigint,\n  isLE = false\n): bigint {\n  hash = ensureBytes('privateHash', hash);\n  const hashLen = hash.length;\n  const minLen = nLength(groupOrder).nByteLength + 8;\n  if (minLen < 24 || hashLen < minLen || hashLen > 1024)\n    throw new Error(\n      'hashToPrivateScalar: expected ' + minLen + '-1024 bytes of input, got ' + hashLen\n    );\n  const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);\n  return mod(num, groupOrder - _1n) + _1n;\n}\n\n/**\n * Returns total number of bytes consumed by the field element.\n * For example, 32 bytes for usual 256-bit weierstrass curve.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of field\n */\nexport function getFieldBytesLength(fieldOrder: bigint): number {\n  if (typeof fieldOrder !== 'bigint') throw new Error('field order must be bigint');\n  const bitLength = fieldOrder.toString(2).length;\n  return Math.ceil(bitLength / 8);\n}\n\n/**\n * Returns minimal amount of bytes that can be safely reduced\n * by field order.\n * Should be 2^-128 for 128-bit curve such as P256.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of target hash\n */\nexport function getMinHashLength(fieldOrder: bigint): number {\n  const length = getFieldBytesLength(fieldOrder);\n  return length + Math.ceil(length / 2);\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF\n * and convert them into private scalar, with the modulo bias being negligible.\n * Needs at least 48 bytes of input for 32-byte private key.\n * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/\n * FIPS 186-5, A.2 https://csrc.nist.gov/publications/detail/fips/186/5/final\n * RFC 9380, https://www.rfc-editor.org/rfc/rfc9380#section-5\n * @param hash hash output from SHA3 or a similar function\n * @param groupOrder size of subgroup - (e.g. secp256k1.CURVE.n)\n * @param isLE interpret hash bytes as LE num\n * @returns valid private scalar\n */\nexport function mapHashToField(key: Uint8Array, fieldOrder: bigint, isLE = false): Uint8Array {\n  const len = key.length;\n  const fieldLen = getFieldBytesLength(fieldOrder);\n  const minLen = getMinHashLength(fieldOrder);\n  // No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.\n  if (len < 16 || len < minLen || len > 1024)\n    throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);\n  const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);\n  // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n  const reduced = mod(num, fieldOrder - _1n) + _1n;\n  return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);\n}\n","/**\n * Methods for elliptic curve multiplication by scalars.\n * Contains wNAF, pippenger.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { bitLen, bitMask, validateObject } from '../utils.ts';\nimport { Field, FpInvertBatch, nLength, validateField, type IField } from './modular.ts';\n\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\n\nexport type AffinePoint<T> = {\n  x: T;\n  y: T;\n} & { Z?: never };\n\n// This was initialy do this way to re-use montgomery ladder in field (add->mul,double->sqr), but\n// that didn't happen and there is probably not much reason to have separate Group like this?\nexport interface Group<T extends Group<T>> {\n  double(): T;\n  negate(): T;\n  add(other: T): T;\n  subtract(other: T): T;\n  equals(other: T): boolean;\n  multiply(scalar: bigint): T;\n  toAffine?(invertedZ?: any): AffinePoint<any>;\n}\n\n// We can't \"abstract out\" coordinates (X, Y, Z; and T in Edwards): argument names of constructor\n// are not accessible. See Typescript gh-56093, gh-41594.\n//\n// We have to use recursive types, so it will return actual point, not constained `CurvePoint`.\n// If, at any point, P is `any`, it will erase all types and replace it\n// with `any`, because of recursion, `any implements CurvePoint`,\n// but we lose all constrains on methods.\n\n/** Base interface for all elliptic curve Points. */\nexport interface CurvePoint<F, P extends CurvePoint<F, P>> extends Group<P> {\n  /** Affine x coordinate. Different from projective / extended X coordinate. */\n  x: F;\n  /** Affine y coordinate. Different from projective / extended Y coordinate. */\n  y: F;\n  Z?: F;\n  double(): P;\n  negate(): P;\n  add(other: P): P;\n  subtract(other: P): P;\n  equals(other: P): boolean;\n  multiply(scalar: bigint): P;\n  assertValidity(): void;\n  clearCofactor(): P;\n  is0(): boolean;\n  isTorsionFree(): boolean;\n  isSmallOrder(): boolean;\n  multiplyUnsafe(scalar: bigint): P;\n  /**\n   * Massively speeds up `p.multiply(n)` by using precompute tables (caching). See {@link wNAF}.\n   * @param isLazy calculate cache now. Default (true) ensures it's deferred to first `multiply()`\n   */\n  precompute(windowSize?: number, isLazy?: boolean): P;\n  /** Converts point to 2D xy affine coordinates */\n  toAffine(invertedZ?: F): AffinePoint<F>;\n  toBytes(): Uint8Array;\n  toHex(): string;\n}\n\n/** Base interface for all elliptic curve Point constructors. */\nexport interface CurvePointCons<P extends CurvePoint<any, P>> {\n  [Symbol.hasInstance]: (item: unknown) => boolean;\n  BASE: P;\n  ZERO: P;\n  /** Field for basic curve math */\n  Fp: IField<P_F<P>>;\n  /** Scalar field, for scalars in multiply and others */\n  Fn: IField<bigint>;\n  /** Creates point from x, y. Does NOT validate if the point is valid. Use `.assertValidity()`. */\n  fromAffine(p: AffinePoint<P_F<P>>): P;\n  fromBytes(bytes: Uint8Array): P;\n  fromHex(hex: Uint8Array | string): P;\n}\n\n// Type inference helpers: PC - PointConstructor, P - Point, Fp - Field element\n// Short names, because we use them a lot in result types:\n// * we can't do 'P = GetCurvePoint<PC>': this is default value and doesn't constrain anything\n// * we can't do 'type X = GetCurvePoint<PC>': it won't be accesible for arguments/return types\n// * `CurvePointCons<P extends CurvePoint<any, P>>` constraints from interface definition\n//   won't propagate, if `PC extends CurvePointCons<any>`: the P would be 'any', which is incorrect\n// * PC could be super specific with super specific P, which implements CurvePoint<any, P>.\n//   this means we need to do stuff like\n//   `function test<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(`\n//   if we want type safety around P, otherwise PC_P<PC> will be any\n\n/** Returns Fp type from Point (P_F<P> == P.F) */\nexport type P_F<P extends CurvePoint<any, P>> = P extends CurvePoint<infer F, P> ? F : never;\n/** Returns Fp type from PointCons (PC_F<PC> == PC.P.F) */\nexport type PC_F<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['Fp']['ZERO'];\n/** Returns Point type from PointCons (PC_P<PC> == PC.P) */\nexport type PC_P<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['ZERO'];\n\n// Ugly hack to get proper type inference, because in typescript fails to infer resursively.\n// The hack allows to do up to 10 chained operations without applying type erasure.\n//\n// Types which won't work:\n// * `CurvePointCons<CurvePoint<any, any>>`, will return `any` after 1 operation\n// * `CurvePointCons<any>: WeierstrassPointCons<bigint> extends CurvePointCons<any> = false`\n// * `P extends CurvePoint, PC extends CurvePointCons<P>`\n//     * It can't infer P from PC alone\n//     * Too many relations between F, P & PC\n//     * It will infer P/F if `arg: CurvePointCons<F, P>`, but will fail if PC is generic\n//     * It will work correctly if there is an additional argument of type P\n//     * But generally, we don't want to parametrize `CurvePointCons` over `F`: it will complicate\n//       types, making them un-inferable\n// prettier-ignore\nexport type PC_ANY = CurvePointCons<\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any,\n  CurvePoint<any, any>\n  >>>>>>>>>\n>;\n\nexport interface CurveLengths {\n  secretKey?: number;\n  publicKey?: number;\n  publicKeyUncompressed?: number;\n  publicKeyHasPrefix?: boolean;\n  signature?: number;\n  seed?: number;\n}\nexport type GroupConstructor<T> = {\n  BASE: T;\n  ZERO: T;\n};\n/** @deprecated */\nexport type ExtendedGroupConstructor<T> = GroupConstructor<T> & {\n  Fp: IField<any>;\n  Fn: IField<bigint>;\n  fromAffine(ap: AffinePoint<any>): T;\n};\nexport type Mapper<T> = (i: T[]) => T[];\n\nexport function negateCt<T extends { negate: () => T }>(condition: boolean, item: T): T {\n  const neg = item.negate();\n  return condition ? neg : item;\n}\n\n/**\n * Takes a bunch of Projective Points but executes only one\n * inversion on all of them. Inversion is very slow operation,\n * so this improves performance massively.\n * Optimization: converts a list of projective points to a list of identical points with Z=1.\n */\nexport function normalizeZ<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n  c: PC,\n  points: P[]\n): P[] {\n  const invertedZs = FpInvertBatch(\n    c.Fp,\n    points.map((p) => p.Z!)\n  );\n  return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));\n}\n\nfunction validateW(W: number, bits: number) {\n  if (!Number.isSafeInteger(W) || W <= 0 || W > bits)\n    throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);\n}\n\n/** Internal wNAF opts for specific W and scalarBits */\nexport type WOpts = {\n  windows: number;\n  windowSize: number;\n  mask: bigint;\n  maxNumber: number;\n  shiftBy: bigint;\n};\n\nfunction calcWOpts(W: number, scalarBits: number): WOpts {\n  validateW(W, scalarBits);\n  const windows = Math.ceil(scalarBits / W) + 1; // W=8 33. Not 32, because we skip zero\n  const windowSize = 2 ** (W - 1); // W=8 128. Not 256, because we skip zero\n  const maxNumber = 2 ** W; // W=8 256\n  const mask = bitMask(W); // W=8 255 == mask 0b11111111\n  const shiftBy = BigInt(W); // W=8 8\n  return { windows, windowSize, mask, maxNumber, shiftBy };\n}\n\nfunction calcOffsets(n: bigint, window: number, wOpts: WOpts) {\n  const { windowSize, mask, maxNumber, shiftBy } = wOpts;\n  let wbits = Number(n & mask); // extract W bits.\n  let nextN = n >> shiftBy; // shift number by W bits.\n\n  // What actually happens here:\n  // const highestBit = Number(mask ^ (mask >> 1n));\n  // let wbits2 = wbits - 1; // skip zero\n  // if (wbits2 & highestBit) { wbits2 ^= Number(mask); // (~);\n\n  // split if bits > max: +224 => 256-32\n  if (wbits > windowSize) {\n    // we skip zero, which means instead of `>= size-1`, we do `> size`\n    wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.\n    nextN += _1n; // +256 (carry)\n  }\n  const offsetStart = window * windowSize;\n  const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero\n  const isZero = wbits === 0; // is current window slice a 0?\n  const isNeg = wbits < 0; // is current window slice negative?\n  const isNegF = window % 2 !== 0; // fake random statement for noise\n  const offsetF = offsetStart; // fake offset for noise\n  return { nextN, offset, isZero, isNeg, isNegF, offsetF };\n}\n\nfunction validateMSMPoints(points: any[], c: any) {\n  if (!Array.isArray(points)) throw new Error('array expected');\n  points.forEach((p, i) => {\n    if (!(p instanceof c)) throw new Error('invalid point at index ' + i);\n  });\n}\nfunction validateMSMScalars(scalars: any[], field: any) {\n  if (!Array.isArray(scalars)) throw new Error('array of scalars expected');\n  scalars.forEach((s, i) => {\n    if (!field.isValid(s)) throw new Error('invalid scalar at index ' + i);\n  });\n}\n\n// Since points in different groups cannot be equal (different object constructor),\n// we can have single place to store precomputes.\n// Allows to make points frozen / immutable.\nconst pointPrecomputes = new WeakMap<any, any[]>();\nconst pointWindowSizes = new WeakMap<any, number>();\n\nfunction getW(P: any): number {\n  // To disable precomputes:\n  // return 1;\n  return pointWindowSizes.get(P) || 1;\n}\n\nfunction assert0(n: bigint): void {\n  if (n !== _0n) throw new Error('invalid wNAF');\n}\n\n/**\n * Elliptic curve multiplication of Point by scalar. Fragile.\n * Table generation takes **30MB of ram and 10ms on high-end CPU**,\n * but may take much longer on slow devices. Actual generation will happen on\n * first call of `multiply()`. By default, `BASE` point is precomputed.\n *\n * Scalars should always be less than curve order: this should be checked inside of a curve itself.\n * Creates precomputation tables for fast multiplication:\n * - private scalar is split by fixed size windows of W bits\n * - every window point is collected from window's table & added to accumulator\n * - since windows are different, same point inside tables won't be accessed more than once per calc\n * - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)\n * - +1 window is neccessary for wNAF\n * - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication\n *\n * @todo Research returning 2d JS array of windows, instead of a single window.\n * This would allow windows to be in different memory locations\n */\nexport class wNAF<PC extends PC_ANY> {\n  private readonly BASE: PC_P<PC>;\n  private readonly ZERO: PC_P<PC>;\n  private readonly Fn: PC['Fn'];\n  readonly bits: number;\n\n  // Parametrized with a given Point class (not individual point)\n  constructor(Point: PC, bits: number) {\n    this.BASE = Point.BASE;\n    this.ZERO = Point.ZERO;\n    this.Fn = Point.Fn;\n    this.bits = bits;\n  }\n\n  // non-const time multiplication ladder\n  _unsafeLadder(elm: PC_P<PC>, n: bigint, p: PC_P<PC> = this.ZERO): PC_P<PC> {\n    let d: PC_P<PC> = elm;\n    while (n > _0n) {\n      if (n & _1n) p = p.add(d);\n      d = d.double();\n      n >>= _1n;\n    }\n    return p;\n  }\n\n  /**\n   * Creates a wNAF precomputation window. Used for caching.\n   * Default window size is set by `utils.precompute()` and is equal to 8.\n   * Number of precomputed points depends on the curve size:\n   * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:\n   * - 𝑊 is the window size\n   * - 𝑛 is the bitlength of the curve order.\n   * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.\n   * @param point Point instance\n   * @param W window size\n   * @returns precomputed point tables flattened to a single array\n   */\n  private precomputeWindow(point: PC_P<PC>, W: number): PC_P<PC>[] {\n    const { windows, windowSize } = calcWOpts(W, this.bits);\n    const points: PC_P<PC>[] = [];\n    let p: PC_P<PC> = point;\n    let base = p;\n    for (let window = 0; window < windows; window++) {\n      base = p;\n      points.push(base);\n      // i=1, bc we skip 0\n      for (let i = 1; i < windowSize; i++) {\n        base = base.add(p);\n        points.push(base);\n      }\n      p = base.double();\n    }\n    return points;\n  }\n\n  /**\n   * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.\n   * More compact implementation:\n   * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541\n   * @returns real and fake (for const-time) points\n   */\n  private wNAF(W: number, precomputes: PC_P<PC>[], n: bigint): { p: PC_P<PC>; f: PC_P<PC> } {\n    // Scalar should be smaller than field order\n    if (!this.Fn.isValid(n)) throw new Error('invalid scalar');\n    // Accumulators\n    let p = this.ZERO;\n    let f = this.BASE;\n    // This code was first written with assumption that 'f' and 'p' will never be infinity point:\n    // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,\n    // there is negate now: it is possible that negated element from low value\n    // would be the same as high element, which will create carry into next window.\n    // It's not obvious how this can fail, but still worth investigating later.\n    const wo = calcWOpts(W, this.bits);\n    for (let window = 0; window < wo.windows; window++) {\n      // (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise\n      const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);\n      n = nextN;\n      if (isZero) {\n        // bits are 0: add garbage to fake point\n        // Important part for const-time getPublicKey: add random \"noise\" point to f.\n        f = f.add(negateCt(isNegF, precomputes[offsetF]));\n      } else {\n        // bits are 1: add to result point\n        p = p.add(negateCt(isNeg, precomputes[offset]));\n      }\n    }\n    assert0(n);\n    // Return both real and fake points: JIT won't eliminate f.\n    // At this point there is a way to F be infinity-point even if p is not,\n    // which makes it less const-time: around 1 bigint multiply.\n    return { p, f };\n  }\n\n  /**\n   * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.\n   * @param acc accumulator point to add result of multiplication\n   * @returns point\n   */\n  private wNAFUnsafe(\n    W: number,\n    precomputes: PC_P<PC>[],\n    n: bigint,\n    acc: PC_P<PC> = this.ZERO\n  ): PC_P<PC> {\n    const wo = calcWOpts(W, this.bits);\n    for (let window = 0; window < wo.windows; window++) {\n      if (n === _0n) break; // Early-exit, skip 0 value\n      const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);\n      n = nextN;\n      if (isZero) {\n        // Window bits are 0: skip processing.\n        // Move to next window.\n        continue;\n      } else {\n        const item = precomputes[offset];\n        acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM\n      }\n    }\n    assert0(n);\n    return acc;\n  }\n\n  private getPrecomputes(W: number, point: PC_P<PC>, transform?: Mapper<PC_P<PC>>): PC_P<PC>[] {\n    // Calculate precomputes on a first run, reuse them after\n    let comp = pointPrecomputes.get(point);\n    if (!comp) {\n      comp = this.precomputeWindow(point, W) as PC_P<PC>[];\n      if (W !== 1) {\n        // Doing transform outside of if brings 15% perf hit\n        if (typeof transform === 'function') comp = transform(comp);\n        pointPrecomputes.set(point, comp);\n      }\n    }\n    return comp;\n  }\n\n  cached(\n    point: PC_P<PC>,\n    scalar: bigint,\n    transform?: Mapper<PC_P<PC>>\n  ): { p: PC_P<PC>; f: PC_P<PC> } {\n    const W = getW(point);\n    return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);\n  }\n\n  unsafe(point: PC_P<PC>, scalar: bigint, transform?: Mapper<PC_P<PC>>, prev?: PC_P<PC>): PC_P<PC> {\n    const W = getW(point);\n    if (W === 1) return this._unsafeLadder(point, scalar, prev); // For W=1 ladder is ~x2 faster\n    return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);\n  }\n\n  // We calculate precomputes for elliptic curve point multiplication\n  // using windowed method. This specifies window size and\n  // stores precomputed values. Usually only base point would be precomputed.\n  createCache(P: PC_P<PC>, W: number): void {\n    validateW(W, this.bits);\n    pointWindowSizes.set(P, W);\n    pointPrecomputes.delete(P);\n  }\n\n  hasCache(elm: PC_P<PC>): boolean {\n    return getW(elm) !== 1;\n  }\n}\n\n/**\n * Endomorphism-specific multiplication for Koblitz curves.\n * Cost: 128 dbl, 0-256 adds.\n */\nexport function mulEndoUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n  Point: PC,\n  point: P,\n  k1: bigint,\n  k2: bigint\n): { p1: P; p2: P } {\n  let acc = point;\n  let p1 = Point.ZERO;\n  let p2 = Point.ZERO;\n  while (k1 > _0n || k2 > _0n) {\n    if (k1 & _1n) p1 = p1.add(acc);\n    if (k2 & _1n) p2 = p2.add(acc);\n    acc = acc.double();\n    k1 >>= _1n;\n    k2 >>= _1n;\n  }\n  return { p1, p2 };\n}\n\n/**\n * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * 30x faster vs naive addition on L=4096, 10x faster than precomputes.\n * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.\n * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.\n * @param c Curve Point constructor\n * @param fieldN field over CURVE.N - important that it's not over CURVE.P\n * @param points array of L curve points\n * @param scalars array of L scalars (aka secret keys / bigints)\n */\nexport function pippenger<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n  c: PC,\n  fieldN: IField<bigint>,\n  points: P[],\n  scalars: bigint[]\n): P {\n  // If we split scalars by some window (let's say 8 bits), every chunk will only\n  // take 256 buckets even if there are 4096 scalars, also re-uses double.\n  // TODO:\n  // - https://eprint.iacr.org/2024/750.pdf\n  // - https://tches.iacr.org/index.php/TCHES/article/view/10287\n  // 0 is accepted in scalars\n  validateMSMPoints(points, c);\n  validateMSMScalars(scalars, fieldN);\n  const plength = points.length;\n  const slength = scalars.length;\n  if (plength !== slength) throw new Error('arrays of points and scalars must have equal length');\n  // if (plength === 0) throw new Error('array must be of length >= 2');\n  const zero = c.ZERO;\n  const wbits = bitLen(BigInt(plength));\n  let windowSize = 1; // bits\n  if (wbits > 12) windowSize = wbits - 3;\n  else if (wbits > 4) windowSize = wbits - 2;\n  else if (wbits > 0) windowSize = 2;\n  const MASK = bitMask(windowSize);\n  const buckets = new Array(Number(MASK) + 1).fill(zero); // +1 for zero array\n  const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;\n  let sum = zero;\n  for (let i = lastBits; i >= 0; i -= windowSize) {\n    buckets.fill(zero);\n    for (let j = 0; j < slength; j++) {\n      const scalar = scalars[j];\n      const wbits = Number((scalar >> BigInt(i)) & MASK);\n      buckets[wbits] = buckets[wbits].add(points[j]);\n    }\n    let resI = zero; // not using this will do small speed-up, but will lose ct\n    // Skip first bucket, because it is zero\n    for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {\n      sumI = sumI.add(buckets[j]);\n      resI = resI.add(sumI);\n    }\n    sum = sum.add(resI);\n    if (i !== 0) for (let j = 0; j < windowSize; j++) sum = sum.double();\n  }\n  return sum as P;\n}\n/**\n * Precomputed multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * @param c Curve Point constructor\n * @param fieldN field over CURVE.N - important that it's not over CURVE.P\n * @param points array of L curve points\n * @returns function which multiplies points with scaars\n */\nexport function precomputeMSMUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n  c: PC,\n  fieldN: IField<bigint>,\n  points: P[],\n  windowSize: number\n): (scalars: bigint[]) => P {\n  /**\n   * Performance Analysis of Window-based Precomputation\n   *\n   * Base Case (256-bit scalar, 8-bit window):\n   * - Standard precomputation requires:\n   *   - 31 additions per scalar × 256 scalars = 7,936 ops\n   *   - Plus 255 summary additions = 8,191 total ops\n   *   Note: Summary additions can be optimized via accumulator\n   *\n   * Chunked Precomputation Analysis:\n   * - Using 32 chunks requires:\n   *   - 255 additions per chunk\n   *   - 256 doublings\n   *   - Total: (255 × 32) + 256 = 8,416 ops\n   *\n   * Memory Usage Comparison:\n   * Window Size | Standard Points | Chunked Points\n   * ------------|-----------------|---------------\n   *     4-bit   |     520         |      15\n   *     8-bit   |    4,224        |     255\n   *    10-bit   |   13,824        |   1,023\n   *    16-bit   |  557,056        |  65,535\n   *\n   * Key Advantages:\n   * 1. Enables larger window sizes due to reduced memory overhead\n   * 2. More efficient for smaller scalar counts:\n   *    - 16 chunks: (16 × 255) + 256 = 4,336 ops\n   *    - ~2x faster than standard 8,191 ops\n   *\n   * Limitations:\n   * - Not suitable for plain precomputes (requires 256 constant doublings)\n   * - Performance degrades with larger scalar counts:\n   *   - Optimal for ~256 scalars\n   *   - Less efficient for 4096+ scalars (Pippenger preferred)\n   */\n  validateW(windowSize, fieldN.BITS);\n  validateMSMPoints(points, c);\n  const zero = c.ZERO;\n  const tableSize = 2 ** windowSize - 1; // table size (without zero)\n  const chunks = Math.ceil(fieldN.BITS / windowSize); // chunks of item\n  const MASK = bitMask(windowSize);\n  const tables = points.map((p: P) => {\n    const res = [];\n    for (let i = 0, acc = p; i < tableSize; i++) {\n      res.push(acc);\n      acc = acc.add(p);\n    }\n    return res;\n  });\n  return (scalars: bigint[]): P => {\n    validateMSMScalars(scalars, fieldN);\n    if (scalars.length > points.length)\n      throw new Error('array of scalars must be smaller than array of points');\n    let res = zero;\n    for (let i = 0; i < chunks; i++) {\n      // No need to double if accumulator is still zero.\n      if (res !== zero) for (let j = 0; j < windowSize; j++) res = res.double();\n      const shiftBy = BigInt(chunks * windowSize - (i + 1) * windowSize);\n      for (let j = 0; j < scalars.length; j++) {\n        const n = scalars[j];\n        const curr = Number((n >> shiftBy) & MASK);\n        if (!curr) continue; // skip zero scalars chunks\n        res = res.add(tables[j][curr - 1]);\n      }\n    }\n    return res;\n  };\n}\n\n// TODO: remove\n/**\n * Generic BasicCurve interface: works even for polynomial fields (BLS): P, n, h would be ok.\n * Though generator can be different (Fp2 / Fp6 for BLS).\n */\nexport type BasicCurve<T> = {\n  Fp: IField<T>; // Field over which we'll do calculations (Fp)\n  n: bigint; // Curve order, total count of valid points in the field\n  nBitLength?: number; // bit length of curve order\n  nByteLength?: number; // byte length of curve order\n  h: bigint; // cofactor. we can assign default=1, but users will just ignore it w/o validation\n  hEff?: bigint; // Number to multiply to clear cofactor\n  Gx: T; // base point X coordinate\n  Gy: T; // base point Y coordinate\n  allowInfinityPoint?: boolean; // bls12-381 requires it. ZERO point is valid, but invalid pubkey\n};\n\n// TODO: remove\n/** @deprecated */\nexport function validateBasic<FP, T>(\n  curve: BasicCurve<FP> & T\n): Readonly<\n  {\n    readonly nBitLength: number;\n    readonly nByteLength: number;\n  } & BasicCurve<FP> &\n    T & {\n      p: bigint;\n    }\n> {\n  validateField(curve.Fp);\n  validateObject(\n    curve,\n    {\n      n: 'bigint',\n      h: 'bigint',\n      Gx: 'field',\n      Gy: 'field',\n    },\n    {\n      nBitLength: 'isSafeInteger',\n      nByteLength: 'isSafeInteger',\n    }\n  );\n  // Set defaults\n  return Object.freeze({\n    ...nLength(curve.n, curve.nBitLength),\n    ...curve,\n    ...{ p: curve.Fp.ORDER },\n  } as const);\n}\n\nexport type ValidCurveParams<T> = {\n  p: bigint;\n  n: bigint;\n  h: bigint;\n  a: T;\n  b?: T;\n  d?: T;\n  Gx: T;\n  Gy: T;\n};\n\nfunction createField<T>(order: bigint, field?: IField<T>, isLE?: boolean): IField<T> {\n  if (field) {\n    if (field.ORDER !== order) throw new Error('Field.ORDER must match order: Fp == p, Fn == n');\n    validateField(field);\n    return field;\n  } else {\n    return Field(order, { isLE }) as unknown as IField<T>;\n  }\n}\nexport type FpFn<T> = { Fp: IField<T>; Fn: IField<bigint> };\n\n/** Validates CURVE opts and creates fields */\nexport function _createCurveFields<T>(\n  type: 'weierstrass' | 'edwards',\n  CURVE: ValidCurveParams<T>,\n  curveOpts: Partial<FpFn<T>> = {},\n  FpFnLE?: boolean\n): FpFn<T> & { CURVE: ValidCurveParams<T> } {\n  if (FpFnLE === undefined) FpFnLE = type === 'edwards';\n  if (!CURVE || typeof CURVE !== 'object') throw new Error(`expected valid ${type} CURVE object`);\n  for (const p of ['p', 'n', 'h'] as const) {\n    const val = CURVE[p];\n    if (!(typeof val === 'bigint' && val > _0n))\n      throw new Error(`CURVE.${p} must be positive bigint`);\n  }\n  const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);\n  const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);\n  const _b: 'b' | 'd' = type === 'weierstrass' ? 'b' : 'd';\n  const params = ['Gx', 'Gy', 'a', _b] as const;\n  for (const p of params) {\n    // @ts-ignore\n    if (!Fp.isValid(CURVE[p]))\n      throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);\n  }\n  CURVE = Object.freeze(Object.assign({}, CURVE));\n  return { CURVE, Fp, Fn };\n}\n","/**\n * Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².\n * For design rationale of types / exports, see weierstrass module documentation.\n * Untwisted Edwards curves exist, but they aren't used in real-world protocols.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n  _validateObject,\n  _abool2 as abool,\n  _abytes2 as abytes,\n  aInRange,\n  bytesToHex,\n  bytesToNumberLE,\n  concatBytes,\n  copyBytes,\n  ensureBytes,\n  isBytes,\n  memoized,\n  notImplemented,\n  randomBytes as randomBytesWeb,\n  type FHash,\n  type Hex,\n} from '../utils.ts';\nimport {\n  _createCurveFields,\n  normalizeZ,\n  pippenger,\n  wNAF,\n  type AffinePoint,\n  type BasicCurve,\n  type CurveLengths,\n  type CurvePoint,\n  type CurvePointCons,\n} from './curve.ts';\nimport { Field, type IField, type NLength } from './modular.ts';\n\n// Be friendly to bad ECMAScript parsers by not using bigint literals\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _8n = BigInt(8);\n\nexport type UVRatio = (u: bigint, v: bigint) => { isValid: boolean; value: bigint };\n\n/** Instance of Extended Point with coordinates in X, Y, Z, T. */\nexport interface EdwardsPoint extends CurvePoint<bigint, EdwardsPoint> {\n  /** extended X coordinate. Different from affine x. */\n  readonly X: bigint;\n  /** extended Y coordinate. Different from affine y. */\n  readonly Y: bigint;\n  /** extended Z coordinate */\n  readonly Z: bigint;\n  /** extended T coordinate */\n  readonly T: bigint;\n\n  /** @deprecated use `toBytes` */\n  toRawBytes(): Uint8Array;\n  /** @deprecated use `p.precompute(windowSize)` */\n  _setWindowSize(windowSize: number): void;\n  /** @deprecated use .X */\n  readonly ex: bigint;\n  /** @deprecated use .Y */\n  readonly ey: bigint;\n  /** @deprecated use .Z */\n  readonly ez: bigint;\n  /** @deprecated use .T */\n  readonly et: bigint;\n}\n/** Static methods of Extended Point with coordinates in X, Y, Z, T. */\nexport interface EdwardsPointCons extends CurvePointCons<EdwardsPoint> {\n  new (X: bigint, Y: bigint, Z: bigint, T: bigint): EdwardsPoint;\n  CURVE(): EdwardsOpts;\n  fromBytes(bytes: Uint8Array, zip215?: boolean): EdwardsPoint;\n  fromHex(hex: Hex, zip215?: boolean): EdwardsPoint;\n  /** @deprecated use `import { pippenger } from '@noble/curves/abstract/curve.js';` */\n  msm(points: EdwardsPoint[], scalars: bigint[]): EdwardsPoint;\n}\n/** @deprecated use EdwardsPoint */\nexport type ExtPointType = EdwardsPoint;\n/** @deprecated use EdwardsPointCons */\nexport type ExtPointConstructor = EdwardsPointCons;\n\n/**\n * Twisted Edwards curve options.\n *\n * * a: formula param\n * * d: formula param\n * * p: prime characteristic (order) of finite field, in which arithmetics is done\n * * n: order of prime subgroup a.k.a total amount of valid curve points\n * * h: cofactor. h*n is group order; n is subgroup order\n * * Gx: x coordinate of generator point a.k.a. base point\n * * Gy: y coordinate of generator point\n */\nexport type EdwardsOpts = Readonly<{\n  p: bigint;\n  n: bigint;\n  h: bigint;\n  a: bigint;\n  d: bigint;\n  Gx: bigint;\n  Gy: bigint;\n}>;\n\n/**\n * Extra curve options for Twisted Edwards.\n *\n * * Fp: redefined Field over curve.p\n * * Fn: redefined Field over curve.n\n * * uvRatio: helper function for decompression, calculating √(u/v)\n */\nexport type EdwardsExtraOpts = Partial<{\n  Fp: IField<bigint>;\n  Fn: IField<bigint>;\n  FpFnLE: boolean;\n  uvRatio: (u: bigint, v: bigint) => { isValid: boolean; value: bigint };\n}>;\n\n/**\n * EdDSA (Edwards Digital Signature algorithm) options.\n *\n * * hash: hash function used to hash secret keys and messages\n * * adjustScalarBytes: clears bits to get valid field element\n * * domain: Used for hashing\n * * mapToCurve: for hash-to-curve standard\n * * prehash: RFC 8032 pre-hashing of messages to sign() / verify()\n * * randomBytes: function generating random bytes, used for randomSecretKey\n */\nexport type EdDSAOpts = Partial<{\n  adjustScalarBytes: (bytes: Uint8Array) => Uint8Array;\n  domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;\n  mapToCurve: (scalar: bigint[]) => AffinePoint<bigint>;\n  prehash: FHash;\n  randomBytes: (bytesLength?: number) => Uint8Array;\n}>;\n\n/**\n * EdDSA (Edwards Digital Signature algorithm) interface.\n *\n * Allows to create and verify signatures, create public and secret keys.\n */\nexport interface EdDSA {\n  keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };\n  getPublicKey: (secretKey: Hex) => Uint8Array;\n  sign: (message: Hex, secretKey: Hex, options?: { context?: Hex }) => Uint8Array;\n  verify: (\n    sig: Hex,\n    message: Hex,\n    publicKey: Hex,\n    options?: { context?: Hex; zip215: boolean }\n  ) => boolean;\n  Point: EdwardsPointCons;\n  utils: {\n    randomSecretKey: (seed?: Uint8Array) => Uint8Array;\n    isValidSecretKey: (secretKey: Uint8Array) => boolean;\n    isValidPublicKey: (publicKey: Uint8Array, zip215?: boolean) => boolean;\n\n    /**\n     * Converts ed public key to x public key.\n     *\n     * There is NO `fromMontgomery`:\n     * - There are 2 valid ed25519 points for every x25519, with flipped coordinate\n     * - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*\n     *   accepts inputs on the quadratic twist, which can't be moved to ed25519\n     *\n     * @example\n     * ```js\n     * const someonesPub = ed25519.getPublicKey(ed25519.utils.randomSecretKey());\n     * const aPriv = x25519.utils.randomSecretKey();\n     * x25519.getSharedSecret(aPriv, ed25519.utils.toMontgomery(someonesPub))\n     * ```\n     */\n    toMontgomery: (publicKey: Uint8Array) => Uint8Array;\n    /**\n     * Converts ed secret key to x secret key.\n     * @example\n     * ```js\n     * const someonesPub = x25519.getPublicKey(x25519.utils.randomSecretKey());\n     * const aPriv = ed25519.utils.randomSecretKey();\n     * x25519.getSharedSecret(ed25519.utils.toMontgomerySecret(aPriv), someonesPub)\n     * ```\n     */\n    toMontgomerySecret: (privateKey: Uint8Array) => Uint8Array;\n    getExtendedPublicKey: (key: Hex) => {\n      head: Uint8Array;\n      prefix: Uint8Array;\n      scalar: bigint;\n      point: EdwardsPoint;\n      pointBytes: Uint8Array;\n    };\n\n    /** @deprecated use `randomSecretKey` */\n    randomPrivateKey: (seed?: Uint8Array) => Uint8Array;\n    /** @deprecated use `point.precompute()` */\n    precompute: (windowSize?: number, point?: EdwardsPoint) => EdwardsPoint;\n  };\n  lengths: CurveLengths;\n}\n\nfunction isEdValidXY(Fp: IField<bigint>, CURVE: EdwardsOpts, x: bigint, y: bigint): boolean {\n  const x2 = Fp.sqr(x);\n  const y2 = Fp.sqr(y);\n  const left = Fp.add(Fp.mul(CURVE.a, x2), y2);\n  const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));\n  return Fp.eql(left, right);\n}\n\nexport function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}): EdwardsPointCons {\n  const validated = _createCurveFields('edwards', params, extraOpts, extraOpts.FpFnLE);\n  const { Fp, Fn } = validated;\n  let CURVE = validated.CURVE as EdwardsOpts;\n  const { h: cofactor } = CURVE;\n  _validateObject(extraOpts, {}, { uvRatio: 'function' });\n\n  // Important:\n  // There are some places where Fp.BYTES is used instead of nByteLength.\n  // So far, everything has been tested with curves of Fp.BYTES == nByteLength.\n  // TODO: test and find curves which behave otherwise.\n  const MASK = _2n << (BigInt(Fn.BYTES * 8) - _1n);\n  const modP = (n: bigint) => Fp.create(n); // Function overrides\n\n  // sqrt(u/v)\n  const uvRatio =\n    extraOpts.uvRatio ||\n    ((u: bigint, v: bigint) => {\n      try {\n        return { isValid: true, value: Fp.sqrt(Fp.div(u, v)) };\n      } catch (e) {\n        return { isValid: false, value: _0n };\n      }\n    });\n\n  // Validate whether the passed curve params are valid.\n  // equation ax² + y² = 1 + dx²y² should work for generator point.\n  if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy))\n    throw new Error('bad curve params: generator point');\n\n  /**\n   * Asserts coordinate is valid: 0 <= n < MASK.\n   * Coordinates >= Fp.ORDER are allowed for zip215.\n   */\n  function acoord(title: string, n: bigint, banZero = false) {\n    const min = banZero ? _1n : _0n;\n    aInRange('coordinate ' + title, n, min, MASK);\n    return n;\n  }\n\n  function aextpoint(other: unknown) {\n    if (!(other instanceof Point)) throw new Error('ExtendedPoint expected');\n  }\n  // Converts Extended point to default (x, y) coordinates.\n  // Can accept precomputed Z^-1 - for example, from invertBatch.\n  const toAffineMemo = memoized((p: Point, iz?: bigint): AffinePoint<bigint> => {\n    const { X, Y, Z } = p;\n    const is0 = p.is0();\n    if (iz == null) iz = is0 ? _8n : (Fp.inv(Z) as bigint); // 8 was chosen arbitrarily\n    const x = modP(X * iz);\n    const y = modP(Y * iz);\n    const zz = Fp.mul(Z, iz);\n    if (is0) return { x: _0n, y: _1n };\n    if (zz !== _1n) throw new Error('invZ was invalid');\n    return { x, y };\n  });\n  const assertValidMemo = memoized((p: Point) => {\n    const { a, d } = CURVE;\n    if (p.is0()) throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?\n    // Equation in affine coordinates: ax² + y² = 1 + dx²y²\n    // Equation in projective coordinates (X/Z, Y/Z, Z):  (aX² + Y²)Z² = Z⁴ + dX²Y²\n    const { X, Y, Z, T } = p;\n    const X2 = modP(X * X); // X²\n    const Y2 = modP(Y * Y); // Y²\n    const Z2 = modP(Z * Z); // Z²\n    const Z4 = modP(Z2 * Z2); // Z⁴\n    const aX2 = modP(X2 * a); // aX²\n    const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²\n    const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²\n    if (left !== right) throw new Error('bad point: equation left != right (1)');\n    // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T\n    const XY = modP(X * Y);\n    const ZT = modP(Z * T);\n    if (XY !== ZT) throw new Error('bad point: equation left != right (2)');\n    return true;\n  });\n\n  // Extended Point works in extended coordinates: (X, Y, Z, T) ∋ (x=X/Z, y=Y/Z, T=xy).\n  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates\n  class Point implements EdwardsPoint {\n    // base / generator point\n    static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));\n    // zero / infinity / identity point\n    static readonly ZERO = new Point(_0n, _1n, _1n, _0n); // 0, 1, 1, 0\n    // math field\n    static readonly Fp = Fp;\n    // scalar field\n    static readonly Fn = Fn;\n\n    readonly X: bigint;\n    readonly Y: bigint;\n    readonly Z: bigint;\n    readonly T: bigint;\n\n    constructor(X: bigint, Y: bigint, Z: bigint, T: bigint) {\n      this.X = acoord('x', X);\n      this.Y = acoord('y', Y);\n      this.Z = acoord('z', Z, true);\n      this.T = acoord('t', T);\n      Object.freeze(this);\n    }\n\n    static CURVE(): EdwardsOpts {\n      return CURVE;\n    }\n\n    static fromAffine(p: AffinePoint<bigint>): Point {\n      if (p instanceof Point) throw new Error('extended point not allowed');\n      const { x, y } = p || {};\n      acoord('x', x);\n      acoord('y', y);\n      return new Point(x, y, _1n, modP(x * y));\n    }\n\n    // Uses algo from RFC8032 5.1.3.\n    static fromBytes(bytes: Uint8Array, zip215 = false): Point {\n      const len = Fp.BYTES;\n      const { a, d } = CURVE;\n      bytes = copyBytes(abytes(bytes, len, 'point'));\n      abool(zip215, 'zip215');\n      const normed = copyBytes(bytes); // copy again, we'll manipulate it\n      const lastByte = bytes[len - 1]; // select last byte\n      normed[len - 1] = lastByte & ~0x80; // clear last bit\n      const y = bytesToNumberLE(normed);\n\n      // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.\n      // RFC8032 prohibits >= p, but ZIP215 doesn't\n      // zip215=true:  0 <= y < MASK (2^256 for ed25519)\n      // zip215=false: 0 <= y < P (2^255-19 for ed25519)\n      const max = zip215 ? MASK : Fp.ORDER;\n      aInRange('point.y', y, _0n, max);\n\n      // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:\n      // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)\n      const y2 = modP(y * y); // denominator is always non-0 mod p.\n      const u = modP(y2 - _1n); // u = y² - 1\n      const v = modP(d * y2 - a); // v = d y² + 1.\n      let { isValid, value: x } = uvRatio(u, v); // √(u/v)\n      if (!isValid) throw new Error('bad point: invalid y coordinate');\n      const isXOdd = (x & _1n) === _1n; // There are 2 square roots. Use x_0 bit to select proper\n      const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit\n      if (!zip215 && x === _0n && isLastByteOdd)\n        // if x=0 and x_0 = 1, fail\n        throw new Error('bad point: x=0 and x_0=1');\n      if (isLastByteOdd !== isXOdd) x = modP(-x); // if x_0 != x mod 2, set x = p-x\n      return Point.fromAffine({ x, y });\n    }\n    static fromHex(bytes: Uint8Array, zip215 = false): Point {\n      return Point.fromBytes(ensureBytes('point', bytes), zip215);\n    }\n\n    get x(): bigint {\n      return this.toAffine().x;\n    }\n    get y(): bigint {\n      return this.toAffine().y;\n    }\n\n    precompute(windowSize: number = 8, isLazy = true) {\n      wnaf.createCache(this, windowSize);\n      if (!isLazy) this.multiply(_2n); // random number\n      return this;\n    }\n\n    // Useful in fromAffine() - not for fromBytes(), which always created valid points.\n    assertValidity(): void {\n      assertValidMemo(this);\n    }\n\n    // Compare one point to another.\n    equals(other: Point): boolean {\n      aextpoint(other);\n      const { X: X1, Y: Y1, Z: Z1 } = this;\n      const { X: X2, Y: Y2, Z: Z2 } = other;\n      const X1Z2 = modP(X1 * Z2);\n      const X2Z1 = modP(X2 * Z1);\n      const Y1Z2 = modP(Y1 * Z2);\n      const Y2Z1 = modP(Y2 * Z1);\n      return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;\n    }\n\n    is0(): boolean {\n      return this.equals(Point.ZERO);\n    }\n\n    negate(): Point {\n      // Flips point sign to a negative one (-x, y in affine coords)\n      return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T));\n    }\n\n    // Fast algo for doubling Extended Point.\n    // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd\n    // Cost: 4M + 4S + 1*a + 6add + 1*2.\n    double(): Point {\n      const { a } = CURVE;\n      const { X: X1, Y: Y1, Z: Z1 } = this;\n      const A = modP(X1 * X1); // A = X12\n      const B = modP(Y1 * Y1); // B = Y12\n      const C = modP(_2n * modP(Z1 * Z1)); // C = 2*Z12\n      const D = modP(a * A); // D = a*A\n      const x1y1 = X1 + Y1;\n      const E = modP(modP(x1y1 * x1y1) - A - B); // E = (X1+Y1)2-A-B\n      const G = D + B; // G = D+B\n      const F = G - C; // F = G-C\n      const H = D - B; // H = D-B\n      const X3 = modP(E * F); // X3 = E*F\n      const Y3 = modP(G * H); // Y3 = G*H\n      const T3 = modP(E * H); // T3 = E*H\n      const Z3 = modP(F * G); // Z3 = F*G\n      return new Point(X3, Y3, Z3, T3);\n    }\n\n    // Fast algo for adding 2 Extended Points.\n    // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd\n    // Cost: 9M + 1*a + 1*d + 7add.\n    add(other: Point) {\n      aextpoint(other);\n      const { a, d } = CURVE;\n      const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;\n      const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;\n      const A = modP(X1 * X2); // A = X1*X2\n      const B = modP(Y1 * Y2); // B = Y1*Y2\n      const C = modP(T1 * d * T2); // C = T1*d*T2\n      const D = modP(Z1 * Z2); // D = Z1*Z2\n      const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B\n      const F = D - C; // F = D-C\n      const G = D + C; // G = D+C\n      const H = modP(B - a * A); // H = B-a*A\n      const X3 = modP(E * F); // X3 = E*F\n      const Y3 = modP(G * H); // Y3 = G*H\n      const T3 = modP(E * H); // T3 = E*H\n      const Z3 = modP(F * G); // Z3 = F*G\n      return new Point(X3, Y3, Z3, T3);\n    }\n\n    subtract(other: Point): Point {\n      return this.add(other.negate());\n    }\n\n    // Constant-time multiplication.\n    multiply(scalar: bigint): Point {\n      // 1 <= scalar < L\n      if (!Fn.isValidNot0(scalar)) throw new Error('invalid scalar: expected 1 <= sc < curve.n');\n      const { p, f } = wnaf.cached(this, scalar, (p) => normalizeZ(Point, p));\n      return normalizeZ(Point, [p, f])[0];\n    }\n\n    // Non-constant-time multiplication. Uses double-and-add algorithm.\n    // It's faster, but should only be used when you don't care about\n    // an exposed private key e.g. sig verification.\n    // Does NOT allow scalars higher than CURVE.n.\n    // Accepts optional accumulator to merge with multiply (important for sparse scalars)\n    multiplyUnsafe(scalar: bigint, acc = Point.ZERO): Point {\n      // 0 <= scalar < L\n      if (!Fn.isValid(scalar)) throw new Error('invalid scalar: expected 0 <= sc < curve.n');\n      if (scalar === _0n) return Point.ZERO;\n      if (this.is0() || scalar === _1n) return this;\n      return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p), acc);\n    }\n\n    // Checks if point is of small order.\n    // If you add something to small order point, you will have \"dirty\"\n    // point with torsion component.\n    // Multiplies point by cofactor and checks if the result is 0.\n    isSmallOrder(): boolean {\n      return this.multiplyUnsafe(cofactor).is0();\n    }\n\n    // Multiplies point by curve order and checks if the result is 0.\n    // Returns `false` is the point is dirty.\n    isTorsionFree(): boolean {\n      return wnaf.unsafe(this, CURVE.n).is0();\n    }\n\n    // Converts Extended point to default (x, y) coordinates.\n    // Can accept precomputed Z^-1 - for example, from invertBatch.\n    toAffine(invertedZ?: bigint): AffinePoint<bigint> {\n      return toAffineMemo(this, invertedZ);\n    }\n\n    clearCofactor(): Point {\n      if (cofactor === _1n) return this;\n      return this.multiplyUnsafe(cofactor);\n    }\n\n    toBytes(): Uint8Array {\n      const { x, y } = this.toAffine();\n      // Fp.toBytes() allows non-canonical encoding of y (>= p).\n      const bytes = Fp.toBytes(y);\n      // Each y has 2 valid points: (x, y), (x,-y).\n      // When compressing, it's enough to store y and use the last byte to encode sign of x\n      bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0;\n      return bytes;\n    }\n    toHex(): string {\n      return bytesToHex(this.toBytes());\n    }\n\n    toString() {\n      return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;\n    }\n\n    // TODO: remove\n    get ex(): bigint {\n      return this.X;\n    }\n    get ey(): bigint {\n      return this.Y;\n    }\n    get ez(): bigint {\n      return this.Z;\n    }\n    get et(): bigint {\n      return this.T;\n    }\n    static normalizeZ(points: Point[]): Point[] {\n      return normalizeZ(Point, points);\n    }\n    static msm(points: Point[], scalars: bigint[]): Point {\n      return pippenger(Point, Fn, points, scalars);\n    }\n    _setWindowSize(windowSize: number) {\n      this.precompute(windowSize);\n    }\n    toRawBytes(): Uint8Array {\n      return this.toBytes();\n    }\n  }\n  const wnaf = new wNAF(Point, Fn.BITS);\n  Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.\n  return Point;\n}\n\n/**\n * Base class for prime-order points like Ristretto255 and Decaf448.\n * These points eliminate cofactor issues by representing equivalence classes\n * of Edwards curve points.\n */\nexport abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>\n  implements CurvePoint<bigint, T>\n{\n  static BASE: PrimeEdwardsPoint<any>;\n  static ZERO: PrimeEdwardsPoint<any>;\n  static Fp: IField<bigint>;\n  static Fn: IField<bigint>;\n\n  protected readonly ep: EdwardsPoint;\n\n  constructor(ep: EdwardsPoint) {\n    this.ep = ep;\n  }\n\n  // Abstract methods that must be implemented by subclasses\n  abstract toBytes(): Uint8Array;\n  abstract equals(other: T): boolean;\n\n  // Static methods that must be implemented by subclasses\n  static fromBytes(_bytes: Uint8Array): any {\n    notImplemented();\n  }\n\n  static fromHex(_hex: Hex): any {\n    notImplemented();\n  }\n\n  get x(): bigint {\n    return this.toAffine().x;\n  }\n  get y(): bigint {\n    return this.toAffine().y;\n  }\n\n  // Common implementations\n  clearCofactor(): T {\n    // no-op for prime-order groups\n    return this as any;\n  }\n\n  assertValidity(): void {\n    this.ep.assertValidity();\n  }\n\n  toAffine(invertedZ?: bigint): AffinePoint<bigint> {\n    return this.ep.toAffine(invertedZ);\n  }\n\n  toHex(): string {\n    return bytesToHex(this.toBytes());\n  }\n\n  toString(): string {\n    return this.toHex();\n  }\n\n  isTorsionFree(): boolean {\n    return true;\n  }\n\n  isSmallOrder(): boolean {\n    return false;\n  }\n\n  add(other: T): T {\n    this.assertSame(other);\n    return this.init(this.ep.add(other.ep));\n  }\n\n  subtract(other: T): T {\n    this.assertSame(other);\n    return this.init(this.ep.subtract(other.ep));\n  }\n\n  multiply(scalar: bigint): T {\n    return this.init(this.ep.multiply(scalar));\n  }\n\n  multiplyUnsafe(scalar: bigint): T {\n    return this.init(this.ep.multiplyUnsafe(scalar));\n  }\n\n  double(): T {\n    return this.init(this.ep.double());\n  }\n\n  negate(): T {\n    return this.init(this.ep.negate());\n  }\n\n  precompute(windowSize?: number, isLazy?: boolean): T {\n    return this.init(this.ep.precompute(windowSize, isLazy));\n  }\n\n  // Helper methods\n  abstract is0(): boolean;\n  protected abstract assertSame(other: T): void;\n  protected abstract init(ep: EdwardsPoint): T;\n\n  /** @deprecated use `toBytes` */\n  toRawBytes(): Uint8Array {\n    return this.toBytes();\n  }\n}\n\n/**\n * Initializes EdDSA signatures over given Edwards curve.\n */\nexport function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpts = {}): EdDSA {\n  if (typeof cHash !== 'function') throw new Error('\"hash\" function param is required');\n  _validateObject(\n    eddsaOpts,\n    {},\n    {\n      adjustScalarBytes: 'function',\n      randomBytes: 'function',\n      domain: 'function',\n      prehash: 'function',\n      mapToCurve: 'function',\n    }\n  );\n\n  const { prehash } = eddsaOpts;\n  const { BASE, Fp, Fn } = Point;\n\n  const randomBytes = eddsaOpts.randomBytes || randomBytesWeb;\n  const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes: Uint8Array) => bytes);\n  const domain =\n    eddsaOpts.domain ||\n    ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {\n      abool(phflag, 'phflag');\n      if (ctx.length || phflag) throw new Error('Contexts/pre-hash are not supported');\n      return data;\n    }); // NOOP\n\n  // Little-endian SHA512 with modulo n\n  function modN_LE(hash: Uint8Array): bigint {\n    return Fn.create(bytesToNumberLE(hash)); // Not Fn.fromBytes: it has length limit\n  }\n\n  // Get the hashed private scalar per RFC8032 5.1.5\n  function getPrivateScalar(key: Hex) {\n    const len = lengths.secretKey;\n    key = ensureBytes('private key', key, len);\n    // Hash private key with curve's hash function to produce uniformingly random input\n    // Check byte lengths: ensure(64, h(ensure(32, key)))\n    const hashed = ensureBytes('hashed private key', cHash(key), 2 * len);\n    const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE\n    const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)\n    const scalar = modN_LE(head); // The actual private scalar\n    return { head, prefix, scalar };\n  }\n\n  /** Convenience method that creates public key from scalar. RFC8032 5.1.5 */\n  function getExtendedPublicKey(secretKey: Hex) {\n    const { head, prefix, scalar } = getPrivateScalar(secretKey);\n    const point = BASE.multiply(scalar); // Point on Edwards curve aka public key\n    const pointBytes = point.toBytes();\n    return { head, prefix, scalar, point, pointBytes };\n  }\n\n  /** Calculates EdDSA pub key. RFC8032 5.1.5. */\n  function getPublicKey(secretKey: Hex): Uint8Array {\n    return getExtendedPublicKey(secretKey).pointBytes;\n  }\n\n  // int('LE', SHA512(dom2(F, C) || msgs)) mod N\n  function hashDomainToScalar(context: Hex = Uint8Array.of(), ...msgs: Uint8Array[]) {\n    const msg = concatBytes(...msgs);\n    return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));\n  }\n\n  /** Signs message with privateKey. RFC8032 5.1.6 */\n  function sign(msg: Hex, secretKey: Hex, options: { context?: Hex } = {}): Uint8Array {\n    msg = ensureBytes('message', msg);\n    if (prehash) msg = prehash(msg); // for ed25519ph etc.\n    const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);\n    const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)\n    const R = BASE.multiply(r).toBytes(); // R = rG\n    const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)\n    const s = Fn.create(r + k * scalar); // S = (r + k * s) mod L\n    if (!Fn.isValid(s)) throw new Error('sign failed: invalid s'); // 0 <= s < L\n    const rs = concatBytes(R, Fn.toBytes(s));\n    return abytes(rs, lengths.signature, 'result');\n  }\n\n  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:\n  const verifyOpts: { context?: Hex; zip215?: boolean } = { zip215: true };\n\n  /**\n   * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.\n   * An extended group equation is checked.\n   */\n  function verify(sig: Hex, msg: Hex, publicKey: Hex, options = verifyOpts): boolean {\n    const { context, zip215 } = options;\n    const len = lengths.signature;\n    sig = ensureBytes('signature', sig, len);\n    msg = ensureBytes('message', msg);\n    publicKey = ensureBytes('publicKey', publicKey, lengths.publicKey);\n    if (zip215 !== undefined) abool(zip215, 'zip215');\n    if (prehash) msg = prehash(msg); // for ed25519ph, etc\n\n    const mid = len / 2;\n    const r = sig.subarray(0, mid);\n    const s = bytesToNumberLE(sig.subarray(mid, len));\n    let A, R, SB;\n    try {\n      // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.\n      // zip215=true:  0 <= y < MASK (2^256 for ed25519)\n      // zip215=false: 0 <= y < P (2^255-19 for ed25519)\n      A = Point.fromBytes(publicKey, zip215);\n      R = Point.fromBytes(r, zip215);\n      SB = BASE.multiplyUnsafe(s); // 0 <= s < l is done inside\n    } catch (error) {\n      return false;\n    }\n    if (!zip215 && A.isSmallOrder()) return false; // zip215 allows public keys of small order\n\n    const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);\n    const RkA = R.add(A.multiplyUnsafe(k));\n    // Extended group equation\n    // [8][S]B = [8]R + [8][k]A'\n    return RkA.subtract(SB).clearCofactor().is0();\n  }\n\n  const _size = Fp.BYTES; // 32 for ed25519, 57 for ed448\n  const lengths = {\n    secretKey: _size,\n    publicKey: _size,\n    signature: 2 * _size,\n    seed: _size,\n  };\n  function randomSecretKey(seed = randomBytes(lengths.seed)): Uint8Array {\n    return abytes(seed, lengths.seed, 'seed');\n  }\n  function keygen(seed?: Uint8Array) {\n    const secretKey = utils.randomSecretKey(seed);\n    return { secretKey, publicKey: getPublicKey(secretKey) };\n  }\n  function isValidSecretKey(key: Uint8Array): boolean {\n    return isBytes(key) && key.length === Fn.BYTES;\n  }\n  function isValidPublicKey(key: Uint8Array, zip215?: boolean): boolean {\n    try {\n      return !!Point.fromBytes(key, zip215);\n    } catch (error) {\n      return false;\n    }\n  }\n\n  const utils = {\n    getExtendedPublicKey,\n    randomSecretKey,\n    isValidSecretKey,\n    isValidPublicKey,\n    /**\n     * Converts ed public key to x public key. Uses formula:\n     * - ed25519:\n     *   - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`\n     *   - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`\n     * - ed448:\n     *   - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`\n     *   - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`\n     */\n    toMontgomery(publicKey: Uint8Array): Uint8Array {\n      const { y } = Point.fromBytes(publicKey);\n      const size = lengths.publicKey;\n      const is25519 = size === 32;\n      if (!is25519 && size !== 57) throw new Error('only defined for 25519 and 448');\n      const u = is25519 ? Fp.div(_1n + y, _1n - y) : Fp.div(y - _1n, y + _1n);\n      return Fp.toBytes(u);\n    },\n\n    toMontgomerySecret(secretKey: Uint8Array): Uint8Array {\n      const size = lengths.secretKey;\n      abytes(secretKey, size);\n      const hashed = cHash(secretKey.subarray(0, size));\n      return adjustScalarBytes(hashed).subarray(0, size);\n    },\n\n    /** @deprecated */\n    randomPrivateKey: randomSecretKey,\n    /** @deprecated */\n    precompute(windowSize = 8, point: EdwardsPoint = Point.BASE): EdwardsPoint {\n      return point.precompute(windowSize, false);\n    },\n  };\n\n  return Object.freeze({\n    keygen,\n    getPublicKey,\n    sign,\n    verify,\n    utils,\n    Point,\n    lengths,\n  });\n}\n\n// TODO: remove everything below\nexport type CurveType = BasicCurve<bigint> & {\n  a: bigint; // curve param a\n  d: bigint; // curve param d\n  /** @deprecated the property will be removed in next release */\n  hash: FHash; // Hashing\n  randomBytes?: (bytesLength?: number) => Uint8Array; // CSPRNG\n  adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array; // clears bits to get valid field elemtn\n  domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array; // Used for hashing\n  uvRatio?: UVRatio; // Ratio √(u/v)\n  prehash?: FHash; // RFC 8032 pre-hashing of messages to sign() / verify()\n  mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>; // for hash-to-curve standard\n};\nexport type CurveTypeWithLength = Readonly<CurveType & Partial<NLength>>;\nexport type CurveFn = {\n  /** @deprecated the property will be removed in next release */\n  CURVE: CurveType;\n  keygen: EdDSA['keygen'];\n  getPublicKey: EdDSA['getPublicKey'];\n  sign: EdDSA['sign'];\n  verify: EdDSA['verify'];\n  Point: EdwardsPointCons;\n  /** @deprecated use `Point` */\n  ExtendedPoint: EdwardsPointCons;\n  utils: EdDSA['utils'];\n  lengths: CurveLengths;\n};\nexport type EdComposed = {\n  CURVE: EdwardsOpts;\n  curveOpts: EdwardsExtraOpts;\n  hash: FHash;\n  eddsaOpts: EdDSAOpts;\n};\nfunction _eddsa_legacy_opts_to_new(c: CurveTypeWithLength): EdComposed {\n  const CURVE: EdwardsOpts = {\n    a: c.a,\n    d: c.d,\n    p: c.Fp.ORDER,\n    n: c.n,\n    h: c.h,\n    Gx: c.Gx,\n    Gy: c.Gy,\n  };\n  const Fp = c.Fp;\n  const Fn = Field(CURVE.n, c.nBitLength, true);\n  const curveOpts: EdwardsExtraOpts = { Fp, Fn, uvRatio: c.uvRatio };\n  const eddsaOpts: EdDSAOpts = {\n    randomBytes: c.randomBytes,\n    adjustScalarBytes: c.adjustScalarBytes,\n    domain: c.domain,\n    prehash: c.prehash,\n    mapToCurve: c.mapToCurve,\n  };\n  return { CURVE, curveOpts, hash: c.hash, eddsaOpts };\n}\nfunction _eddsa_new_output_to_legacy(c: CurveTypeWithLength, eddsa: EdDSA): CurveFn {\n  const Point = eddsa.Point;\n  const legacy = Object.assign({}, eddsa, {\n    ExtendedPoint: Point,\n    CURVE: c,\n    nBitLength: Point.Fn.BITS,\n    nByteLength: Point.Fn.BYTES,\n  });\n  return legacy;\n}\n// TODO: remove. Use eddsa\nexport function twistedEdwards(c: CurveTypeWithLength): CurveFn {\n  const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);\n  const Point = edwards(CURVE, curveOpts);\n  const EDDSA = eddsa(Point, hash, eddsaOpts);\n  return _eddsa_new_output_to_legacy(c, EDDSA);\n}\n","/**\n * ed25519 Twisted Edwards curve with following addons:\n * - X25519 ECDH\n * - Ristretto cofactor elimination\n * - Elligator hash-to-group / point indistinguishability\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { sha512 } from '@noble/hashes/sha2.js';\nimport { abytes, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js';\nimport { pippenger, type AffinePoint } from './abstract/curve.ts';\nimport {\n  PrimeEdwardsPoint,\n  twistedEdwards,\n  type CurveFn,\n  type EdwardsOpts,\n  type EdwardsPoint,\n} from './abstract/edwards.ts';\nimport {\n  _DST_scalar,\n  createHasher,\n  expand_message_xmd,\n  type H2CHasher,\n  type H2CHasherBase,\n  type H2CMethod,\n  type htfBasicOpts,\n} from './abstract/hash-to-curve.ts';\nimport {\n  Field,\n  FpInvertBatch,\n  FpSqrtEven,\n  isNegativeLE,\n  mod,\n  pow2,\n  type IField,\n} from './abstract/modular.ts';\nimport { montgomery, type MontgomeryECDH as XCurveFn } from './abstract/montgomery.ts';\nimport { bytesToNumberLE, ensureBytes, equalBytes, type Hex } from './utils.ts';\n\n// prettier-ignore\nconst _0n = /* @__PURE__ */ BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);\n// prettier-ignore\nconst _5n = BigInt(5), _8n = BigInt(8);\n\n// P = 2n**255n-19n\nconst ed25519_CURVE_p = BigInt(\n  '0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed'\n);\n\n// N = 2n**252n + 27742317777372353535851937790883648493n\n// a = Fp.create(BigInt(-1))\n// d = -121665/121666 a.k.a. Fp.neg(121665 * Fp.inv(121666))\nconst ed25519_CURVE: EdwardsOpts = /* @__PURE__ */ (() => ({\n  p: ed25519_CURVE_p,\n  n: BigInt('0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'),\n  h: _8n,\n  a: BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec'),\n  d: BigInt('0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'),\n  Gx: BigInt('0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a'),\n  Gy: BigInt('0x6666666666666666666666666666666666666666666666666666666666666658'),\n}))();\n\nfunction ed25519_pow_2_252_3(x: bigint) {\n  // prettier-ignore\n  const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);\n  const P = ed25519_CURVE_p;\n  const x2 = (x * x) % P;\n  const b2 = (x2 * x) % P; // x^3, 11\n  const b4 = (pow2(b2, _2n, P) * b2) % P; // x^15, 1111\n  const b5 = (pow2(b4, _1n, P) * x) % P; // x^31\n  const b10 = (pow2(b5, _5n, P) * b5) % P;\n  const b20 = (pow2(b10, _10n, P) * b10) % P;\n  const b40 = (pow2(b20, _20n, P) * b20) % P;\n  const b80 = (pow2(b40, _40n, P) * b40) % P;\n  const b160 = (pow2(b80, _80n, P) * b80) % P;\n  const b240 = (pow2(b160, _80n, P) * b80) % P;\n  const b250 = (pow2(b240, _10n, P) * b10) % P;\n  const pow_p_5_8 = (pow2(b250, _2n, P) * x) % P;\n  // ^ To pow to (p+3)/8, multiply it by x.\n  return { pow_p_5_8, b2 };\n}\n\nfunction adjustScalarBytes(bytes: Uint8Array): Uint8Array {\n  // Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,\n  // set the three least significant bits of the first byte\n  bytes[0] &= 248; // 0b1111_1000\n  // and the most significant bit of the last to zero,\n  bytes[31] &= 127; // 0b0111_1111\n  // set the second most significant bit of the last byte to 1\n  bytes[31] |= 64; // 0b0100_0000\n  return bytes;\n}\n\n// √(-1) aka √(a) aka 2^((p-1)/4)\n// Fp.sqrt(Fp.neg(1))\nconst ED25519_SQRT_M1 = /* @__PURE__ */ BigInt(\n  '19681161376707505956807079304988542015446066515923890162744021073123829784752'\n);\n// sqrt(u/v)\nfunction uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {\n  const P = ed25519_CURVE_p;\n  const v3 = mod(v * v * v, P); // v³\n  const v7 = mod(v3 * v3 * v, P); // v⁷\n  // (p+3)/8 and (p-5)/8\n  const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;\n  let x = mod(u * v3 * pow, P); // (uv³)(uv⁷)^(p-5)/8\n  const vx2 = mod(v * x * x, P); // vx²\n  const root1 = x; // First root candidate\n  const root2 = mod(x * ED25519_SQRT_M1, P); // Second root candidate\n  const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root\n  const useRoot2 = vx2 === mod(-u, P); // If vx² = -u, set x <-- x * 2^((p-1)/4)\n  const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P); // There is no valid root, vx² = -u√(-1)\n  if (useRoot1) x = root1;\n  if (useRoot2 || noRoot) x = root2; // We return root2 anyway, for const-time\n  if (isNegativeLE(x, P)) x = mod(-x, P);\n  return { isValid: useRoot1 || useRoot2, value: x };\n}\n\nconst Fp = /* @__PURE__ */ (() => Field(ed25519_CURVE.p, { isLE: true }))();\nconst Fn = /* @__PURE__ */ (() => Field(ed25519_CURVE.n, { isLE: true }))();\n\nconst ed25519Defaults = /* @__PURE__ */ (() => ({\n  ...ed25519_CURVE,\n  Fp,\n  hash: sha512,\n  adjustScalarBytes,\n  // dom2\n  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.\n  // Constant-time, u/√v\n  uvRatio,\n}))();\n\n/**\n * ed25519 curve with EdDSA signatures.\n * @example\n * import { ed25519 } from '@noble/curves/ed25519';\n * const { secretKey, publicKey } = ed25519.keygen();\n * const msg = new TextEncoder().encode('hello');\n * const sig = ed25519.sign(msg, priv);\n * ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215\n * ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5\n */\nexport const ed25519: CurveFn = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();\n\nfunction ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {\n  if (ctx.length > 255) throw new Error('Context is too big');\n  return concatBytes(\n    utf8ToBytes('SigEd25519 no Ed25519 collisions'),\n    new Uint8Array([phflag ? 1 : 0, ctx.length]),\n    ctx,\n    data\n  );\n}\n\n/** Context of ed25519. Uses context for domain separation. */\nexport const ed25519ctx: CurveFn = /* @__PURE__ */ (() =>\n  twistedEdwards({\n    ...ed25519Defaults,\n    domain: ed25519_domain,\n  }))();\n\n/** Prehashed version of ed25519. Accepts already-hashed messages in sign() and verify(). */\nexport const ed25519ph: CurveFn = /* @__PURE__ */ (() =>\n  twistedEdwards(\n    Object.assign({}, ed25519Defaults, {\n      domain: ed25519_domain,\n      prehash: sha512,\n    })\n  ))();\n\n/**\n * ECDH using curve25519 aka x25519.\n * @example\n * import { x25519 } from '@noble/curves/ed25519';\n * const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';\n * const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';\n * x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases\n * x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);\n * x25519.getPublicKey(x25519.utils.randomSecretKey());\n */\nexport const x25519: XCurveFn = /* @__PURE__ */ (() => {\n  const P = Fp.ORDER;\n  return montgomery({\n    P,\n    type: 'x25519',\n    powPminus2: (x: bigint): bigint => {\n      // x^(p-2) aka x^(2^255-21)\n      const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);\n      return mod(pow2(pow_p_5_8, _3n, P) * b2, P);\n    },\n    adjustScalarBytes,\n  });\n})();\n\n// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)\n// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since\n// SageMath returns different root first and everything falls apart\nconst ELL2_C1 = /* @__PURE__ */ (() => (ed25519_CURVE_p + _3n) / _8n)(); // 1. c1 = (q + 3) / 8       # Integer arithmetic\nconst ELL2_C2 = /* @__PURE__ */ (() => Fp.pow(_2n, ELL2_C1))(); // 2. c2 = 2^c1\nconst ELL2_C3 = /* @__PURE__ */ (() => Fp.sqrt(Fp.neg(Fp.ONE)))(); // 3. c3 = sqrt(-1)\n\n// prettier-ignore\nfunction map_to_curve_elligator2_curve25519(u: bigint) {\n  const ELL2_C4 = (ed25519_CURVE_p - _5n) / _8n; // 4. c4 = (q - 5) / 8       # Integer arithmetic\n  const ELL2_J = BigInt(486662);\n\n  let tv1 = Fp.sqr(u);          //  1.  tv1 = u^2\n  tv1 = Fp.mul(tv1, _2n);       //  2.  tv1 = 2 * tv1\n  let xd = Fp.add(tv1, Fp.ONE); //  3.   xd = tv1 + 1         # Nonzero: -1 is square (mod p), tv1 is not\n  let x1n = Fp.neg(ELL2_J);     //  4.  x1n = -J              # x1 = x1n / xd = -J / (1 + 2 * u^2)\n  let tv2 = Fp.sqr(xd);         //  5.  tv2 = xd^2\n  let gxd = Fp.mul(tv2, xd);    //  6.  gxd = tv2 * xd        # gxd = xd^3\n  let gx1 = Fp.mul(tv1, ELL2_J);//  7.  gx1 = J * tv1         # x1n + J * xd\n  gx1 = Fp.mul(gx1, x1n);       //  8.  gx1 = gx1 * x1n       # x1n^2 + J * x1n * xd\n  gx1 = Fp.add(gx1, tv2);       //  9.  gx1 = gx1 + tv2       # x1n^2 + J * x1n * xd + xd^2\n  gx1 = Fp.mul(gx1, x1n);       //  10. gx1 = gx1 * x1n       # x1n^3 + J * x1n^2 * xd + x1n * xd^2\n  let tv3 = Fp.sqr(gxd);        //  11. tv3 = gxd^2\n  tv2 = Fp.sqr(tv3);            //  12. tv2 = tv3^2           # gxd^4\n  tv3 = Fp.mul(tv3, gxd);       //  13. tv3 = tv3 * gxd       # gxd^3\n  tv3 = Fp.mul(tv3, gx1);       //  14. tv3 = tv3 * gx1       # gx1 * gxd^3\n  tv2 = Fp.mul(tv2, tv3);       //  15. tv2 = tv2 * tv3       # gx1 * gxd^7\n  let y11 = Fp.pow(tv2, ELL2_C4); //  16. y11 = tv2^c4        # (gx1 * gxd^7)^((p - 5) / 8)\n  y11 = Fp.mul(y11, tv3);       //  17. y11 = y11 * tv3       # gx1*gxd^3*(gx1*gxd^7)^((p-5)/8)\n  let y12 = Fp.mul(y11, ELL2_C3); //  18. y12 = y11 * c3\n  tv2 = Fp.sqr(y11);            //  19. tv2 = y11^2\n  tv2 = Fp.mul(tv2, gxd);       //  20. tv2 = tv2 * gxd\n  let e1 = Fp.eql(tv2, gx1);    //  21.  e1 = tv2 == gx1\n  let y1 = Fp.cmov(y12, y11, e1); //  22.  y1 = CMOV(y12, y11, e1)  # If g(x1) is square, this is its sqrt\n  let x2n = Fp.mul(x1n, tv1);   //  23. x2n = x1n * tv1       # x2 = x2n / xd = 2 * u^2 * x1n / xd\n  let y21 = Fp.mul(y11, u);     //  24. y21 = y11 * u\n  y21 = Fp.mul(y21, ELL2_C2);   //  25. y21 = y21 * c2\n  let y22 = Fp.mul(y21, ELL2_C3); //  26. y22 = y21 * c3\n  let gx2 = Fp.mul(gx1, tv1);   //  27. gx2 = gx1 * tv1       # g(x2) = gx2 / gxd = 2 * u^2 * g(x1)\n  tv2 = Fp.sqr(y21);            //  28. tv2 = y21^2\n  tv2 = Fp.mul(tv2, gxd);       //  29. tv2 = tv2 * gxd\n  let e2 = Fp.eql(tv2, gx2);    //  30.  e2 = tv2 == gx2\n  let y2 = Fp.cmov(y22, y21, e2); //  31.  y2 = CMOV(y22, y21, e2)  # If g(x2) is square, this is its sqrt\n  tv2 = Fp.sqr(y1);             //  32. tv2 = y1^2\n  tv2 = Fp.mul(tv2, gxd);       //  33. tv2 = tv2 * gxd\n  let e3 = Fp.eql(tv2, gx1);    //  34.  e3 = tv2 == gx1\n  let xn = Fp.cmov(x2n, x1n, e3); //  35.  xn = CMOV(x2n, x1n, e3)  # If e3, x = x1, else x = x2\n  let y = Fp.cmov(y2, y1, e3);  //  36.   y = CMOV(y2, y1, e3)    # If e3, y = y1, else y = y2\n  let e4 = Fp.isOdd!(y);         //  37.  e4 = sgn0(y) == 1        # Fix sign of y\n  y = Fp.cmov(y, Fp.neg(y), e3 !== e4); //  38.   y = CMOV(y, -y, e3 XOR e4)\n  return { xMn: xn, xMd: xd, yMn: y, yMd: _1n }; //  39. return (xn, xd, y, 1)\n}\n\nconst ELL2_C1_EDWARDS = /* @__PURE__ */ (() => FpSqrtEven(Fp, Fp.neg(BigInt(486664))))(); // sgn0(c1) MUST equal 0\nfunction map_to_curve_elligator2_edwards25519(u: bigint) {\n  const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); //  1.  (xMn, xMd, yMn, yMd) =\n  // map_to_curve_elligator2_curve25519(u)\n  let xn = Fp.mul(xMn, yMd); //  2.  xn = xMn * yMd\n  xn = Fp.mul(xn, ELL2_C1_EDWARDS); //  3.  xn = xn * c1\n  let xd = Fp.mul(xMd, yMn); //  4.  xd = xMd * yMn    # xn / xd = c1 * xM / yM\n  let yn = Fp.sub(xMn, xMd); //  5.  yn = xMn - xMd\n  let yd = Fp.add(xMn, xMd); //  6.  yd = xMn + xMd    # (n / d - 1) / (n / d + 1) = (n - d) / (n + d)\n  let tv1 = Fp.mul(xd, yd); //  7. tv1 = xd * yd\n  let e = Fp.eql(tv1, Fp.ZERO); //  8.   e = tv1 == 0\n  xn = Fp.cmov(xn, Fp.ZERO, e); //  9.  xn = CMOV(xn, 0, e)\n  xd = Fp.cmov(xd, Fp.ONE, e); //  10. xd = CMOV(xd, 1, e)\n  yn = Fp.cmov(yn, Fp.ONE, e); //  11. yn = CMOV(yn, 1, e)\n  yd = Fp.cmov(yd, Fp.ONE, e); //  12. yd = CMOV(yd, 1, e)\n  const [xd_inv, yd_inv] = FpInvertBatch(Fp, [xd, yd], true); // batch division\n  return { x: Fp.mul(xn, xd_inv), y: Fp.mul(yn, yd_inv) }; //  13. return (xn, xd, yn, yd)\n}\n\n/** Hashing to ed25519 points / field. RFC 9380 methods. */\nexport const ed25519_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>\n  createHasher(\n    ed25519.Point,\n    (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),\n    {\n      DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',\n      encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',\n      p: ed25519_CURVE_p,\n      m: 1,\n      k: 128,\n      expand: 'xmd',\n      hash: sha512,\n    }\n  ))();\n\n// √(-1) aka √(a) aka 2^((p-1)/4)\nconst SQRT_M1 = ED25519_SQRT_M1;\n// √(ad - 1)\nconst SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt(\n  '25063068953384623474111414158702152701244531502492656460079210482610430750235'\n);\n// 1 / √(a-d)\nconst INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt(\n  '54469307008909316920995813868745141605393597292927456921205312896311721017578'\n);\n// 1-d²\nconst ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt(\n  '1159843021668779879193775521855586647937357759715417654439879720876111806838'\n);\n// (d-1)²\nconst D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt(\n  '40440834346308536858101042469323190826248399146238708352240133220865137265952'\n);\n// Calculates 1/√(number)\nconst invertSqrt = (number: bigint) => uvRatio(_1n, number);\n\nconst MAX_255B = /* @__PURE__ */ BigInt(\n  '0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'\n);\nconst bytes255ToNumberLE = (bytes: Uint8Array) =>\n  ed25519.Point.Fp.create(bytesToNumberLE(bytes) & MAX_255B);\n\ntype ExtendedPoint = EdwardsPoint;\n\n/**\n * Computes Elligator map for Ristretto255.\n * Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-B) and on\n * the [website](https://ristretto.group/formulas/elligator.html).\n */\nfunction calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {\n  const { d } = ed25519_CURVE;\n  const P = ed25519_CURVE_p;\n  const mod = (n: bigint) => Fp.create(n);\n  const r = mod(SQRT_M1 * r0 * r0); // 1\n  const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2\n  let c = BigInt(-1); // 3\n  const D = mod((c - d * r) * mod(r + d)); // 4\n  let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5\n  let s_ = mod(s * r0); // 6\n  if (!isNegativeLE(s_, P)) s_ = mod(-s_);\n  if (!Ns_D_is_sq) s = s_; // 7\n  if (!Ns_D_is_sq) c = r; // 8\n  const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9\n  const s2 = s * s;\n  const W0 = mod((s + s) * D); // 10\n  const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11\n  const W2 = mod(_1n - s2); // 12\n  const W3 = mod(_1n + s2); // 13\n  return new ed25519.Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));\n}\n\nfunction ristretto255_map(bytes: Uint8Array): _RistrettoPoint {\n  abytes(bytes, 64);\n  const r1 = bytes255ToNumberLE(bytes.subarray(0, 32));\n  const R1 = calcElligatorRistrettoMap(r1);\n  const r2 = bytes255ToNumberLE(bytes.subarray(32, 64));\n  const R2 = calcElligatorRistrettoMap(r2);\n  return new _RistrettoPoint(R1.add(R2));\n}\n\n/**\n * Wrapper over Edwards Point for ristretto255.\n *\n * Each ed25519/ExtendedPoint has 8 different equivalent points. This can be\n * a source of bugs for protocols like ring signatures. Ristretto was created to solve this.\n * Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,\n * but it should work in its own namespace: do not combine those two.\n * See [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).\n */\nclass _RistrettoPoint extends PrimeEdwardsPoint<_RistrettoPoint> {\n  // Do NOT change syntax: the following gymnastics is done,\n  // because typescript strips comments, which makes bundlers disable tree-shaking.\n  // prettier-ignore\n  static BASE: _RistrettoPoint =\n    /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.BASE))();\n  // prettier-ignore\n  static ZERO: _RistrettoPoint =\n    /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.ZERO))();\n  // prettier-ignore\n  static Fp: IField<bigint> =\n    /* @__PURE__ */ (() => Fp)();\n  // prettier-ignore\n  static Fn: IField<bigint> =\n    /* @__PURE__ */ (() => Fn)();\n\n  constructor(ep: ExtendedPoint) {\n    super(ep);\n  }\n\n  static fromAffine(ap: AffinePoint<bigint>): _RistrettoPoint {\n    return new _RistrettoPoint(ed25519.Point.fromAffine(ap));\n  }\n\n  protected assertSame(other: _RistrettoPoint): void {\n    if (!(other instanceof _RistrettoPoint)) throw new Error('RistrettoPoint expected');\n  }\n\n  protected init(ep: EdwardsPoint): _RistrettoPoint {\n    return new _RistrettoPoint(ep);\n  }\n\n  /** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */\n  static hashToCurve(hex: Hex): _RistrettoPoint {\n    return ristretto255_map(ensureBytes('ristrettoHash', hex, 64));\n  }\n\n  static fromBytes(bytes: Uint8Array): _RistrettoPoint {\n    abytes(bytes, 32);\n    const { a, d } = ed25519_CURVE;\n    const P = ed25519_CURVE_p;\n    const mod = (n: bigint) => Fp.create(n);\n    const s = bytes255ToNumberLE(bytes);\n    // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.\n    // 3. Check that s is non-negative, or else abort\n    if (!equalBytes(Fp.toBytes(s), bytes) || isNegativeLE(s, P))\n      throw new Error('invalid ristretto255 encoding 1');\n    const s2 = mod(s * s);\n    const u1 = mod(_1n + a * s2); // 4 (a is -1)\n    const u2 = mod(_1n - a * s2); // 5\n    const u1_2 = mod(u1 * u1);\n    const u2_2 = mod(u2 * u2);\n    const v = mod(a * d * u1_2 - u2_2); // 6\n    const { isValid, value: I } = invertSqrt(mod(v * u2_2)); // 7\n    const Dx = mod(I * u2); // 8\n    const Dy = mod(I * Dx * v); // 9\n    let x = mod((s + s) * Dx); // 10\n    if (isNegativeLE(x, P)) x = mod(-x); // 10\n    const y = mod(u1 * Dy); // 11\n    const t = mod(x * y); // 12\n    if (!isValid || isNegativeLE(t, P) || y === _0n)\n      throw new Error('invalid ristretto255 encoding 2');\n    return new _RistrettoPoint(new ed25519.Point(x, y, _1n, t));\n  }\n\n  /**\n   * Converts ristretto-encoded string to ristretto point.\n   * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).\n   * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding\n   */\n  static fromHex(hex: Hex): _RistrettoPoint {\n    return _RistrettoPoint.fromBytes(ensureBytes('ristrettoHex', hex, 32));\n  }\n\n  static msm(points: _RistrettoPoint[], scalars: bigint[]): _RistrettoPoint {\n    return pippenger(_RistrettoPoint, ed25519.Point.Fn, points, scalars);\n  }\n\n  /**\n   * Encodes ristretto point to Uint8Array.\n   * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).\n   */\n  toBytes(): Uint8Array {\n    let { X, Y, Z, T } = this.ep;\n    const P = ed25519_CURVE_p;\n    const mod = (n: bigint) => Fp.create(n);\n    const u1 = mod(mod(Z + Y) * mod(Z - Y)); // 1\n    const u2 = mod(X * Y); // 2\n    // Square root always exists\n    const u2sq = mod(u2 * u2);\n    const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3\n    const D1 = mod(invsqrt * u1); // 4\n    const D2 = mod(invsqrt * u2); // 5\n    const zInv = mod(D1 * D2 * T); // 6\n    let D: bigint; // 7\n    if (isNegativeLE(T * zInv, P)) {\n      let _x = mod(Y * SQRT_M1);\n      let _y = mod(X * SQRT_M1);\n      X = _x;\n      Y = _y;\n      D = mod(D1 * INVSQRT_A_MINUS_D);\n    } else {\n      D = D2; // 8\n    }\n    if (isNegativeLE(X * zInv, P)) Y = mod(-Y); // 9\n    let s = mod((Z - Y) * D); // 10 (check footer's note, no sqrt(-a))\n    if (isNegativeLE(s, P)) s = mod(-s);\n    return Fp.toBytes(s); // 11\n  }\n\n  /**\n   * Compares two Ristretto points.\n   * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).\n   */\n  equals(other: _RistrettoPoint): boolean {\n    this.assertSame(other);\n    const { X: X1, Y: Y1 } = this.ep;\n    const { X: X2, Y: Y2 } = other.ep;\n    const mod = (n: bigint) => Fp.create(n);\n    // (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)\n    const one = mod(X1 * Y2) === mod(Y1 * X2);\n    const two = mod(Y1 * Y2) === mod(X1 * X2);\n    return one || two;\n  }\n\n  is0(): boolean {\n    return this.equals(_RistrettoPoint.ZERO);\n  }\n}\n\nexport const ristretto255: {\n  Point: typeof _RistrettoPoint;\n} = { Point: _RistrettoPoint };\n\n/** Hashing to ristretto255 points / field. RFC 9380 methods. */\nexport const ristretto255_hasher: H2CHasherBase<bigint> = {\n  hashToCurve(msg: Uint8Array, options?: htfBasicOpts): _RistrettoPoint {\n    const DST = options?.DST || 'ristretto255_XMD:SHA-512_R255MAP_RO_';\n    const xmd = expand_message_xmd(msg, DST, 64, sha512);\n    return ristretto255_map(xmd);\n  },\n  hashToScalar(msg: Uint8Array, options: htfBasicOpts = { DST: _DST_scalar }) {\n    const xmd = expand_message_xmd(msg, options.DST, 64, sha512);\n    return Fn.create(bytesToNumberLE(xmd));\n  },\n};\n\n// export const ristretto255_oprf: OPRF = createORPF({\n//   name: 'ristretto255-SHA512',\n//   Point: RistrettoPoint,\n//   hash: sha512,\n//   hashToGroup: ristretto255_hasher.hashToCurve,\n//   hashToScalar: ristretto255_hasher.hashToScalar,\n// });\n\n/**\n * Weird / bogus points, useful for debugging.\n * All 8 ed25519 points of 8-torsion subgroup can be generated from the point\n * T = `26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05`.\n * ⟨T⟩ = { O, T, 2T, 3T, 4T, 5T, 6T, 7T }\n */\nexport const ED25519_TORSION_SUBGROUP: string[] = [\n  '0100000000000000000000000000000000000000000000000000000000000000',\n  'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',\n  '0000000000000000000000000000000000000000000000000000000000000080',\n  '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',\n  'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',\n  '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',\n  '0000000000000000000000000000000000000000000000000000000000000000',\n  'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',\n];\n\n/** @deprecated use `ed25519.utils.toMontgomery` */\nexport function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array {\n  return ed25519.utils.toMontgomery(ensureBytes('pub', edwardsPub));\n}\n/** @deprecated use `ed25519.utils.toMontgomery` */\nexport const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontgomeryPub;\n\n/** @deprecated use `ed25519.utils.toMontgomerySecret` */\nexport function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array {\n  return ed25519.utils.toMontgomerySecret(ensureBytes('pub', edwardsPriv));\n}\n\n/** @deprecated use `ristretto255.Point` */\nexport const RistrettoPoint: typeof _RistrettoPoint = _RistrettoPoint;\n/** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */\nexport const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed25519_hasher.hashToCurve)();\n/** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */\nexport const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>\n  ed25519_hasher.encodeToCurve)();\ntype RistHasher = (msg: Uint8Array, options: htfBasicOpts) => _RistrettoPoint;\n/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */\nexport const hashToRistretto255: RistHasher = /* @__PURE__ */ (() =>\n  ristretto255_hasher.hashToCurve as RistHasher)();\n/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */\nexport const hash_to_ristretto255: RistHasher = /* @__PURE__ */ (() =>\n  ristretto255_hasher.hashToCurve as RistHasher)();\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 { PalbaseError, type PalbaseResponse } from '@palbase/core';\n\nexport interface FieldError {\n  field: string;\n  message: string;\n}\n\nexport type BackendErrorKind =\n  | 'notConfigured'\n  | 'validation'\n  | 'unauthorized'\n  | 'rateLimited'\n  | 'server'\n  | 'network'\n  | 'decode';\n\ninterface BackendErrorParams {\n  code: string;\n  message: string;\n  status?: number;\n  requestId?: string;\n  fields?: FieldError[];\n  retryAfter?: number;\n  data?: unknown;\n}\n\nexport class BackendError extends Error {\n  readonly kind: BackendErrorKind;\n  readonly code: string;\n  readonly status: number;\n  readonly requestId?: string;\n  readonly fields?: FieldError[];\n  readonly retryAfter?: number;\n  readonly data?: unknown;\n\n  constructor(kind: BackendErrorKind, params: BackendErrorParams) {\n    super(params.message);\n    this.name = 'BackendError';\n    this.kind = kind;\n    this.code = params.code;\n    this.status = params.status ?? 0;\n    this.requestId = params.requestId;\n    this.fields = params.fields;\n    this.retryAfter = params.retryAfter;\n    this.data = params.data;\n  }\n\n  static notConfigured(): BackendError {\n    return new BackendError('notConfigured', {\n      code: 'not_configured',\n      message:\n        \"Palbe is not configured. Run 'palbase web link' in your project and make sure palbe.gen.ts is imported once at app startup.\",\n    });\n  }\n}\n\nfunction isFieldErrorArray(value: unknown): value is FieldError[] {\n  return (\n    Array.isArray(value) &&\n    value.length > 0 &&\n    value.every(\n      (v) =>\n        typeof v === 'object' &&\n        v !== null &&\n        typeof (v as Record<string, unknown>).field === 'string' &&\n        typeof (v as Record<string, unknown>).message === 'string',\n    )\n  );\n}\n\n/**\n * Find the field-error array in a wire envelope.\n *\n * `data.fields` IS THE CONTRACT: the backend SDK declares\n * `bad_request: { fields: [{ field, message }] }` in its error registry, so\n * codegen types it as `error.data.fields`, `throw new BadRequest({ fields })`\n * answers in that shape, and — since 22.1.0 — so do the engine's own automatic\n * `@Body`/`@QueryParams`/`@Headers` refusals.\n *\n * The top-level `fields` is the SAME array as emitted by backend 22.0.x and\n * earlier, which is still what every tenant deployed before that release\n * answers. A browser gets the SDK long before its tenant redeploys, so this\n * reader covers both until the fleet has rolled; drop it once it has.\n *\n * A nested `details: [{ field, message }]` was read here until 8.0.0 and is NOT\n * read any more: no Palbase surface has ever emitted it. Believing in it is why\n * `kind: 'validation'` was unreachable for every real 400 the platform sends.\n */\nfunction fieldErrorsOf(envelope: unknown): FieldError[] | undefined {\n  const scoped = pickField(pickField(envelope, 'data'), 'fields');\n  if (isFieldErrorArray(scoped)) return scoped;\n  const flat = pickField(envelope, 'fields');\n  return isFieldErrorArray(flat) ? flat : undefined;\n}\n\n/**\n * Find the rate-limit hint in a wire envelope.\n *\n * Two producers, both real and both measured. palauth answers a lockout with a\n * top-level `retry_after` (`auth/internal/ratelimit/limiter.go`). Everything\n * built on the backend SDK — the engine's per-route limiter, and\n * `throw new TooManyRequests({ retryAfter })` — answers with `data.retryAfter`,\n * the name its error registry publishes and codegen types.\n */\nfunction retryAfterOf(envelope: unknown): number | undefined {\n  return (\n    pickNumber(envelope, 'retry_after') ?? pickNumber(pickField(envelope, 'data'), 'retryAfter')\n  );\n}\n\nfunction pickField(value: unknown, key: string): unknown {\n  if (typeof value === 'object' && value !== null) {\n    return (value as Record<string, unknown>)[key];\n  }\n  return undefined;\n}\n\nfunction pickNumber(value: unknown, key: string): number | undefined {\n  const n = pickField(value, key);\n  return typeof n === 'number' ? n : undefined;\n}\n\nfunction pickString(value: unknown, key: string): string | undefined {\n  const s = pickField(value, key);\n  return typeof s === 'string' ? s : undefined;\n}\n\nexport function fromPalbaseError(err: PalbaseError): BackendError {\n  // HttpClient stores the WHOLE wire envelope as err.details:\n  // { error, error_description, status, request_id, retry_after?, data? }\n  const base: BackendErrorParams = {\n    code: err.code,\n    message: err.message,\n    status: err.status,\n    requestId: pickString(err.details, 'request_id'),\n    data: pickField(err.details, 'data'),\n  };\n  if (err.code === 'network_error') return new BackendError('network', base);\n  if (err.status === 401) return new BackendError('unauthorized', base);\n  if (err.status === 429)\n    return new BackendError('rateLimited', { ...base, retryAfter: retryAfterOf(err.details) });\n  const fields = fieldErrorsOf(err.details);\n  if (err.status === 400 && fields) return new BackendError('validation', { ...base, fields });\n  // Fallthrough also covers status-0 non-network errors (e.g. auth client's\n  // synthetic 'no_refresh_token' with status 0) — those intentionally map to 'server'.\n  return new BackendError('server', base);\n}\n\n/** Decode a raw wire body (used by paths that bypass HttpClient, e.g. upload). */\nexport function fromEnvelope(status: number, body: unknown): BackendError {\n  const code = pickString(body, 'error') ?? 'http_error';\n  const message = pickString(body, 'error_description') ?? `HTTP ${status}`;\n  const requestId = pickString(body, 'request_id');\n  const params: BackendErrorParams = {\n    code,\n    message,\n    status,\n    requestId,\n    data: pickField(body, 'data'),\n  };\n  if (status === 401) return new BackendError('unauthorized', params);\n  if (status === 429)\n    return new BackendError('rateLimited', { ...params, retryAfter: retryAfterOf(body) });\n  const fields = fieldErrorsOf(body);\n  if (status === 400 && fields) return new BackendError('validation', { ...params, fields });\n  return new BackendError('server', params);\n}\n\n/**\n * Type guard for BackendError that survives module-identity splits.\n * This package ships dual ESM + CJS builds; if both end up loaded (or the\n * package is installed twice), two distinct BackendError classes coexist and\n * `instanceof` fails for errors thrown by \"the other\" copy. Falls back to a\n * structural check on `name` + `kind`.\n */\nexport function isBackendError(e: unknown): e is BackendError {\n  return (\n    e instanceof BackendError ||\n    (typeof e === 'object' &&\n      e !== null &&\n      (e as Record<string, unknown>).name === 'BackendError' &&\n      typeof (e as Record<string, unknown>).kind === 'string')\n  );\n}\n\n/**\n * Structural fallback after instanceof for PalbaseError — same dual ESM+CJS\n * identity-split rationale as isBackendError above: two loaded PalbaseError\n * classes break `instanceof` across copies; the name check bridges that.\n * Returns the error as PalbaseError, or null when it isn't one.\n */\nexport function asPalbaseError(e: unknown): PalbaseError | null {\n  if (e instanceof PalbaseError) return e;\n  if (e instanceof Error && e.name === 'PalbaseError') return e as PalbaseError;\n  return null;\n}\n\n/** Convert an internal {data,error} envelope into data-or-throw. */\nexport function unwrap<T>(res: PalbaseResponse<T>): T {\n  if (res.error) throw fromPalbaseError(res.error);\n  return res.data as T;\n}\n","const ID_SEGMENT =\n  /^(?:\\d+|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;\n\n// An email lands in a path segment as `jane@acme.com` or percent-encoded\n// `jane%40acme.com`. Either form is PII and must never survive into a metric\n// name, so a segment carrying an `@` (encoded or raw) is masked like an id.\nconst EMAIL_SEGMENT = /(?:@|%40)/i;\n\nfunction isSensitiveSegment(seg: string): boolean {\n  return ID_SEGMENT.test(seg) || EMAIL_SEGMENT.test(seg);\n}\n\n/**\n * Capture-time URL redaction (§4.1 privacy, client half). Collapses a request\n * URL to a PII-free, low-cardinality path pattern BEFORE it leaves the browser:\n * query string dropped wholesale, id-like segments masked. The ingest scrubber\n * re-applies server-side (defense in depth).\n *\n * Rules:\n *  - absolute URL → keep only `pathname` (scheme/host/query/hash dropped);\n *  - relative URL → drop everything from the first `?` onward;\n *  - any segment that is purely numeric, a UUID, or carries an email (`@` /\n *    `%40`) → `:id`;\n *  - credentials/tokens live in the query (dropped wholesale), emails in a\n *    path segment (masked), so neither survives into the metric name.\n */\nexport function redactUrl(rawUrl: string): string {\n  let path = rawUrl;\n  try {\n    // Absolute URLs: take the pathname (drops scheme/host/query/hash).\n    path = new URL(rawUrl).pathname;\n  } catch {\n    const q = path.indexOf('?');\n    if (q >= 0) path = path.slice(0, q);\n  }\n  return path\n    .split('/')\n    .map((seg) => (isSensitiveSegment(seg) ? ':id' : seg))\n    .join('/');\n}\n","import { BackendError } from './errors.js';\n\n/**\n * The web half of streaming responses.\n *\n * The rule the parser exists to keep: a frame ends at a BLANK line, never at a\n * chunk boundary. Nothing about how the bytes were split on the way here may\n * change what the caller sees — a `data:` line arriving in three pieces is one\n * frame, and two frames arriving in one piece are two.\n */\n\nexport interface SseFrame {\n  /** `undefined` for a plain `data:` frame; `\"error\"` for the terminal one. */\n  event?: string;\n  payload: string;\n}\n\n/** Incremental SSE parser. Feed it decoded text; it answers with completed frames. */\nexport class SseParser {\n  private pending = '';\n  private dataLines: string[] = [];\n  private eventName: string | undefined;\n\n  consume(chunk: string): SseFrame[] {\n    // CRLF is normalised on the way IN. A server that writes \\r\\n would\n    // otherwise leave a stray \\r on every field value, and `JSON.parse` of\n    // `{\"n\":1}\\r` throws — a decode failure invented by the transport.\n    this.pending += chunk.replace(/\\r\\n/g, '\\n');\n    const out: SseFrame[] = [];\n    let nl = this.pending.indexOf('\\n');\n    while (nl !== -1) {\n      const line = this.pending.slice(0, nl);\n      this.pending = this.pending.slice(nl + 1);\n      const trimmed = line.endsWith('\\r') ? line.slice(0, -1) : line;\n\n      if (trimmed === '') {\n        // A blank line with nothing accumulated is a keep-alive separator or the\n        // gap after a comment — emitting nothing for it is correct.\n        if (this.dataLines.length > 0) {\n          out.push({ event: this.eventName, payload: this.dataLines.join('\\n') });\n        }\n        this.dataLines = [];\n        this.eventName = undefined;\n      } else if (trimmed.startsWith(':')) {\n        // A comment — the conventional keep-alive. Ignored, not surfaced.\n      } else if (trimmed.startsWith('data:')) {\n        const v = trimmed.slice(5);\n        this.dataLines.push(v.startsWith(' ') ? v.slice(1) : v);\n      } else if (trimmed.startsWith('event:')) {\n        const v = trimmed.slice(6);\n        this.eventName = v.startsWith(' ') ? v.slice(1) : v;\n      }\n      // Unknown fields (id:, retry:) are ignored rather than refused: a reader\n      // that rejects a field it does not know breaks when the server adds one.\n      nl = this.pending.indexOf('\\n');\n    }\n    return out;\n  }\n}\n\n/**\n * Turn a byte stream into the decoded frames a generated client hands its caller.\n *\n * `controller` is aborted when the caller stops iterating — `for await`'s early\n * exit calls `return()` on the iterator, which reaches the `finally` below. That\n * is the whole cancellation story on the web, and it is what stops the server's\n * producer being pulled.\n */\nexport async function* sseIterable(\n  body: ReadableStream<Uint8Array>,\n  controller: AbortController,\n): AsyncGenerator<unknown, void, undefined> {\n  const reader = body.getReader();\n  const decoder = new TextDecoder();\n  const parser = new SseParser();\n  try {\n    for (;;) {\n      const { done, value } = await reader.read();\n      if (done) break;\n      for (const frame of parser.consume(decoder.decode(value, { stream: true }))) {\n        if (frame.event === 'error') {\n          // After the first frame the status line is already spent, so this is\n          // how a failure reaches the caller: as a throw out of their loop.\n          throw new BackendError('network', {\n            code: 'stream_failed',\n            message: `stream failed: ${frame.payload}`,\n          });\n        }\n        let decoded: unknown;\n        try {\n          decoded = JSON.parse(frame.payload);\n        } catch {\n          // A frame that will not decode ends the stream rather than being\n          // skipped: a silently dropped frame is a hole in the middle of the\n          // caller's data, and holes are worse than failures.\n          throw new BackendError('decode', {\n            code: 'invalid_frame',\n            message: `stream frame is not valid JSON: ${frame.payload.slice(0, 120)}`,\n          });\n        }\n        yield decoded;\n      }\n    }\n  } finally {\n    controller.abort();\n    try {\n      await reader.cancel();\n    } catch {\n      // The reader may already be closed — that is a normal ending, not a fault.\n    }\n  }\n}\n","import { asPowChallenge, solvePowChallenge } from '@palbase/core';\nimport {\n  asPalbaseError,\n  BackendError,\n  fromEnvelope,\n  fromPalbaseError,\n  isBackendError,\n  unwrap,\n} from './errors.js';\nimport { redactUrl } from './perf/url-redactor.js';\nimport type { PalbeRuntime } from './runtime.js';\nimport { sseIterable } from './sse.js';\n\nexport interface RequestSpec {\n  body?: unknown;\n  headers?: Record<string, string>;\n  signal?: AbortSignal;\n}\n\nexport interface CallOptions {\n  headers?: Record<string, string>;\n  signal?: AbortSignal;\n}\n\nconst MUTATING = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);\n\n// The perf flush (`POST /v1/analytics/perf`) and analytics event ingest\n// (`/v1/analytics/*`) BOTH funnel through `palbeRequest`. Tracing them would\n// make every flush emit another `network` item that the next flush ships,\n// then traces again — a self-measurement loop. Excluding the whole\n// `/v1/analytics/` prefix breaks it. This is the SAME self-exclusion shape as\n// the iOS network trace (1b-3), keyed on the identical ingest prefix.\nconst PERF_EXCLUDED_PREFIX = '/v1/analytics/';\n\nfunction isSelfTraced(path: string): boolean {\n  return path.startsWith(PERF_EXCLUDED_PREFIX);\n}\n\n/**\n * Codes meaning the server-side session is GONE — a token refresh cannot help\n * and the client must tear its local session down. `subject_fenced` is palauth's\n * wire-true erasure-fence code (`bridge.go`); `subject_erased` is accepted for\n * forward-compat. `session_revoked` is palauth's revoked-session 401.\n * A PLAIN 403 (ordinary authz / RLS denial) is intentionally NOT here — matching\n * all 403s would sign users out on routine permission errors.\n */\nfunction isSessionKilled(status: number, code: string): boolean {\n  if (status === 401) return code === 'session_revoked';\n  if (status === 403) return code === 'subject_fenced' || code === 'subject_erased';\n  return false;\n}\n\n/** Monotonic millisecond clock — `performance.now()` when present, else\n * `Date.now()`. Mirrors `perf-facade.ts`'s `nowMs()` so network durations and\n * custom-trace durations share one time base. */\nfunction nowMs(): number {\n  return typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now();\n}\n\n/** An `AbortError` (caller-cancelled request) is NOT a completed network call,\n * so it must never produce a trace. */\nfunction isAbort(e: unknown): boolean {\n  return e instanceof Error && e.name === 'AbortError';\n}\n\n/**\n * `palbeRequest`'s streaming sibling: opens the response and hands back the\n * frames as an async iterable.\n *\n * No retry and no reactive-401 refresh loop here, on purpose. Both replay the\n * request, and a stream the caller has begun reading cannot be replayed — the\n * frames it already yielded would arrive twice. A stream that fails to OPEN\n * fails to the caller once, with the status the server gave.\n *\n * An `AbortController` is chained to the caller's signal so that leaving the\n * loop aborts the request: that is what stops the server's producer being\n * pulled, and it is the half that decides the customer's bill.\n */\nexport async function palbeStream(\n  rt: PalbeRuntime,\n  method: string,\n  path: string,\n  spec: RequestSpec = {},\n): Promise<AsyncIterable<unknown>> {\n  const controller = new AbortController();\n  if (spec.signal) {\n    if (spec.signal.aborted) controller.abort();\n    else spec.signal.addEventListener('abort', () => controller.abort(), { once: true });\n  }\n\n  const headers: Record<string, string> = { ...spec.headers };\n  const callerHasKey = Object.keys(headers).some((k) => k.toLowerCase() === 'idempotency-key');\n  if (MUTATING.has(method) && !callerHasKey) {\n    headers['Idempotency-Key'] = crypto.randomUUID();\n  }\n\n  const open = async (extra?: Record<string, string>) =>\n    rt.http.requestStream(method, path, {\n      body: spec.body,\n      headers: extra ? { ...headers, ...extra } : headers,\n      signal: controller.signal,\n    });\n\n  let opened: Awaited<ReturnType<typeof rt.http.requestStream>>;\n  try {\n    opened = await open();\n\n    // The abuse gate answers the same way here as anywhere else, and a stream\n    // that has not yielded a frame yet can be retried safely — nothing was\n    // handed to the caller. ONE solve, exactly as the buffered path: a 403 that\n    // says `pow_required` without a challenge is a gate the client cannot\n    // satisfy, and looping would turn it into a hang.\n    // Reactive 401, on the same terms as the buffered path. A route that a\n    // customer converts to `@Sse` must not silently lose session recovery: the\n    // failure would look like \"streaming is flaky\" and be blamed on streaming.\n    if (\n      opened.status === 401 &&\n      rt.tokenManager.getRefreshToken() &&\n      rt.tokenManager.refreshFunction\n    ) {\n      const text = opened.body ? await new Response(opened.body).text() : '';\n      let envelope: unknown;\n      try {\n        envelope = JSON.parse(text);\n      } catch {\n        envelope = undefined;\n      }\n      // A revoked session is terminal — a refresh cannot resurrect it.\n      const code = (envelope as { error?: string } | undefined)?.error;\n      if (code === 'session_revoked') throw fromEnvelope(401, envelope);\n      try {\n        await rt.tokenManager.refreshSession();\n      } catch (refreshErr) {\n        const pe = asPalbaseError(refreshErr);\n        const status = pe?.status ?? 0;\n        if (status === 400 || status === 401 || status === 403) {\n          // The refresh token is dead: sign out and surface the ORIGINAL 401.\n          rt.tokenManager.clearSession();\n          throw fromEnvelope(401, envelope);\n        }\n        throw pe ? fromPalbaseError(pe) : refreshErr;\n      }\n      opened = await open();\n    }\n\n    if (opened.status === 403) {\n      const text = opened.body ? await new Response(opened.body).text() : '';\n      let envelope: unknown;\n      try {\n        envelope = JSON.parse(text);\n      } catch {\n        envelope = undefined;\n      }\n      // `asPowChallenge` reads the WHOLE envelope (it checks `error` and\n      // `challenge` itself), so it is handed the parsed body rather than a\n      // hand-picked field — one place that knows the challenge's shape.\n      const challenge = asPowChallenge(envelope);\n      if (challenge) {\n        opened = await open(await solvePowChallenge(challenge));\n      } else {\n        // A 403 that is not a solvable challenge is an ordinary refusal.\n        throw fromEnvelope(403, envelope);\n      }\n    }\n  } catch (e) {\n    if (isBackendError(e)) throw e;\n    const pe = asPalbaseError(e);\n    throw pe ? fromPalbaseError(pe) : e;\n  }\n\n  if (opened.status < 200 || opened.status >= 300) {\n    // Before the first frame the status line is still available, so a failure\n    // here is an ORDINARY error — same shape as any other call's.\n    const text = opened.body ? await new Response(opened.body).text() : '';\n    let envelope: unknown;\n    try {\n      envelope = JSON.parse(text);\n    } catch {\n      envelope = undefined;\n    }\n\n    // The SAME mapping the buffered path uses. A streaming route that refuses\n    // must be indistinguishable, to the caller, from any other route refusing —\n    // a second status→kind table here would be a second chance to disagree.\n    throw fromEnvelope(opened.status, envelope);\n  }\n\n  if (!opened.body) {\n    throw new BackendError('network', {\n      code: 'empty_stream',\n      message: 'the server answered a streaming route with no body',\n    });\n  }\n\n  return sseIterable(opened.body, controller);\n}\n\nexport async function palbeRequest<T>(\n  rt: PalbeRuntime,\n  method: string,\n  path: string,\n  spec: RequestSpec = {},\n): Promise<T> {\n  const headers: Record<string, string> = { ...spec.headers };\n  // Case-insensitive scan: a caller-supplied `idempotency-key` must suppress\n  // generation, otherwise Headers merges both casings and dedup breaks.\n  const callerHasKey = Object.keys(headers).some((k) => k.toLowerCase() === 'idempotency-key');\n  if (MUTATING.has(method) && !callerHasKey) {\n    headers['Idempotency-Key'] = crypto.randomUUID();\n  }\n\n  // `extra` carries the proof-of-work headers on the one retry that needs them.\n  // The base `headers` are reused rather than rebuilt, so a retry keeps the same\n  // Idempotency-Key and the server still sees one logical request.\n  const attempt = async (extra?: Record<string, string>) => {\n    try {\n      return await rt.http.request<T>(method, path, {\n        body: spec.body,\n        headers: extra ? { ...headers, ...extra } : headers,\n        signal: spec.signal,\n        // A header alone does not implement server-side deduplication. A lost\n        // response can follow a successful COMMIT; replaying a write here may\n        // duplicate it. Surface overload too, so domain recovery is explicit.\n        retry: method === 'GET' || method === 'HEAD',\n      });\n    } catch (e) {\n      const pe = asPalbaseError(e);\n      throw pe ? fromPalbaseError(pe) : e;\n    }\n  };\n\n  // The single network-trace choke point: every SDK fetch funnels through\n  // `palbeRequest`, so timing it here records one `network` PerfItem per call —\n  // redacted URL + method + final HTTP status + wall-clock duration. The\n  // `/v1/analytics/` ingest paths are self-excluded (no recursion) and aborts\n  // are skipped (not a completed call).\n  // `rt.perf` is guarded too: `buildRuntime` always wires it, but a hand-built\n  // runtime (tests, embedders) may omit it — a missing facade must never break\n  // the request path.\n  const traced = !isSelfTraced(path) && rt.perf !== undefined;\n  const startedAt = traced ? nowMs() : 0;\n  // Exactly ONE trace per `palbeRequest`: the inner refresh-catch records with\n  // the precise status and rethrows; that rethrow is then caught by the outer\n  // catch, so the guard keeps the second `record()` a no-op (no double-count).\n  let recorded = false;\n  const record = (status: number): void => {\n    if (!traced || recorded) return;\n    recorded = true;\n    rt.perf.recordNetwork(method, redactUrl(path), status, nowMs() - startedAt);\n  };\n\n  let res: Awaited<ReturnType<typeof attempt>>;\n  try {\n    res = await attempt();\n\n    // Reactive 401: refresh once, retry once with the same Idempotency-Key.\n    // A revoked session (401 session_revoked) is terminal — a refresh cannot\n    // resurrect it, so skip straight to the teardown check below.\n    if (\n      res.error?.status === 401 &&\n      res.error.code !== 'session_revoked' &&\n      rt.tokenManager.getRefreshToken() &&\n      rt.tokenManager.refreshFunction\n    ) {\n      try {\n        await rt.tokenManager.refreshSession();\n      } catch (refreshErr) {\n        const pe = asPalbaseError(refreshErr);\n        const status = pe?.status ?? 0;\n        if (status === 400 || status === 401 || status === 403) {\n          // Terminal: the refresh token is dead. Sign out and surface the\n          // ORIGINAL 401 (mirrors HttpClient's pre-flight terminal split).\n          rt.tokenManager.clearSession();\n          record(res.error.status);\n          throw fromPalbaseError(res.error);\n        }\n        // Transient (network/5xx): keep the session, surface the refresh failure.\n        record(pe?.status ?? 0);\n        throw pe ? fromPalbaseError(pe) : refreshErr;\n      }\n      res = await attempt();\n    }\n\n    // Reactive proof-of-work: signup and login sit behind a bot gate that\n    // answers an unsolved request with 403 and the challenge in the body. Solve\n    // it once and repeat the request with the headers; the caller never learns\n    // the gate is there.\n    //\n    // Placed after the 401 branch so it sees whichever response is current — a\n    // refresh-and-retry can land on the gate just as a first attempt can.\n    //\n    // Only ONE retry, and only when the body really carries a challenge. A 403\n    // that merely says pow_required without one is a server the client cannot\n    // satisfy, and looping on it would turn a broken gate into a hang.\n    if (res.error?.status === 403 && res.error.code === 'pow_required') {\n      const challenge = asPowChallenge(res.error.details);\n      if (challenge) {\n        res = await attempt(await solvePowChallenge(challenge));\n      }\n    }\n  } catch (e) {\n    // A thrown error here is a network/transport failure (the `{data,error}`\n    // envelope never throws). Record it as a completed-with-error call unless\n    // the caller aborted — an abort is a cancellation, not a measurement.\n    if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);\n    throw e;\n  }\n\n  // Reactive session teardown: a server-side session kill (subject erased /\n  // session revoked) means the local session is dead regardless of which facade\n  // issued this call — tear it down + emit signedOut{sessionInvalid} once. Scoped\n  // to the exact codes so an ordinary 403 authz denial does NOT sign the user out.\n  if (res.error && isSessionKilled(res.error.status, res.error.code)) {\n    rt.auth.reactiveTeardown();\n  }\n\n  // Response resolved (2xx or an error envelope): record the real HTTP status\n  // BEFORE `unwrap` may throw, so a 4xx/5xx is measured with its true status.\n  record(res.error?.status ?? 200);\n  return unwrap(res);\n}\n","// Passkeys (WebAuthn platform credentials) for the browser, surfaced through\n// `pb.auth.*` with the SAME names the iOS SDK uses — signInWithPasskey,\n// signUpWithPasskey, registerPasskey — so the two surfaces are learned once.\n//\n// A passkey is DISCOVERABLE, so signing in needs no e-mail, no password and no\n// code: the browser lists the accounts stored for this relying party and the\n// user picks one.\n//\n// The three palauth calls are the same ones iOS makes:\n//   POST /auth/webauthn/login/begin    {}                   → assertion options\n//   POST /auth/webauthn/login/finish   <WebAuthn JSON>       → session\n//   POST /auth/webauthn/signup/begin   {email, user_name?}   → creation options + user_id\n//   POST /auth/webauthn/signup/finish?user_id=…  <WebAuthn JSON>\n//   POST /auth/webauthn/register/begin|finish                → add to a signed-in account\n//\n// This module is the ONLY place that translates between palauth's WebAuthn JSON\n// (base64URL strings) and the ArrayBuffers `navigator.credentials` wants. There\n// is deliberately no dependency added for it: @simplewebauthn is Studio's\n// internal choice, and a customer bundle should not grow one for ~60 lines of\n// base64URL.\n//\n// CROSS-DOMAIN NOTE. The relying-party id is the Environment's own host. A page\n// served from the customer's OWN domain can still use those passkeys, but only\n// through WebAuthn Related Origin Requests — the browser fetches\n// https://<rpId>/.well-known/webauthn and checks this origin against it. ROR is\n// not universal: Firefox on Android has it OFF by default, and a client without\n// it throws SecurityError rather than degrading. So `isPasskeySupported()`\n// exists and every caller needs a non-passkey fallback.\n\nimport { asWireAuthResult, type WireAuthResult } from './auth-wire.js';\nimport { palbeRequest } from './request.js';\nimport type { PalbeRuntime } from './runtime.js';\n\n/** palauth wraps both ceremonies' options as `{options: {publicKey: {…}}}`. */\ninterface OptionsEnvelope {\n  options: { publicKey: Record<string, unknown> };\n}\n\ninterface SignupBeginResponse extends OptionsEnvelope {\n  user_id: string;\n}\n\n/**\n * Decode WebAuthn's base64URL (RFC 4648 §5, no padding). Plain atob rejects\n * these strings, which is how a passkey integration fails at the first\n * challenge with an error that names nothing.\n */\nfunction base64UrlToBytes(value: string): Uint8Array<ArrayBuffer> {\n  const padded = value.replace(/-/g, '+').replace(/_/g, '/');\n  const binary = atob(padded.padEnd(padded.length + ((4 - (padded.length % 4)) % 4), '='));\n  const bytes = new Uint8Array(new ArrayBuffer(binary.length));\n  for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);\n  return bytes;\n}\n\n/** Encode as base64URL without padding — the only form WebAuthn accepts. */\nfunction bytesToBase64Url(buffer: ArrayBuffer): string {\n  const bytes = new Uint8Array(buffer);\n  let binary = '';\n  for (const b of bytes) binary += String.fromCharCode(b);\n  return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction requireString(source: Record<string, unknown>, key: string): string {\n  const value = source[key];\n  if (typeof value !== 'string' || value === '') {\n    throw new Error(`passkey options are missing ${key}`);\n  }\n  return value;\n}\n\n/**\n * Turn palauth's creation options into the shape navigator.credentials.create\n * wants. Only the fields the ceremony requires are translated; anything else\n * the server sends rides along untouched.\n */\nfunction toCreationOptions(publicKey: Record<string, unknown>): PublicKeyCredentialCreationOptions {\n  const rp = publicKey.rp as { id?: string; name?: string } | undefined;\n  const user = publicKey.user as { id?: string; name?: string; displayName?: string } | undefined;\n  if (!user?.id) {\n    throw new Error('passkey options carry no user id — the credential would be unusable');\n  }\n  const excludeCredentials = Array.isArray(publicKey.excludeCredentials)\n    ? (publicKey.excludeCredentials as Array<{ id: string; type: string }>).map((c) => ({\n        id: base64UrlToBytes(c.id),\n        type: 'public-key' as const,\n      }))\n    : undefined;\n\n  return {\n    challenge: base64UrlToBytes(requireString(publicKey, 'challenge')),\n    rp: { id: rp?.id, name: rp?.name ?? rp?.id ?? '' },\n    user: {\n      id: base64UrlToBytes(user.id),\n      name: user.name ?? '',\n      displayName: user.displayName ?? user.name ?? '',\n    },\n    pubKeyCredParams:\n      (publicKey.pubKeyCredParams as PublicKeyCredentialParameters[] | undefined) ?? [],\n    authenticatorSelection: publicKey.authenticatorSelection as\n      | AuthenticatorSelectionCriteria\n      | undefined,\n    timeout: publicKey.timeout as number | undefined,\n    attestation: publicKey.attestation as AttestationConveyancePreference | undefined,\n    excludeCredentials,\n  };\n}\n\n/** Assertion options carry `rpId` at the top level, not `rp.id`. */\nfunction toRequestOptions(publicKey: Record<string, unknown>): PublicKeyCredentialRequestOptions {\n  const allowCredentials = Array.isArray(publicKey.allowCredentials)\n    ? (publicKey.allowCredentials as Array<{ id: string }>).map((c) => ({\n        id: base64UrlToBytes(c.id),\n        type: 'public-key' as const,\n      }))\n    : undefined;\n\n  return {\n    challenge: base64UrlToBytes(requireString(publicKey, 'challenge')),\n    rpId: publicKey.rpId as string | undefined,\n    timeout: publicKey.timeout as number | undefined,\n    userVerification: publicKey.userVerification as UserVerificationRequirement | undefined,\n    allowCredentials,\n  };\n}\n\nfunction attestationToJSON(credential: PublicKeyCredential): Record<string, unknown> {\n  const response = credential.response as AuthenticatorAttestationResponse;\n  return {\n    id: credential.id,\n    rawId: bytesToBase64Url(credential.rawId),\n    type: credential.type,\n    response: {\n      clientDataJSON: bytesToBase64Url(response.clientDataJSON),\n      attestationObject: bytesToBase64Url(response.attestationObject),\n    },\n  };\n}\n\nfunction assertionToJSON(credential: PublicKeyCredential): Record<string, unknown> {\n  const response = credential.response as AuthenticatorAssertionResponse;\n  return {\n    id: credential.id,\n    rawId: bytesToBase64Url(credential.rawId),\n    type: credential.type,\n    response: {\n      clientDataJSON: bytesToBase64Url(response.clientDataJSON),\n      authenticatorData: bytesToBase64Url(response.authenticatorData),\n      signature: bytesToBase64Url(response.signature),\n      // The user handle is how palauth resolves WHO signed in on a discoverable\n      // login — there is no identifier in the request.\n      userHandle: response.userHandle ? bytesToBase64Url(response.userHandle) : null,\n    },\n  };\n}\n\n/**\n * Whether this browser can run a passkey ceremony at all.\n *\n * Callers MUST branch on this rather than assuming: a client without WebAuthn —\n * or without Related Origin Requests, when the page is on a different domain\n * than the relying party — throws instead of degrading, so the UI needs a\n * password or e-mail path beside the passkey button.\n */\nexport function isPasskeySupported(): boolean {\n  return (\n    typeof window !== 'undefined' &&\n    typeof window.PublicKeyCredential === 'function' &&\n    typeof navigator !== 'undefined' &&\n    navigator.credentials !== undefined\n  );\n}\n\nfunction ensureSupported(): void {\n  if (!isPasskeySupported()) {\n    throw new Error('This browser cannot use passkeys — offer a password or e-mail sign-in');\n  }\n}\n\nasync function createCredential(publicKey: Record<string, unknown>): Promise<PublicKeyCredential> {\n  const credential = await navigator.credentials.create({\n    publicKey: toCreationOptions(publicKey),\n  });\n  if (credential === null) {\n    throw new Error('the browser returned no credential');\n  }\n  return credential as PublicKeyCredential;\n}\n\nasync function getCredential(publicKey: Record<string, unknown>): Promise<PublicKeyCredential> {\n  const credential = await navigator.credentials.get({\n    publicKey: toRequestOptions(publicKey),\n  });\n  if (credential === null) {\n    throw new Error('the browser returned no credential');\n  }\n  return credential as PublicKeyCredential;\n}\n\n/** Sign in with a passkey already stored for this relying party. */\nexport async function passkeySignIn(rt: PalbeRuntime): Promise<WireAuthResult> {\n  ensureSupported();\n  // An EMPTY body is what makes this discoverable: palauth reads no user_id and\n  // asks the authenticator for whatever it holds for this relying party.\n  const envelope = await palbeRequest<OptionsEnvelope>(rt, 'POST', '/auth/webauthn/login/begin', {\n    body: {},\n  });\n  const credential = await getCredential(envelope.options.publicKey);\n  const raw = await palbeRequest<unknown>(rt, 'POST', '/auth/webauthn/login/finish', {\n    body: assertionToJSON(credential),\n  });\n  const result = asWireAuthResult(raw);\n  if (result === null) {\n    throw new Error('passkey sign-in returned an unusable session');\n  }\n  return result;\n}\n\n/**\n * Create an account whose only credential is a passkey — no password ever\n * exists for it.\n */\nexport async function passkeySignUp(\n  rt: PalbeRuntime,\n  email: string,\n  displayName?: string,\n): Promise<WireAuthResult> {\n  ensureSupported();\n  const begun = await palbeRequest<SignupBeginResponse>(rt, 'POST', '/auth/webauthn/signup/begin', {\n    body: { email, user_name: displayName },\n  });\n  const credential = await createCredential(begun.options.publicKey);\n  // user_id travels as a QUERY parameter: the server keys the pending ceremony\n  // by it. The account does NOT exist yet — begin writes nothing, and finish\n  // opens the account in the same transaction as the credential, so an\n  // abandoned ceremony leaves no row and burns no address.\n  await palbeRequest<unknown>(\n    rt,\n    'POST',\n    `/auth/webauthn/signup/finish?user_id=${encodeURIComponent(begun.user_id)}`,\n    { body: attestationToJSON(credential) },\n  );\n  // signup/finish returns the CREDENTIAL, not a session: the account exists but\n  // nobody is signed in. Signing in immediately is what a caller means by \"sign\n  // up\", and it also proves the credential just created actually works.\n  return await passkeySignIn(rt);\n}\n\n/**\n * Add a passkey to the account that is already signed in.\n *\n * Requires a RECENT sign-in: palauth answers 403 `reauthentication_required`\n * when the session is older than its freshness window, because a passkey keeps\n * working after a password reset and a merely-valid session must not be able to\n * enroll one. Callers should re-authenticate and retry.\n */\nexport async function passkeyRegister(rt: PalbeRuntime, name?: string): Promise<void> {\n  ensureSupported();\n  const envelope = await palbeRequest<OptionsEnvelope>(\n    rt,\n    'POST',\n    '/auth/webauthn/register/begin',\n    { body: { name } },\n  );\n  const credential = await createCredential(envelope.options.publicKey);\n  await palbeRequest<unknown>(rt, 'POST', '/auth/webauthn/register/finish', {\n    body: attestationToJSON(credential),\n  });\n}\n","import type {\n  User as AuthClientUser,\n  Identity,\n  OAuthOptions,\n  OAuthProvider,\n  OAuthTransaction,\n} from '@palbase/auth';\nimport type { Session } from '@palbase/core';\nimport {\n  asWireAuthResult,\n  requiredPermission,\n  type WireAuthResult,\n  type WireMe,\n  type WireUser,\n} from './auth-wire.js';\nimport { BackendError, unwrap } from './errors.js';\nimport { isPasskeySupported, passkeyRegister, passkeySignIn, passkeySignUp } from './passkey.js';\nimport type { RealtimeSubscription } from './realtime/facade.js';\nimport { palbeRequest } from './request.js';\nimport type { PalbeRuntime } from './runtime.js';\n\nexport type MagicLinkResult =\n  | ({ status: 'signedIn' } & AuthSuccess)\n  | { status: 'mfaRequired'; mfaToken: string; factors: string[] };\n\nexport type OAuthExchangeResult =\n  | ({ status: 'signedIn'; isNewUser: boolean } & AuthSuccess)\n  | { status: 'mfaRequired'; mfaToken: string; factors: string[] }\n  | { status: 'linked'; identity: Identity; userId: string };\n\nexport interface AuthUser {\n  id: string;\n  /** null for phone-only users (the server omits email). */\n  email: string | null;\n  emailVerified: boolean;\n  createdAt: string;\n  /**\n   * The caller's APPLICATION roles, as assigned in `auth.user_roles`.\n   *\n   * Compare against the generated `Roles` constants rather than string\n   * literals — a role withdrawn upstream disappears from that module, so code\n   * still naming it stops building instead of quietly losing access:\n   *\n   * ```ts\n   * import { Roles } from './palbe.gen';\n   * if (pb.auth.currentUser?.roles.includes(Roles.moderator)) …\n   * ```\n   *\n   * Empty array for a caller who holds none, never null: `.includes(…)` needs\n   * no guard. This is the UI's hint, not the boundary — the server decides,\n   * and it decides again on every request.\n   */\n  roles: string[];\n}\n\n/** What `pb.auth.getSignInMethods()` reports about an account's credentials. */\nexport interface SignInMethods {\n  /** A local password exists — offer \"change password\", not \"set password\". */\n  password: boolean;\n  /** An MFA factor is enrolled. */\n  mfa: boolean;\n  /**\n   * Linked OAuth providers, e.g. `['google']`. `[]` means none are linked;\n   * `null` means the server could not determine it (social login is not\n   * configured, or the lookup failed) — treat null as unknown, not as none.\n   */\n  providers: string[] | null;\n}\n\nexport interface AuthSuccess {\n  user: AuthUser;\n  session: Session;\n}\n\nexport type AuthState = { status: 'signedIn'; user: AuthUser } | { status: 'signedOut' };\n\nexport type AuthChangeEvent =\n  | { type: 'signedIn'; user: AuthUser }\n  | {\n      type: 'signedOut';\n      /**\n       * `userInitiated` — pb.auth.signOut(); `sessionExpired` — a refresh\n       * ultimately failed; `accountDeleted` — this device ran deleteAccount();\n       * `sessionInvalid` — a server-side session kill (erased/revoked subject)\n       * was observed on a request and the client tore down reactively.\n       */\n      reason: 'userInitiated' | 'sessionExpired' | 'accountDeleted' | 'sessionInvalid';\n    }\n  | { type: 'tokenRefreshed' };\n\nexport type Unsubscribe = () => void;\n\n/** Map the wire bare-user shape (GET /auth/user) to AuthUser. */\nfunction mapWireUser(raw: WireUser): AuthUser {\n  return {\n    id: raw.id,\n    email: raw.email ?? null,\n    emailVerified: raw.email_verified,\n    createdAt: raw.created_at,\n    // A stack older than the roles surface omits the key entirely; `[]` is the\n    // honest reading there — it holds no roles because it has none to hold.\n    roles: raw.roles ?? [],\n  };\n}\n\n/** Map @palbase/auth's camelCase User to palbe's AuthUser (drop extra fields). */\nfunction mapClientUser(u: AuthClientUser): AuthUser {\n  // AuthClient types email as a required string, but the wire omits it for\n  // phone-only users — normalize missing/empty to null at this boundary.\n  return {\n    id: u.id,\n    email: u.email || null,\n    emailVerified: u.emailVerified,\n    createdAt: u.createdAt,\n    roles: u.roles ?? [],\n  };\n}\n\n/** Key-order-proof equality on the four AuthUser fields (refreshUser change detection). */\nfunction usersEqual(a: AuthUser, b: AuthUser | null): boolean {\n  return (\n    b !== null &&\n    a.id === b.id &&\n    a.email === b.email &&\n    a.emailVerified === b.emailVerified &&\n    a.createdAt === b.createdAt\n  );\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null;\n}\nfunction isString(v: unknown): v is string {\n  return typeof v === 'string';\n}\n\n/** Process-wide `onPermissionDenied` handlers — survive a runtime re-`__configure`. */\nconst permissionDeniedHandlers = new Set<(required: string) => void>();\n\n/** Test-only (called by `__reset`): the relay outlives a runtime on purpose, a test run does not. */\nexport function __resetPermissionDeniedHandlers(): void {\n  permissionDeniedHandlers.clear();\n}\n\nexport class PalbeAuth {\n  private cachedUser: AuthUser | null = null;\n  private signingOut = false;\n  // Explicit signedOut reason pinned for the NEXT session clear (deleteAccount /\n  // reactiveTeardown set it before clearSession; the SIGNED_OUT handler consumes\n  // it exactly once, then resets to null → normal signOut/expiry split resumes).\n  private nextSignOutReason: 'accountDeleted' | 'sessionInvalid' | null = null;\n  private signingIn = false; // suppresses AuthClient's TOKEN_REFRESHED during re-signIn\n  private readonly oauthCompletions = new Map<\n    string,\n    { resultCode?: string; callbackURL?: string; promise: Promise<OAuthExchangeResult> }\n  >();\n  private signedInState = false; // dedupes AuthClient's repeated SIGNED_OUT events\n  private hydratingUser = false; // guards hydrateUser() to a single boot fetch\n  private readonly stateListeners = new Set<(state: AuthState) => void>();\n  private readonly eventListeners = new Set<(event: AuthChangeEvent) => void>();\n  private readonly userListeners = new Set<(user: AuthUser) => void>();\n\n  constructor(private readonly rt: PalbeRuntime) {\n    // Every runtime's HttpClient feeds the same process-wide relay (FR-010).\n    rt.http.onForbidden((body) => {\n      const required = requiredPermission(body);\n      if (required === null) return;\n      for (const handler of permissionDeniedHandlers) this.safeInvoke(() => handler(required));\n    });\n    // AuthClient fires SIGNED_OUT on any session clear and TOKEN_REFRESHED on\n    // refresh. SIGNED_IN is emitted by the facade itself (it knows the user);\n    // after hydration AuthClient never fires SIGNED_IN anyway (hasSession=true).\n    rt.authClient.onAuthStateChange((event, _session) => {\n      if (event === 'SIGNED_OUT') {\n        if (!this.signedInState) return; // duplicate clear — already signed out\n        this.signedInState = false;\n        this.cachedUser = null;\n        // A caller (deleteAccount / reactiveTeardown) may pin an explicit reason\n        // for THIS clear; otherwise fall back to the signOut-vs-expiry split.\n        const reason =\n          this.nextSignOutReason ?? (this.signingOut ? 'userInitiated' : 'sessionExpired');\n        this.nextSignOutReason = null;\n        this.emitState({ status: 'signedOut' });\n        this.emitEvent({ type: 'signedOut', reason });\n      } else if (event === 'TOKEN_REFRESHED') {\n        // Re-signIn while signed in makes AuthClient map the new session to\n        // TOKEN_REFRESHED (hasSession=true) — that would leak a tokenRefreshed\n        // with the OLD user just before signedIn. iOS emits exactly one\n        // signedIn per login; suppress it here.\n        if (this.signingIn) return;\n        this.emitEvent({ type: 'tokenRefreshed' });\n      }\n    });\n    // Hydrated runtime starts in a signed-in-ish state (pending refresh).\n    this.signedInState = rt.tokenManager.getRefreshToken() !== null;\n  }\n\n  // ── state ──────────────────────────────────────────────\n\n  get currentUser(): AuthUser | null {\n    return this.cachedUser;\n  }\n\n  get isSignedIn(): boolean {\n    return this.rt.tokenManager.getRefreshToken() !== null;\n  }\n\n  // ── core flows ─────────────────────────────────────────\n\n  /**\n   * Create an account.\n   *\n   * `locale` is an explicit choice of the language the account's mail is\n   * written in, and the stack STORES it. Left out, the request carries the\n   * PAGE's language (`<html lang>`) as its Accept-Language — the language the\n   * person is reading the sign-up form in — and nothing is stored: the stack\n   * reads it for this mail only (palgroup/palbase#24).\n   *\n   * Why not store the page language: a template's hard-coded `lang=\"en\"` is\n   * common, and a stored \"en\" would outrank every later request's language for\n   * good. Why not leave the browser's own header: it is the browser's interface\n   * language, and a Turkish page in an English browser would get English mail.\n   */\n  async signUp(params: { email: string; password: string; locale?: string }): Promise<AuthSuccess> {\n    this.signingIn = true;\n    try {\n      const lang = params.locale ? undefined : pageLanguage();\n      const data = unwrap(\n        await this.rt.authClient.signUp(\n          params,\n          lang ? { headers: { 'Accept-Language': lang } } : undefined,\n        ),\n      );\n      return this.adopt(data);\n    } finally {\n      this.signingIn = false;\n    }\n  }\n\n  async signIn(params: { email: string; password: string }): Promise<AuthSuccess> {\n    this.signingIn = true;\n    try {\n      const data = unwrap(await this.rt.authClient.signIn(params));\n      return this.adopt(data);\n    } finally {\n      this.signingIn = false;\n    }\n  }\n\n  async signOut(): Promise<void> {\n    this.signingOut = true;\n    try {\n      await this.rt.authClient.signOut();\n    } catch {\n      // local sign-out must win even when the server call fails (offline etc.)\n    } finally {\n      this.rt.tokenManager.clearSession(); // idempotent; deduped by signedInState\n      this.signingOut = false; // AFTER clear → reason stays userInitiated\n      this.rt.storage.clear();\n      this.cachedUser = null;\n    }\n  }\n\n  /**\n   * Self-service account erasure (\"right to be forgotten\"). Calls palauth\n   * `DELETE /auth/user` (session-authed + fresh re-auth): password users pass\n   * `{ password }`; passwordless/OAuth users rely on a freshly stepped-up\n   * session. The handler answers **204 with no body** — the erasure has already\n   * finished and every session is already revoked server-side — so we tear down\n   * local state (mirroring `signOut()`'s clear, minus the pointless `/logout`)\n   * and emit `signedOut{reason:'accountDeleted'}`.\n   *\n   * Returns nothing, because there is nothing to return: the handler used to\n   * answer 202 with an `{erasure_id}` naming an asynchronous run, and that id\n   * was removed along with the run (`gdpr_handlers.go:221-229`). Reading it\n   * here threw a `TypeError` AFTER the account was already gone — a success\n   * reported as a failure.\n   *\n   * On 401 `reauth_required` / 503 `not_configured` (or `erasure_unavailable`)\n   * the request throws BEFORE the teardown line, so the local session is left\n   * fully intact — the deletion did not happen and the user is still signed in.\n   */\n  async deleteAccount(params: { password?: string } = {}): Promise<void> {\n    await palbeRequest<null>(this.rt, 'DELETE', '/auth/user', {\n      body: params.password ? { password: params.password } : {},\n    });\n    // Reached only on 204 (2xx): sessions already revoked server-side.\n    this.nextSignOutReason = 'accountDeleted';\n    this.rt.tokenManager.clearSession(); // fires SIGNED_OUT → emits accountDeleted\n    this.rt.storage.clear();\n    this.cachedUser = null;\n  }\n\n  /**\n   * @internal — invoked by the transport choke point (`request.ts`), not app code.\n   * Reactive teardown when the server reports the session is gone: a 403\n   * `subject_fenced`/`subject_erased` (subject being erased) or a 401\n   * `session_revoked`. Clears local state and emits\n   * `signedOut{reason:'sessionInvalid'}` exactly once (deduped by\n   * `signedInState`). An ordinary 403 authz denial does NOT reach here —\n   * `request.ts` matches only the exact session-kill codes.\n   */\n  reactiveTeardown(): void {\n    if (!this.signedInState) return; // already torn down — exactly-once\n    this.nextSignOutReason = 'sessionInvalid';\n    this.rt.tokenManager.clearSession(); // fires SIGNED_OUT → emits sessionInvalid\n    this.rt.storage.clear();\n    this.cachedUser = null;\n  }\n\n  async getUser(): Promise<AuthUser> {\n    const raw = await palbeRequest<WireUser>(this.rt, 'GET', '/auth/user');\n    return mapWireUser(raw);\n  }\n\n  /**\n   * Which credentials this account actually has.\n   *\n   * An account reached through Google has no password, so showing it a\n   * \"current password\" field gives the user something they can never fill —\n   * and `getUser()` cannot tell you, because GET /auth/user carries no\n   * credential information. Read this before rendering any re-auth or\n   * change-password form.\n   */\n  async getSignInMethods(): Promise<SignInMethods> {\n    const raw = await palbeRequest<WireMe>(this.rt, 'GET', '/auth/me');\n    return {\n      password: raw.has_password,\n      mfa: raw.has_mfa,\n      providers: raw.providers ?? null,\n    };\n  }\n\n  async refreshUser(): Promise<AuthUser> {\n    const user = await this.getUser();\n    const changed = !usersEqual(user, this.cachedUser);\n    this.cachedUser = user;\n    if (changed) for (const cb of this.userListeners) this.safeInvoke(() => cb(user));\n    return user;\n  }\n\n  /**\n   * Restore the user after a session was rehydrated from storage (page reload).\n   * Hydration in buildRuntime restores the TOKENS synchronously, but the access\n   * token JWT does not carry emailVerified/createdAt, so the full AuthUser can't\n   * be reconstructed offline — this fetches GET /auth/user once and announces\n   * `signedIn`, so the app no longer has to `await pb.auth.refreshUser()` itself\n   * on boot. Idempotent (runs once), browser-safe (no-op when not signed in or\n   * a user is already cached), and never throws (a boot-time network failure\n   * must not break app startup — isSignedIn stays true, the app can retry).\n   */\n  hydrateUser(): void {\n    if (this.hydratingUser || this.cachedUser || !this.isSignedIn) return;\n    this.hydratingUser = true;\n    void this.refreshUser()\n      .then((user) => {\n        // Only announce if we're still signed in (a sign-out may have raced).\n        if (this.isSignedIn) {\n          this.signedInState = true;\n          this.emitState({ status: 'signedIn', user });\n        }\n      })\n      .catch(() => {\n        // Swallow: a failed boot fetch leaves isSignedIn true; the app can\n        // call refreshUser() again or the next authed request will 401→refresh.\n      })\n      .finally(() => {\n        this.hydratingUser = false;\n      });\n  }\n\n  // ── listeners ──────────────────────────────────────────\n\n  private permissionsStore: PalbePermissions | null = null;\n\n  /** The caller's live permission set — see PalbePermissions. Lazy: a server\n   * request that never asks pays nothing (no realtime socket). The FIRST access\n   * binds synchronously and lets a realtime refusal (no browser environment)\n   * THROW here, with the guided message — an empty set answered in silence\n   * would read as \"no permissions\". */\n  get permissions(): PalbePermissions {\n    if (!this.permissionsStore) {\n      const store = new PalbePermissions(this.rt);\n      store.attach(this);\n      this.permissionsStore = store;\n    }\n    return this.permissionsStore;\n  }\n\n  /** FR-010: fires with the permission a 403 named in `required`. Refetch the\n   * object the screen was drawn from; the error itself is thrown as always.\n   * Handlers live in a module-level relay (like iOS' PermissionDeniedRelay), so\n   * a re-`__configure` — which replaces the HttpClient — does not lose them. */\n  onPermissionDenied(handler: (required: string) => void): Unsubscribe {\n    permissionDeniedHandlers.add(handler);\n    return () => permissionDeniedHandlers.delete(handler);\n  }\n\n  /**\n   * Subscribe to signed-in/signed-out state. Fires immediately with the\n   * current snapshot (iOS parity). A restored session (page reload) hydrates\n   * the user asynchronously via `hydrateUser()` (fired once at boot), so the\n   * FIRST snapshot may report signedOut for a tick even when `isSignedIn` is\n   * true; the listener then fires again with `signedIn` once the user lands.\n   * Rely on `isSignedIn` for the session truth if you need it synchronously.\n   */\n  onAuthStateChange(callback: (state: AuthState) => void): Unsubscribe {\n    this.stateListeners.add(callback);\n    this.safeInvoke(() => callback(this.snapshotState()));\n    return () => this.stateListeners.delete(callback);\n  }\n\n  onAuthEvent(callback: (event: AuthChangeEvent) => void): Unsubscribe {\n    this.eventListeners.add(callback);\n    return () => this.eventListeners.delete(callback);\n  }\n\n  /** Subscribe to user-profile changes. Replays the cached user on subscribe (iOS parity). */\n  onUserChange(callback: (user: AuthUser) => void): Unsubscribe {\n    this.userListeners.add(callback);\n    const u = this.cachedUser;\n    if (u) this.safeInvoke(() => callback(u));\n    return () => this.userListeners.delete(callback);\n  }\n\n  // ── internals ──────────────────────────────────────────\n\n  private snapshotState(): AuthState {\n    return this.cachedUser && this.isSignedIn\n      ? { status: 'signedIn', user: this.cachedUser }\n      : { status: 'signedOut' };\n  }\n\n  /**\n   * Listener exception isolation: a throwing consumer callback must never\n   * break delivery to other listeners nor propagate into the emit caller\n   * (tokenManager.clearSession callers, pb.call paths, signOut, ...).\n   */\n  private safeInvoke(fn: () => void): void {\n    try {\n      fn();\n    } catch {\n      // consumer callback errors are intentionally swallowed\n    }\n  }\n\n  private emitState(state: AuthState): void {\n    for (const cb of this.stateListeners) this.safeInvoke(() => cb(state));\n  }\n\n  private emitEvent(event: AuthChangeEvent): void {\n    for (const cb of this.eventListeners) this.safeInvoke(() => cb(event));\n  }\n\n  /** Cache the user + announce sign-in. Session was already set by AuthClient. */\n  private adopt(data: { user: AuthClientUser; session: Session }): AuthSuccess {\n    const user = mapClientUser(data.user);\n    this.cachedUser = user;\n    this.signedInState = true;\n    this.emitState({ status: 'signedIn', user });\n    this.emitEvent({ type: 'signedIn', user });\n    return { user, session: data.session };\n  }\n\n  /** Adopt a raw palauth AuthResult wire shape: wire tokens, cache user, announce. */\n  private adoptWire(raw: WireAuthResult): AuthSuccess {\n    this.rt.authClient.setTokens(raw.access_token, raw.refresh_token, raw.expires_in);\n    const user = mapWireUser(raw.user);\n    this.cachedUser = user;\n    this.signedInState = true;\n    this.emitState({ status: 'signedIn', user });\n    this.emitEvent({ type: 'signedIn', user });\n    const session: Session = {\n      accessToken: raw.access_token,\n      refreshToken: raw.refresh_token,\n      expiresAt: Date.now() + raw.expires_in * 1000,\n    };\n    return { user, session };\n  }\n\n  /** Run a sign-in flow under the signingIn flag to suppress spurious tokenRefreshed. */\n  private async withSigningIn<T>(fn: () => Promise<T>): Promise<T> {\n    this.signingIn = true;\n    try {\n      return await fn();\n    } finally {\n      this.signingIn = false;\n    }\n  }\n\n  /**\n   * Defensively decode a 200 union body (AuthResult | mfa-required) and\n   * complete the flow. The wire contract promises one of the two shapes, but\n   * a literal-`null` (or otherwise malformed) JSON body must surface as\n   * BackendError('decode') — never a raw TypeError from probing a non-object.\n   * The mfa branch validates its fields: `mfa_token` is required; the factor\n   * list (named `factors` by magic-link verify, `mfa_factors` by the OAuth\n   * callback — extraction-verified against palauth) tolerates a missing or\n   * malformed value as []. The signedIn branch validates the FULL AuthResult\n   * shape (asWireAuthResult) — an incomplete body falls through to decode,\n   * never half-adopts.\n   */\n  private completeAuthUnion(\n    raw: unknown,\n    factorsKey: 'factors' | 'mfa_factors',\n    context: string,\n  ): MagicLinkResult {\n    if (typeof raw === 'object' && raw !== null) {\n      const obj = raw as Record<string, unknown>;\n      if (obj.mfa_required === true) {\n        if (typeof obj.mfa_token === 'string') {\n          const list = obj[factorsKey];\n          const factors = Array.isArray(list)\n            ? list.filter((f): f is string => typeof f === 'string')\n            : [];\n          return { status: 'mfaRequired', mfaToken: obj.mfa_token, factors };\n        }\n        // mfa_required without a usable mfa_token is unrecoverable — fall\n        // through to decode (NOT the signedIn branch).\n      } else {\n        const wire = asWireAuthResult(raw);\n        if (wire) return { status: 'signedIn', ...this.adoptWire(wire) };\n      }\n    }\n    // 200 body matching neither shape — never fabricate a result.\n    throw this.decodeError(context);\n  }\n\n  private decodeError(context: string): BackendError {\n    return new BackendError('decode', {\n      code: 'decode_error',\n      message: `Unexpected ${context} response`,\n    });\n  }\n\n  // ── additional auth flows ──────────────────────────────\n\n  async signInWithOTP(params: { phone: string }): Promise<void> {\n    // The server only supports the 'sms' channel (rejects anything else).\n    await palbeRequest(this.rt, 'POST', '/auth/otp', {\n      body: { phone: params.phone, channel: 'sms' },\n    });\n  }\n\n  async verifyOTP(params: { phone: string; token: string }): Promise<AuthSuccess> {\n    return this.withSigningIn(async () => {\n      const raw = await palbeRequest<unknown>(this.rt, 'POST', '/auth/otp/verify', {\n        body: params,\n      });\n      // The OTP-verify wire is AuthResult ONLY (palauth phoneLoginResponse —\n      // no MFA union on this route): the same zombie-session guard applies,\n      // and an mfa-shaped body here is a decode error, not an MFA result.\n      const wire = asWireAuthResult(raw);\n      if (!wire) throw this.decodeError('OTP verify');\n      return this.adoptWire(wire);\n    });\n  }\n\n  async resetPassword(email: string): Promise<void> {\n    unwrap(await this.rt.authClient.requestPasswordReset({ email }));\n  }\n\n  async confirmPasswordReset(params: { token: string; newPassword: string }): Promise<void> {\n    unwrap(\n      await this.rt.authClient.confirmPasswordReset({\n        token: params.token,\n        new_password: params.newPassword,\n      }),\n    );\n  }\n\n  async updatePassword(params: { currentPassword: string; newPassword: string }): Promise<void> {\n    unwrap(\n      await this.rt.authClient.changePassword({\n        current_password: params.currentPassword,\n        new_password: params.newPassword,\n      }),\n    );\n  }\n\n  /**\n   * Give a passwordless account its FIRST password, in-app.\n   *\n   * For accounts created with a passkey or a social provider: they have no\n   * current password, so `updatePassword` cannot serve them — it sends one and\n   * the server answers 401. Before this existed the only route was the\n   * password-RESET e-mail, which asks someone already signed in to go find\n   * their inbox.\n   *\n   * Requires a RECENT sign-in, not merely a session: a first password is a\n   * credential that outlives the rest, so the server answers 403\n   * `reauthentication_required` on a stale one — the same gate\n   * `registerPasskey` carries. An account that already has a password gets 409\n   * `password_already_set`; change it with `updatePassword` instead.\n   *\n   * The session stays valid — no re-login.\n   */\n  async setPassword(newPassword: string): Promise<void> {\n    unwrap(await this.rt.authClient.setPassword({ new_password: newPassword }));\n  }\n\n  async verifyEmail(params: { token: string } | { code: string; email: string }): Promise<void> {\n    unwrap(await this.rt.authClient.verifyEmail(params));\n  }\n\n  async resendVerification(email: string): Promise<void> {\n    unwrap(await this.rt.authClient.resendVerification(email));\n  }\n\n  async signInWithMagicLink(email: string): Promise<void> {\n    unwrap(await this.rt.authClient.requestMagicLink({ email }));\n  }\n\n  async verifyMagicLink(token: string): Promise<MagicLinkResult> {\n    return this.withSigningIn(async () => {\n      const raw = await palbeRequest<unknown>(this.rt, 'POST', '/auth/magic-link/verify', {\n        body: { token },\n      });\n      return this.completeAuthUnion(raw, 'factors', 'magic-link verify');\n    });\n  }\n\n  /**\n   * Sign in with a passkey stored for this Environment. No identifier is typed:\n   * the browser lists the accounts it holds and the user picks one.\n   *\n   * Throws when the browser cannot run a ceremony — check `passkeysSupported`\n   * first and keep a password or e-mail path beside the button.\n   */\n  async signInWithPasskey(): Promise<AuthSuccess> {\n    return this.withSigningIn(async () => this.adoptWire(await passkeySignIn(this.rt)));\n  }\n\n  /**\n   * Create an account whose only credential is a passkey — the e-mail is the\n   * identifier, the passkey is the credential, and no password ever exists.\n   */\n  async signUpWithPasskey(email: string, displayName?: string): Promise<AuthSuccess> {\n    return this.withSigningIn(async () =>\n      this.adoptWire(await passkeySignUp(this.rt, email, displayName)),\n    );\n  }\n\n  /**\n   * Add a passkey to the signed-in account, so the next sign-in is one tap.\n   *\n   * Rejects with a 403 `reauthentication_required` when the session is not\n   * recent: a passkey outlives a password reset, so enrolling one takes more\n   * than a valid session.\n   */\n  async registerPasskey(name?: string): Promise<void> {\n    await passkeyRegister(this.rt, name);\n  }\n\n  /** Whether this browser can run a passkey ceremony at all. */\n  get passkeysSupported(): boolean {\n    return isPasskeySupported();\n  }\n\n  async signInWithOAuth(params: {\n    provider: OAuthProvider;\n    redirectTo?: string;\n    /** Set false to skip the browser redirect (popup/manual flows). Default true. */\n    redirect?: boolean;\n  }): Promise<{ url: string }> {\n    const { redirect = true, ...opts } = params;\n    const transaction = await this.beginOAuth(opts);\n    const url = transaction.authorizationURL;\n    if (redirect && typeof window !== 'undefined' && typeof window.location !== 'undefined') {\n      window.location.assign(url);\n    }\n    return { url };\n  }\n\n  async beginOAuth(options: OAuthOptions): Promise<OAuthTransaction> {\n    return unwrap(await this.rt.authClient.beginOAuth(options));\n  }\n\n  /** Complete with the application's result_code; the provider code stays on the backend. */\n  exchangeCodeForSession(params: {\n    transactionId: string;\n    resultCode: string;\n    callbackURL?: string;\n  }): Promise<OAuthExchangeResult> {\n    return this.completeOAuth(params);\n  }\n\n  completeOAuth(params: {\n    transactionId: string;\n    resultCode?: string;\n    callbackURL?: string;\n  }): Promise<OAuthExchangeResult> {\n    const current = this.oauthCompletions.get(params.transactionId);\n    if (current) {\n      if (current.resultCode !== params.resultCode || current.callbackURL !== params.callbackURL) {\n        return Promise.reject(\n          new BackendError('validation', {\n            code: 'invalid_result_code',\n            message: 'A different OAuth completion is already in progress',\n          }),\n        );\n      }\n      return current.promise;\n    }\n    const operation = this.withSigningIn(async (): Promise<OAuthExchangeResult> => {\n      const result = unwrap(await this.rt.authClient.completeOAuth(params));\n      if (result.status === 'signedIn')\n        return { status: 'signedIn', isNewUser: result.isNewUser, ...this.adopt(result) };\n      return result;\n    });\n    this.oauthCompletions.set(params.transactionId, {\n      resultCode: params.resultCode,\n      callbackURL: params.callbackURL,\n      promise: operation,\n    });\n    void operation.then(\n      () => this.oauthCompletions.delete(params.transactionId),\n      () => this.oauthCompletions.delete(params.transactionId),\n    );\n    return operation;\n  }\n\n  async cancelOAuth(transactionId: string): Promise<void> {\n    unwrap(await this.rt.authClient.cancelOAuth(transactionId));\n  }\n\n  async linkIdentity(options: Omit<OAuthOptions, 'purpose'>): Promise<OAuthTransaction> {\n    return unwrap(await this.rt.authClient.linkIdentity(options));\n  }\n\n  async signInWithGoogle(opts?: { redirectTo?: string; redirect?: boolean }): Promise<{\n    url: string;\n  }> {\n    return this.signInWithOAuth({ provider: 'google', ...opts });\n  }\n\n  async signInWithApple(opts?: { redirectTo?: string; redirect?: boolean }): Promise<{\n    url: string;\n  }> {\n    return this.signInWithOAuth({ provider: 'apple', ...opts });\n  }\n}\n\n/**\n * `pb.auth.permissions` — the caller's live permission set (FR-020 = iOS\n * FR-016…019). Affordance, never authority: it decides what to draw, the\n * server decides what is allowed on every request. Bound to\n * `roles:<projectRef>:<uid>` through the general realtime state path, whose\n * gap→resync and reconnect→rejoin already cover FR-018.\n */\nexport class PalbePermissions {\n  /** True after an unreadable `values` push; a later `sync_version` alone must not restore a version. */\n  private unreadable = false;\n  private set: ReadonlySet<string> = new Set();\n  private version = '';\n  private userId: string | null = null;\n  private subs: RealtimeSubscription[] = [];\n  private readonly listeners = new Set<(set: ReadonlySet<string>) => void>();\n\n  constructor(private readonly rt: PalbeRuntime) {}\n\n  /** Bind to the auth lifecycle. The CURRENT state binds synchronously — a\n   * realtime refusal throws to the caller of `pb.auth.permissions`; later\n   * transitions bind inside the auth emitter, where a failure is reported\n   * rather than swallowed. */\n  attach(auth: PalbeAuth): void {\n    // Now, OUTSIDE the auth emitter (whose safeInvoke would swallow the refusal).\n    const current = auth.currentUser;\n    this.bind(current !== null && auth.isSignedIn ? current.id : null);\n    // Later transitions arrive through the emitter; the replay it fires first\n    // carries the state just bound and is a no-op. A failure there is reported,\n    // not hidden — and `userId` stays unset so the next transition retries.\n    auth.onAuthStateChange((state) => {\n      try {\n        this.bind(state.status === 'signedIn' ? state.user.id : null);\n      } catch (err) {\n        console.warn('palbe permissions: could not bind to the roles channel', err);\n      }\n    });\n  }\n\n  holds(permission: string): boolean {\n    return this.set.has(permission);\n  }\n  get all(): ReadonlySet<string> {\n    return this.set;\n  }\n  get syncVersion(): string {\n    return this.version;\n  }\n  onChange(callback: (set: ReadonlySet<string>) => void): Unsubscribe {\n    this.listeners.add(callback);\n    return () => this.listeners.delete(callback);\n  }\n  /** `for await (const set of pb.auth.permissions.changes())` — the current set first. */\n  async *changes(): AsyncIterable<ReadonlySet<string>> {\n    const queue: ReadonlySet<string>[] = [this.set];\n    let wake: (() => void) | null = null;\n    const off = this.onChange((set) => {\n      queue.push(set);\n      wake?.();\n      wake = null;\n    });\n    try {\n      while (true) {\n        while (queue.length > 0) yield queue.shift()!;\n        await new Promise<void>((resolve) => {\n          wake = resolve;\n        });\n      }\n    } finally {\n      off();\n    }\n  }\n\n  private bind(userId: string | null): void {\n    if (userId === this.userId) return;\n    for (const s of this.subs) s.cancel();\n    this.subs = [];\n    this.apply(new Set(), '');\n    if (userId === null) {\n      this.userId = null;\n      return;\n    }\n    // `channel()` can refuse (no browser realtime). userId is recorded only\n    // AFTER the subscriptions exist — and cleared BEFORE the attempt — so a\n    // refusal leaves the store unbound and the next auth transition (even back\n    // to the same user) retries instead of early-returning forever.\n    this.userId = null;\n    const channel = this.rt.realtime.channel(`roles:${this.rt.projectRef}:${userId}`);\n    this.subs = [\n      channel.onState('values', (value) => {\n        const decoded = PalbePermissions.decode(value);\n        // An UNREADABLE set is not \"no permissions as of version N\": the set is\n        // emptied AND the version forgotten, and stays forgotten until a readable\n        // set arrives — the same pair iOS refuses to produce (NFR-005).\n        this.unreadable = decoded === null;\n        this.apply(decoded ?? new Set(), decoded === null ? '' : this.version);\n      }),\n      channel.onState('sync_version', (value) => {\n        const v = isRecord(value) ? value.sync_version : undefined;\n        if (typeof v === 'number' && !this.unreadable) this.apply(this.set, String(v));\n      }),\n      // A refusal the socket will not retry means this channel is gone: a set\n      // kept from before it is stale-OPEN, the wrong direction to fail.\n      channel.onError((err) => {\n        if (!err.retryable) this.apply(new Set(), '');\n      }),\n    ];\n    this.userId = userId;\n  }\n\n  /** `values` is an array of permission names (NFR-004); anything else is\n   * UNREADABLE (null) — treated as \"none\" for the set, and as \"unknown\" for the\n   * version, never as \"none as of version N\". */\n  private static decode(value: unknown): ReadonlySet<string> | null {\n    return Array.isArray(value) && value.every(isString) ? new Set(value) : null;\n  }\n\n  private apply(next: ReadonlySet<string>, version: string): void {\n    this.version = version;\n    const same = next.size === this.set.size && [...next].every((p) => this.set.has(p));\n    if (same) return;\n    this.set = next;\n    for (const l of this.listeners) l(next);\n  }\n}\n\n/** The page's declared language (`<html lang>`), or undefined outside a browser or when unset. */\nfunction pageLanguage(): string | undefined {\n  if (typeof document === 'undefined') return undefined;\n  const lang = document.documentElement?.lang?.trim();\n  return lang ? lang : undefined;\n}\n","import type { NamespaceTree } from './namespaces.js';\nimport type { PalbeRuntime } from './runtime.js';\n\nexport interface PalbeGlobalState {\n  runtime: PalbeRuntime | null;\n  registry: NamespaceTree;\n  /** Memoized materialized namespaces (per top-level key); reset on (re-)register. */\n  nsCache: Record<string, unknown>;\n  /** Listeners fired synchronously after every successful __configure call. */\n  configuredListeners: Set<() => void>;\n}\n\n/**\n * Module-level state would split between the ESM and CJS bundles of the two\n * entries (esbuild only code-splits ESM) and between dual-package copies in\n * one process. A globalThis slot keyed by Symbol.for converges them all.\n */\nconst STATE_KEY: unique symbol = Symbol.for('palbe.state.v1');\n\ninterface PalbeGlobals {\n  [STATE_KEY]?: PalbeGlobalState;\n}\n\nexport function palbeState(): PalbeGlobalState {\n  // Single direct widening view of globalThis — typed via the unique-symbol\n  // key above so reads/writes of the slot stay fully typed.\n  const g = globalThis as PalbeGlobals;\n  let state = g[STATE_KEY];\n  if (!state) {\n    state = { runtime: null, registry: {}, nsCache: {}, configuredListeners: new Set() };\n    g[STATE_KEY] = state;\n  }\n  return state;\n}\n","import { BackendError, isBackendError } from './errors.js';\nimport { getRuntime } from './internal.js';\nimport { type CallOptions, palbeRequest, palbeStream } from './request.js';\nimport type { PalbeRuntime } from './runtime.js';\nimport { palbeState } from './state.js';\n\nexport interface EndpointDescriptor {\n  method: string;\n  path: string;\n  /** `{name}` segments consumed as leading call args, in order. */\n  pathParams?: string[];\n  /**\n   * 'body' (default for non-GET) | 'query' (serialize input into the URL) |\n   * 'none' (no input arg — options come straight after path params).\n   */\n  input?: 'body' | 'query' | 'none';\n  /** wire error code → lift fn; the materializer rethrows the lifted error. */\n  errors?: Record<string, (e: BackendError) => Error>;\n  /**\n   * The route answers `text/event-stream`. Emitted by the generator for an\n   * operation carrying `x-palbase-sse`, and it changes what the call RETURNS:\n   * an async iterable of frames instead of one parsed body. Without this branch\n   * the generated signature would be a lie — it declares `AsyncIterable<T>`\n   * while the buffered path hands back a single object (measured 2026-08-30,\n   * against a real stack).\n   */\n  sse?: boolean;\n}\n\nexport type NamespaceTree = { [key: string]: NamespaceTree | EndpointDescriptor };\n\n// Reserved surface names on pb — cannot be shadowed at the top level by codegen\n// namespaces. `perf` sits next to `analytics`: `pb.perf` is the PalPerf facade,\n// so a generated controller named `perf` must NOT collide with it.\nexport const RESERVED = new Set([\n  'call',\n  'upload',\n  'auth',\n  'flags',\n  'realtime',\n  'analytics',\n  'calls',\n  'messaging',\n  'perf',\n]);\n\nfunction reservedNamespaceError(key: string): BackendError {\n  return new BackendError('validation', {\n    code: 'reserved_namespace',\n    message: `Cannot register endpoint namespace '${key}': the name is reserved on pb.`,\n  });\n}\n\nfunction isDescriptor(node: NamespaceTree | EndpointDescriptor): node is EndpointDescriptor {\n  return (\n    typeof (node as EndpointDescriptor).path === 'string' &&\n    typeof (node as EndpointDescriptor).method === 'string'\n  );\n}\n\n/**\n * Validate + normalize one tree level, recursively:\n * - plain-object guard (a literal `__proto__:` in a hand-written tree would\n *   swap the node's prototype — cheap proto-pollution insurance);\n * - reject 'then' at EVERY level (a nested then makes that namespace object\n *   thenable → `await pb.rooms` hangs) and every Object.prototype member\n *   name (`'valueOf' in {}` is true — covers toString, __proto__, …);\n * - uppercase descriptor methods (request.ts matches mutating methods\n *   against an uppercase set; a codegen 'get' would otherwise send a body\n *   and an Idempotency-Key).\n */\nfunction validateDescriptorExtensions(d: EndpointDescriptor, path: string): void {\n  if (d.pathParams !== undefined) {\n    if (!Array.isArray(d.pathParams) || !d.pathParams.every((p) => typeof p === 'string')) {\n      throw new BackendError('validation', {\n        code: 'invalid_namespace_tree',\n        message: `Descriptor '${path}': pathParams must be an array of strings.`,\n      });\n    }\n    // Cross-check: a pathParams entry without a matching placeholder would\n    // silently consume a call arg and substitute nothing — fail at registration.\n    for (const p of d.pathParams) {\n      if (!d.path.includes(`{${p}}`)) {\n        throw new BackendError('validation', {\n          code: 'invalid_namespace_tree',\n          message: `Descriptor '${path}': pathParams entry '${p}' has no '{${p}}' placeholder in the path.`,\n        });\n      }\n    }\n  }\n  if (d.sse !== undefined && typeof d.sse !== 'boolean') {\n    throw new BackendError('validation', {\n      code: 'invalid_namespace_tree',\n      message: `Descriptor '${path}': sse must be a boolean.`,\n    });\n  }\n  if (d.sse === true && d.input === 'query') {\n    // A streaming route's input travels in the body; serializing it into the\n    // query would silently send nothing. Refuse at registration, not at 3am.\n    throw new BackendError('validation', {\n      code: 'invalid_namespace_tree',\n      message: `Descriptor '${path}': an sse endpoint cannot take query input.`,\n    });\n  }\n  if (d.input !== undefined && d.input !== 'body' && d.input !== 'query' && d.input !== 'none') {\n    throw new BackendError('validation', {\n      code: 'invalid_namespace_tree',\n      message: `Descriptor '${path}': input must be 'body', 'query' or 'none'.`,\n    });\n  }\n  if (d.errors !== undefined) {\n    for (const [code, fn] of Object.entries(d.errors)) {\n      if (typeof fn !== 'function') {\n        throw new BackendError('validation', {\n          code: 'invalid_namespace_tree',\n          message: `Descriptor '${path}': errors['${code}'] must be a function.`,\n        });\n      }\n    }\n  }\n}\n\nfunction validateTree(node: NamespaceTree): void {\n  const proto = Object.getPrototypeOf(node) as unknown;\n  if (proto !== Object.prototype && proto !== null) {\n    throw new BackendError('validation', {\n      code: 'invalid_namespace_tree',\n      message: 'Namespace tree nodes must be plain objects.',\n    });\n  }\n  for (const [key, child] of Object.entries(node)) {\n    if (key === 'then' || key in {}) throw reservedNamespaceError(key);\n    if (isDescriptor(child)) {\n      child.method = child.method.toUpperCase();\n      validateDescriptorExtensions(child, child.path);\n    } else {\n      validateTree(child);\n    }\n  }\n}\n\nexport function __registerNamespaces(tree: NamespaceTree): void {\n  for (const key of Object.keys(tree)) {\n    if (RESERVED.has(key)) throw reservedNamespaceError(key);\n  }\n  validateTree(tree);\n  const state = palbeState();\n  state.registry = tree;\n  state.nsCache = {};\n}\n\nexport function resetNamespaces(): void {\n  const state = palbeState();\n  state.registry = {};\n  state.nsCache = {};\n}\n\nexport function getRegistry(): NamespaceTree {\n  return palbeState().registry;\n}\n\nfunction serializeQuery(input: unknown): string {\n  if (input === undefined || input === null) return '';\n  const entries = Object.entries(input as Record<string, unknown>)\n    .filter(([, v]) => v !== undefined && v !== null)\n    .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n  if (entries.length === 0) return '';\n  const parts = entries.map(([k, v]) => {\n    if (typeof v !== 'string' && typeof v !== 'number' && typeof v !== 'boolean') {\n      // Objects/arrays would stringify to '[object Object]' on the wire — fail loud.\n      throw new BackendError('validation', {\n        code: 'invalid_query_value',\n        message: `Query parameter '${k}' must be a string, number, or boolean.`,\n      });\n    }\n    return `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`;\n  });\n  return `?${parts.join('&')}`;\n}\n\nasync function invokeDescriptor(\n  rt: PalbeRuntime,\n  d: EndpointDescriptor,\n  args: unknown[],\n): Promise<unknown> {\n  const params = d.pathParams ?? [];\n  let path = d.path;\n  for (let i = 0; i < params.length; i++) {\n    const v = args[i];\n    if (typeof v !== 'string' && typeof v !== 'number') {\n      throw new BackendError('validation', {\n        code: 'missing_path_param',\n        message: `${d.path}: path parameter '${params[i]}' must be a string or number`,\n      });\n    }\n    path = path.replace(`{${params[i]}}`, encodeURIComponent(String(v)));\n  }\n  // input:'none' ops have NO input slot — options come straight after the\n  // path params (a generated `get(id, options?)` would otherwise drop its\n  // options into the input slot: GET throws, POST sends them as the body).\n  if (d.input === 'none' && args.length > params.length + 1) {\n    throw new BackendError('validation', {\n      code: 'unexpected_argument',\n      message: `${d.path}: endpoint takes no input — pass only path params and options`,\n    });\n  }\n  const input = d.input === 'none' ? undefined : args[params.length];\n  const optionsSlot = d.input === 'none' ? params.length : params.length + 1;\n  const options = args[optionsSlot] as CallOptions | undefined;\n  let body: unknown;\n  if (d.input === 'query') {\n    path += serializeQuery(input);\n  } else if (d.input !== 'none') {\n    if (d.method === 'GET') {\n      if (input !== undefined) {\n        throw new BackendError('validation', {\n          code: 'unsupported_get_input',\n          message: `${d.path}: GET endpoints take no body input`,\n        });\n      }\n    } else {\n      body = input;\n    }\n  }\n  try {\n    if (d.sse === true) {\n      return await palbeStream(rt, d.method, path, {\n        body,\n        headers: options?.headers,\n        signal: options?.signal,\n      });\n    }\n    return await palbeRequest(rt, d.method, path, {\n      body,\n      headers: options?.headers,\n      signal: options?.signal,\n    });\n  } catch (e) {\n    if (d.errors && isBackendError(e)) {\n      const lift = d.errors[e.code];\n      if (lift) throw lift(e);\n    }\n    throw e;\n  }\n}\n\n/**\n * The runtime is resolved AT CALL TIME via `resolveRt` (late binding): the\n * global path passes `getRuntime` so a `__configure` swap is picked up by\n * already-materialized namespaces; bound clients pass `() => rt` so the\n * captured runtime never changes.\n */\nfunction materialize(\n  node: NamespaceTree | EndpointDescriptor,\n  resolveRt: () => PalbeRuntime,\n): unknown {\n  if (isDescriptor(node)) {\n    // async wrapper: resolveRt() may throw (notConfigured) — endpoint methods\n    // must ALWAYS reject, never throw synchronously (callers use .catch()).\n    return async (...args: unknown[]) => invokeDescriptor(resolveRt(), node, args);\n  }\n  const out: Record<string, unknown> = {};\n  for (const [key, child] of Object.entries(node)) {\n    out[key] = materialize(child, resolveRt);\n  }\n  return out;\n}\n\n/** Global path: resolves the global runtime slot, memoizes in the global nsCache. */\nexport function getNamespace(name: string): unknown {\n  const state = palbeState();\n  const cached = state.nsCache[name];\n  if (cached !== undefined) return cached;\n  const node = state.registry[name];\n  if (node === undefined) return undefined;\n  const ns = materialize(node, getRuntime);\n  state.nsCache[name] = ns;\n  return ns;\n}\n\n/**\n * Bound path: namespaces materialize against ONE fixed runtime, memoized in a\n * per-client closure cache (the global nsCache stays global-only — a bound\n * entry there would leak one request's runtime into every other client).\n * The cache is invalidated when the registry object is swapped\n * (__registerNamespaces replaces it wholesale, e.g. watch-mode regen).\n */\nexport function boundNamespaceAccessor(rt: PalbeRuntime): (name: string) => unknown {\n  let cacheRegistry = palbeState().registry;\n  let cache: Record<string, unknown> = {};\n  return (name: string): unknown => {\n    const registry = palbeState().registry;\n    if (registry !== cacheRegistry) {\n      cacheRegistry = registry;\n      cache = {};\n    }\n    const cached = cache[name];\n    if (cached !== undefined) return cached;\n    const node = registry[name];\n    if (node === undefined) return undefined;\n    const ns = materialize(node, () => rt);\n    cache[name] = ns;\n    return ns;\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","// `pb.analytics` — the stateful analytics surface. Mirrors the iOS\n// `AnalyticsClient`/`AnalyticsStorage` pair (palbackend-ios-src\n// Sources/Palbe/Analytics/): anonymous distinct-id, in-memory buffer with\n// size/timer flushing, identify/alias/reset/optOut, and auth-lifecycle\n// bindings. Transport is direct `palbeRequest` to palanalytics' live\n// ingestion wire (verified against modules/analytics Go handlers):\n//\n//   POST /v1/analytics/batch     {events:[{event,distinct_id,properties?,timestamp,sent_at}]}\n//   POST /v1/analytics/capture   single event (server mode — no buffering)\n//   POST /v1/analytics/identify  {distinct_id,anonymous_id,traits?,timestamp,sent_at}\n//   POST /v1/analytics/alias     {from,to,timestamp,sent_at}\n//\n// Ingestion is fire-and-forget (iOS K11): nothing here ever throws into the\n// caller — failures are console.warn'ed and the events dropped. The only\n// awaited surface is `flush()`, which still never rejects.\n//\n// Wire decisions (documented deviations):\n// - screen() emits the SERVER-canonical mapping (event `$screen` +\n//   `properties.screen_name` — exactly what Go's /v1/analytics/screen\n//   shorthand stores), NOT iOS's event-named-after-the-screen variant, so\n//   batched screens and shorthand screens collapse to one stored shape.\n// - `sent_at` is stamped at SEND time (flush), not enqueue time like iOS:\n//   the server's skew correction (`timestamp + (received_at - sent_at)`)\n//   assumes send time; the iOS enqueue-time stamp inflates corrected\n//   timestamps by the buffering delay.\n// - optOut gates ALL ingest calls (capture/screen/identify/alias) — iOS\n//   parity. reset() and the X-Distinct-Id header are NOT gated (also iOS\n//   parity: the header resolver never checks opt-out).\n\nimport type { AuthChangeEvent } from './auth-facade.js';\nimport { palbeRequest } from './request.js';\nimport type { PalbeRuntime } from './runtime.js';\n\n/** Free-form event property bag (JSON object on the wire). */\nexport type AnalyticsProperties = Record<string, unknown>;\n\n/** Server event-name rule — matches modules/analytics/internal/validator/event.go\n * eventNameRegex exactly: leading letter or `$`, max 64 chars total,\n * MaxEventNameLen=64 (i.e. body up to 63 chars after the leading char). */\nconst EVENT_NAME_RE = /^[a-zA-Z$][a-zA-Z0-9_.:$-]{0,63}$/;\n\nconst FLUSH_AT = 20;\nconst FLUSH_INTERVAL_MS = 10_000;\n/** Server hard cap: /v1/analytics/batch rejects > 100 events per request. */\nconst MAX_BATCH_SIZE = 100;\n\n/** A buffered capture event — distinct_id is stamped at CAPTURE time so the\n * anon id is preserved on the wire for pre-login events (the gateway's Bearer\n * override applies to the REQUEST's X-Distinct-Id header, not the event body).\n * `sent_at` is added at flush time. */\ninterface CaptureWire {\n  event: string;\n  distinct_id: string;\n  properties?: AnalyticsProperties;\n  timestamp: number;\n}\n\nlet warnedInvalidEventName = false;\n\nfunction warnInvalidEventName(name: string): void {\n  if (warnedInvalidEventName) return;\n  warnedInvalidEventName = true;\n  console.warn(\n    `palbe analytics: dropping event \"${name}\" — names must match ^[a-zA-Z$][a-zA-Z0-9_.:$-]{0,63}$ (warned once per process)`,\n  );\n}\n\n/** Minimal persisted string store: localStorage in browsers, per-runtime\n * memory elsewhere (SSR anon ids are ephemeral by design). Browser detection\n * matches the facade (`document`, not localStorage presence) — server\n * runtimes must NEVER touch storage, even when a localStorage global exists\n * (the flags server-env contract pins that). */\ninterface StringStore {\n  get(key: string): string | null;\n  set(key: string, value: string): void;\n  remove(key: string): void;\n}\n\nfunction defaultStringStore(): StringStore {\n  if (typeof document !== 'undefined' && typeof localStorage !== 'undefined') {\n    return {\n      get: (key) => {\n        try {\n          return localStorage.getItem(key);\n        } catch {\n          return null;\n        }\n      },\n      set: (key, value) => {\n        try {\n          localStorage.setItem(key, value);\n        } catch {\n          // quota/private mode — the id just won't survive a reload\n        }\n      },\n      remove: (key) => {\n        try {\n          localStorage.removeItem(key);\n        } catch {\n          // ignore\n        }\n      },\n    };\n  }\n  const mem = new Map<string, string>();\n  return {\n    get: (key) => mem.get(key) ?? null,\n    set: (key, value) => {\n      mem.set(key, value);\n    },\n    remove: (key) => {\n      mem.delete(key);\n    },\n  };\n}\n\n/**\n * Runtime-scoped analytics identity — constructed EAGERLY in `buildRuntime`\n * (cheap: listener wiring only, no I/O) because the X-Distinct-Id header\n * interceptor must stamp every request from the first one, even when\n * `pb.analytics` is never touched (iOS: the resolver is wired at\n * PalBackend init). The facade wraps this state lazily.\n *\n * Auth events: while no facade exists, the state maintains identity only\n * (user id for the header, anon rotation on user-initiated sign-out). Once\n * the facade attaches, it takes over wholesale and adds the ingest\n * side-effects (flush + identify / flush + reset).\n */\nexport class AnalyticsState {\n  identifiedUserId: string | null = null;\n  /** Set by PalbeAnalytics on construction — delegates auth events to it. */\n  facadeAuthHandler: ((event: AuthChangeEvent) => void) | null = null;\n\n  private anonId: string | null = null;\n  private readonly store = defaultStringStore();\n  private readonly idKey: string;\n  private readonly optOutKey: string;\n\n  constructor(rt: PalbeRuntime) {\n    const ref = rt.projectRef;\n    this.idKey = ref ? `palbe.analytics.id.${ref}` : 'palbe.analytics.id';\n    this.optOutKey = ref ? `palbe.analytics.optout.${ref}` : 'palbe.analytics.optout';\n    rt.auth.onAuthEvent((event) => {\n      if (this.facadeAuthHandler) {\n        this.facadeAuthHandler(event);\n        return;\n      }\n      if (event.type === 'signedIn') {\n        // Identity for the header only — no identify POST without a facade\n        // (an app that never uses pb.analytics generates no analytics\n        // traffic). Opt-out gates the link, mirroring the gated identify.\n        if (!this.isOptedOut()) this.identifiedUserId = event.user.id;\n      } else if (event.type === 'signedOut' && event.reason === 'userInitiated') {\n        this.identifiedUserId = null;\n        this.rotateAnonymousId();\n      }\n      // sessionExpired / tokenRefreshed: identity preserved (iOS K9)\n    });\n  }\n\n  /** User id when identified, else the stable anon id. NEVER empty —\n   * this is what `identify()` links, so stamping it on every request lets\n   * the trace pipeline stitch pre-login activity to the user. */\n  distinctId(): string {\n    return this.identifiedUserId ?? this.anonymousId();\n  }\n\n  anonymousId(): string {\n    if (this.anonId) return this.anonId;\n    const stored = this.store.get(this.idKey);\n    if (stored) {\n      this.anonId = stored;\n      return stored;\n    }\n    return this.rotateAnonymousId();\n  }\n\n  rotateAnonymousId(): string {\n    const fresh = crypto.randomUUID();\n    this.store.set(this.idKey, fresh);\n    this.anonId = fresh;\n    return fresh;\n  }\n\n  isOptedOut(): boolean {\n    return this.store.get(this.optOutKey) === 'true';\n  }\n\n  setOptOut(on: boolean): void {\n    if (on) this.store.set(this.optOutKey, 'true');\n    else this.store.remove(this.optOutKey);\n  }\n}\n\nexport class PalbeAnalytics {\n  private readonly buffer: CaptureWire[] = [];\n  private flushTimer: ReturnType<typeof setTimeout> | null = null;\n  /** Browser → buffer + size/timer flush. Server (no document) → immediate\n   * per-call POST, zero timers (nothing leaks into RSC/route handlers). */\n  private readonly browser = typeof document !== 'undefined';\n\n  constructor(\n    private readonly rt: PalbeRuntime,\n    private readonly state: AnalyticsState,\n  ) {\n    this.state.facadeAuthHandler = (event) => {\n      this.handleAuthEvent(event);\n    };\n  }\n\n  /** Record an event. Invalid names are dropped (one warn per process). */\n  capture(event: string, properties?: AnalyticsProperties): void {\n    if (this.state.isOptedOut()) return;\n    if (!EVENT_NAME_RE.test(event)) {\n      warnInvalidEventName(event);\n      return;\n    }\n    this.ingest(event, properties);\n  }\n\n  /** Record a screen view — server-canonical `$screen` + `screen_name`.\n   * Validates non-empty only (the live wire at /v1/analytics/screen requires\n   * non-empty screen_name; the event-name regex does NOT apply here). */\n  screen(name: string, properties?: AnalyticsProperties): void {\n    if (this.state.isOptedOut()) return;\n    if (name.trim() === '') {\n      console.warn('palbe analytics: dropping screen() — name must be non-empty');\n      return;\n    }\n    this.ingest('$screen', { ...properties, screen_name: name });\n  }\n\n  /** Link the current anon id to `userId` and adopt it as the distinct id.\n   * Immediate POST (not buffered). Re-identifying a DIFFERENT user\n   * auto-resets first (iOS K10) so one anon id never links two users. */\n  identify(userId: string, traits?: AnalyticsProperties): void {\n    if (this.state.isOptedOut()) return;\n    const existing = this.state.identifiedUserId;\n    if (existing && existing !== userId) {\n      console.warn(\n        `palbe analytics: re-identify changes the user from ${existing} to ${userId} — auto-resetting (call reset() first if this is intentional)`,\n      );\n      this.reset();\n    }\n    const ts = Date.now();\n    const body: Record<string, unknown> = {\n      distinct_id: userId,\n      anonymous_id: this.state.anonymousId(),\n      timestamp: ts,\n      sent_at: ts,\n    };\n    if (traits) body.traits = traits;\n    this.state.identifiedUserId = userId;\n    void this.post('/v1/analytics/identify', body);\n  }\n\n  /** Merge distinct id `from` into `to` (identity stitching). Immediate POST. */\n  alias(from: string, to: string): void {\n    if (this.state.isOptedOut()) return;\n    const ts = Date.now();\n    void this.post('/v1/analytics/alias', { from, to, timestamp: ts, sent_at: ts });\n  }\n\n  /** Drop the buffer, clear the identified user and rotate the anon id\n   * (sign-out hygiene). Callers wanting pending events delivered flush first\n   * — the auth binding does. */\n  reset(): void {\n    this.buffer.length = 0;\n    this.cancelTimer();\n    this.state.identifiedUserId = null;\n    this.state.rotateAnonymousId();\n  }\n\n  /** Persisted GDPR opt-out. Opting out drops anything pending so nothing\n   * already-buffered leaks after the user said stop. */\n  setOptOut(on: boolean): void {\n    this.state.setOptOut(on);\n    if (on) {\n      this.buffer.length = 0;\n      this.cancelTimer();\n    }\n  }\n\n  /** Drain the buffer to /v1/analytics/batch (≤100 per request, sequential).\n   * Resolves when delivery finished; NEVER rejects — failed slices are\n   * dropped with one warn per flush. 207 partial-reject is also warned once\n   * (fire-and-forget: no retry for already-delivered batches). */\n  async flush(): Promise<void> {\n    this.cancelTimer();\n    if (this.buffer.length === 0) return;\n    const sentAt = Date.now();\n    let warned = false;\n    while (this.buffer.length > 0) {\n      const slice = this.buffer.splice(0, MAX_BATCH_SIZE);\n      try {\n        const result = await palbeRequest<{ accepted?: number; rejected?: unknown[] }>(\n          this.rt,\n          'POST',\n          '/v1/analytics/batch',\n          { body: { events: slice.map((e) => ({ ...e, sent_at: sentAt })) } },\n        );\n        if (Array.isArray(result?.rejected) && result.rejected.length > 0) {\n          console.warn(\n            `palbe analytics: batch partial-reject — ${result.rejected.length} event(s) rejected by server`,\n          );\n        }\n      } catch (err) {\n        if (!warned) {\n          warned = true;\n          console.warn('palbe analytics: batch flush failed — events dropped', err);\n        }\n      }\n    }\n  }\n\n  // ── internals ──────────────────────────────────────────\n\n  private ingest(event: string, properties?: AnalyticsProperties): void {\n    const wire: CaptureWire = {\n      event,\n      distinct_id: this.state.distinctId(), // stamped at capture time\n      timestamp: Date.now(),\n    };\n    if (properties) wire.properties = properties;\n    if (!this.browser) {\n      void this.post('/v1/analytics/capture', { ...wire, sent_at: wire.timestamp });\n      return;\n    }\n    this.buffer.push(wire);\n    if (this.buffer.length >= FLUSH_AT) void this.flush();\n    else this.startTimer();\n  }\n\n  /** iOS PalBackend auth-binding parity: signedIn → flush + identify;\n   * userInitiated signedOut → flush + reset; sessionExpired → flush only. */\n  private handleAuthEvent(event: AuthChangeEvent): void {\n    if (event.type === 'signedIn') {\n      void this.flush().then(() => {\n        this.identify(event.user.id);\n      });\n    } else if (event.type === 'signedOut') {\n      if (event.reason === 'userInitiated') {\n        void this.flush().then(() => {\n          this.reset();\n        });\n      } else {\n        void this.flush();\n      }\n    }\n    // tokenRefreshed: nothing\n  }\n\n  private startTimer(): void {\n    if (this.flushTimer !== null) return;\n    this.flushTimer = setTimeout(() => {\n      this.flushTimer = null;\n      void this.flush();\n    }, FLUSH_INTERVAL_MS);\n  }\n\n  private cancelTimer(): void {\n    if (this.flushTimer !== null) {\n      clearTimeout(this.flushTimer);\n      this.flushTimer = null;\n    }\n  }\n\n  private async post(path: string, body: unknown): Promise<void> {\n    try {\n      await palbeRequest(this.rt, 'POST', path, { body });\n    } catch (err) {\n      console.warn(`palbe analytics: POST ${path} failed`, err);\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","// `pb.calls` — SP-4 voice/video call surface for the web SDK.\n//\n// Architecture: thin wrapper around the embedded media engine (browser WebRTC) +\n// the messaging server's call REST endpoints:\n//   POST /v1/messaging/groups/{gid}/calls           → start a call\n//   POST /v1/messaging/groups/{gid}/calls/{cid}/accept  → join a call\n//   POST /v1/messaging/groups/{gid}/calls/{cid}/decline → decline\n//   POST /v1/messaging/groups/{gid}/calls/{cid}/mute    → mute/unmute (host)\n//   POST /v1/messaging/groups/{gid}/calls/{cid}/kick    → kick (host)\n//\n// The {gid} is a messaging group display-id (`grp_<uuidv7>`).\n//\n// ─── E2EE NOTE ─────────────────────────────────────────────────────────────\n// The media engine's hop-by-hop transport is already DTLS-SRTP encrypted.\n// Frame-level end-to-end encryption (MLS-derived keys via the engine's external\n// key provider) is the SP-1.x web-MLS work and is OUT OF SCOPE for this surface.\n// The `setMediaKey` method is wired to that key provider as a design seam; call\n// it AFTER web-MLS delivers a shared frame key. Until then, rooms connect without\n// e2ee.\n// TODO(SP-1-web): derive the frame key from the MLS exporter and call\n//   call.setMediaKey(derivedKeyArrayBuffer)\n// ───────────────────────────────────────────────────────────────────────────\n\nimport {\n  ExternalE2EEKeyProvider,\n  type RemoteParticipant,\n  type RemoteTrack,\n  type RemoteTrackPublication,\n  Room,\n  RoomEvent,\n  Track,\n} from 'livekit-client';\nimport type { Unsubscribe } from '../auth-facade.js';\nimport { BackendError } from '../errors.js';\nimport { palbeRequest } from '../request.js';\nimport type { PalbeRuntime } from '../runtime.js';\n\n// ─── Wire types ────────────────────────────────────────────────────────────\n\ninterface StartCallResponse {\n  call_id: string;\n  token: string;\n  edge_url: string;\n  max_members: number;\n}\n\ninterface AcceptCallResponse {\n  token: string;\n  edge_url: string;\n}\n\n// ─── Public types ──────────────────────────────────────────────────────────\n\nexport type CallState = 'connecting' | 'active' | 'ended';\n\nexport interface CallParticipant {\n  identity: string;\n  isSpeaking: boolean;\n  audioMuted: boolean;\n  videoEnabled: boolean;\n  /** The live <video> element for this participant, or null before track arrives. */\n  videoElement: HTMLVideoElement | null;\n  /** The live <audio> element for this participant, or null before track arrives. */\n  audioElement: HTMLAudioElement | null;\n}\n\nexport type CallChangeCallback = (call: Call) => void;\n\n/**\n * A live call session. Obtain via `pb.calls.start()` or `pb.calls.accept()`.\n *\n * Lifecycle:\n *   connecting → active (room joined, tracks flowing)\n *   active → ended   (leave() / remote disconnect)\n *\n * Subscribe to changes via `call.subscribe(cb)` which fires on state or\n * participant changes (mirrors flags `onChange` / realtime `on` pattern).\n */\nexport class Call {\n  readonly id: string;\n\n  private _state: CallState = 'connecting';\n  private readonly _participants = new Map<string, CallParticipant>();\n  private readonly _listeners = new Set<CallChangeCallback>();\n  private readonly _room: Room;\n  private readonly _keyProvider: ExternalE2EEKeyProvider;\n\n  // PRIVATE constructor + `@internal` factory: the media-engine types (`Room`,\n  // `ExternalE2EEKeyProvider`) appear ONLY on a private constructor and an\n  // `@internal` static factory, both of which `stripInternal` (set in this\n  // package's tsconfig) removes from the emitted public `.d.ts`. So no engine type\n  // ever reaches the public API surface — the same \"no engine type in the public\n  // interface\" contract the iOS SDK enforces. Consumers obtain a `Call` only\n  // through `pb.calls.start()` / `.accept()`.\n  private constructor(callId: string, room: Room, keyProvider: ExternalE2EEKeyProvider) {\n    this.id = callId;\n    this._room = room;\n    this._keyProvider = keyProvider;\n    this._wireMediaEvents();\n  }\n\n  /** @internal — facade-only factory; stripped from the public `.d.ts`. */\n  static _create(callId: string, room: Room, keyProvider: ExternalE2EEKeyProvider): Call {\n    return new Call(callId, room, keyProvider);\n  }\n\n  // ─── State ──────────────────────────────────────────────────────────────\n\n  get state(): CallState {\n    return this._state;\n  }\n\n  /** Snapshot of current remote participants (does NOT include the local participant). */\n  get participants(): readonly CallParticipant[] {\n    return Array.from(this._participants.values());\n  }\n\n  // (No `localParticipant` accessor: it would return a raw media-engine participant\n  // object and leak the engine type onto the public API. Local mic/camera control is\n  // exposed engine-agnostically via `mute()` / `setCamera()` below.)\n\n  // ─── Subscribe ──────────────────────────────────────────────────────────\n\n  /**\n   * Subscribe to call changes (state + participant updates).\n   * Returns an `Unsubscribe` function — matches the SDK's flags/auth pattern.\n   */\n  subscribe(callback: CallChangeCallback): Unsubscribe {\n    this._listeners.add(callback);\n    return () => {\n      this._listeners.delete(callback);\n    };\n  }\n\n  // ─── Controls ───────────────────────────────────────────────────────────\n\n  /** Mute / unmute the local microphone. */\n  async mute(on: boolean): Promise<void> {\n    await this._room.localParticipant.setMicrophoneEnabled(!on);\n  }\n\n  /** Enable / disable the local camera. */\n  async setCamera(on: boolean): Promise<void> {\n    await this._room.localParticipant.setCameraEnabled(on);\n  }\n\n  /**\n   * Set a raw frame encryption key (ArrayBuffer) for this call.\n   * Design seam for SP-1.x web-MLS: call this with the MLS exporter secret\n   * to enable frame-level E2EE via the media engine's external key provider.\n   *\n   * NOTE: The room must have been opened with `e2ee` options for this to take\n   * effect. Currently calls connect WITHOUT e2ee — see module docstring.\n   *\n   * TODO(SP-1-web): wire this to MLS-derived key on session join.\n   */\n  async setMediaKey(key: ArrayBuffer): Promise<void> {\n    await this._keyProvider.setKey(key);\n  }\n\n  /** Leave the call and disconnect from the media room. */\n  async leave(): Promise<void> {\n    await this._room.disconnect();\n    this._setState('ended');\n  }\n\n  // ─── Internal ───────────────────────────────────────────────────────────\n\n  private _setState(next: CallState): void {\n    if (this._state === next) return;\n    this._state = next;\n    this._emit();\n  }\n\n  private _emit(): void {\n    for (const cb of this._listeners) cb(this);\n  }\n\n  private _upsertParticipant(p: RemoteParticipant): void {\n    const existing = this._participants.get(p.identity);\n    const entry: CallParticipant = {\n      identity: p.identity,\n      isSpeaking: p.isSpeaking,\n      audioMuted: !p.isMicrophoneEnabled,\n      videoEnabled: p.isCameraEnabled,\n      videoElement: existing?.videoElement ?? null,\n      audioElement: existing?.audioElement ?? null,\n    };\n    this._participants.set(p.identity, entry);\n  }\n\n  private _attachTrack(track: RemoteTrack, participant: RemoteParticipant): void {\n    const element = track.attach();\n    const entry = this._participants.get(participant.identity);\n    if (track.kind === Track.Kind.Video) {\n      if (entry) {\n        entry.videoElement = element as HTMLVideoElement;\n      }\n    } else if (track.kind === Track.Kind.Audio) {\n      if (entry) {\n        entry.audioElement = element as HTMLAudioElement;\n        // Auto-play audio (browser policy: audio elements can autoplay when\n        // created by a user gesture chain; the call starts from a user tap).\n        (element as HTMLAudioElement).play().catch(() => {});\n      }\n    }\n    this._emit();\n  }\n\n  private _wireMediaEvents(): void {\n    this._room\n      .on(RoomEvent.Connected, () => {\n        this._setState('active');\n      })\n      .on(\n        RoomEvent.TrackSubscribed,\n        (track: RemoteTrack, _pub: RemoteTrackPublication, participant: RemoteParticipant) => {\n          this._upsertParticipant(participant);\n          this._attachTrack(track, participant);\n        },\n      )\n      .on(\n        RoomEvent.TrackUnsubscribed,\n        (_track: RemoteTrack, _pub: RemoteTrackPublication, participant: RemoteParticipant) => {\n          this._upsertParticipant(participant);\n          this._emit();\n        },\n      )\n      .on(RoomEvent.ParticipantConnected, (participant: RemoteParticipant) => {\n        this._upsertParticipant(participant);\n        this._emit();\n      })\n      .on(RoomEvent.ParticipantDisconnected, (participant: RemoteParticipant) => {\n        this._participants.delete(participant.identity);\n        this._emit();\n      })\n      .on(RoomEvent.ActiveSpeakersChanged, (speakers) => {\n        for (const [id, entry] of this._participants) {\n          entry.isSpeaking = speakers.some((s) => s.identity === id);\n        }\n        this._emit();\n      })\n      .on(RoomEvent.Disconnected, () => {\n        this._setState('ended');\n      });\n  }\n}\n\n// ─── Facade ────────────────────────────────────────────────────────────────\n\nexport class PalbeCalls {\n  private readonly rt: PalbeRuntime;\n\n  constructor(rt: PalbeRuntime) {\n    this.rt = rt;\n  }\n\n  /**\n   * Start a new call in a messaging group.\n   *\n   * @param groupId  - Messaging group display-id (`grp_<uuidv7>`)\n   * @param media    - Which media tracks to publish (default: audio + video)\n   * @returns        A `Call` in `connecting` state; transitions to `active` once the media room connects.\n   *\n   * Every failure below arrives as kind `'server'` — this SDK's error kinds are\n   * `notConfigured | validation | unauthorized | rateLimited | server | network\n   * | decode`, and only a 401, a 429 or a 400 carrying a field-error array gets\n   * its own kind. So branch on `err.code`, never on the kind.\n   *\n   * @throws BackendError('server', { code: 'calling_unavailable' })  no SFU configured on this stack (503)\n   * @throws BackendError('server', { code: 'not_group_member' })     the caller is not a member of the group (403)\n   * @throws BackendError('server', { code: 'call_room_full' })       the call is at its participant limit (409)\n   * @throws BackendError('server', { code: 'call_provider_error' })  the media provider failed upstream (502)\n   */\n  async start(\n    groupId: string,\n    { media = ['audio', 'video'] }: { media?: Array<'audio' | 'video'> } = {},\n  ): Promise<Call> {\n    if (!groupId) {\n      throw new BackendError('validation', {\n        code: 'invalid_group_id',\n        message: 'groupId must be a non-empty string',\n      });\n    }\n    const res = await palbeRequest<StartCallResponse>(\n      this.rt,\n      'POST',\n      `/v1/messaging/groups/${encodeURIComponent(groupId)}/calls`,\n      { body: { media } },\n    );\n    return this._connect(res.call_id, res.token, res.edge_url, media);\n  }\n\n  /**\n   * Accept an incoming call in a messaging group.\n   *\n   * @param groupId  - Messaging group display-id\n   * @param callId   - Call identifier, carried by the `call_invite` the server\n   *   fans onto the group's conversation topic\n   *   (`pb.realtime.channel('messaging:conv:<rfcGroupId>').on('call_invite', …)`).\n   *   This SDK ships no web push: on the web the invite arrives over realtime or\n   *   over whatever signalling the app already runs.\n   * @param media    - Which media tracks to publish (default: audio + video)\n   */\n  async accept(\n    groupId: string,\n    callId: string,\n    { media = ['audio', 'video'] }: { media?: Array<'audio' | 'video'> } = {},\n  ): Promise<Call> {\n    const res = await palbeRequest<AcceptCallResponse>(\n      this.rt,\n      'POST',\n      `/v1/messaging/groups/${encodeURIComponent(groupId)}/calls/${encodeURIComponent(callId)}/accept`,\n      { body: {} },\n    );\n    return this._connect(callId, res.token, res.edge_url, media);\n  }\n\n  /**\n   * Decline an incoming call.\n   *\n   * @param groupId  - Messaging group display-id\n   * @param callId   - Call identifier\n   * @param reason   - Optional decline reason string\n   */\n  async decline(groupId: string, callId: string, reason?: string): Promise<void> {\n    await palbeRequest<void>(\n      this.rt,\n      'POST',\n      `/v1/messaging/groups/${encodeURIComponent(groupId)}/calls/${encodeURIComponent(callId)}/decline`,\n      { body: { reason: reason ?? '' } },\n    );\n  }\n\n  // ─── Internal ─────────────────────────────────────────────────────────\n\n  private async _connect(\n    callId: string,\n    token: string,\n    edgeUrl: string,\n    media: Array<'audio' | 'video'>,\n  ): Promise<Call> {\n    // ExternalE2EEKeyProvider is the MLS seam (see module docstring).\n    // Constructed but NOT passed to Room options — we connect without e2ee.\n    // TODO(SP-1-web): pass { e2ee: { worker, keyProvider } } when MLS is ready.\n    const keyProvider = new ExternalE2EEKeyProvider();\n\n    const room = new Room({\n      adaptiveStream: true,\n      dynacast: true,\n    });\n\n    const call = Call._create(callId, room, keyProvider);\n\n    // Connect first; track publishing follows after Connected fires.\n    // LiveKit requires the room to be connected before publishing.\n    await room.connect(edgeUrl, token);\n\n    if (media.includes('audio')) {\n      await room.localParticipant.setMicrophoneEnabled(true);\n    }\n    if (media.includes('video')) {\n      await room.localParticipant.setCameraEnabled(true);\n    }\n\n    return call;\n  }\n}\n","import type { HttpClient, PalbaseResponse } from '@palbase/core';\nimport type { FlagValue } from './types.js';\n\n/**\n * Admin client for the user-flags module — wraps the system flag CRUD\n * and per-user override endpoints exposed by `modules/user-flags`.\n *\n * Two surfaces:\n *   - `.system.*` — project-wide flag defaults (platform auth)\n *   - `.users.*`  — per-user overrides (service-side)\n */\nexport class FlagsAdminClient {\n  readonly system: SystemFlagsAdminClient;\n  readonly users: UserFlagsAdminClient;\n\n  constructor(httpClient: HttpClient) {\n    this.system = new SystemFlagsAdminClient(httpClient);\n    this.users = new UserFlagsAdminClient(httpClient);\n  }\n}\n\nexport interface SystemFlag {\n  key: string;\n  value: FlagValue;\n  /** Optional variant label when the flag is variant-typed. */\n  variant?: string;\n  /** Optional targeting rules (shape passes through from the backend). */\n  rules?: unknown;\n  updated_at?: string;\n}\n\nexport interface UserFlagOverride {\n  user_id: string;\n  key: string;\n  value: FlagValue;\n  variant?: string;\n  updated_at?: string;\n}\n\nexport interface UserFlagsSnapshot {\n  user_id: string;\n  flags: Record<string, FlagValue>;\n}\n\nexport interface BatchFlagInput {\n  /** Optional: evaluate for these user IDs. */\n  user_ids?: string[];\n  /** Optional: evaluate a subset of flag keys. */\n  keys?: string[];\n}\n\nexport interface BatchFlagResult {\n  user_id: string;\n  flags: Record<string, FlagValue>;\n}\n\nexport class SystemFlagsAdminClient {\n  constructor(private readonly http: HttpClient) {}\n\n  list(): Promise<PalbaseResponse<SystemFlag[]>> {\n    return this.http.request<SystemFlag[]>('GET', '/v1/user-flags/system');\n  }\n\n  get(key: string): Promise<PalbaseResponse<SystemFlag>> {\n    return this.http.request<SystemFlag>('GET', `/v1/user-flags/system/${encodeURIComponent(key)}`);\n  }\n\n  put(\n    key: string,\n    input: { value: FlagValue; variant?: string; rules?: unknown },\n  ): Promise<PalbaseResponse<SystemFlag>> {\n    return this.http.request<SystemFlag>(\n      'PUT',\n      `/v1/user-flags/system/${encodeURIComponent(key)}`,\n      { body: input },\n    );\n  }\n\n  delete(key: string): Promise<PalbaseResponse<void>> {\n    return this.http.request<void>('DELETE', `/v1/user-flags/system/${encodeURIComponent(key)}`);\n  }\n}\n\nexport class UserFlagsAdminClient {\n  constructor(private readonly http: HttpClient) {}\n\n  /** Read evaluated flags for a user (defaults + overrides merged). */\n  get(userId: string): Promise<PalbaseResponse<UserFlagsSnapshot>> {\n    return this.http.request<UserFlagsSnapshot>(\n      'GET',\n      `/v1/user-flags/users/${encodeURIComponent(userId)}`,\n    );\n  }\n\n  /**\n   * Replace the full set of overrides for a user in one call. Any key not\n   * present in `overrides` is removed.\n   */\n  putBulk(\n    userId: string,\n    overrides: Record<string, FlagValue>,\n  ): Promise<PalbaseResponse<UserFlagsSnapshot>> {\n    return this.http.request<UserFlagsSnapshot>(\n      'PUT',\n      `/v1/user-flags/users/${encodeURIComponent(userId)}`,\n      { body: { overrides } },\n    );\n  }\n\n  putOverride(\n    userId: string,\n    key: string,\n    input: { value: FlagValue; variant?: string },\n  ): Promise<PalbaseResponse<UserFlagOverride>> {\n    return this.http.request<UserFlagOverride>(\n      'PUT',\n      `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n      { body: input },\n    );\n  }\n\n  deleteOverride(userId: string, key: string): Promise<PalbaseResponse<void>> {\n    return this.http.request<void>(\n      'DELETE',\n      `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n    );\n  }\n\n  deleteAllOverrides(userId: string): Promise<PalbaseResponse<void>> {\n    return this.http.request<void>('DELETE', `/v1/user-flags/users/${encodeURIComponent(userId)}`);\n  }\n\n  /** Evaluate flags for a batch of users / a subset of keys. */\n  batch(input?: BatchFlagInput): Promise<PalbaseResponse<BatchFlagResult[]>> {\n    return this.http.request<BatchFlagResult[]>('POST', '/v1/user-flags/batch', {\n      body: input ?? {},\n    });\n  }\n}\n","import type { HttpClient, PalbaseResponse } from '@palbase/core';\nimport type {\n  Flag,\n  FlagContext,\n  FlagSource,\n  FlagsDelta,\n  FlagsSnapshot,\n  FlagValue,\n  FlagVariant,\n} from './types.js';\n\nconst FLAG_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Wire shape of the merged read endpoints `GET /v1/user-flags` (current auth\n * user) and `GET /v1/user-flags/users/{userId}` (a named user). Both return the\n * server-resolved flag values (system defaults + that user's overrides).\n */\ninterface MergedSnapshotResponse {\n  values: Record<string, FlagValue> | null;\n  fetched_at: string;\n}\n\n/** Coerce a resolved flag value to an enabled boolean. A boolean flag is itself;\n * any other present, non-empty, non-zero value counts as enabled; missing = off. */\nfunction flagEnabled(value: FlagValue | undefined): boolean {\n  if (typeof value === 'boolean') return value;\n  return value != null && value !== 0 && value !== '';\n}\n\n/** Derive a {@link FlagVariant} from a resolved flag value. A \"variant\" is the\n * value of a multivariate (string) flag, so a string flag's value IS its variant\n * name. Boolean / numeric / object flags and missing flags have no variant →\n * `null` (so a caller's `getVariant` resolves to null, per the \"no variant\"\n * contract). */\nfunction flagVariant(value: FlagValue | undefined): FlagVariant | null {\n  return typeof value === 'string' ? { name: value } : null;\n}\n\n/** Re-map the `data` of a successful response; pass errors / empty bodies through\n * unchanged (typed to the new payload). */\nfunction mapResponse<A, B>(res: PalbaseResponse<A>, fn: (data: A) => B): PalbaseResponse<B> {\n  if (res.error || res.data == null) {\n    return { ...res, data: null } as PalbaseResponse<B>;\n  }\n  return { ...res, data: fn(res.data) };\n}\n\n/**\n * Result of writing a single user override (`PUT .../{userId}/{key}`) — echoes\n * the resolved key/value with `source: \"override\"`.\n */\nexport interface SetOverrideResult {\n  key: string;\n  value: FlagValue;\n  source: FlagSource;\n}\n\n/**\n * Result of replacing all overrides for one user (`PUT .../{userId}`).\n * `values` is the resolved override set after the write.\n */\nexport interface SetOverridesResult {\n  values: Record<string, FlagValue>;\n}\n\n/**\n * Result of clearing a single override (`DELETE .../{userId}/{key}`). `value`\n * is the system (default) value the user falls back to after removal, with\n * `source: \"system\"`.\n */\nexport interface ClearOverrideResult {\n  key: string;\n  value: FlagValue;\n  source: FlagSource;\n}\n\n/** Result of clearing all overrides for a user (`DELETE .../{userId}`). */\nexport interface ClearAllOverridesResult {\n  deleted: number;\n}\n\n/** One cross-user override operation for {@link FlagsServiceClient.batchSetOverrides}. */\nexport interface BatchOverrideOperation {\n  userId: string;\n  values: Record<string, FlagValue>;\n}\n\n/** Result of a cross-user batch write (`POST /v1/user-flags/batch`). */\nexport interface BatchSetOverridesResult {\n  applied: number;\n}\n\n/**\n * Cross-user admin write surface, reached via {@link FlagsClient.asService}.\n *\n * These five methods set/clear overrides for an ARBITRARY user (named\n * explicitly), so they bypass the current-user scope that the default\n * `FlagsClient.setOverride(...)` is bound to. Mirrors the\n * `Database` / `Database.asService()` split: the privileged cross-user path is\n * moved OFF the default surface so it is greppable + intentional. Requires a\n * privileged key (service_role / managed runtime).\n */\nexport interface FlagsServiceClient {\n  /**\n   * Set (or replace) a single feature-flag override for one user.\n   * `PUT /v1/user-flags/users/{userId}/{key}` with body `{ value }`.\n   */\n  setOverrideForUser(\n    userId: string,\n    key: string,\n    value: FlagValue,\n  ): Promise<PalbaseResponse<SetOverrideResult>>;\n\n  /**\n   * Set multiple feature-flag overrides for one user in a single call.\n   * `PUT /v1/user-flags/users/{userId}` with body `{ values }`.\n   */\n  setOverridesForUser(\n    userId: string,\n    values: Record<string, FlagValue>,\n  ): Promise<PalbaseResponse<SetOverridesResult>>;\n\n  /**\n   * Clear a single override for one user, restoring the project (system)\n   * default for that key. `DELETE /v1/user-flags/users/{userId}/{key}`.\n   */\n  clearOverrideForUser(userId: string, key: string): Promise<PalbaseResponse<ClearOverrideResult>>;\n\n  /**\n   * Clear all overrides for one user, restoring project defaults for every\n   * key. `DELETE /v1/user-flags/users/{userId}`.\n   */\n  clearAllOverridesForUser(userId: string): Promise<PalbaseResponse<ClearAllOverridesResult>>;\n\n  /**\n   * Apply override writes across many users in one request (max 1000 ops).\n   * `POST /v1/user-flags/batch` with body `{ operations: [{ user_id, values }] }`.\n   */\n  batchSetOverrides(\n    operations: ReadonlyArray<BatchOverrideOperation>,\n  ): Promise<PalbaseResponse<BatchSetOverridesResult>>;\n}\n\n/**\n * Stateless, one-shot HTTP wrapper for the flags API. Reads (`isEnabled` /\n * `getVariant` / `getAll`) resolve against the live `GET /v1/user-flags` merged\n * endpoint and derive their result from the returned value map; it is also the\n * transport layer underneath `FlagsPool` (which adds caching, polling and\n * auth-state binding on top).\n *\n * Writes mirror the `Database` / `Database.asService()` model:\n * — {@link setOverride} (default) writes an override for the CURRENT user (the\n *   `getCurrentUserId` getter supplied at construction). No userId argument; it\n *   errors clearly when there is no signed-in user.\n * — {@link asService} returns the cross-user admin surface\n *   ({@link FlagsServiceClient}) for writing overrides for an arbitrary user.\n */\nexport class FlagsClient {\n  private readonly httpClient: HttpClient;\n  private readonly getCurrentUserId?: () => string | null | undefined;\n\n  /**\n   * @param httpClient transport.\n   * @param getCurrentUserId optional getter resolving the signed-in user's id\n   *   for {@link setOverride}. When omitted (or it returns no id), `setOverride`\n   *   errors and the caller must use {@link asService} for cross-user writes.\n   */\n  constructor(httpClient: HttpClient, getCurrentUserId?: () => string | null | undefined) {\n    this.httpClient = httpClient;\n    this.getCurrentUserId = getCurrentUserId;\n  }\n\n  async isEnabled(flagName: string, context?: FlagContext): Promise<PalbaseResponse<boolean>> {\n    if (!FLAG_NAME_RE.test(flagName)) {\n      throw new Error(\n        `Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`,\n      );\n    }\n\n    const res = await this.httpClient.request<MergedSnapshotResponse>(\n      'GET',\n      this.mergedPath(context),\n    );\n    return mapResponse(res, (snap) => flagEnabled(snap.values?.[flagName]));\n  }\n\n  async getVariant(flagName: string, context?: FlagContext): Promise<PalbaseResponse<FlagVariant>> {\n    if (!FLAG_NAME_RE.test(flagName)) {\n      throw new Error(\n        `Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`,\n      );\n    }\n\n    const res = await this.httpClient.request<MergedSnapshotResponse>(\n      'GET',\n      this.mergedPath(context),\n    );\n    // Inlined (not via mapResponse) so the `FlagVariant | null` payload stays\n    // assignable to the public `PalbaseResponse<FlagVariant>` return type.\n    if (res.error || res.data == null) {\n      return { ...res, data: null };\n    }\n    return { ...res, data: flagVariant(res.data.values?.[flagName]) };\n  }\n\n  async getAll(context?: FlagContext): Promise<PalbaseResponse<Flag[]>> {\n    const res = await this.httpClient.request<MergedSnapshotResponse>(\n      'GET',\n      this.mergedPath(context),\n    );\n    return mapResponse(res, (snap) => {\n      const values = snap.values ?? {};\n      return Object.keys(values).map((name) => {\n        const value = values[name];\n        const flag: Flag = { name, enabled: flagEnabled(value) };\n        if (typeof value === 'string') flag.variant = { name: value };\n        return flag;\n      });\n    });\n  }\n\n  /**\n   * Cold-start read: the full merged flag set for the current auth identity.\n   * With a Bearer token the backend returns the user-merged view; without one\n   * it returns project (system) defaults.\n   */\n  snapshot(validator?: string): Promise<PalbaseResponse<FlagsSnapshot>> {\n    return this.httpClient.request<FlagsSnapshot>(\n      'GET',\n      '/v1/user-flags/snapshot',\n      validator ? { headers: { 'If-None-Match': validator } } : undefined,\n    );\n  }\n\n  /**\n   * Incremental read of version-ordered ops since `sinceVersion`.\n   *\n   * `validator` is the ETag the SERVER last issued, echoed verbatim so an\n   * unchanged server can answer `304 Not Modified` cheaply. It used to be the\n   * cursor itself, and the server's ETag is `\"<sync_version>-<client-context\n   * hash>\"` — two values that can never compare equal, so the 304 this method\n   * exists to earn was unreachable in production (measured on centauri\n   * 2026-09-11: every 30s poll came back 200 with a full body).\n   *\n   * The hash half is not decoration: it is how the server notices the CLIENT\n   * CONTEXT changed (app version, locale, device targeting), a change that moves\n   * no row version and so cannot be seen through `since` alone. Sending nothing\n   * would earn a 304 for values that have genuinely re-resolved.\n   *\n   * The 304 surfaces as a `PalbaseResponse` with `status === 304` (the core http\n   * client maps non-2xx to an error/empty body); callers treat that as\n   * \"no change\".\n   */\n  delta(sinceVersion: string, validator?: string): Promise<PalbaseResponse<FlagsDelta>> {\n    return this.httpClient.request<FlagsDelta>(\n      'GET',\n      `/v1/user-flags/delta?since=${encodeURIComponent(sinceVersion)}`,\n      validator ? { headers: { 'If-None-Match': validator } } : undefined,\n    );\n  }\n\n  /**\n   * Set (or replace) a single feature-flag override for the CURRENT USER.\n   *\n   * Resolves the signed-in user from the `getCurrentUserId` getter supplied at\n   * construction and issues `PUT /v1/user-flags/users/{uid}/{key}` with body\n   * `{ value }`. No userId argument — the override is bound to the current\n   * user, so no admin power is required.\n   *\n   * Errors when there is no signed-in user (anonymous, or no getter supplied);\n   * use {@link asService}`.setOverrideForUser(userId, key, value)` to write a\n   * flag override for an arbitrary (cross-user) target.\n   */\n  setOverride(key: string, value: FlagValue): Promise<PalbaseResponse<SetOverrideResult>> {\n    const userId = this.getCurrentUserId?.();\n    if (!userId) {\n      throw new Error(\n        'setOverride requires a signed-in user; use FlagsClient.asService().setOverrideForUser(userId, key, value) for cross-user writes',\n      );\n    }\n    return this.httpClient.request<SetOverrideResult>(\n      'PUT',\n      `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n      { body: { value } },\n    );\n  }\n\n  /**\n   * Return the cross-user admin write surface ({@link FlagsServiceClient}).\n   *\n   * Use sparingly and explicitly — the default {@link setOverride} path is\n   * bound to the current user; `asService()` is how you write a flag override\n   * for an ARBITRARY user. Mirrors `Database.asService()`. The returned client\n   * shares this client's transport (the privileged service_role key).\n   */\n  asService(): FlagsServiceClient {\n    const http = this.httpClient;\n    return {\n      setOverrideForUser(userId, key, value) {\n        return http.request<SetOverrideResult>(\n          'PUT',\n          `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n          { body: { value } },\n        );\n      },\n      setOverridesForUser(userId, values) {\n        return http.request<SetOverridesResult>(\n          'PUT',\n          `/v1/user-flags/users/${encodeURIComponent(userId)}`,\n          { body: { values } },\n        );\n      },\n      clearOverrideForUser(userId, key) {\n        return http.request<ClearOverrideResult>(\n          'DELETE',\n          `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n        );\n      },\n      clearAllOverridesForUser(userId) {\n        return http.request<ClearAllOverridesResult>(\n          'DELETE',\n          `/v1/user-flags/users/${encodeURIComponent(userId)}`,\n        );\n      },\n      batchSetOverrides(operations) {\n        return http.request<BatchSetOverridesResult>('POST', '/v1/user-flags/batch', {\n          body: {\n            operations: operations.map((op) => ({\n              user_id: op.userId,\n              values: op.values,\n            })),\n          },\n        });\n      },\n    };\n  }\n\n  /**\n   * Resolve the merged-read path for a context. With `context.userId` present the\n   * read targets that specific user's merged view (`/v1/user-flags/users/{id}`, a\n   * privileged cross-user read); otherwise the current auth user's view\n   * (`/v1/user-flags`). `context.properties` has no server-side targeting support\n   * in the user-flags module and is ignored.\n   */\n  private mergedPath(context?: FlagContext): string {\n    const uid = context?.userId;\n    return uid ? `/v1/user-flags/users/${encodeURIComponent(uid)}` : '/v1/user-flags';\n  }\n}\n","import type { FlagsClient } from './flags-client.js';\nimport type {\n  AuthStateSource,\n  FlagSource,\n  FlagsChangeListener,\n  FlagsSnapshot,\n  FlagValue,\n  Unsubscribe,\n} from './types.js';\n\n/** Options controlling pool behaviour. All have sensible defaults. */\nexport interface FlagsPoolOptions {\n  /** Delta poll interval in ms. Default 30_000. Set `0` to disable polling. */\n  pollIntervalMs?: number;\n  /**\n   * localStorage key for cold-start persistence. Default\n   * `palbase.flags.snapshot`. Ignored when localStorage is unavailable (SSR).\n   */\n  storageKey?: string;\n  /** Disable localStorage persistence even in the browser. Default false. */\n  persist?: boolean;\n  /**\n   * Auth-state source. When provided, the pool re-snapshots on sign-in and\n   * sign-out so the cache switches between user overrides and project defaults.\n   */\n  auth?: AuthStateSource;\n  /**\n   * Inject timer/visibility primitives for testing. Defaults to the global\n   * `setInterval`/`clearInterval` and the browser `document`/`window`.\n   */\n  env?: PoolEnv;\n}\n\n/** Injectable runtime seams (browser globals) so the pool stays testable. */\nexport interface PoolEnv {\n  now(): number;\n  setInterval(handler: () => void, ms: number): IntervalHandle;\n  clearInterval(handle: IntervalHandle): void;\n  /** localStorage-like store, or `null` when unavailable (SSR). */\n  storage: KeyValueStore | null;\n  /** Visibility source, or `null` when there is no document (SSR). */\n  visibility: VisibilitySource | null;\n}\n\nexport type IntervalHandle = ReturnType<typeof setInterval>;\n\nexport interface KeyValueStore {\n  getItem(key: string): string | null;\n  setItem(key: string, value: string): void;\n  removeItem(key: string): void;\n}\n\nexport interface VisibilitySource {\n  isHidden(): boolean;\n  onVisibilityChange(cb: () => void): Unsubscribe;\n}\n\nconst DEFAULT_POLL_MS = 30_000;\nconst DEFAULT_STORAGE_KEY = 'palbase.flags.snapshot';\n\ninterface CacheState {\n  values: Record<string, FlagValue>;\n  sources: Record<string, FlagSource>;\n  syncVersion: string | null;\n}\n\nconst EMPTY_STATE: CacheState = {\n  values: {},\n  sources: {},\n  syncVersion: null,\n};\n\n/**\n * Stateful, auto-pooling flag cache built on top of the stateless\n * {@link FlagsClient} transport.\n *\n * Responsibilities:\n *  - Cold start from a snapshot (and from localStorage for instant boot).\n *  - Poll deltas with conditional `If-None-Match` (304 → no-op).\n *  - Re-snapshot on a version gap / tombstone-expiry signalled by the backend.\n *  - Re-snapshot on auth sign-in / sign-out (override view ↔ defaults).\n *  - Notify subscribers (drives `useFlag`/`useFlags`).\n *\n * Resolution is server-side: `get(key, default)` returns the cached value or\n * the supplied default; the pool never merges.\n */\nexport class FlagsPool {\n  private readonly transport: FlagsClient;\n  private readonly pollIntervalMs: number;\n  private readonly storageKey: string;\n  private readonly persist: boolean;\n  private readonly env: PoolEnv;\n\n  private state: CacheState = EMPTY_STATE;\n  /**\n   * The validator the SERVER issued, echoed on the next conditional request.\n   *\n   * In memory only, deliberately: a cold boot hydrates values from storage and\n   * then asks for the truth unconditionally, so a stale or corrupt cached body\n   * can never be confirmed by a validator that outlived it.\n   */\n  private validator: string | undefined;\n  private readonly listeners = new Set<FlagsChangeListener>();\n\n  private timer: IntervalHandle | null = null;\n  private polling = false;\n  private started = false;\n  private destroyed = false;\n\n  private readyPromise: Promise<void>;\n  private resolveReady: (() => void) | null = null;\n  private firstLoadDone = false;\n\n  private authUnsub: Unsubscribe | null = null;\n  private visibilityUnsub: Unsubscribe | null = null;\n  private lastAuthHasSession: boolean | null = null;\n\n  /** Cached frozen view for `getSnapshot` identity stability (React). */\n  private frozenView: Readonly<Record<string, FlagValue>> = Object.freeze({});\n  private viewDirty = true;\n\n  constructor(transport: FlagsClient, options: FlagsPoolOptions = {}) {\n    this.transport = transport;\n    this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_MS;\n    this.storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;\n    this.persist = options.persist ?? true;\n    this.env = options.env ?? defaultEnv();\n\n    this.readyPromise = new Promise<void>((resolve) => {\n      this.resolveReady = resolve;\n    });\n\n    // Hydrate synchronously from persisted snapshot for instant cold-start.\n    this.hydrateFromStorage();\n\n    if (options.auth) {\n      this.bindAuth(options.auth);\n    }\n  }\n\n  // ---- public surface -----------------------------------------------------\n\n  /** Start cold-start fetch + polling + visibility binding. Idempotent. */\n  start(): void {\n    if (this.started || this.destroyed) {\n      return;\n    }\n    this.started = true;\n\n    void this.refresh();\n    this.startPolling();\n    this.bindVisibility();\n  }\n\n  /** Resolves once the first snapshot (or persisted hydrate) is available. */\n  ready(): Promise<void> {\n    if (this.firstLoadDone) {\n      return Promise.resolve();\n    }\n    if (!this.started) {\n      this.start();\n    }\n    return this.readyPromise;\n  }\n\n  /** Returns the cached value for `key`, or `fallback` when absent. */\n  get<T extends FlagValue>(key: string, fallback: T): T {\n    const value = this.state.values[key];\n    return value === undefined ? fallback : (value as T);\n  }\n\n  /** Boolean convenience: cached value strictly equals `true`, else `fallback`. */\n  isEnabled(key: string, fallback = false): boolean {\n    const value = this.state.values[key];\n    if (value === undefined) {\n      return fallback;\n    }\n    return value === true;\n  }\n\n  /** Returns the cached value's source (`system`/`user`) when known. */\n  getSource(key: string): FlagSource | undefined {\n    return this.state.sources[key];\n  }\n\n  /** Returns a frozen snapshot of all cached values (stable identity). */\n  all(): Readonly<Record<string, FlagValue>> {\n    if (this.viewDirty) {\n      this.frozenView = Object.freeze({ ...this.state.values });\n      this.viewDirty = false;\n    }\n    return this.frozenView;\n  }\n\n  /** Current opaque sync version (null before first load). */\n  get syncVersion(): string | null {\n    return this.state.syncVersion;\n  }\n\n  /** Subscribe to any change in the cached set. Returns unsubscribe. */\n  onChange(listener: FlagsChangeListener): Unsubscribe {\n    this.listeners.add(listener);\n    return () => {\n      this.listeners.delete(listener);\n    };\n  }\n\n  /**\n   * `useSyncExternalStore`-compatible subscribe. Auto-starts the pool on first\n   * subscription so a React component mount triggers cold-start.\n   */\n  subscribe = (listener: FlagsChangeListener): Unsubscribe => {\n    if (!this.started) {\n      this.start();\n    }\n    return this.onChange(listener);\n  };\n\n  /** Force an immediate re-snapshot (used on auth change / manual refresh). */\n  async refresh(): Promise<void> {\n    if (this.destroyed) {\n      return;\n    }\n    const res = await this.transport.snapshot(this.validator);\n    if (res.etag) {\n      this.validator = res.etag;\n    }\n    if (res.error || res.data == null) {\n      // Keep any persisted/previous state; still mark first load complete so\n      // `ready()` does not hang forever on a transient network failure.\n      this.markFirstLoadDone();\n      return;\n    }\n    this.applySnapshot(res.data);\n    this.markFirstLoadDone();\n  }\n\n  /** Stop timers and detach all auth/visibility listeners. */\n  destroy(): void {\n    this.destroyed = true;\n    this.stopPolling();\n    this.authUnsub?.();\n    this.authUnsub = null;\n    this.visibilityUnsub?.();\n    this.visibilityUnsub = null;\n    this.listeners.clear();\n  }\n\n  // ---- internals ----------------------------------------------------------\n\n  private async poll(): Promise<void> {\n    if (this.polling || this.destroyed) {\n      return;\n    }\n    const since = this.state.syncVersion;\n    if (since == null) {\n      // No baseline yet — fall back to a snapshot.\n      await this.refresh();\n      return;\n    }\n    this.polling = true;\n    try {\n      const res = await this.transport.delta(since, this.validator);\n      if (res.etag) {\n        this.validator = res.etag;\n      }\n      if (res.status === 304) {\n        return; // not modified — cheap no-op\n      }\n      if (res.error || res.data == null) {\n        // A version gap / expired tombstone window is signalled by 409/410.\n        if (res.status === 409 || res.status === 410) {\n          await this.refresh();\n        }\n        return;\n      }\n      this.applyDelta(res.data.ops as readonly unknown[], res.data.sync_version);\n    } finally {\n      this.polling = false;\n    }\n  }\n\n  private applySnapshot(snapshot: FlagsSnapshot): void {\n    this.state = {\n      values: { ...snapshot.values },\n      sources: { ...(snapshot.sources ?? {}) },\n      syncVersion: snapshot.sync_version,\n    };\n    this.viewDirty = true;\n    this.persistState();\n    this.notify();\n  }\n\n  private applyDelta(ops: readonly unknown[], nextVersion: string): void {\n    // Each op is re-narrowed defensively via `isDeltaOp`.\n    const values = { ...this.state.values };\n    const sources = { ...this.state.sources };\n    let changed = false;\n\n    for (const raw of ops) {\n      if (!isDeltaOp(raw)) {\n        continue;\n      }\n      if (raw.op === 'delete') {\n        if (raw.key in values) {\n          delete values[raw.key];\n          delete sources[raw.key];\n          changed = true;\n        }\n      } else {\n        values[raw.key] = raw.value;\n        if (raw.source) {\n          sources[raw.key] = raw.source;\n        }\n        changed = true;\n      }\n    }\n\n    this.state = { values, sources, syncVersion: this.advance(nextVersion) };\n    if (changed) {\n      this.viewDirty = true;\n      this.persistState();\n      this.notify();\n    } else {\n      // version still advances even with no value change\n      this.persistState();\n    }\n  }\n\n  private startPolling(): void {\n    if (this.pollIntervalMs <= 0 || this.timer != null) {\n      return;\n    }\n    this.timer = this.env.setInterval(() => {\n      void this.poll();\n    }, this.pollIntervalMs);\n  }\n\n  private stopPolling(): void {\n    if (this.timer != null) {\n      this.env.clearInterval(this.timer);\n      this.timer = null;\n    }\n  }\n\n  private bindVisibility(): void {\n    const vis = this.env.visibility;\n    if (!vis) {\n      return;\n    }\n    this.visibilityUnsub = vis.onVisibilityChange(() => {\n      if (vis.isHidden()) {\n        this.stopPolling();\n      } else {\n        // Came back to foreground: catch up immediately, then resume polling.\n        void this.poll();\n        this.startPolling();\n      }\n    });\n  }\n\n  private bindAuth(auth: AuthStateSource): void {\n    const handle = auth.onAuthStateChange((_event, session) => {\n      const hasSession = session != null;\n      // Fires immediately with current state on subscribe; only re-snapshot\n      // when the identity actually flips (sign-in ↔ sign-out), not on every\n      // token refresh, to avoid redundant cold-starts.\n      if (this.lastAuthHasSession === null) {\n        this.lastAuthHasSession = hasSession;\n        return;\n      }\n      if (hasSession !== this.lastAuthHasSession) {\n        this.lastAuthHasSession = hasSession;\n        if (this.started) {\n          void this.refresh();\n        }\n      }\n    });\n    // Normalize the Supabase-style handle to a plain unsubscribe.\n    this.authUnsub = () => handle.data.subscription.unsubscribe();\n  }\n\n  private notify(): void {\n    for (const listener of this.listeners) {\n      listener();\n    }\n  }\n\n  private markFirstLoadDone(): void {\n    if (!this.firstLoadDone) {\n      this.firstLoadDone = true;\n      this.resolveReady?.();\n      this.resolveReady = null;\n    }\n  }\n\n  private hydrateFromStorage(): void {\n    if (!this.persist) {\n      return;\n    }\n    const store = this.env.storage;\n    if (!store) {\n      return;\n    }\n    const raw = store.getItem(this.storageKey);\n    if (!raw) {\n      return;\n    }\n    const parsed = parsePersisted(raw);\n    if (!parsed) {\n      return;\n    }\n    this.state = parsed;\n    this.viewDirty = true;\n    // A persisted snapshot is enough to satisfy `ready()` instantly; a live\n    // `refresh()` will still run on `start()` to revalidate.\n    this.markFirstLoadDone();\n  }\n\n  /**\n   * A DELTA's cursor may not move backwards.\n   *\n   * `FlagsDelta.sync_version` is documented as monotonic in `types.ts`, and\n   * nothing enforced it. A delta carries a change set, never a whole truth, so a\n   * cursor lower than the one already held cannot be believed — believing it\n   * silently re-requests everything the client already has. Measured on centauri\n   * (8bbwb2pbm) 2026-09-11 against a stack whose delta reported the max row\n   * version in the response, and 0 when there were no rows:\n   *\n   *     since=0  -> ops up to 14, sync_version \"14\"\n   *     since=14 -> ops [],       sync_version \"0\"   <- the cursor fell to zero\n   *     since=0  -> the whole set again, every 30s, for ever\n   *\n   * The server side of that is fixed, but a published client outlives the stack\n   * version it happens to meet — tenants roll on their own schedule — so the\n   * invariant belongs on both sides.\n   *\n   * A genuine rewind (a restored stack) has its own channel: the backend answers\n   * 409/410 when it cannot serve incrementally from our version, and `poll()`\n   * re-snapshots on it. Silence is not that signal.\n   *\n   * A non-numeric cursor is adopted as-is: the format is the server's, and this\n   * client must not invent an ordering for one it cannot read.\n   */\n  private advance(proposed: string): string {\n    const current = this.state.syncVersion;\n    if (current == null) {\n      return proposed;\n    }\n    const next = Number(proposed);\n    const held = Number(current);\n    if (!Number.isFinite(next) || !Number.isFinite(held)) {\n      return proposed;\n    }\n    return next >= held ? proposed : current;\n  }\n\n  private persistState(): void {\n    if (!this.persist) {\n      return;\n    }\n    const store = this.env.storage;\n    if (!store || this.state.syncVersion == null) {\n      return;\n    }\n    try {\n      store.setItem(this.storageKey, JSON.stringify(this.state));\n    } catch {\n      // Quota / private-mode — persistence is best-effort.\n    }\n  }\n}\n\n// ---- guards / helpers -----------------------------------------------------\n\nfunction isDeltaOp(\n  value: unknown,\n): value is\n  | { op: 'put'; key: string; value: FlagValue; source?: FlagSource }\n  | { op: 'delete'; key: string } {\n  if (typeof value !== 'object' || value === null) {\n    return false;\n  }\n  const rec = value as Record<string, unknown>;\n  if (typeof rec.key !== 'string') {\n    return false;\n  }\n  if (rec.op === 'delete') {\n    return true;\n  }\n  return rec.op === 'put' && 'value' in rec;\n}\n\nfunction parsePersisted(raw: string): CacheState | null {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch {\n    return null;\n  }\n  if (typeof parsed !== 'object' || parsed === null) {\n    return null;\n  }\n  const rec = parsed as Record<string, unknown>;\n  if (typeof rec.syncVersion !== 'string') {\n    return null;\n  }\n  if (typeof rec.values !== 'object' || rec.values === null) {\n    return null;\n  }\n  const sources =\n    typeof rec.sources === 'object' && rec.sources !== null\n      ? (rec.sources as Record<string, FlagSource>)\n      : {};\n  return {\n    values: rec.values as Record<string, FlagValue>,\n    sources,\n    syncVersion: rec.syncVersion,\n  };\n}\n\n/** Build the default browser/Node runtime seam, guarding all DOM globals. */\nfunction defaultEnv(): PoolEnv {\n  const storage = resolveStorage();\n  const visibility = resolveVisibility();\n  return {\n    now: () => Date.now(),\n    setInterval: (handler, ms) => setInterval(handler, ms),\n    clearInterval: (handle) => clearInterval(handle),\n    storage,\n    visibility,\n  };\n}\n\nfunction resolveStorage(): KeyValueStore | null {\n  try {\n    if (typeof localStorage === 'undefined') {\n      return null;\n    }\n    // Touch it to surface private-mode/security errors up front.\n    const probe = '__palbase_flags_probe__';\n    localStorage.setItem(probe, '1');\n    localStorage.removeItem(probe);\n    return localStorage;\n  } catch {\n    return null;\n  }\n}\n\nfunction resolveVisibility(): VisibilitySource | null {\n  if (typeof document === 'undefined') {\n    return null;\n  }\n  const doc = document;\n  return {\n    isHidden: () => doc.visibilityState === 'hidden',\n    onVisibilityChange: (cb) => {\n      doc.addEventListener('visibilitychange', cb);\n      return () => doc.removeEventListener('visibilitychange', cb);\n    },\n  };\n}\n","import type { PalbaseResponse } from '@palbase/core';\nimport {\n  type AuthStateSource,\n  FlagsClient,\n  FlagsPool,\n  type FlagsPoolOptions,\n  type FlagValue,\n  type FlagVariant,\n  type PoolEnv,\n} from '@palbase/flags';\nimport type { PalbeAuth, Unsubscribe } from './auth-facade.js';\nimport { BackendError } from './errors.js';\nimport type { PalbeRuntime } from './runtime.js';\n\nexport type { FlagValue } from '@palbase/flags';\n\n/** Frozen view of all cached flag values (what `all()` returns / `changes()` yields). */\nexport type FlagsView = Readonly<Record<string, FlagValue>>;\n\n/**\n * Adapt PalbeAuth's `(state: AuthState) => void` listener contract to the\n * Supabase-style `AuthStateSource` FlagsPool binds to (`(event, session)`\n * callback + `{ data: { subscription: { unsubscribe } } }` handle).\n *\n * PalbeAuth fires the callback IMMEDIATELY on subscribe (iOS parity); the\n * pool's bindAuth treats that first call as the baseline (its\n * `lastAuthHasSession === null` branch) and only re-snapshots on a later\n * identity flip — exactly the behaviour we want, no suppression needed.\n */\nexport function palbeAuthAdapter(auth: PalbeAuth): AuthStateSource {\n  return {\n    onAuthStateChange(callback) {\n      const unsubscribe = auth.onAuthStateChange(() => {\n        // Token truth, not state.status: a restored session (page reload) has\n        // no cachedUser yet, so snapshotState() reports signedOut while\n        // isSignedIn is true. Using the token-manager directly ensures the pool\n        // baseline matches the actual session presence on the first fire.\n        const signedIn = auth.isSignedIn;\n        callback(signedIn ? 'SIGNED_IN' : 'SIGNED_OUT', signedIn ? { signedIn } : null);\n      });\n      return { data: { subscription: { unsubscribe } } };\n    },\n  };\n}\n\n/**\n * Server-side pool seams: no storage, no visibility, and — because polling is\n * disabled via `pollIntervalMs: 0` — an interval seam that must never be\n * reached. Throwing keeps a future regression loud instead of leaking timers\n * into RSC/route-handler processes.\n */\nfunction serverPoolEnv(): PoolEnv {\n  return {\n    now: () => Date.now(),\n    setInterval: () => {\n      throw new Error('palbe flags: polling is disabled server-side');\n    },\n    clearInterval: () => {},\n    storage: null,\n    visibility: null,\n  };\n}\n\n/** Object.is for primitives; objects/arrays by JSON text. Snapshots are\n * re-frozen NEW references on every re-snapshot, so reference equality would\n * report structurally-identical values as \"changed\". JSON compare is\n * key-order-sensitive — a server that reorders keys without changing values\n * may fire a spurious per-key callback (accepted tradeoff, documented). */\nfunction sameFlagValue(a: FlagValue | undefined, b: FlagValue | undefined): boolean {\n  if (Object.is(a, b)) return true;\n  if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n    return JSON.stringify(a) === JSON.stringify(b);\n  }\n  return false;\n}\n\n/**\n * `pb.flags` — iOS-parity facade over `FlagsPool` (cache + delta polling +\n * auth binding) and `FlagsClient` (stateless transport).\n *\n * Start semantics: the facade is constructed lazily (first `pb.flags` touch).\n * - Browser: the pool starts right here in the constructor — cold snapshot +\n *   30s delta polling + visibility pause. \"First use starts the machinery\"\n *   without per-method start checks.\n * - Server (no `document`): NEVER auto-starts. `ready()`/`refresh()` are\n *   one-shot snapshot fetches with zero timers and zero storage access, so a\n *   pbServer request that reads flags pays exactly one HTTP call.\n *\n * localStorage persistence is scoped per environment ref (`palbe.flags.<ref>`),\n * mirroring the session-storage key convention.\n */\nexport class PalbeFlags {\n  private readonly transport: FlagsClient;\n  private readonly pool: FlagsPool;\n\n  constructor(rt: PalbeRuntime) {\n    this.transport = new FlagsClient(rt.http);\n    const browser = typeof document !== 'undefined';\n    const ref = rt.projectRef;\n    const options: FlagsPoolOptions = {\n      auth: palbeAuthAdapter(rt.auth),\n      ...(ref ? { storageKey: `palbe.flags.${ref}` } : {}),\n      ...(browser ? {} : { pollIntervalMs: 0, env: serverPoolEnv() }),\n    };\n    this.pool = new FlagsPool(this.transport, options);\n    if (browser) this.pool.start();\n  }\n\n  /** Resolves once the first snapshot (or persisted hydrate) is available. Auto-starts the pool. */\n  ready(): Promise<void> {\n    return this.pool.ready();\n  }\n\n  /** Force an immediate re-snapshot. */\n  refresh(): Promise<void> {\n    return this.pool.refresh();\n  }\n\n  /** Frozen snapshot of all cached values (identity-stable until a change). */\n  all(): FlagsView {\n    return this.pool.all();\n  }\n\n  /** Raw cached value for `key`, or `undefined` when not in the cache. */\n  get(key: string): FlagValue | undefined {\n    return this.pool.all()[key];\n  }\n\n  /** `true` only when the cached value is strictly `true`; `fallback` when the key is absent. */\n  isEnabled(key: string, fallback = false): boolean {\n    return this.pool.isEnabled(key, fallback);\n  }\n\n  /** Alias of {@link isEnabled} (iOS parity). */\n  bool(key: string, fallback = false): boolean {\n    return this.isEnabled(key, fallback);\n  }\n\n  /** Cached value when it is a string, else `fallback`. */\n  getString(key: string, fallback: string): string {\n    const value = this.pool.all()[key];\n    return typeof value === 'string' ? value : fallback;\n  }\n\n  /** Cached value when it is an integer number, else `fallback`. */\n  getInt(key: string, fallback: number): number {\n    const value = this.pool.all()[key];\n    return typeof value === 'number' && Number.isInteger(value) ? value : fallback;\n  }\n\n  /** Cached value when it is a number (integers included), else `fallback`. */\n  getDouble(key: string, fallback: number): number {\n    const value = this.pool.all()[key];\n    return typeof value === 'number' ? value : fallback;\n  }\n\n  /**\n   * Resolve the multivariate variant for `key` — the variant name, or `null`\n   * when the flag has no variant (or the read fails).\n   *\n   * Wire failures (network errors, 404, etc.) resolve to `null`.\n   * Invalid flag names throw `BackendError('validation', { code: 'invalid_flag_name' })`.\n   *\n   * DEVIATION from iOS sync-cache parity: the platform does not propagate\n   * variant metadata into the user-flags snapshot/delta cache, so this is an\n   * ASYNC transport read (derived from `GET /v1/user-flags`), not a cache lookup.\n   */\n  async getVariant(key: string): Promise<string | null> {\n    let res: PalbaseResponse<FlagVariant>;\n    try {\n      res = await this.transport.getVariant(key);\n    } catch (err) {\n      // FlagsClient throws synchronously for invalid flag names; map to a\n      // typed validation error so callers can distinguish \"bad name\" from\n      // \"no variant\" (which resolves null).\n      throw new BackendError('validation', {\n        code: 'invalid_flag_name',\n        message: err instanceof Error ? err.message : String(err),\n      });\n    }\n    return res.data?.name ?? null;\n  }\n\n  /** Subscribe to any change in the cached flag set. */\n  onChange(callback: () => void): Unsubscribe {\n    return this.pool.onChange(callback);\n  }\n\n  /**\n   * Observe ONE key: fires only when that key's value actually changes\n   * (per {@link sameFlagValue} — structural compare for objects), with the\n   * new value (`undefined` = deleted). P5 React-hook substrate.\n   */\n  subscribeKey(key: string, callback: (value: FlagValue | undefined) => void): Unsubscribe {\n    let last = this.pool.all()[key];\n    return this.pool.onChange(() => {\n      const next = this.pool.all()[key];\n      if (sameFlagValue(last, next)) return;\n      last = next;\n      callback(next);\n    });\n  }\n\n  /**\n   * Async iteration over flag changes: yields the new {@link all} view on\n   * every pool change notification. The listener is detached when the\n   * consumer `break`s/`return`s/`throw`s — including while a `next()` is\n   * still pending (it resolves `{ done: true }` instead of hanging, which a\n   * plain async-generator `finally` would not guarantee).\n   */\n  changes(): AsyncIterableIterator<FlagsView> {\n    const queue: FlagsView[] = [];\n    const pending: Array<(result: IteratorResult<FlagsView, undefined>) => void> = [];\n    let finished = false;\n    const unsubscribe = this.pool.onChange(() => {\n      const snapshot = this.pool.all();\n      const resolve = pending.shift();\n      if (resolve) resolve({ value: snapshot, done: false });\n      else queue.push(snapshot);\n    });\n    const finish = (): void => {\n      if (finished) return;\n      finished = true;\n      unsubscribe();\n      while (pending.length > 0) pending.shift()?.({ value: undefined, done: true });\n    };\n    return {\n      next: (): Promise<IteratorResult<FlagsView, undefined>> => {\n        if (finished) return Promise.resolve({ value: undefined, done: true });\n        const head = queue.shift();\n        if (head !== undefined) return Promise.resolve({ value: head, done: false });\n        return new Promise((resolve) => {\n          pending.push(resolve);\n        });\n      },\n      return: (): Promise<IteratorResult<FlagsView, undefined>> => {\n        finish();\n        return Promise.resolve({ value: undefined, done: true });\n      },\n      throw: (error?: unknown): Promise<IteratorResult<FlagsView, undefined>> => {\n        finish();\n        return Promise.reject(error);\n      },\n      [Symbol.asyncIterator](): AsyncIterableIterator<FlagsView> {\n        return this;\n      },\n    };\n  }\n\n  /** Stop polling and detach all listeners (auth + visibility + subscribers). */\n  destroy(): void {\n    this.pool.destroy();\n  }\n}\n","/**\n * Pure deadline math — the web mirror of iOS DeadlineCalculator (Codex-finalized\n * restart conversion rule). Identical algorithm; web uses ms internally and\n * compares against ttlSeconds (converted). Clock readings are passed in so it is\n * fully table-testable and byte-identical with iOS.\n *\n * NOTE on the send-vs-arrival clamp: like iOS T3, this Calculator stays PURE — it\n * consumes an already-resolved anchor + the current clock readings. The\n * `min(sender_send_ts + ttl, first_arrival_monotonic + ttl)` effective-deadline\n * basis is applied at ARM time by the caller (Chat, T10), which picks the anchor's\n * monotonic baseline; the Calculator only converts that anchor into remaining/purge.\n */\nexport interface AnchorTriple {\n  mAnchorMs: number; // performance.now() at capture\n  wAnchorEpochMs: number; // Date.now() at capture\n  bAnchorToken: string; // per-page-session token (changes across reload/reboot)\n}\n\nexport type DeadlineResult = { kind: 'remaining'; seconds: number } | { kind: 'purgeNow' };\n\nexport function remainingSeconds(args: {\n  ttlSeconds: number;\n  anchor: AnchorTriple;\n  nowMonotonicMs: number;\n  nowWallEpochMs: number;\n  nowBootToken: string;\n}): DeadlineResult {\n  const ttl = args.ttlSeconds;\n  const wallDeltaSec = (args.nowWallEpochMs - args.anchor.wAnchorEpochMs) / 1000;\n  let elapsed: number;\n  if (args.nowBootToken === args.anchor.bAnchorToken) {\n    const monoDeltaSec = Math.max(0, args.nowMonotonicMs - args.anchor.mAnchorMs) / 1000;\n    elapsed = Math.max(monoDeltaSec, wallDeltaSec); // larger-elapsed: backward wall can't extend\n  } else {\n    elapsed = wallDeltaSec; // reboot: monotonic meaningless → wall-only (best-effort, bounded)\n  }\n  const remaining = Math.min(ttl, ttl - elapsed); // clamp: never MORE than ttl of life\n  return remaining <= 0 ? { kind: 'purgeNow' } : { kind: 'remaining', seconds: remaining };\n}\n\n/** Impure clock seam. The boot token is minted once per page-session via\n * crypto.randomUUID() and persisted (sessionStorage), so it is stable within a\n * boot and changes across a reload/reboot — making the monotonic reading\n * comparable across a restart (same-boot vs reboot conversion). */\nlet cachedBootToken: string | null = null;\nexport const MonotonicClock = {\n  nowMs(): number {\n    return typeof performance !== 'undefined' ? performance.now() : Date.now();\n  },\n  nowWallEpochMs(): number {\n    return Date.now();\n  },\n  bootToken(): string {\n    if (cachedBootToken !== null) return cachedBootToken;\n    try {\n      const existing =\n        typeof sessionStorage !== 'undefined' ? sessionStorage.getItem('pb_boot_token') : null;\n      if (existing) {\n        cachedBootToken = existing;\n        return existing;\n      }\n      const fresh = crypto.randomUUID();\n      if (typeof sessionStorage !== 'undefined') sessionStorage.setItem('pb_boot_token', fresh);\n      cachedBootToken = fresh;\n      return fresh;\n    } catch {\n      cachedBootToken = crypto.randomUUID();\n      return cachedBootToken;\n    }\n  },\n};\n","/**\n * DeleteFold — pure fold of delete-for-everyone tombstones into a monotonic\n * `tombstoned` set.\n *\n * Algorithm mirrors iOS `DeleteFold` (DeleteFold.swift) byte-for-byte in\n * behaviour so the two SDKs compute the IDENTICAL tombstoned set from the same\n * events:\n *\n *  - **Dedup first** on `eventClientMsgId` (a re-delivered logical tombstone\n *    applies at most once). Dedup is recorded ONLY for events the fold could\n *    actually evaluate (target present, or parked in pending) — an unverifiable\n *    event (unresolved sender AND absent target) is held by its own id without\n *    being marked seen, so it can be re-attempted when more resolves.\n *  - **Author-gate (the #1 security property):** a tombstone scrubs a target\n *    ONLY when its resolved authenticated sender (`actorUserId`) equals the\n *    TARGET message's author (`authorOfTarget(target)`). A non-author tombstone\n *    is a forgery → IGNORED. This gate is enforced IDENTICALLY on the in-order\n *    path AND the deferred/pending path — there is NO code path that tombstones\n *    without passing it.\n *  - **ABSORBING / sticky (NOT LWW):** once a target is in `tombstoned` it is\n *    NEVER removed. No later event, no higher seq, no reevaluate can\n *    un-tombstone it. (Eviction within the retention window is the STORE's job,\n *    not the fold's.)\n *  - **Pending (dangling target):** a valid-shaped tombstone whose target isn't\n *    local yet is parked in `pending` CARRYING its authenticated actor, so the\n *    deferred sender-match can be enforced when the target finally arrives\n *    (`reevaluatePending`). A forged early tombstone parked in pending is\n *    DISCARDED on the target's arrival (sender-match fails) → the genuine\n *    message renders.\n *  - **Unresolved sender + absent target:** nothing can be verified yet (neither\n *    side resolved). The event is parked in `held` keyed by its\n *    `eventClientMsgId` and re-ingested on `reevaluatePending` — it never\n *    tombstones until BOTH the actor and the target's author are known AND match.\n *\n * Pure: no I/O, fully table-testable.\n */\n\n/**\n * One delete-for-everyone tombstone event for a target message. Carries\n * everything the fold needs and nothing it must read from the ciphertext: the\n * actor is the AUTHENTICATED sender resolved upstream (`actorUserId`), NEVER an\n * actor field on the wire.\n */\nexport interface DeleteEvent {\n  targetClientMsgId: string;\n  /** Resolved authenticated sender userId; null = unresolved sender. */\n  actorUserId: string | null;\n  epoch: number;\n  serverSeq: number;\n  /** Dedup key — the tombstone's own client_msg_id (unique per logical event). */\n  eventClientMsgId: string;\n}\n\nimport type { AuthorResolution } from './edit-fold.js';\n\n/**\n * Resolves the target message's author via {@link AuthorResolution} (the SAME\n * orphan-aware resolution the edit gate uses): `'author'` → run the author-gate;\n * `'unknown'` → defer (target absent locally → pending/held); `'purged'` → NO-OP\n * (the target was TTL-purged — a delete of an already-gone message is already\n * satisfied; never park in pending, never re-attempt).\n */\ntype AuthorOfTarget = (targetClientMsgId: string) => AuthorResolution;\n\nexport class DeleteFold {\n  // targets with a confirmed valid tombstone — MONOTONIC (never removed within retention).\n  private readonly tombstoned = new Set<string>();\n  // target → the tombstone's authenticated actor userId, awaiting the target's arrival.\n  private readonly pending = new Map<string, string>();\n  // dedup of real wire events the fold could evaluate (tombstoned or parked in pending).\n  private readonly seen = new Set<string>();\n  // events parked because NEITHER the actor NOR the target's author was resolvable at ingest;\n  // keyed by eventClientMsgId so a re-delivered unverifiable event is held exactly once.\n  private held: DeleteEvent[] = [];\n\n  /**\n   * Ingest one tombstone. `authorOfTarget` resolves the target message's author via\n   * {@link AuthorResolution}: `'author'` → run the author-gate; `'unknown'` → defer\n   * (target absent locally → pending/held); `'purged'` → NO-OP, mark seen (the target\n   * was TTL-purged — a delete of an already-gone message is already satisfied; never\n   * park in pending, never re-attempt).\n   */\n  ingest(e: DeleteEvent, authorOfTarget: AuthorOfTarget): void {\n    // Already absorbed → no-op (idempotent, absorbing).\n    if (this.tombstoned.has(e.targetClientMsgId)) return;\n    // Dedup of the same logical tombstone (only events we actually parked/evaluated are seen).\n    if (this.seen.has(e.eventClientMsgId)) return;\n    if (this.heldContains(e.eventClientMsgId)) return;\n\n    const res = authorOfTarget(e.targetClientMsgId);\n    if (res.kind === 'purged') {\n      // Target already TTL-purged → already gone. No-op, mark seen (never park in pending).\n      this.seen.add(e.eventClientMsgId);\n      return;\n    }\n    if (res.kind === 'author') {\n      // Target present → run the author-gate NOW.\n      this.seen.add(e.eventClientMsgId);\n      if (e.actorUserId === null || e.actorUserId !== res.userId) return; // forgery / unresolved actor → ignore\n      this.tombstoned.add(e.targetClientMsgId);\n    } else if (e.actorUserId !== null) {\n      // Target absent but actor resolved → park the authenticated actor for the deferred gate.\n      this.seen.add(e.eventClientMsgId);\n      this.pending.set(e.targetClientMsgId, e.actorUserId);\n    } else {\n      // Neither actor NOR target resolved — cannot verify anything yet. Hold by id and\n      // re-ingest on reevaluate; NOT marked seen so it stays re-attemptable.\n      this.held.push(e);\n    }\n  }\n\n  /** True once a valid tombstone has absorbed this target. */\n  isTombstoned(targetClientMsgId: string): boolean {\n    return this.tombstoned.has(targetClientMsgId);\n  }\n\n  /**\n   * When a target message newly arrives with a resolved `author`, re-check any\n   * pending tombstone for it AND re-attempt any held (unverifiable) tombstones\n   * whose target is now resolvable. The deferred gate is the SAME comparison as\n   * the in-order path.\n   */\n  reevaluatePending(target: string, author: AuthorResolution): void {\n    const res = author;\n    // Deferred gate for a parked pending tombstone.\n    const actor = this.pending.get(target);\n    if (actor !== undefined) {\n      // Absorbing: only ADD on a match; a mismatch DISCARDS the (forged) pending entry so it\n      // can never scrub the genuine message.\n      if (res.kind === 'author') {\n        if (actor === res.userId) this.tombstoned.add(target); // match → absorbed\n        this.pending.delete(target); // match → absorbed; mismatch → forged tombstone loses\n      } else if (res.kind === 'purged') {\n        // Target was TTL-purged → already gone; nothing left to scrub or defer. Discard.\n        this.pending.delete(target);\n      }\n      // 'unknown' → cannot decide yet, keep the pending entry.\n    }\n    // Re-attempt any held events whose target now has a resolvable author. Re-ingest runs the\n    // full gate (dedup via seen, author-match / purged no-op), so it can neither double-apply\n    // nor scrub without the match. Events that still don't resolve are re-held.\n    if (this.held.length === 0) return;\n    const pendingHeld = this.held;\n    this.held = [];\n    for (const e of pendingHeld) {\n      this.ingest(e, (t): AuthorResolution => (t === target ? res : { kind: 'unknown' }));\n    }\n  }\n\n  private heldContains(eventClientMsgId: string): boolean {\n    return this.held.some((h) => h.eventClientMsgId === eventClientMsgId);\n  }\n}\n","/**\n * EditFold — pure fold of edit-by-supersession events into a per-target winning\n * text + a write-once `edited` flag.\n *\n * Algorithm mirrors iOS `EditFold` (EditFold.swift) byte-for-byte in behaviour so\n * the two SDKs compute the IDENTICAL winning edit from the same events:\n *\n *  - **Author-gate first, dedup after** on `eventClientMsgId`. Dedup happens only\n *    AFTER the event is both resolvable (target+sender) and authorized, so a HELD\n *    event is never prematurely consumed by the seen-set (matching iOS ordering).\n *  - **HOLD (unresolved/dangling):** if the target's author is not yet resolvable\n *    (`authorOfTarget` returns null — target unknown), OR the sender is unresolved\n *    (`editorUserId == null` — roster gap), the event is parked in `held` (deduped\n *    by `eventClientMsgId`) and re-attempted by `reevaluateHeld(...)` once the\n *    roster/target arrives. Never folds an unresolved sender; never silently drops\n *    a holdable edit.\n *  - **Author-gate:** the edit's resolved sender (`editorUserId`) must equal the\n *    TARGET message's author (`authorOfTarget(target)`). A non-author edit is a\n *    forgery → DROPPED (not held). It is NOT marked seen — letting the gate re-drop\n *    a re-delivery is harmless and idempotent (it never reaches the winner state,\n *    so the winner is unaffected).\n *  - **LWW per target** on `(epoch, serverSeq)` ascending. An incoming order that\n *    is `< stored`, or `== stored` and loses the id backstop, is ignored.\n *  - **Exact-tie rule (cross-SDK contract — MUST match iOS):** on an exact\n *    `(epoch, serverSeq)` tie the edit whose `eventClientMsgId` is **lexicographically\n *    GREATER (`>`) wins**. Implemented as \"incoming `<= stored.lastEventId` → loses\"\n *    (identical comparison direction to iOS EditFold.swift). The server guarantees\n *    `(epoch, serverSeq)` is unique per logical event, so this is a theoretical\n *    backstop only — but it is fully deterministic + order-independent.\n *  - **Write-once `edited`:** once ANY valid edit applies to a target it stays\n *    edited forever (editing back to the original text still shows edited). Never\n *    unset.\n *\n * Pure: no I/O, fully table-testable.\n */\n\nimport type { MentionRange } from './group-messaging.js';\n\n/**\n * One edit-by-supersession event for the LATEST edit's text to be folded onto a\n * target message in place. Carries everything the fold needs and nothing it must\n * read from the ciphertext: the actor is the AUTHENTICATED sender resolved\n * upstream (`editorUserId`), never an actor field on the wire.\n */\nexport interface EditEvent {\n  targetClientMsgId: string;\n  /** Resolved sender userId; null = unresolved (roster gap) → HOLD. */\n  editorUserId: string | null;\n  newText: string;\n  epoch: number;\n  serverSeq: number;\n  /** Dedup key — the edit's own client_msg_id (unique per logical event). */\n  eventClientMsgId: string;\n  /**\n   * The edit's REPLACEMENT mention ranges (raw, un-normalized). The fold tracks them\n   * on the WINNING edit only, so the edited message's mentions re-resolve from the\n   * LWW-winning edit's ranges (mentions T6). Undefined/null = the edit carried none.\n   */\n  bodyRanges?: MentionRange[] | null;\n}\n\ninterface TargetState {\n  orderEpoch: number;\n  orderSeq: number;\n  lastEventId: string;\n  text: string;\n  /** The WINNING edit's replacement mention ranges (raw); null when it carried none. */\n  bodyRanges: MentionRange[] | null;\n}\n\n/**\n * Orphan-aware author resolution (web mirror of iOS `TargetAuthor`):\n *  - `{ kind: 'author'; userId }` — target present, author known → run the author-gate.\n *  - `{ kind: 'purged' }` — the target was TTL-purged (its `client_msg_id` is in the\n *    persistent `purgedClientMsgIds` STRING set, namespace-separate from the int\n *    `server_seq` tombstone) → DROP an edit (no held leak, never resurrects).\n *  - `{ kind: 'unknown' }` — target not locally resolvable yet → HOLD (re-attempt later).\n */\nexport type AuthorResolution =\n  | { kind: 'author'; userId: string }\n  | { kind: 'purged' }\n  | { kind: 'unknown' };\n\n/**\n * Resolves the target message's AUTHOR via {@link AuthorResolution}. ALL call-sites\n * (`chat.ts` author closure, `coordinator.ts` `projectHistory`) return this union\n * directly (the legacy `string | null` shim was deleted in Task 10).\n */\ntype AuthorOfTarget = (targetClientMsgId: string) => AuthorResolution;\n\n/**\n * Lexicographic (epoch, serverSeq) comparison. Returns true if a < b\n * (the incoming order is strictly older than the stored order).\n */\nfunction orderLt(aEpoch: number, aSeq: number, bEpoch: number, bSeq: number): boolean {\n  if (aEpoch !== bEpoch) return aEpoch < bEpoch;\n  return aSeq < bSeq;\n}\n\n/** True if (aEpoch, aSeq) equals (bEpoch, bSeq). */\nfunction orderEq(aEpoch: number, aSeq: number, bEpoch: number, bSeq: number): boolean {\n  return aEpoch === bEpoch && aSeq === bSeq;\n}\n\nexport class EditFold {\n  // target → winning edit state\n  private readonly states = new Map<string, TargetState>();\n  // dedup of real wire events that reached (and were resolvable enough to evaluate at) the fold\n  private readonly seenEvents = new Set<string>();\n  // events parked because target/author or sender was unresolved at ingest time\n  private held: EditEvent[] = [];\n  // targets that have had ≥1 valid edit applied (write-once)\n  private readonly editedTargets = new Set<string>();\n\n  /**\n   * Ingest one edit. `authorOfTarget` resolves the target message's author via\n   * {@link AuthorResolution}: `'author'` → run the author-gate; `'unknown'` → HOLD\n   * (target/author not yet known); `'purged'` → DROP (the target was TTL-purged —\n   * editing a disappeared message is a no-op; mark the event seen so it never re-holds\n   * and a later author \"resolution\" cannot resurrect it).\n   */\n  ingest(e: EditEvent, authorOfTarget: AuthorOfTarget): void {\n    const res = authorOfTarget(e.targetClientMsgId);\n    if (res.kind === 'unknown') {\n      this.holdIfNew(e); // target/author not yet known → HOLD\n      return;\n    }\n    if (res.kind === 'purged') {\n      this.seenEvents.add(e.eventClientMsgId); // mark seen → never re-held, never resurrects\n      return; // DROP: editing a disappeared message is a no-op\n    }\n    const author = res.userId;\n    // Sender not yet resolvable (roster gap) → hold; we must never fold an unattributed edit.\n    if (e.editorUserId === null) {\n      this.holdIfNew(e);\n      return;\n    }\n    // Author-gate: a non-author edit is a forgery — dropped, not held, not marked seen\n    // (the gate re-drops any re-delivery; it never touches winner state, so it's idempotent).\n    if (e.editorUserId !== author) return;\n\n    // Resolvable + authorized: dedup, then LWW.\n    if (this.seenEvents.has(e.eventClientMsgId)) return; // re-delivery of same logical edit\n    this.seenEvents.add(e.eventClientMsgId);\n\n    const prev = this.states.get(e.targetClientMsgId);\n    if (prev !== undefined) {\n      // stale / out-of-order\n      if (orderLt(e.epoch, e.serverSeq, prev.orderEpoch, prev.orderSeq)) return;\n      // exact (epoch, serverSeq) tie: lexicographically GREATER eventClientMsgId wins,\n      // so an incoming id <= the stored one loses (identical to iOS EditFold's `<=`).\n      if (\n        orderEq(e.epoch, e.serverSeq, prev.orderEpoch, prev.orderSeq) &&\n        e.eventClientMsgId <= prev.lastEventId\n      ) {\n        return;\n      }\n    }\n    this.states.set(e.targetClientMsgId, {\n      orderEpoch: e.epoch,\n      orderSeq: e.serverSeq,\n      lastEventId: e.eventClientMsgId,\n      text: e.newText,\n      bodyRanges: e.bodyRanges ?? null,\n    });\n    this.editedTargets.add(e.targetClientMsgId); // write-once\n  }\n\n  /**\n   * Park an event for later re-attempt, deduping held re-deliveries by\n   * eventClientMsgId so a repeatedly-delivered unresolvable edit is held exactly\n   * once (and never double-applies when it finally resolves on reevaluate).\n   */\n  private holdIfNew(e: EditEvent): void {\n    if (this.held.some((h) => h.eventClientMsgId === e.eventClientMsgId)) return;\n    this.held.push(e);\n  }\n\n  /** The winning edit text for a target, or null if no valid edit has applied. */\n  text(targetClientMsgId: string): string | null {\n    return this.states.get(targetClientMsgId)?.text ?? null;\n  }\n\n  /** Write-once: true once any valid edit applied to the target. */\n  isEdited(targetClientMsgId: string): boolean {\n    return this.editedTargets.has(targetClientMsgId);\n  }\n\n  /**\n   * The WINNING edit's replacement mention ranges for a target (raw, un-normalized),\n   * or null when no valid edit applied or the winning edit carried none. The Chat\n   * normalizes these against the edited text to compute the edited message's mentions\n   * (mentions T6). LWW-consistent: always the same edit that `text(...)` returns.\n   */\n  bodyRanges(targetClientMsgId: string): MentionRange[] | null {\n    return this.states.get(targetClientMsgId)?.bodyRanges ?? null;\n  }\n\n  /**\n   * Re-run HELD edits when the roster/target newly resolves (call on member/roster\n   * change and when a target message arrives). Clears `held` and re-ingests each\n   * event with the fresh `authorOfTarget` — events that still don't resolve are\n   * simply re-held; events that now resolve fold via the normal LWW path.\n   * Idempotent: re-ingest is deduped by `seenEvents` (applied events) and by\n   * `holdIfNew` (still-held events), so reevaluating repeatedly can neither\n   * double-apply nor lose an edit.\n   */\n  reevaluateHeld(authorOfTarget: AuthorOfTarget): void {\n    const pending = this.held;\n    this.held = [];\n    for (const e of pending) this.ingest(e, authorOfTarget);\n  }\n}\n","// Byte / base64 helpers — portable across browser and Node (no Buffer dep on\n// the browser path). All MLS blobs cross the wire as base64 strings.\n\n/** Encode bytes to a standard (non-url-safe) base64 string. */\nexport function toBase64(bytes: Uint8Array): string {\n  if (typeof Buffer !== 'undefined') {\n    return Buffer.from(bytes).toString('base64');\n  }\n  let binary = '';\n  const chunk = 0x8000;\n  for (let i = 0; i < bytes.length; i += chunk) {\n    binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n  }\n  return btoa(binary);\n}\n\n/** Decode a standard base64 string to bytes. */\nexport function fromBase64(b64: string): Uint8Array {\n  if (typeof Buffer !== 'undefined') {\n    return new Uint8Array(Buffer.from(b64, 'base64'));\n  }\n  const binary = atob(b64);\n  const out = new Uint8Array(binary.length);\n  for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);\n  return out;\n}\n\n/** Lowercase hex of a byte buffer (a stable string key for any blob). */\nexport function bytesToHex(bytes: Uint8Array): string {\n  let s = '';\n  for (let i = 0; i < bytes.length; i++) {\n    s += (bytes[i] ?? 0).toString(16).padStart(2, '0');\n  }\n  return s;\n}\n\nconst utf8Encoder = new TextEncoder();\nconst utf8Decoder = new TextDecoder();\n\nexport const encodeUtf8 = (s: string): Uint8Array => utf8Encoder.encode(s);\nexport const decodeUtf8 = (b: Uint8Array): string => utf8Decoder.decode(b);\n\n/** Bytes of a device id (the MLS credential identity == the `mdv_` device id). */\nexport const deviceIdBytes = (deviceId: string): Uint8Array => encodeUtf8(deviceId);\n\n/** A fresh client idempotency / id value (crypto-strong; never Math.random). */\nexport function randomId(): string {\n  return crypto.randomUUID();\n}\n\n/** Mint a client-side `mdv_<uuidv7>` device id (SP-1.6 client-minted). The\n * server (messaging `ValidateDeviceID`) requires the mdv_ prefix followed by a\n * canonical UUID *version 7* — a v4 (what `crypto.randomUUID()` emits) is\n * rejected with `invalid_device_id`. So mint a real v7 here: the version must\n * match the server's id-validator, not just the prefix. A random v7 bound to\n * the caller's iJWT sub stays squat-safe (ownership = sub, uniqueness = PK). */\nexport function mintDeviceId(): string {\n  return `mdv_${uuidV7()}`;\n}\n\n/**\n * Generate a canonical RFC 9562 UUID version 7 (time-ordered): 48-bit big-endian\n * Unix-ms timestamp, version nibble 7, variant bits 10, the rest CSPRNG random.\n * `crypto.randomUUID()` only emits v4, and the messaging server validates v7, so\n * the device-id minter cannot reuse it — this is the byte-shape the server's\n * `uuid.Version() == 7` check accepts.\n */\nexport function uuidV7(): string {\n  const bytes = new Uint8Array(16);\n  crypto.getRandomValues(bytes);\n  const ts = Date.now(); // ms since epoch fits in 48 bits until year 10889\n  // A DataView write avoids `noUncheckedIndexedAccess` \"possibly undefined\" on\n  // raw index assignment and writes the 48-bit timestamp big-endian in one shot.\n  const view = new DataView(bytes.buffer);\n  view.setUint32(0, Math.floor(ts / 2 ** 16)); // high 32 bits of the 48-bit ms\n  view.setUint16(4, ts & 0xffff); // low 16 bits\n  view.setUint8(6, (view.getUint8(6) & 0x0f) | 0x70); // version 7\n  view.setUint8(8, (view.getUint8(8) & 0x3f) | 0x80); // variant 10\n  const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/** The canonical sorted-pair direct_key for a 1:1 chat (`dm:<a>|<b>`). */\nexport function directKey(userA: string, userB: string): string {\n  const [a, b] = [userA, userB].sort();\n  return `dm:${a}|${b}`;\n}\n\n/** Mint a `msg_<32 hex>` client message id (matches iOS format). */\nexport function mintClientMsgId(): string {\n  const b = new Uint8Array(16);\n  crypto.getRandomValues(b);\n  return `msg_${Array.from(b, (x) => x.toString(16).padStart(2, '0')).join('')}`;\n}\n\n/** Truncate a string to 240 Unicode scalars (code points). Returns [truncated, wasTruncated]. */\nexport function truncateQuote(s: string): [string, boolean] {\n  const scalars = [...s];\n  if (scalars.length <= 240) return [s, false];\n  return [scalars.slice(0, 240).join(''), true];\n}\n","// The messaging wire protocol for the web SDK — paths + request/response shapes.\n//\n// CRITICAL (differs from iOS): the web HttpClient does a RAW JSON.stringify of\n// the request body (NO camel↔snake conversion — verified @palbase/core\n// HttpClient). So every field here is snake_case to match the server tags\n// VERBATIM. The field names are the live server JSON tags, cross-checked against\n// modules/messaging/internal/handler/{group,message,keypackage,trust}.go and the\n// iOS MessagingTypes.swift wire doc (live-proven). All blobs are base64 strings.\n//\n// Paths mirror the iOS MessagingPaths (the M3 #7 contract): a {gid} segment is\n// ALWAYS a `grp_<uuidv7>` display_id (url-safe), NEVER the base64 rfc_group_id.\n\n// ─── Paths ───────────────────────────────────────────────────────────────────\n\nconst GROUPS = '/v1/messaging/groups';\nconst DEVICES = '/v1/messaging/devices';\nconst KEYDIR = '/v1/messaging/keydir';\n\n/** encodeURIComponent a single path segment (defense in depth; the real fix is\n * passing the url-safe grp_/mdv_ id, never the base64 rfc_group_id — M3 #7). */\nconst seg = (s: string): string => encodeURIComponent(s);\n\nexport const MessagingPaths = {\n  groups: GROUPS,\n  groupsDirect: `${GROUPS}/direct`,\n  group: (displayId: string) => `${GROUPS}/${seg(displayId)}`,\n  groupMetadata: (displayId: string) => `${GROUPS}/${seg(displayId)}/metadata`,\n  groupMembers: (displayId: string) => `${GROUPS}/${seg(displayId)}/members`,\n  groupMemberDevice: (displayId: string, deviceId: string) =>\n    `${GROUPS}/${seg(displayId)}/members/${seg(deviceId)}`,\n  groupMessages: (displayId: string) => `${GROUPS}/${seg(displayId)}/messages`,\n  groupCommits: (displayId: string) => `${GROUPS}/${seg(displayId)}/commits`,\n  groupRead: (displayId: string) => `${GROUPS}/${seg(displayId)}/read`,\n  // Server-metadata cluster: the per-(user,group) notify scope (mute toggle, GET/PUT)\n  // + the caller's own unread view (GET). {gid} is the grp_ display_id (M3 #7).\n  groupNotify: (displayId: string) => `${GROUPS}/${seg(displayId)}/notify`,\n  groupUnread: (displayId: string) => `${GROUPS}/${seg(displayId)}/unread`,\n\n  deviceWelcomes: (deviceId: string) => `${DEVICES}/${seg(deviceId)}/welcomes`,\n  deviceQueue: (deviceId: string) => `${DEVICES}/${seg(deviceId)}/queue`,\n  deviceQueueAck: (deviceId: string) => `${DEVICES}/${seg(deviceId)}/queue/ack`,\n\n  keydirDevices: `${KEYDIR}/devices`,\n  keydirDeviceKeyPackages: (deviceId: string) => `${KEYDIR}/devices/${seg(deviceId)}/keypackages`,\n  keydirUserDevices: (userId: string) => `${KEYDIR}/users/${seg(userId)}/devices`,\n  keydirUserClaim: (userId: string) => `${KEYDIR}/users/${seg(userId)}/keypackages/claim`,\n  keydirPinsVerify: `${KEYDIR}/pins/verify`,\n\n  prefs: '/v1/messaging/prefs',\n} as const;\n\n/** True iff `s` is safe to place RAW in a URL path segment (M3 #7 gate). A\n * grp_/mdv_ id passes; a base64 rfc_group_id (`/`, `=`, `+`) FAILS. */\nexport function isUrlSafePathSegment(s: string): boolean {\n  return s.length > 0 && /^[A-Za-z0-9\\-._~]+$/.test(s);\n}\n\n// ─── Keydir (SP-0) ───────────────────────────────────────────────────────────\n\nexport type MessagingPlatform = 'android' | 'ios' | 'web';\n\nexport interface EnrollDeviceBody {\n  device_id: string;\n  platform: MessagingPlatform;\n  device_name?: string;\n  cipher_suite: number;\n  signature_key: string; // base64 raw curve public key\n  credential: string; // base64 TLS-encoded MLS Credential (identity == device_id)\n  capabilities: string; // base64\n}\n\nexport interface EnrollResponse {\n  device_id: string;\n  signature_key_fingerprint: string;\n  trust_tier: string;\n  one_time_count: number;\n}\n\nexport interface ReplenishBody {\n  key_packages: string[]; // base64 raw KeyPackages\n}\n\nexport interface DeviceInfo {\n  device_id: string;\n  signature_key: string;\n  credential: string;\n  cipher_suite: number;\n  key_epoch: number;\n  trust_tier: string;\n  first_seen_at: string;\n}\n\nexport interface DeviceListResponse {\n  device_set_version: string;\n  devices: DeviceInfo[];\n  warnings?: unknown[];\n}\n\nexport interface ClaimedKeyPackage {\n  device_id: string;\n  cipher_suite: number;\n  key_package: string; // base64\n  reused: boolean;\n}\n\nexport interface ClaimResponse {\n  key_packages: ClaimedKeyPackage[];\n  depleted_devices?: string[];\n}\n\nexport interface VerifyBody {\n  peer_user_id: string;\n  verified_device_set_hash: string;\n}\n\n// ─── Group create / direct ────────────────────────────────────────────────────\n\nexport interface CreateGroupBody {\n  rfc_group_id: string; // base64\n  cipher_suite: number;\n  creator_device_id: string;\n  creator_leaf_index: number;\n  metadata?: string; // base64 sealed-name blob; omitted on web (no exporter yet)\n}\n\nexport interface CreateGroupResponse {\n  display_id: string;\n  rfc_group_id: string;\n  current_epoch: number;\n  metadata?: string;\n}\n\nexport interface CreateDirectGroupBody {\n  direct_key: string;\n  peer_user_id: string;\n  rfc_group_id: string; // base64\n  cipher_suite: number;\n  creator_device_id: string;\n  creator_leaf_index: number;\n}\n\nexport interface CreateDirectGroupResponse {\n  display_id: string;\n  rfc_group_id: string;\n  current_epoch: number;\n  owner_user_id?: string;\n  exists?: boolean;\n}\n\nexport interface GroupReadResponse {\n  display_id: string;\n  rfc_group_id: string;\n  current_epoch: number;\n  status?: string;\n  metadata?: string;\n}\n\n// ─── Members ───────────────────────────────────────────────────────────────────\n\nexport type MessagingGroupRole = 'owner' | 'admin' | 'member';\n\nexport interface GroupMemberRow {\n  device_id: string;\n  user_id: string;\n  role: MessagingGroupRole;\n  leaf_index: number;\n}\n\nexport interface ListMembersResponse {\n  members: GroupMemberRow[];\n}\n\nexport interface WelcomeBody {\n  recipient_device_id: string;\n  recipient_user_id: string;\n  welcome_b64: string;\n}\n\n/** `POST /groups/{gid}/members` — declared add + opaque commit + welcomes. */\nexport interface AddMemberBody {\n  op: string;\n  commit_b64: string;\n  target_device_ids: string[];\n  leaf_indexes: number[];\n  user_ids: string[];\n  key_package_refs: string[];\n  welcomes: WelcomeBody[];\n}\n\n/** `DELETE /groups/{gid}/members/{deviceId}` — multi-remove / self-leave. */\nexport interface RemoveMembersBody {\n  op: string;\n  commit_b64: string;\n  target_device_ids: string[];\n  user_ids: string[];\n}\n\n/** `{ epoch }` — the advanced-to epoch a membership/commit write returns. */\nexport interface CommitAccepted {\n  epoch: number;\n}\n\n// ─── Messages ──────────────────────────────────────────────────────────────────\n\nexport interface SendMessageBody {\n  ciphertext_b64: string;\n  client_idem_key: string;\n}\n\nexport interface SentReceipt {\n  server_seq: number;\n  epoch: number;\n}\n\n/** One queue row from `GET /devices/{deviceId}/queue`. */\nexport interface QueuedMessage {\n  id: string;\n  epoch: number;\n  content_type: number; // 1=app, 2=proposal, 3=commit\n  wire_format: number; // 1=public, 2=private\n  ciphertext_b64: string;\n  server_seq: number;\n  // OPTIONAL group attribution + the fanned-out declaration (the live server\n  // does not fan these on queue rows yet — nil today, gate engages when present).\n  rfc_group_id_b64?: string;\n  sender_device_id?: string;\n  declared_added_device_ids?: string[];\n  declared_removed_device_ids?: string[];\n  declared_op?: string;\n}\n\nexport interface QueuePage {\n  messages: QueuedMessage[];\n}\n\n/** One row from `GET /devices/{deviceId}/welcomes` — a new-member bootstrap. */\nexport interface PendingWelcome {\n  id: string;\n  display_id: string; // the group's grp_ routing id (url-safe; NOT the base64 rfc)\n  rfc_group_id_b64: string;\n  welcome_b64: string;\n  added_at_epoch: number;\n}\n\nexport interface WelcomePage {\n  welcomes: PendingWelcome[];\n}\n\nexport interface AckBody {\n  message_ids: string[];\n}\n\n/** Queue-row content-type discriminator (matches the server `content_type`). */\nexport const ContentType = {\n  application: 1,\n  proposal: 2,\n  commit: 3,\n} as const;\n\n// ─── SP-3 comms (read receipts / prefs / presence / typing) ──────────────────\n\nexport interface MarkReadBody {\n  read_seq: number;\n  read_epoch: number;\n  is_private: boolean;\n}\n\nexport interface MarkReadResponse {\n  read_seq: number;\n  advanced: boolean;\n  broadcast: boolean;\n}\n\nexport interface CommsPrefsResponse {\n  share_presence: boolean;\n  share_receipts: boolean;\n  updated_at?: string;\n}\n\nexport interface SetPrefsBody {\n  share_presence?: boolean;\n  share_receipts?: boolean;\n}\n\nexport interface CommsPrefs {\n  sharePresence: boolean;\n  shareReceipts: boolean;\n}\n","// The MLS key directory (SP-0) mechanics — INTERNAL, mirroring the iOS\n// KeyDirectoryInternal. Hidden behind the coordinator's implicit enroll (the\n// first chat op self-enrolls). Byte-identical wire calls to iOS: same\n// /v1/messaging/keydir/* routes, same iJWT bearer (palbeRequest), same\n// snake_case bodies.\n\nimport { palbeRequest } from '../request.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport type { MlsEngine } from './mls-engine.js';\nimport type { DeviceIdStore } from './storage.js';\nimport { toBase64 } from './util.js';\nimport {\n  type ClaimResponse,\n  type DeviceListResponse,\n  type EnrollDeviceBody,\n  type EnrollResponse,\n  MessagingPaths,\n  type ReplenishBody,\n  type VerifyBody,\n} from './wire.js';\n\n/**\n * Enroll THIS device + publish its first KeyPackages from REAL engine material.\n * Idempotent: a returning user (persisted device id) skips the POST and just\n * replenishes. Returns the resolved device id.\n *\n * Flow (mirrors iOS enroll):\n *   1. engine.enrollmentMaterial() → { signatureKey, credential, capabilities }\n *   2. POST /keydir/devices (the server validates the client-minted mdv_ id +\n *      credential.identity == device_id + ownership == iJWT sub)\n *   3. generate N key packages → POST /keydir/devices/{id}/keypackages\n */\nexport async function enrollDevice(\n  rt: PalbeRuntime,\n  engine: MlsEngine,\n  deviceStore: DeviceIdStore,\n  opts: { keyPackageCount?: number; deviceName?: string } = {},\n): Promise<string> {\n  const keyPackageCount = opts.keyPackageCount ?? 10;\n  const deviceId = engine.deviceId;\n  const alreadyEnrolled = (await deviceStore.load(engine.userId)) === deviceId;\n\n  if (!alreadyEnrolled) {\n    const material = await engine.enrollmentMaterial();\n    const body: EnrollDeviceBody = {\n      device_id: deviceId,\n      platform: 'web',\n      device_name: opts.deviceName,\n      cipher_suite: 1,\n      signature_key: toBase64(material.signatureKey),\n      credential: toBase64(material.credential),\n      capabilities: toBase64(material.capabilities),\n    };\n    await palbeRequest<EnrollResponse>(rt, 'POST', MessagingPaths.keydirDevices, { body });\n    await deviceStore.save(engine.userId, deviceId);\n  }\n\n  if (keyPackageCount > 0) {\n    const raws: string[] = [];\n    for (let i = 0; i < keyPackageCount; i++) {\n      raws.push(toBase64(await engine.generateKeyPackage()));\n    }\n    await replenish(rt, deviceId, raws);\n  }\n  return deviceId;\n}\n\n/** Publish more one-use KeyPackages for a device. */\nexport async function replenish(\n  rt: PalbeRuntime,\n  deviceId: string,\n  rawKeyPackagesB64: string[],\n): Promise<void> {\n  const body: ReplenishBody = { key_packages: rawKeyPackagesB64 };\n  await palbeRequest<void>(rt, 'POST', MessagingPaths.keydirDeviceKeyPackages(deviceId), { body });\n}\n\n/** Claim a peer's KeyPackages (one per device) to add them to a group. */\nexport async function claimKeyPackages(rt: PalbeRuntime, userId: string): Promise<ClaimResponse> {\n  return palbeRequest<ClaimResponse>(rt, 'POST', MessagingPaths.keydirUserClaim(userId), {\n    body: {},\n  });\n}\n\n/** List a user's enrolled devices (for the safety number + roster resolution). */\nexport async function listDevices(rt: PalbeRuntime, userId: string): Promise<DeviceListResponse> {\n  return palbeRequest<DeviceListResponse>(rt, 'GET', MessagingPaths.keydirUserDevices(userId));\n}\n\n/** Record a TOFU verify pin for a peer's current device set. */\nexport async function verifyPeer(\n  rt: PalbeRuntime,\n  peerUserId: string,\n  verifiedDeviceSetHash: string,\n): Promise<void> {\n  const body: VerifyBody = {\n    peer_user_id: peerUserId,\n    verified_device_set_hash: verifiedDeviceSetHash,\n  };\n  await palbeRequest<void>(rt, 'POST', MessagingPaths.keydirPinsVerify, { body });\n}\n","// The membership/send orchestrator — the web mirror of iOS GroupMessaging.\n// Two correctness invariants (design §3, identical to iOS):\n//\n//  (1) ATOMIC-PERSIST AROUND A COMMIT. Stage a pending commit in the engine,\n//      POST it, apply ONLY on a 200. On a 409 epoch_conflict clearPendingCommit —\n//      the local epoch is NEVER ahead of the server-accepted epoch.\n//  (2) THE STALE-EPOCH REBASE LOOP. On 409 drain the winning commits, rebuild at\n//      the new epoch, re-POST — bounded + jittered. Exhaustion throws.\n//\n// sendMessage NEVER rebases: an application message is epoch-bound; a 422\n// stale_application surfaces to the caller (re-send after the delivery source\n// catches up). Only membership COMMITS rebase.\n//\n// WEB GAP vs iOS: there is no MLS exporter export in the WASM surface yet, so\n// the group NAME is not sealed (metadata omitted; the server stays blind and the\n// UI falls back to a friendly label). Text/membership flows are byte-identical.\n\nimport { BackendError, isBackendError } from '../errors.js';\nimport { palbeRequest } from '../request.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport type { MessageStore, StoredMessage } from './history.js';\nimport { claimKeyPackages } from './keydir.js';\nimport type { MlsEngine } from './mls-engine.js';\nimport type { ResolvedReply, SentReceipt } from './types.js';\nimport {\n  decodeUtf8,\n  deviceIdBytes,\n  encodeUtf8,\n  fromBase64,\n  directKey as makeDirectKey,\n  mintClientMsgId,\n  randomId,\n  toBase64,\n} from './util.js';\nimport {\n  type AddMemberBody,\n  type ClaimResponse,\n  type CommitAccepted,\n  ContentType,\n  type CreateDirectGroupBody,\n  type CreateDirectGroupResponse,\n  type CreateGroupBody,\n  type CreateGroupResponse,\n  type ListMembersResponse,\n  MessagingPaths,\n  type QueuePage,\n  type RemoveMembersBody,\n  type SendMessageBody,\n  type WelcomeBody,\n  type SentReceipt as WireReceipt,\n} from './wire.js';\n\n/** A resolved group as the SDK tracks it. `name` is always null on web (no exporter). */\nexport interface MessagingGroup {\n  displayId: string;\n  rfcGroupId: string; // base64 routing key\n  currentEpoch: number;\n  ownerUserId: string | null;\n  directKey: string | null;\n  name: string | null;\n}\n\nexport interface QuotePreview {\n  kind: string;\n  author_user_id: string;\n  body?: string;\n  body_truncated: boolean;\n}\nexport interface ReplyRef {\n  v: number;\n  client_msg_id: string;\n  preview?: QuotePreview;\n}\n\n/** A single mention range inside a message body.\n * Offsets are UTF-16 code units, half-open [start, start+length).\n * Wire: snake_case (mentioned_user_id, body_ranges) — web does RAW JSON, no case-convert.\n */\nexport interface MentionRange {\n  start: number;\n  length: number;\n  mentionedUserId: string;\n}\n\n/** The typed E2E message envelope (matches the iOS wire format exactly). */\ninterface MsgEnvelope {\n  v: 1;\n  type: 'text';\n  client_msg_id: string;\n  text: string;\n  reply_to?: ReplyRef;\n  body_ranges?: Array<{ start: number; length: number; mentioned_user_id: string }>;\n  // Per-message TTL — sender_send_ts present IFF start === 'send' (raw snake_case wire).\n  expiry?: { v: number; ttl_seconds: number; start: 'send' | 'read'; sender_send_ts?: number };\n}\n\nexport interface ReactionPayload {\n  targetClientMsgId: string;\n  emoji: string;\n  op: 'add' | 'remove';\n}\n\nexport interface EditPayload {\n  targetClientMsgId: string;\n  newText: string;\n}\n\nexport interface DeletePayload {\n  targetClientMsgId: string;\n  scope: string;\n}\n\n/** Per-message TTL spec (decoded). senderSendTs present iff start === 'send'. */\nexport interface ExpirySpec {\n  v: number;\n  ttlSeconds: number;\n  start: 'send' | 'read';\n  senderSendTs: number | null;\n}\n\n/** Encode a delete event into the wire envelope bytes. */\nexport function encodeDelete(args: { clientMsgId: string; targetClientMsgId: string }): Uint8Array {\n  return encodeUtf8(\n    JSON.stringify({\n      v: 1,\n      type: 'delete',\n      client_msg_id: args.clientMsgId,\n      target_client_msg_id: args.targetClientMsgId,\n      scope: 'everyone',\n    }),\n  );\n}\n\n/** Encode an edit event into the wire envelope bytes. */\nexport function encodeEdit(args: {\n  clientMsgId: string;\n  targetClientMsgId: string;\n  newText: string;\n  bodyRanges?: MentionRange[] | null;\n}): Uint8Array {\n  return encodeUtf8(\n    JSON.stringify({\n      v: 1,\n      type: 'edit',\n      client_msg_id: args.clientMsgId,\n      target_client_msg_id: args.targetClientMsgId,\n      new_text: args.newText,\n      ...(args.bodyRanges && args.bodyRanges.length > 0\n        ? {\n            body_ranges: args.bodyRanges.map((r) => ({\n              start: r.start,\n              length: r.length,\n              mentioned_user_id: r.mentionedUserId,\n            })),\n          }\n        : {}),\n    }),\n  );\n}\n\n/** Encode a reaction event into the wire envelope bytes. */\nexport function encodeReaction(args: {\n  clientMsgId: string;\n  targetClientMsgId: string;\n  emoji: string;\n  op: 'add' | 'remove';\n}): Uint8Array {\n  return encodeUtf8(\n    JSON.stringify({\n      v: 1,\n      type: 'reaction',\n      client_msg_id: args.clientMsgId,\n      target_client_msg_id: args.targetClientMsgId,\n      emoji: args.emoji,\n      op: args.op,\n    }),\n  );\n}\n\n/** Encode a text message into the wire envelope bytes. */\nexport function encodeEnvelope(args: {\n  text: string;\n  clientMsgId: string;\n  replyTo?: ReplyRef | null;\n  bodyRanges?: MentionRange[] | null;\n  expiry?: ExpirySpec | null;\n}): Uint8Array {\n  const env: MsgEnvelope = {\n    v: 1,\n    type: 'text',\n    client_msg_id: args.clientMsgId,\n    text: args.text,\n    ...(args.replyTo ? { reply_to: args.replyTo } : {}),\n    ...(args.bodyRanges && args.bodyRanges.length > 0\n      ? {\n          body_ranges: args.bodyRanges.map((r) => ({\n            start: r.start,\n            length: r.length,\n            mentioned_user_id: r.mentionedUserId,\n          })),\n        }\n      : {}),\n    ...(args.expiry\n      ? {\n          expiry: {\n            v: args.expiry.v,\n            ttl_seconds: args.expiry.ttlSeconds,\n            start: args.expiry.start,\n            // present IFF send (drop a stray senderSendTs on a read anchor)\n            ...(args.expiry.start === 'send' && args.expiry.senderSendTs != null\n              ? { sender_send_ts: args.expiry.senderSendTs }\n              : {}),\n          },\n        }\n      : {}),\n  };\n  return encodeUtf8(JSON.stringify(env));\n}\n\n/** Encode a per-chat default disappearing-timer control envelope. ttlSeconds === null\n * disables the chat default; it is OMITTED from the wire (absent === null === disable). */\nexport function encodeTimerSet(args: {\n  clientMsgId: string;\n  ttlSeconds: number | null;\n  start: 'send' | 'read';\n}): Uint8Array {\n  return encodeUtf8(\n    JSON.stringify({\n      v: 1,\n      type: 'timer_set',\n      client_msg_id: args.clientMsgId,\n      ...(args.ttlSeconds != null ? { ttl_seconds: args.ttlSeconds } : {}),\n      start: args.start,\n    }),\n  );\n}\n\n/** Decode an application plaintext (tolerant: bare-text or missing-v → legacy fallback). */\nexport function decodeEnvelope(bytes: Uint8Array): {\n  type?: string;\n  text: string | null;\n  clientMsgId: string;\n  replyTo: ReplyRef | null;\n  reaction?: ReactionPayload;\n  edit?: EditPayload;\n  delete?: DeletePayload;\n  bodyRanges?: MentionRange[];\n  expiry?: ExpirySpec;\n  timer?: { ttlSeconds: number | null; start: 'send' | 'read' };\n} {\n  const s = decodeUtf8(bytes);\n  try {\n    const o = JSON.parse(s) as {\n      type?: string;\n      v?: number;\n      text?: string;\n      client_msg_id?: string;\n      reply_to?: ReplyRef;\n      target_client_msg_id?: string;\n      emoji?: string;\n      op?: string;\n      new_text?: string;\n      scope?: string;\n      body_ranges?: Array<{ start: number; length: number; mentioned_user_id: string }>;\n      expiry?: unknown;\n      ttl_seconds?: number;\n      sender_send_ts?: number;\n      start?: string;\n    };\n    if (typeof o === 'object' && o !== null && o.type === 'timer_set') {\n      // timer_set control envelope — ttl_seconds absent === null === disable.\n      return {\n        type: 'timer_set',\n        text: null,\n        clientMsgId: o.client_msg_id ?? '',\n        replyTo: null,\n        timer: {\n          ttlSeconds: typeof o.ttl_seconds === 'number' ? o.ttl_seconds : null,\n          start: o.start === 'read' ? 'read' : 'send',\n        },\n      };\n    }\n    if (typeof o === 'object' && o !== null && o.type === 'delete') {\n      // Delete envelope.\n      return {\n        type: 'delete',\n        text: null,\n        clientMsgId: o.client_msg_id ?? '',\n        replyTo: null,\n        delete: {\n          targetClientMsgId: o.target_client_msg_id ?? '',\n          scope: o.scope ?? 'everyone',\n        },\n      };\n    }\n    if (typeof o === 'object' && o !== null && o.type === 'reaction') {\n      // Reaction envelope.\n      return {\n        type: 'reaction',\n        text: null,\n        clientMsgId: o.client_msg_id ?? '',\n        replyTo: null,\n        reaction: {\n          targetClientMsgId: o.target_client_msg_id ?? '',\n          emoji: o.emoji ?? '',\n          op: (o.op as 'add' | 'remove') ?? 'add',\n        },\n      };\n    }\n    if (typeof o === 'object' && o !== null && o.type === 'edit') {\n      // Edit envelope.\n      const editRanges = decodeBodyRanges(o.body_ranges);\n      return {\n        type: 'edit',\n        text: null,\n        clientMsgId: o.client_msg_id ?? '',\n        replyTo: null,\n        edit: {\n          targetClientMsgId: o.target_client_msg_id ?? '',\n          newText: o.new_text ?? '',\n        },\n        ...(editRanges ? { bodyRanges: editRanges } : {}),\n      };\n    }\n    if (typeof o === 'object' && o !== null && o.type === 'text' && typeof o.v === 'number') {\n      // Full v:1 envelope — extract all fields.\n      const textRanges = decodeBodyRanges(o.body_ranges);\n      const expiry = decodeExpiry(o.expiry);\n      return {\n        type: 'text',\n        text: o.text ?? null,\n        clientMsgId: o.client_msg_id ?? '',\n        replyTo: o.reply_to ?? null,\n        ...(textRanges ? { bodyRanges: textRanges } : {}),\n        ...(expiry ? { expiry } : {}),\n      };\n    }\n    if (typeof o === 'object' && o !== null && o.type === 'text') {\n      // Legacy envelope (no v) — extract text, no reply context.\n      return { type: 'text', text: o.text ?? null, clientMsgId: '', replyTo: null };\n    }\n    // A media envelope (not yet supported on web) → no text.\n    if (typeof o === 'object' && o !== null && o.type === 'media')\n      return { type: 'media', text: null, clientMsgId: '', replyTo: null };\n  } catch {\n    // legacy/bare plaintext\n  }\n  return { text: s, clientMsgId: '', replyTo: null };\n}\n\n/** Map a raw wire expiry object (snake_case) to ExpirySpec. Returns undefined if absent\n * or malformed (no ttl_seconds) — an old decoder with this branch stripped ignores it. */\nfunction decodeExpiry(raw: unknown): ExpirySpec | undefined {\n  if (typeof raw !== 'object' || raw === null) return undefined;\n  const o = raw as { v?: number; ttl_seconds?: number; start?: string; sender_send_ts?: number };\n  if (typeof o.ttl_seconds !== 'number') return undefined;\n  const start: 'send' | 'read' = o.start === 'read' ? 'read' : 'send';\n  return {\n    v: typeof o.v === 'number' ? o.v : 1,\n    ttlSeconds: o.ttl_seconds,\n    start,\n    // tolerant: only honor sender_send_ts on a send anchor; null otherwise.\n    senderSendTs:\n      start === 'send' && typeof o.sender_send_ts === 'number' ? o.sender_send_ts : null,\n  };\n}\n\n/** Map raw wire body_ranges (snake_case) to MentionRange[]. Returns undefined if absent or empty. */\nfunction decodeBodyRanges(\n  raw: Array<{ start: number; length: number; mentioned_user_id: string }> | undefined | null,\n): MentionRange[] | undefined {\n  if (!raw || raw.length === 0) return undefined;\n  return raw.map((r) => ({\n    start: r.start,\n    length: r.length,\n    mentionedUserId: r.mentioned_user_id,\n  }));\n}\n\n/**\n * Resolve a reply reference against local history.\n *\n * `lookup(clientMsgId)` should return `{ text, senderUserId }` when the parent\n * is in local history, or `null` when not found.\n *\n * Spoof defense: when the parent IS found, the REAL text from local history wins\n * over the embedded `preview.body` — an attacker cannot make a reply appear to\n * quote different text than what was actually sent.\n */\nexport function resolveReply(\n  ref: ReplyRef,\n  lookup: (clientMsgId: string) => { text: string; senderUserId: string } | null,\n): ResolvedReply {\n  const parent = lookup(ref.client_msg_id);\n  if (parent !== null) {\n    return {\n      parentClientMsgId: ref.client_msg_id,\n      state: 'resolved',\n      quoteSenderUserId: parent.senderUserId,\n      quoteText: parent.text,\n      quoteKind: ref.preview?.kind ?? 'text',\n    };\n  }\n  return {\n    parentClientMsgId: ref.client_msg_id,\n    state: 'unavailable',\n    quoteSenderUserId: ref.preview?.author_user_id ?? '',\n    quoteText: ref.preview?.body ?? null,\n    quoteKind: ref.preview?.kind ?? 'text',\n  };\n}\n\nexport interface RebaseOptions {\n  maxAttempts: number;\n  baseDelayMs: number;\n  jitterMs: number;\n}\n\nconst DEFAULT_REBASE: RebaseOptions = { maxAttempts: 6, baseDelayMs: 80, jitterMs: 120 };\n\n/** Thrown when the rebase loop exhausts its budget (the change did NOT land). */\nexport class RebaseExhausted extends Error {\n  constructor(\n    readonly attempts: number,\n    readonly lastKnownEpoch: number | null,\n  ) {\n    super(`commit rebase exhausted after ${attempts} attempts`);\n    this.name = 'RebaseExhausted';\n  }\n}\n\nexport class GroupMessaging {\n  constructor(\n    private readonly rt: PalbeRuntime,\n    private readonly engine: MlsEngine,\n    private readonly selfUserId: string,\n    private readonly selfDeviceId: string,\n    private readonly messageStore: MessageStore,\n    private readonly rebase: RebaseOptions = DEFAULT_REBASE,\n  ) {}\n\n  // ── Create ──\n\n  /** Create a group: mint the rfc_group_id, POST create, return the server group.\n   * No name sealing on web (metadata omitted — server-blind, label fallback). */\n  async createGroup(cipherSuite = 1): Promise<MessagingGroup> {\n    const rfcGroupId = await this.engine.createGroup();\n    const body: CreateGroupBody = {\n      rfc_group_id: toBase64(rfcGroupId),\n      cipher_suite: cipherSuite,\n      creator_device_id: this.selfDeviceId,\n      creator_leaf_index: 0,\n    };\n    const res = await palbeRequest<CreateGroupResponse>(this.rt, 'POST', MessagingPaths.groups, {\n      body,\n    });\n    return {\n      displayId: res.display_id,\n      rfcGroupId: res.rfc_group_id,\n      currentEpoch: res.current_epoch,\n      ownerUserId: this.selfUserId,\n      directKey: null,\n      name: null,\n    };\n  }\n\n  // ── Direct (1:1) get-or-create ──\n\n  /** Materialize a DIRECT chat keyed by the stable direct_key (sorted user pair).\n   * EXISTS → adopt (the Welcome drains via the pump); ABSENT → create + add peer. */\n  async getOrCreateDirect(peerUserId: string): Promise<MessagingGroup> {\n    const dk = makeDirectKey(this.selfUserId, peerUserId);\n    const rfcGroupId = await this.engine.createGroup(); // reserved (used only if INSERT)\n    const body: CreateDirectGroupBody = {\n      direct_key: dk,\n      peer_user_id: peerUserId,\n      rfc_group_id: toBase64(rfcGroupId),\n      cipher_suite: 1,\n      creator_device_id: this.selfDeviceId,\n      creator_leaf_index: 0,\n    };\n    const res = await palbeRequest<CreateDirectGroupResponse>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupsDirect,\n      { body },\n    );\n\n    if (res.exists === true) {\n      // ADOPT — discard the reserved group; the founder's Welcome drains in.\n      await this.engine.clearPendingCommit(rfcGroupId);\n      return {\n        displayId: res.display_id,\n        rfcGroupId: res.rfc_group_id,\n        currentEpoch: res.current_epoch,\n        ownerUserId: res.owner_user_id ?? null,\n        directKey: dk,\n        name: null,\n      };\n    }\n\n    // CREATE branch — the server bound the group to direct_key; add the peer.\n    const group: MessagingGroup = {\n      displayId: res.display_id,\n      rfcGroupId: res.rfc_group_id,\n      currentEpoch: res.current_epoch,\n      ownerUserId: this.selfUserId,\n      directKey: dk,\n      name: null,\n    };\n    const claimed = await claimKeyPackages(this.rt, peerUserId);\n    await this.addMember(group, peerUserId, claimed);\n    return group;\n  }\n\n  // ── Members ──\n\n  /** The group roster (device leaves). The coordinator dedups to users. */\n  async listMembers(displayId: string): Promise<ListMembersResponse['members']> {\n    const res = await palbeRequest<ListMembersResponse>(\n      this.rt,\n      'GET',\n      MessagingPaths.groupMembers(displayId),\n    );\n    return res.members;\n  }\n\n  /** Add a member: claim → stage the add commit → run the rebase loop. SP-1.6:\n   * EVERY device of the user joins in ONE atomic commit (one shared Welcome). */\n  async addMember(group: MessagingGroup, userId: string, claimed?: ClaimResponse): Promise<void> {\n    const claim = claimed ?? (await claimKeyPackages(this.rt, userId));\n    const adds = claim.key_packages\n      .map((kp) => {\n        try {\n          return { deviceId: kp.device_id, kp: fromBase64(kp.key_package) };\n        } catch {\n          return null;\n        }\n      })\n      .filter((x): x is { deviceId: string; kp: Uint8Array } => x !== null);\n    if (adds.length === 0) {\n      throw new BackendError('validation', {\n        code: 'no_keypackage',\n        message: 'no claimable key package for user',\n        status: 422,\n      });\n    }\n    const userIds = adds.map(() => userId);\n\n    await this.commitWithRebase(group.rfcGroupId, async () => {\n      const out = await this.engine.commitChanges(\n        fromBase64(group.rfcGroupId),\n        adds.map((a) => a.kp),\n        [],\n      );\n      // One shared Welcome per added device (the engine returns one welcome for a\n      // single-Welcome multi-add; route it to each added device).\n      const welcomeB64 = out.welcome ? toBase64(out.welcome) : '';\n      const welcomes: WelcomeBody[] = adds.map((a) => ({\n        recipient_device_id: a.deviceId,\n        recipient_user_id: userId,\n        welcome_b64: welcomeB64,\n      }));\n      const memberBody: AddMemberBody = {\n        op: 'add',\n        commit_b64: toBase64(out.commit),\n        target_device_ids: adds.map((a) => a.deviceId),\n        leaf_indexes: out.addedLeafIndices,\n        user_ids: userIds,\n        key_package_refs: [],\n        welcomes,\n      };\n      return {\n        method: 'POST',\n        path: MessagingPaths.groupMembers(group.displayId),\n        body: memberBody,\n      };\n    });\n  }\n\n  /** Remove a user = evict ALL their device leaves in ONE commit (SP-1.6 D4). */\n  async removeMember(group: MessagingGroup, userId: string): Promise<void> {\n    const members = await this.listMembers(group.displayId);\n    const deviceIds = members.filter((m) => m.user_id === userId).map((m) => m.device_id);\n    if (deviceIds.length === 0) {\n      throw new BackendError('validation', {\n        code: 'not_a_member',\n        message: 'user has no device in this group',\n        status: 404,\n      });\n    }\n    await this.stageMultiRemove(group, deviceIds, [userId]);\n  }\n\n  /** Leave = remove the CALLING device's leaf only (per-device self-leave). */\n  async leaveGroup(group: MessagingGroup): Promise<void> {\n    await this.stageMultiRemove(group, [this.selfDeviceId], [this.selfUserId]);\n  }\n\n  private async stageMultiRemove(\n    group: MessagingGroup,\n    deviceIds: string[],\n    removedUserIds: string[],\n  ): Promise<void> {\n    const pathDeviceId = deviceIds[0];\n    if (!pathDeviceId) throw new Error('no device to remove');\n    await this.commitWithRebase(group.rfcGroupId, async () => {\n      const out = await this.engine.commitChanges(\n        fromBase64(group.rfcGroupId),\n        [],\n        deviceIds.map(deviceIdBytes),\n      );\n      const body: RemoveMembersBody = {\n        op: 'remove',\n        commit_b64: toBase64(out.commit),\n        target_device_ids: deviceIds,\n        user_ids: removedUserIds,\n      };\n      return {\n        method: 'DELETE',\n        path: MessagingPaths.groupMemberDevice(group.displayId, pathDeviceId),\n        body,\n      };\n    });\n  }\n\n  // ── Send ──\n\n  /** Send a text message. Encrypt at the current epoch, POST, return the receipt +\n   * the client-minted `clientMsgId` (needed by the Chat layer for reply indexing).\n   * NEVER rebases (a 422 stale_application surfaces to the caller). */\n  async sendText(\n    group: MessagingGroup,\n    text: string,\n    replyTo?: ReplyRef | null,\n    bodyRanges?: MentionRange[] | null,\n    expiry?: ExpirySpec | null,\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const clientMsgId = mintClientMsgId();\n    const plaintext = encodeEnvelope({ text, clientMsgId, replyTo, bodyRanges, expiry });\n    const ct = await this.engine.encryptApplication(fromBase64(group.rfcGroupId), plaintext);\n    const body: SendMessageBody = {\n      ciphertext_b64: toBase64(ct),\n      client_idem_key: randomId(),\n    };\n    const wire = await palbeRequest<WireReceipt>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupMessages(group.displayId),\n      { body },\n    );\n\n    // Persist the OUTGOING copy — the ONLY durable form of an own-sent message\n    // (the sender can never decrypt its own ciphertext). Best-effort: the send\n    // already landed; a persist failure must not fail/re-trigger it.\n    const stored: StoredMessage = {\n      id: `${group.rfcGroupId}#${wire.server_seq}`,\n      direction: 'outgoing',\n      text,\n      senderDeviceId: this.selfDeviceId,\n      epoch: wire.epoch,\n      serverSeq: wire.server_seq,\n      at: Date.now(),\n      clientMsgId,\n      replyTo: replyTo\n        ? {\n            clientMsgId: replyTo.client_msg_id,\n            previewBody: replyTo.preview?.body ?? null,\n            previewAuthorUserId: replyTo.preview?.author_user_id ?? null,\n            previewKind: replyTo.preview?.kind ?? 'text',\n          }\n        : null,\n      // Persist the OUTGOING bubble's mention ranges so an own-sent mention re-resolves\n      // onto its bubble after a reload (own-send reload parity — the T4-reviewer Minor).\n      ...(bodyRanges && bodyRanges.length > 0 ? { bodyRanges } : {}),\n      // Disappearing T10: persist the per-message TTL so the own-send re-arms its purge\n      // after a cold launch (the projection derives the deadline from this row's expiry).\n      ...(expiry ? { expiry } : {}),\n    };\n    try {\n      await this.messageStore.append(group.rfcGroupId, stored);\n    } catch {\n      // logged at the coordinator level; never fails the send\n    }\n    return { receipt: { serverSeq: wire.server_seq, epoch: wire.epoch }, clientMsgId };\n  }\n\n  /** Send a per-chat default disappearing-timer control envelope (`timer_set`). Encrypts\n   * a `type:'timer_set'` envelope at the current epoch and sends through the SAME MLS\n   * application path as `sendText` (the server stays blind — it's an opaque app message,\n   * NEVER a bubble). `ttlSeconds === null` disables the default (omitted from the wire).\n   * Persists the outgoing `timer_set` row so the chat default re-folds on cold launch\n   * (the page-local TimerFold in projectHistory). NEVER rebases (epoch-bound). */\n  async sendTimerSet(\n    group: MessagingGroup,\n    args: { clientMsgId: string; ttlSeconds: number | null; start: 'send' | 'read' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const plaintext = encodeTimerSet({\n      clientMsgId: args.clientMsgId,\n      ttlSeconds: args.ttlSeconds,\n      start: args.start,\n    });\n    const ct = await this.engine.encryptApplication(fromBase64(group.rfcGroupId), plaintext);\n    const body: SendMessageBody = {\n      ciphertext_b64: toBase64(ct),\n      client_idem_key: randomId(),\n    };\n    const wire = await palbeRequest<WireReceipt>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupMessages(group.displayId),\n      { body },\n    );\n\n    // Persist the OUTGOING timer_set copy (same rationale as sendText: the sender can't\n    // decrypt its own ciphertext). text is null — a timer_set is never a bubble; the\n    // envelopeType + timer fields drive the chat-default re-fold on reload.\n    const stored: StoredMessage = {\n      id: `${group.rfcGroupId}#${wire.server_seq}`,\n      direction: 'outgoing',\n      text: null,\n      senderDeviceId: this.selfDeviceId,\n      epoch: wire.epoch,\n      serverSeq: wire.server_seq,\n      at: Date.now(),\n      clientMsgId: args.clientMsgId,\n      replyTo: null,\n      envelopeType: 'timer_set',\n      timer: { ttlSeconds: args.ttlSeconds, start: args.start },\n    };\n    try {\n      await this.messageStore.append(group.rfcGroupId, stored);\n    } catch {\n      // best-effort, identical to sendText/sendReaction/sendEdit/sendDelete\n    }\n    return {\n      receipt: { serverSeq: wire.server_seq, epoch: wire.epoch },\n      clientMsgId: args.clientMsgId,\n    };\n  }\n\n  /** Send a reaction (add/remove of an emoji on a target message). Encrypts a\n   * `type:'reaction'` envelope at the current epoch and sends through the SAME\n   * MLS application path as `sendText` (the server stays blind — a reaction is\n   * just another application message). Persists the outgoing reaction row so it\n   * re-folds onto its target after a reload (the own-send half of the reload\n   * parity). NEVER rebases (epoch-bound like any application message). */\n  async sendReaction(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string; emoji: string; op: 'add' | 'remove' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const plaintext = encodeReaction({\n      clientMsgId: args.clientMsgId,\n      targetClientMsgId: args.targetClientMsgId,\n      emoji: args.emoji,\n      op: args.op,\n    });\n    const ct = await this.engine.encryptApplication(fromBase64(group.rfcGroupId), plaintext);\n    const body: SendMessageBody = {\n      ciphertext_b64: toBase64(ct),\n      client_idem_key: randomId(),\n    };\n    const wire = await palbeRequest<WireReceipt>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupMessages(group.displayId),\n      { body },\n    );\n\n    // Persist the OUTGOING reaction copy (same rationale as sendText: the sender\n    // can't decrypt its own ciphertext). text is null — a reaction is never a\n    // bubble; the envelopeType + reaction fields drive the re-fold on reload.\n    const stored: StoredMessage = {\n      id: `${group.rfcGroupId}#${wire.server_seq}`,\n      direction: 'outgoing',\n      text: null,\n      senderDeviceId: this.selfDeviceId,\n      epoch: wire.epoch,\n      serverSeq: wire.server_seq,\n      at: Date.now(),\n      clientMsgId: args.clientMsgId,\n      replyTo: null,\n      envelopeType: 'reaction',\n      reaction: {\n        targetClientMsgId: args.targetClientMsgId,\n        emoji: args.emoji,\n        op: args.op,\n      },\n    };\n    try {\n      await this.messageStore.append(group.rfcGroupId, stored);\n    } catch {\n      // best-effort, identical to sendText\n    }\n    return {\n      receipt: { serverSeq: wire.server_seq, epoch: wire.epoch },\n      clientMsgId: args.clientMsgId,\n    };\n  }\n\n  /** Send an edit (edit-by-supersession on a target message). Encrypts a\n   * `type:'edit'` envelope at the current epoch and sends through the SAME MLS\n   * application path as `sendText` (the server stays blind — an edit is just\n   * another application message). Persists the outgoing edit row so it re-folds\n   * onto its target's text after a reload (the own-send half of the reload\n   * parity). NEVER rebases (epoch-bound like any application message). */\n  async sendEdit(\n    group: MessagingGroup,\n    args: {\n      clientMsgId: string;\n      targetClientMsgId: string;\n      newText: string;\n      bodyRanges?: MentionRange[] | null;\n    },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const plaintext = encodeEdit({\n      clientMsgId: args.clientMsgId,\n      targetClientMsgId: args.targetClientMsgId,\n      newText: args.newText,\n      bodyRanges: args.bodyRanges,\n    });\n    const ct = await this.engine.encryptApplication(fromBase64(group.rfcGroupId), plaintext);\n    const body: SendMessageBody = {\n      ciphertext_b64: toBase64(ct),\n      client_idem_key: randomId(),\n    };\n    const wire = await palbeRequest<WireReceipt>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupMessages(group.displayId),\n      { body },\n    );\n\n    // Persist the OUTGOING edit copy (same rationale as sendText: the sender can't\n    // decrypt its own ciphertext). text is null — an edit is never a bubble; the\n    // envelopeType + edit fields drive the re-fold onto the target on reload.\n    const stored: StoredMessage = {\n      id: `${group.rfcGroupId}#${wire.server_seq}`,\n      direction: 'outgoing',\n      text: null,\n      senderDeviceId: this.selfDeviceId,\n      epoch: wire.epoch,\n      serverSeq: wire.server_seq,\n      at: Date.now(),\n      clientMsgId: args.clientMsgId,\n      replyTo: null,\n      envelopeType: 'edit',\n      edit: {\n        targetClientMsgId: args.targetClientMsgId,\n        newText: args.newText,\n        // Persist the edit's REPLACEMENT ranges so the edited message's mentions\n        // re-resolve from this edit after a reload (own-send reload parity — T6).\n        ...(args.bodyRanges && args.bodyRanges.length > 0 ? { bodyRanges: args.bodyRanges } : {}),\n      },\n    };\n    try {\n      await this.messageStore.append(group.rfcGroupId, stored);\n    } catch {\n      // best-effort, identical to sendText/sendReaction\n    }\n    return {\n      receipt: { serverSeq: wire.server_seq, epoch: wire.epoch },\n      clientMsgId: args.clientMsgId,\n    };\n  }\n\n  /** Send a delete-for-everyone tombstone on a target message. Encrypts a\n   * `type:'delete'` envelope at the current epoch and sends through the SAME MLS\n   * application path as `sendText` (the server stays blind — a delete is just\n   * another opaque application message; the original ciphertext row is NOT\n   * removed). Persists the outgoing delete row so the tombstone re-folds onto its\n   * target after a reload (the own-send half of the reload parity — the iOS-review\n   * CRITICAL boundary; the projection's `.delete` branch re-folds it). NEVER\n   * rebases (epoch-bound like any application message). */\n  async sendDelete(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const plaintext = encodeDelete({\n      clientMsgId: args.clientMsgId,\n      targetClientMsgId: args.targetClientMsgId,\n    });\n    const ct = await this.engine.encryptApplication(fromBase64(group.rfcGroupId), plaintext);\n    const body: SendMessageBody = {\n      ciphertext_b64: toBase64(ct),\n      client_idem_key: randomId(),\n    };\n    const wire = await palbeRequest<WireReceipt>(\n      this.rt,\n      'POST',\n      MessagingPaths.groupMessages(group.displayId),\n      { body },\n    );\n\n    // Persist the OUTGOING delete copy (same rationale as sendText: the sender can't\n    // decrypt its own ciphertext). text is null — a delete is never a bubble; the\n    // envelopeType + delete fields drive the re-fold onto the target on reload.\n    const stored: StoredMessage = {\n      id: `${group.rfcGroupId}#${wire.server_seq}`,\n      direction: 'outgoing',\n      text: null,\n      senderDeviceId: this.selfDeviceId,\n      epoch: wire.epoch,\n      serverSeq: wire.server_seq,\n      at: Date.now(),\n      clientMsgId: args.clientMsgId,\n      replyTo: null,\n      envelopeType: 'delete',\n      delete: {\n        targetClientMsgId: args.targetClientMsgId,\n        scope: 'everyone',\n      },\n    };\n    try {\n      await this.messageStore.append(group.rfcGroupId, stored);\n    } catch {\n      // best-effort, identical to sendText/sendReaction/sendEdit\n    }\n    return {\n      receipt: { serverSeq: wire.server_seq, epoch: wire.epoch },\n      clientMsgId: args.clientMsgId,\n    };\n  }\n\n  // ── The rebase loop ──\n\n  private async commitWithRebase(\n    rfcGroupId: string,\n    build: () => Promise<{ method: string; path: string; body: unknown }>,\n  ): Promise<void> {\n    const gidBytes = fromBase64(rfcGroupId);\n    let lastEpoch: number | null = null;\n    for (let attempt = 1; attempt <= this.rebase.maxAttempts; attempt++) {\n      const pending = await build();\n      try {\n        await palbeRequest<CommitAccepted>(this.rt, pending.method, pending.path, {\n          body: pending.body,\n        });\n        await this.engine.applyPendingCommit(gidBytes);\n        return;\n      } catch (e) {\n        if (isBackendError(e) && e.code === 'epoch_conflict') {\n          await this.engine.clearPendingCommit(gidBytes);\n          const ce = (e.data as { current_epoch?: number } | undefined)?.current_epoch;\n          if (typeof ce === 'number') lastEpoch = ce;\n          if (attempt === this.rebase.maxAttempts) break;\n          await this.drain(rfcGroupId);\n          await this.backoff(attempt);\n          continue; // rebuild + re-POST\n        }\n        throw e;\n      }\n    }\n    await this.engine.clearPendingCommit(gidBytes);\n    throw new RebaseExhausted(this.rebase.maxAttempts, lastEpoch);\n  }\n\n  /** Pull the device queue, process the winning commit(s) so the engine advances\n   * to the new epoch, ack the commits (the delivery source owns app messages). */\n  private async drain(rfcGroupId: string): Promise<void> {\n    const page = await palbeRequest<QueuePage>(\n      this.rt,\n      'GET',\n      MessagingPaths.deviceQueue(this.selfDeviceId),\n    );\n    const gidBytes = fromBase64(rfcGroupId);\n    const ackIds: string[] = [];\n    for (const row of page.messages) {\n      if (row.content_type !== ContentType.commit) continue;\n      try {\n        await this.engine.processIncoming(gidBytes, fromBase64(row.ciphertext_b64));\n      } catch {\n        // a non-applicable commit (own / consumed) — still ack so it isn't redelivered\n      }\n      ackIds.push(row.id);\n    }\n    if (ackIds.length > 0) {\n      await palbeRequest<void>(this.rt, 'POST', MessagingPaths.deviceQueueAck(this.selfDeviceId), {\n        body: { message_ids: ackIds },\n      });\n    }\n  }\n\n  private async backoff(attempt: number): Promise<void> {\n    const base = this.rebase.baseDelayMs * attempt;\n    const jitter = this.rebase.jitterMs === 0 ? 0 : Math.random() * this.rebase.jitterMs;\n    const total = base + jitter;\n    if (total <= 0) return;\n    await new Promise((r) => setTimeout(r, total));\n  }\n}\n","import type { MentionRange } from './group-messaging.js';\n\n// Mentions (design 2026-06-20) — the PURE, deterministic decode-time normalization of\n// `body_ranges`. BOTH SDKs (iOS `Palbe` + web `@palbase/web`) apply this exact\n// algorithm bit-identically so a malformed or adversarial `body_ranges` produces the\n// SAME surviving spans on both runtimes. A cross-binding golden (T7) locks this — if\n// one SDK clamped where the other dropped, both could pass their own tests yet diverge\n// on the wire. This is a single PINNED contract, not implementer's choice.\n//\n// OFFSET UNIT = UTF-16 code units (JS string .length IS UTF-16 code units — native).\n// NEVER use [...text] (scalar/codepoint iteration) — mixing units corrupts spans over\n// emoji/surrogate pairs. Use text.length / text.charCodeAt / text.slice only.\n// The `…Utf16` suffix names the unit so an accidental scalar use is visible.\n//\n// THE EXACT ORDERED ALGORITHM (offsets are UTF-16 code units; N = text.length):\n//   1.  DROP-invalid (not clamp): drop if start < 0 || length <= 0 || start + length > N.\n//   1b. DROP-surrogate-boundary: drop if `start` OR `start+length` index falls mid\n//       surrogate pair (the unit BEFORE the index is a high surrogate 0xD800–0xDBFF AND\n//       the unit AT the index is a low surrogate 0xDC00–0xDFFF). Splitting a pair is\n//       invalid. Index 0 and index N never trigger.\n//   2.  SORT: ascending by `start`; ties broken by `length` DESCENDING (wider survives an\n//       equal-start collision); then by original index ascending (stable). Sort BEFORE\n//       the overlap walk — mandatory; walking unsorted input changes which range survives.\n//   3.  DROP-overlap (not merge) + drop-duplicate: walk left-to-right; keep a range only\n//       if its `start >= previous-KEPT range's (start+length)`; otherwise DROP it (the\n//       later overlapper). Exact duplicates fall out as a sub-case. NEVER merge.\n//\n// PURE: no I/O, never throws. A fully-invalid input returns []; the message text always\n// renders regardless. The self-mention-by-sender \"render-but-don't-elevate\" rule is NOT\n// applied here — normalize is purely structural; that gate lives at the elevation\n// decision (T3).\n\n/**\n * Deterministically normalize decode-time mention ranges per the pinned cross-SDK\n * contract (drop-invalid → drop-surrogate-boundary → sort[start asc, length DESC, idx\n * asc] → drop-overlap/duplicate). Offsets are UTF-16 code units into `text`. Pure.\n *\n * Mirrors iOS `normalizeMentionRangesUtf16` BIT-IDENTICALLY (T7 cross-binding golden\n * locks this). NEVER uses `[...text]` scalar spread — only `text.length` / `charCodeAt`.\n */\nexport function normalizeMentionRangesUtf16(ranges: MentionRange[], text: string): MentionRange[] {\n  const n = text.length; // UTF-16 code unit count — native JS string .length\n\n  // True iff splitting `text` AT `index` would cut a surrogate pair — i.e. the unit\n  // just before `index` is a high surrogate and the unit at `index` is a low surrogate.\n  // Boundary indices 0 and n are always safe (no unit before / no unit at).\n  function splitsSurrogatePair(index: number): boolean {\n    if (index <= 0 || index >= n) return false;\n    const before = text.charCodeAt(index - 1);\n    const at = text.charCodeAt(index);\n    const beforeIsHigh = before >= 0xd800 && before <= 0xdbff;\n    const atIsLow = at >= 0xdc00 && at <= 0xdfff;\n    return beforeIsHigh && atIsLow;\n  }\n\n  // Steps 1 + 1b — DROP-invalid then DROP-surrogate-boundary. Retain the original index\n  // for the stable tie-break in step 2.\n  const survivors: Array<{ idx: number; range: MentionRange }> = [];\n  for (let idx = 0; idx < ranges.length; idx++) {\n    const r = ranges[idx];\n    if (r === undefined) continue;\n    // Step 1: validity (drop, do not clamp).\n    if (r.start < 0 || r.length <= 0 || r.start + r.length > n) continue;\n    // Step 1b: surrogate-pair boundary (drop). r.start + r.length <= n is guaranteed\n    // by step 1, so both indices are in [0, n].\n    if (splitsSurrogatePair(r.start) || splitsSurrogatePair(r.start + r.length)) continue;\n    survivors.push({ idx, range: r });\n  }\n\n  // Step 2: sort ascending by start; ties by length DESCENDING (wider wins); then by\n  // original index ascending (stable). Done BEFORE the overlap walk.\n  survivors.sort((lhs, rhs) => {\n    if (lhs.range.start !== rhs.range.start) return lhs.range.start - rhs.range.start;\n    if (lhs.range.length !== rhs.range.length) return rhs.range.length - lhs.range.length; // DESC\n    return lhs.idx - rhs.idx;\n  });\n\n  // Step 3: drop the later overlapper (and exact duplicates as a sub-case) — never merge.\n  const kept: MentionRange[] = [];\n  let prevEnd = Number.NEGATIVE_INFINITY; // exclusive end of the last KEPT range\n  for (const s of survivors) {\n    if (s.range.start >= prevEnd) {\n      kept.push(s.range);\n      prevEnd = s.range.start + s.range.length;\n    }\n    // else: overlaps (or duplicates) the previous kept range → DROP.\n  }\n  return kept;\n}\n","/**\n * ReactionFold — pure fold of reaction events into a per-target emoji tally.\n *\n * Algorithm mirrors iOS `ReactionFold` (ReactionFold.swift) byte-for-byte in\n * behaviour: LWW per (target, actorUserId) on (epoch, serverSeq), idempotent\n * on eventClientMsgId.\n *\n * Tie assumption (same as iOS doc-comment):\n *   The server guarantees (epoch, serverSeq) is unique per logical event, so\n *   exact-order ties cannot occur in practice. The `<=` stale-check (first-\n *   arriving wins on an exact tie) is therefore safe. Re-delivery of the SAME\n *   logical event is already handled by the seenEvents dedup and never reaches\n *   this check.\n */\n\nexport interface ReactionEvent {\n  targetClientMsgId: string;\n  actorUserId: string;\n  emoji: string;\n  op: 'add' | 'remove';\n  epoch: number;\n  serverSeq: number;\n  /** Dedup key — unique per logical event (e.g. the reaction message's clientMsgId). */\n  eventClientMsgId: string;\n}\n\n/** Lexicographic (epoch, serverSeq) comparison. Returns true if a <= b. */\nfunction orderLte(aEpoch: number, aSeq: number, bEpoch: number, bSeq: number): boolean {\n  if (aEpoch !== bEpoch) return aEpoch < bEpoch;\n  return aSeq <= bSeq;\n}\n\ninterface UserState {\n  orderEpoch: number;\n  orderSeq: number;\n  emoji: string | null; // null = removed\n}\n\nexport class ReactionFold {\n  // Map<targetClientMsgId, Map<actorUserId, UserState>>\n  private readonly states = new Map<string, Map<string, UserState>>();\n  // Dedup set: eventClientMsgId values already applied.\n  private readonly seenEvents = new Set<string>();\n\n  ingest(e: ReactionEvent): void {\n    // Idempotency: skip if this exact event was already applied.\n    if (this.seenEvents.has(e.eventClientMsgId)) return;\n    this.seenEvents.add(e.eventClientMsgId);\n\n    let byUser = this.states.get(e.targetClientMsgId);\n    if (byUser === undefined) {\n      byUser = new Map<string, UserState>();\n      this.states.set(e.targetClientMsgId, byUser);\n    }\n\n    const prev = byUser.get(e.actorUserId);\n    if (prev !== undefined) {\n      // Stale / out-of-order: ignore if new order <= stored order.\n      if (orderLte(e.epoch, e.serverSeq, prev.orderEpoch, prev.orderSeq)) return;\n    }\n\n    byUser.set(e.actorUserId, {\n      orderEpoch: e.epoch,\n      orderSeq: e.serverSeq,\n      emoji: e.op === 'add' ? e.emoji : null,\n    });\n  }\n\n  /**\n   * Returns a tally of `{ emoji → sorted userIds[] }` for the given target\n   * message. Users whose last event was a `remove` (emoji === null) are\n   * excluded. userId arrays are sorted for deterministic output (render\n   * stability + golden tests).\n   */\n  tally(targetClientMsgId: string): Record<string, string[]> {\n    const byUser = this.states.get(targetClientMsgId);\n    if (byUser === undefined) return {};\n\n    const out = new Map<string, string[]>();\n    for (const [userId, st] of byUser) {\n      if (st.emoji === null) continue;\n      let users = out.get(st.emoji);\n      if (users === undefined) {\n        users = [];\n        out.set(st.emoji, users);\n      }\n      users.push(userId);\n    }\n\n    // Sort userId arrays for determinism (render stability + golden tests).\n    const result: Record<string, string[]> = {};\n    for (const [emoji, users] of out) {\n      result[emoji] = users.sort();\n    }\n    return result;\n  }\n}\n","/**\n * TimerFold — pure per-chat fold of `timer_set` events into ONE active default\n * cell. LWW on (epoch, serverSeq); idempotent on eventClientMsgId. Mirrors iOS\n * `TimerFold` byte-for-byte in behaviour (and reactions' (epoch,seq) machinery),\n * keyed at the chat level rather than per-target. `actorUserId` is the\n * AUTHENTICATED sender resolved upstream — never a wire field.\n */\nexport interface TimerEvent {\n  ttlSeconds: number | null;\n  start: 'send' | 'read';\n  actorUserId: string;\n  epoch: number;\n  serverSeq: number;\n  eventClientMsgId: string;\n}\n\n/** Lexicographic (epoch, serverSeq) comparison. Returns true if a <= b. */\nfunction orderLte(aEpoch: number, aSeq: number, bEpoch: number, bSeq: number): boolean {\n  if (aEpoch !== bEpoch) return aEpoch < bEpoch;\n  return aSeq <= bSeq;\n}\n\ninterface Cell {\n  orderEpoch: number;\n  orderSeq: number;\n  ttlSeconds: number | null;\n  start: 'send' | 'read';\n  actor: string;\n}\n\nexport class TimerFold {\n  private cell: Cell | null = null;\n  private readonly seenEvents = new Set<string>();\n\n  ingest(e: TimerEvent): void {\n    // Idempotency: skip if this exact event was already applied.\n    if (this.seenEvents.has(e.eventClientMsgId)) return;\n    this.seenEvents.add(e.eventClientMsgId);\n\n    // Stale / out-of-order: ignore if new order <= stored order. The server\n    // guarantees (epoch, serverSeq) is unique per logical event, so exact-order\n    // ties cannot occur in practice; first-arriving wins on an exact tie. SAME\n    // logical event re-delivery is already caught by the seenEvents dedup above.\n    if (\n      this.cell !== null &&\n      orderLte(e.epoch, e.serverSeq, this.cell.orderEpoch, this.cell.orderSeq)\n    ) {\n      return;\n    }\n    this.cell = {\n      orderEpoch: e.epoch,\n      orderSeq: e.serverSeq,\n      ttlSeconds: e.ttlSeconds,\n      start: e.start,\n      actor: e.actorUserId,\n    };\n  }\n\n  /**\n   * The active chat default, or null if no timer_set has applied.\n   * `ttlSeconds === null` means DISABLED (still applied — distinct from \"never\n   * set\"). `start` is meaningful only when ttlSeconds !== null.\n   */\n  active(): { ttlSeconds: number | null; start: 'send' | 'read' } | null {\n    if (this.cell === null) return null;\n    return { ttlSeconds: this.cell.ttlSeconds, start: this.cell.start };\n  }\n\n  /** The userId behind the winning timer_set (for the optional system line). null if unset. */\n  lastActor(): string | null {\n    return this.cell?.actor ?? null;\n  }\n}\n","// The Chat — the one object a chat screen binds to. A DM or a group, uniformly.\n// Web idiom of the iOS `@Observable Chat`: an event-emitter exposing `onChange`\n// returning an Unsubscribe (matches flags/realtime), plus snapshot getters\n// (messages/members/typing/unreadCount/lastMessage). React hooks wrap it with\n// useSyncExternalStore.\n//\n// WhatsApp-lazy: a direct/group chat opens as a `.draft` (no network); the first\n// `send` MATERIALIZES it (claim → create/get-or-create → add → register), flips\n// to `.active`, wires live subscriptions, and hydrates durable history.\n\nimport { type AnchorTriple, MonotonicClock, remainingSeconds } from './deadline-calculator.js';\nimport { DeleteFold } from './delete-fold.js';\nimport type { IncomingMessage } from './delivery-source.js';\nimport { type AuthorResolution, EditFold } from './edit-fold.js';\nimport {\n  type ExpirySpec,\n  type MentionRange,\n  type MessagingGroup,\n  type ReplyRef,\n  resolveReply,\n} from './group-messaging.js';\nimport { normalizeMentionRangesUtf16 } from './mention-ranges.js';\nimport { ReactionFold } from './reaction-fold.js';\nimport { TimerFold } from './timer-fold.js';\nimport type {\n  ChatKind,\n  ChatMember,\n  ChatMessage,\n  ChatMessageKind,\n  ChatState,\n  MessageDirection,\n  NotifyScope,\n  PresenceState,\n  ResolvedMention,\n  ResolvedReply,\n  SentReceipt,\n  UnreadView,\n  Unsubscribe,\n} from './types.js';\nimport { mintClientMsgId, truncateQuote } from './util.js';\n\n/**\n * The neutral copy shown in place of a deleted-for-everyone message. Cooperative\n * erasure — it does NOT imply cryptographic erasure (the design's honest caveat).\n * The single source of truth for the descriptor, used by BOTH the live Chat render\n * precedence and the coordinator history projection so they render identically.\n */\nexport const DELETED_DESCRIPTOR = '🚫 This message was deleted';\n\n/** The intended participants of a draft chat (held until the first send). */\nexport interface ChatDraft {\n  mode: { kind: 'direct'; peerUserId: string } | { kind: 'group'; members: string[] };\n  /** The reserved local id a draft shows before it materializes. */\n  reservedId: string;\n}\n\n/** The seam the Chat talks to for the work needing the resolved machinery. */\nexport interface ChatBackend {\n  selfUserId: string;\n  /** Materialize a draft → the active group (DM get-or-create / group create+add). */\n  materialize(draft: ChatDraft): Promise<MessagingGroup>;\n  sendText(\n    group: MessagingGroup,\n    text: string,\n    replyTo?: ReplyRef | null,\n    bodyRanges?: MentionRange[] | null,\n    expiry?: ExpirySpec | null,\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }>;\n  /** Send a reaction (add/remove an emoji on a target message) through the same\n   * MLS application path as `sendText`. Returns the receipt + the wire clientMsgId. */\n  sendReaction(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string; emoji: string; op: 'add' | 'remove' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }>;\n  /** Send an edit (edit-by-supersession on a target message) through the same MLS\n   * application path as `sendText`. Returns the receipt + the wire clientMsgId. */\n  sendEdit(\n    group: MessagingGroup,\n    args: {\n      clientMsgId: string;\n      targetClientMsgId: string;\n      newText: string;\n      bodyRanges?: MentionRange[] | null;\n    },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }>;\n  /** Send a delete-for-everyone tombstone on a target message through the same MLS\n   * application path as `sendText` (the server stays blind — a delete is just\n   * another opaque application message). Returns the receipt + the wire clientMsgId. */\n  sendDelete(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }>;\n  history(group: MessagingGroup, limit: number, before?: number): Promise<ChatMessage[]>;\n  members(group: MessagingGroup): Promise<ChatMember[]>;\n  addMember(group: MessagingGroup, userId: string): Promise<void>;\n  removeMember(group: MessagingGroup, userId: string): Promise<void>;\n  leave(group: MessagingGroup): Promise<void>;\n  registerActive(group: MessagingGroup): void;\n  setTyping(group: MessagingGroup, isTyping: boolean): void;\n  markRead(group: MessagingGroup, upToServerSeq: number): Promise<void>;\n  /** Server-metadata cluster: set/get the per-(user,group) notify scope (mute) and\n   * fetch the caller's own unread view. The server stays MLS-blind (opaque metadata). */\n  setNotifyScope(group: MessagingGroup, scope: NotifyScope): Promise<NotifyScope>;\n  getNotifyScope(group: MessagingGroup): Promise<NotifyScope>;\n  unread(group: MessagingGroup): Promise<UnreadView>;\n  /** Subscribe live message + conv (presence/typing/read/delivered) for an active group. */\n  subscribeLive(group: MessagingGroup, chat: Chat): Unsubscribe;\n  /** Resolve a sender device id → its owning user id (for senderUserId). */\n  userIdForDevice(group: MessagingGroup, deviceId: string): Promise<string | null>;\n  /** Load this chat's persisted delete-for-me suppression keys (durable, no wire). */\n  loadSuppressed(group: MessagingGroup): Promise<string[]>;\n  /** Persist this chat's delete-for-me suppression keys (durable, no wire). */\n  saveSuppressed(group: MessagingGroup, keys: string[]): Promise<void>;\n  /** Load this chat's persisted self-elevation dedup keys (durable, no wire) so a\n   * re-delivered mention does not re-fire `onMentionElevation` after a cold launch. */\n  loadElevated(group: MessagingGroup): Promise<string[]>;\n  /** Persist this chat's self-elevation dedup keys (durable, no wire). */\n  saveElevated(group: MessagingGroup, keys: string[]): Promise<void>;\n\n  // ── Disappearing / TTL (T10) ──\n\n  /** Send a per-chat default disappearing-timer control envelope (`timer_set`). Goes\n   * through the SAME MLS application path as `sendText` — server-blind, never a bubble.\n   * `ttlSeconds === null` disables the default. Returns the receipt + the wire clientMsgId. */\n  sendTimerSet(\n    group: MessagingGroup,\n    args: { clientMsgId: string; ttlSeconds: number | null; start: 'send' | 'read' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }>;\n  /** The persisted INTEGER `server_seq` tombstone set for a chat — drives transcript\n   * exclusion (cold-launch) + redelivery drop (live arrival). Durable, no wire. */\n  tombstonedSeqs(group: MessagingGroup): Promise<Set<number>>;\n  /** The persisted STRING `client_msg_id` purge set — drives the orphan-fold resolver\n   * (`authorOfTarget → 'purged'`) so a late edit DROPs / a late delete no-ops. */\n  purgedClientMsgIds(group: MessagingGroup): Promise<Set<string>>;\n  /** The persisted write-once anchor triple for a `clientMsgId`, or null if none. */\n  anchor(group: MessagingGroup, clientMsgId: string): Promise<AnchorTriple | null>;\n  /** Write-once: capture the first-arrival/first-read anchor triple for a `clientMsgId`\n   * (a second call for the same id is a no-op, so the deadline never resets). */\n  writeAnchorOnce(group: MessagingGroup, clientMsgId: string, a: AnchorTriple): Promise<void>;\n  /** Tombstone-first purge commit point: persist the int `server_seq` + string\n   * `client_msg_id` purge id in ONE durable record (idempotent). */\n  tombstone(group: MessagingGroup, serverSeq: number, clientMsgId: string): Promise<void>;\n}\n\nexport class Chat {\n  /** Stable, URL/log-safe id (the grp_ display id once active; a reserved local id while draft). */\n  id: string;\n  readonly kind: ChatKind;\n  private _state: ChatState;\n\n  private _group: MessagingGroup | null;\n  private _draft: ChatDraft | null;\n  private readonly backend: ChatBackend;\n\n  private messageList: ChatMessage[] = [];\n  private memberCache: ChatMember[] = [];\n  private typingList: ChatMember[] = [];\n  private presenceStates = new Map<string, PresenceState>();\n  private readWatermark = -1;\n  private titleOverride: string | null = null;\n\n  private readonly seenKeys = new Set<string>();\n  /** Index: clientMsgId → { text, senderUserId } for resolveReply lookups. */\n  private readonly byClientMsgId = new Map<string, { text: string; senderUserId: string }>();\n  /** The single authoritative reaction fold for this chat (live + own-send + history). */\n  private readonly reactionFold = new ReactionFold();\n  /** The single authoritative edit fold for this chat (live + own-send + history). */\n  private readonly editFold = new EditFold();\n  /** The single authoritative delete-for-everyone fold (live + own-send + history).\n   * A tombstone scrubs its target in place (delete DOMINATES edit at render). */\n  private readonly deleteFold = new DeleteFold();\n  /** The per-chat default disappearing-timer fold — the latest valid `timer_set` (LWW\n   * on (epoch, serverSeq), author = the resolved MLS sender). A `timer_set` is NEVER a\n   * bubble; it routes here. The active default governs a subsequent bubble that carries\n   * no per-message expiry (disappearing T10). */\n  private readonly timerFold = new TimerFold();\n  /** Advisory in-memory purge timers, keyed by serverSeq. The DURABLE truth is the\n   * persisted anchor + a re-check on every load; this just drives live eviction while\n   * the tab is open. Cancelled when the message purges (disappearing T10). */\n  private readonly purgeTimers = new Map<number, ReturnType<typeof setTimeout>>();\n  /** In-memory mirror of the durable `purgedClientMsgIds` set (the STRING namespace),\n   * hydrated from `backend.purgedClientMsgIds` and grown by each live purge. Consulted\n   * by `authorOfTarget` so a late edit/delete targeting a TTL-purged message resolves to\n   * `'purged'` (DROP / no-op — never resurrects). Namespace-separate from the int seq\n   * tombstone (disappearing T10). */\n  private readonly purgedCids = new Set<string>();\n  private purgedLoaded = false;\n  /** delete-for-me suppression keys (clientMsgId, or `seq:<serverSeq>` for legacy)\n   * — the message is OMITTED from this view. Local + persisted per chat, NO wire. */\n  private readonly suppressed = new Set<string>();\n  /** True once the persisted suppression set has been loaded (so the omit applies\n   * even on the cold-launch hydrate path before a fresh deleteForMe). */\n  private suppressedLoaded = false;\n  /** Self-elevation dedup keys (`<selfUserId>|<clientMsgId or seq:n>`). Once a\n   * mention of me from another sender fires `onMentionElevation`, its key lands here\n   * + is persisted, so a re-delivery / cold-launch re-hydrate never re-fires. */\n  private readonly elevated = new Set<string>();\n  /** True once the persisted elevation set has been loaded (so a re-delivered mention\n   * on the cold-launch hydrate path dedups against the persisted decision). */\n  private elevatedLoaded = false;\n  /** Per-target BASE (original) text, so the rendered text is `edit ?? original`.\n   * Seeded once per target (write-once base) so a 2nd own edit can't corrupt it. */\n  private readonly originalTextByClientMsgId = new Map<string, string | null>();\n  /** Per-target AUTHOR userId — the EditFold author-gate input (filled at bubble\n   * projection time from senderUserId; '' = resolved-but-unknown peer). */\n  private readonly authorByClientMsgId = new Map<string, string>();\n  private loadedEarliestSeq: number | null = null;\n  private historyLoaded = false;\n  private wired = false;\n  private liveUnsub: Unsubscribe | null = null;\n\n  private readonly listeners = new Set<() => void>();\n\n  /**\n   * Fires ONCE per `(selfUserId, clientMsgId)` when an INCOMING message mentions THIS\n   * user from ANOTHER sender (not an edit). The dedup survives re-delivery + reload\n   * via the persisted elevation set, so this never double-fires for one mention. The\n   * app wires it to a buzz/badge (e.g. an in-app banner). Best-effort cooperative —\n   * the SDK guarantees the DECISION, not the buzz. Mirrors iOS `Chat.onMentionElevation`.\n   */\n  onMentionElevation?: (message: ChatMessage) => void;\n\n  /** @internal — obtain via pb.messaging.directChat / groupChat / chat(id). */\n  constructor(\n    args:\n      | { group: MessagingGroup; kind: ChatKind; backend: ChatBackend }\n      | { draft: ChatDraft; kind: ChatKind; backend: ChatBackend },\n  ) {\n    this.backend = args.backend;\n    if ('group' in args) {\n      this.id = args.group.displayId;\n      this.kind = args.kind;\n      this._state = 'active';\n      this._group = args.group;\n      this._draft = null;\n      this.seedMembersFromGroup(args.group);\n    } else {\n      this.id = args.draft.reservedId;\n      this.kind = args.kind;\n      this._state = 'draft';\n      this._group = null;\n      this._draft = args.draft;\n      this.seedDraftMembers(args.draft);\n    }\n  }\n\n  // ── Observability ──\n\n  /** Subscribe to any change in this chat (messages/members/typing/state). */\n  onChange(cb: () => void): Unsubscribe {\n    this.listeners.add(cb);\n    // Lazily wire live + hydrate history on first observe of an active chat.\n    this.ensureWired();\n    return () => this.listeners.delete(cb);\n  }\n\n  private emit(): void {\n    for (const cb of this.listeners) cb();\n  }\n\n  // ── Snapshot getters ──\n\n  get state(): ChatState {\n    return this._state;\n  }\n  get isDirect(): boolean {\n    return this.kind === 'direct';\n  }\n  get messages(): readonly ChatMessage[] {\n    return this.surfaced();\n  }\n  get members(): readonly ChatMember[] {\n    return this.memberCache;\n  }\n  get typing(): readonly ChatMember[] {\n    return this.typingList;\n  }\n  get lastMessage(): ChatMessage | null {\n    return this.surfaced().at(-1) ?? null;\n  }\n  get unreadCount(): number {\n    // A tombstoned (deleted-for-everyone) message carries no real content, so it\n    // must not inflate the unread badge (mirrors the iOS T3 fix).\n    return this.surfaced().filter(\n      (m) => m.direction === 'incoming' && !m.isDeleted && m.serverSeq > this.readWatermark,\n    ).length;\n  }\n\n  /**\n   * The RENDER PRECEDENCE — the single composition point (live AND history project\n   * through it identically). Over the raw `messageList` (which already carries the\n   * folded edit text + reactions + reply):\n   *   (1) in the delete-for-me suppression set → OMIT the message entirely;\n   *   (2) else tombstoned (delete-for-everyone) → the neutral \"deleted\" descriptor\n   *       with reactions/reply/edit HIDDEN (delete DOMINATES edit — short-circuit);\n   *   (3) else the row as-is (edit overlay + reactions + reply already applied).\n   * Pure over (messageList, deleteFold, suppressed) — recomputed on every read so a\n   * just-folded delete / just-suppressed key takes effect without rewriting rows.\n   */\n  private surfaced(): ChatMessage[] {\n    const out: ChatMessage[] = [];\n    for (const m of this.messageList) {\n      const key = this.suppressionKey(m);\n      if (this.suppressed.has(key)) continue; // (1) for-me → omit\n      // Tombstoned by THIS chat's live fold OR already scrubbed by the coordinator\n      // history projection (the cold-launch path — its own fold pre-applied the\n      // scrub; the Chat's deleteFold is empty until a live re-delivery).\n      const tombstoned =\n        (m.clientMsgId && this.deleteFold.isTombstoned(m.clientMsgId)) || m.isDeleted;\n      if (tombstoned) {\n        // (2) tombstone DOMINATES — scrub to the descriptor, hide everything else\n        // (reactions, reply, edit AND mentions — delete dominates mentions too).\n        out.push({\n          ...m,\n          text: DELETED_DESCRIPTOR,\n          reactions: {},\n          replyTo: null,\n          edited: false,\n          isDeleted: true,\n          mentions: [],\n          // delete DOMINATES disappearing too — a tombstoned message carries no deadline.\n          expiresAt: null,\n        });\n        continue;\n      }\n      out.push(m); // (3) raw row (edit/reactions/reply already overlaid)\n    }\n    return out;\n  }\n\n  /** The delete-for-me suppression key: clientMsgId when present, else `seq:<n>`. */\n  private suppressionKey(m: ChatMessage): string {\n    return m.clientMsgId ? m.clientMsgId : `seq:${m.serverSeq}`;\n  }\n  get title(): string {\n    if (this.titleOverride) return this.titleOverride;\n    if (this._group?.name) return this._group.name;\n    // A DM is named after the PERSON, in EVERY state. `kind` — not `_draft` —\n    // is what makes it a DM: materializeIfNeeded clears `_draft`, so keying on\n    // it renamed a live one-to-one conversation to `Group <last4>` the moment\n    // its first message was sent. The roster survives that transition (the\n    // draft seed, then refreshMembers), so it is the peer's home in both.\n    if (this.kind === 'direct') {\n      const peer = this.memberCache.find((m) => !m.isSelf);\n      return peer?.displayName ?? 'Chat';\n    }\n    if (this._draft) return 'Group';\n    // Active group, no name (web has no exporter yet) — friendly fallback.\n    const tail = this.id.startsWith('grp_') ? this.id.slice(4) : this.id;\n    const short = tail.slice(-4);\n    return short ? `Group ${short}` : 'Group';\n  }\n\n  presence(userId: string): PresenceState | null {\n    return this.presenceStates.get(userId) ?? null;\n  }\n\n  // ── Wiring (live + history) ──\n\n  private ensureWired(): void {\n    if (this.wired || this._state !== 'active' || !this._group) return;\n    this.wired = true;\n    this.liveUnsub = this.backend.subscribeLive(this._group, this);\n    // Load the persisted delete-for-me suppression set FIRST so a for-me'd message\n    // stays omitted from the moment history hydrates (the cold-launch parity). The\n    // hydrate is async too; the load races it but a late load still re-emits so the\n    // omit applies (surfaced() reads the set live on every render).\n    void this.loadSuppressed();\n    // Load the persisted self-elevation dedup set FIRST too, so a re-delivered mention\n    // already-buzzed in a previous session does not re-fire on the cold-launch hydrate.\n    void this.loadElevated();\n    // Load the durable purge set (STRING namespace) BEFORE hydrating history, so the live\n    // fold's `authorOfTarget` resolves a TTL-purged target to 'purged' from the first merge\n    // (a late edit/delete against a disappeared message DROPs/no-ops). Chained so the order\n    // holds; the cold-launch transcript exclusion itself comes from projectHistory.\n    void this.loadPurged().then(() => this.hydrateHistory());\n    void this.refreshMembers();\n  }\n\n  /** Hydrate the durable `purgedClientMsgIds` set (once) into the in-memory mirror so the\n   * live Edit/Delete fold author-gate sees TTL-purged targets as 'purged' on cold launch\n   * (disappearing T10). No re-emit: it only gates the orphan-fold resolution. */\n  private async loadPurged(): Promise<void> {\n    if (this.purgedLoaded || !this._group) return;\n    this.purgedLoaded = true;\n    try {\n      const ids = await this.backend.purgedClientMsgIds(this._group);\n      for (const id of ids) this.purgedCids.add(id);\n    } catch {\n      // best-effort — a load failure just means the mirror starts empty this session\n    }\n  }\n\n  /** Hydrate the persisted delete-for-me suppression keys (once), then re-emit so\n   * any already-surfaced suppressed message is omitted (cold-launch parity). */\n  private async loadSuppressed(): Promise<void> {\n    if (this.suppressedLoaded || !this._group) return;\n    this.suppressedLoaded = true;\n    try {\n      const keys = await this.backend.loadSuppressed(this._group);\n      let changed = false;\n      for (const k of keys) {\n        if (!this.suppressed.has(k)) {\n          this.suppressed.add(k);\n          changed = true;\n        }\n      }\n      if (changed) this.emit();\n    } catch {\n      // best-effort — a load failure just means the set starts empty this session\n    }\n  }\n\n  /** Hydrate the persisted self-elevation dedup keys (once). No re-emit: the set only\n   * gates the elevation DECISION, it does not change what renders. */\n  private async loadElevated(): Promise<void> {\n    if (this.elevatedLoaded || !this._group) return;\n    this.elevatedLoaded = true;\n    try {\n      const keys = await this.backend.loadElevated(this._group);\n      for (const k of keys) this.elevated.add(k);\n    } catch {\n      // best-effort — a load failure just means the set starts empty this session\n    }\n  }\n\n  private async hydrateHistory(): Promise<void> {\n    if (this.historyLoaded || !this._group) return;\n    this.historyLoaded = true;\n    const entries = await this.backend.history(this._group, 50);\n    this.mergeHistory(entries);\n  }\n\n  private mergeHistory(incoming: ChatMessage[]): void {\n    let changed = false;\n    // Pass 1: populate byClientMsgId + the edit base/author maps from all new\n    // history rows (so replies + dangling edits within the same page and against\n    // already-indexed live messages resolve correctly).\n    for (const m of incoming) {\n      if (m.serverSeq <= 0) continue;\n      // A coordinator-scrubbed delete row carries the descriptor as `text`; never\n      // index it as reply text nor seed it as an edit base (it has no real body).\n      if (m.clientMsgId && m.text !== null && !m.isDeleted) {\n        // Index ANY row with a non-empty clientMsgId + non-null text, regardless\n        // of direction. For incoming rows senderUserId is null — use '' so the\n        // lookup entry exists and resolveReply returns state:'resolved' (real text\n        // wins over attacker-controlled preview). Spoof defense covers peer messages.\n        this.byClientMsgId.set(m.clientMsgId, {\n          text: m.text,\n          senderUserId: m.senderUserId ?? '',\n        });\n      }\n      // Seed the edit base/author. The coordinator's page-local fold already\n      // overlaid `text`/`edited` onto this row, but the row's text IS the latest\n      // edit (or original) — for the Chat's authoritative fold we want the ORIGINAL\n      // base. When the fold knows nothing for this target the upstream text IS the\n      // original; when it does know (cross-page/live), recomputeEdit uses fold.text.\n      if (m.clientMsgId && !m.isDeleted) {\n        this.seedEditBase(m.clientMsgId, m.text, m.senderUserId ?? '');\n      }\n    }\n    this.editFold.reevaluateHeld(this.authorOfTarget);\n    // Pass 2: merge into messageList (replyTo is already resolved by coordinator).\n    // The coordinator already page-local-folded reactions + edits and attached each\n    // surfaced row's tally/text; applyReactionTally + applyEditOverlay let the\n    // Chat's authoritative folds (live/own-send/cross-page) override when they hold.\n    for (const m of incoming) {\n      if (m.serverSeq <= 0) continue;\n      const key = this.internalKey(m.serverSeq);\n      if (this.seenKeys.has(key)) continue;\n      this.seenKeys.add(key);\n      // A live tombstone parked in the Chat's fold re-checks its deferred gate when\n      // an older target pages in (loadEarlier). A coordinator-scrubbed row already\n      // carries isDeleted; surfaced() honors either path (delete DOMINATES).\n      if (m.clientMsgId && !m.isDeleted) {\n        this.deleteFold.reevaluatePending(m.clientMsgId, this.authorOfTarget(m.clientMsgId));\n      }\n      // Mentions T6: re-resolve roster names on the projection's null-name spans\n      // (resolution is LIVE), then overlay the live folds (an edit replaces mentions).\n      this.messageList.push(\n        this.applyEditOverlay(this.applyReactionTally(this.resolveMentionNames(m))),\n      );\n      changed = true;\n      this.loadedEarliestSeq = Math.min(this.loadedEarliestSeq ?? m.serverSeq, m.serverSeq);\n      // Disappearing T10 (the cold-launch re-arm — the M1-trap-confirmed gap): re-arm the\n      // purge from the projection's derived EFFECTIVE deadline (own per-message expiry ELSE\n      // the chat default folded forward-only AS OF this message's order, computed in the\n      // pure projectHistory). This makes a default-governed message re-arm from HISTORY on\n      // a fresh tab, not only from a live timer_set (mirrors iOS mergeHistory armPurge).\n      if (m.expiresAt && m.clientMsgId && !m.isDeleted) {\n        void this.armFromDeadline(m.expiresAt, m.serverSeq, m.clientMsgId);\n      }\n    }\n    if (changed) {\n      this.messageList.sort((a, b) => a.serverSeq - b.serverSeq);\n      this.emit();\n    }\n  }\n\n  /** @internal — called by the backend's live subscription. */\n  async ingestLive(incoming: IncomingMessage): Promise<void> {\n    if (!this._group) return;\n    if (incoming.kind === 'commit') {\n      await this.refreshMembers();\n      return;\n    }\n    if (incoming.serverSeq <= 0) return; // welcome/proposal — not a row\n    // Disappearing T10 (redelivery-drop, the M1-trap arrival half): a message whose\n    // server_seq is already TTL-tombstoned in the durable store is DROPPED on arrival and\n    // NEVER re-surfaced. A purge is crash-safe because the tombstone is written FIRST; if\n    // the same seq is re-delivered after a purge it must not resurface (the cold-launch\n    // projectHistory enforces the SAME exclusion on reload). Checked BEFORE the seenKeys\n    // dedup so a purged-then-redelivered seq is dropped, not silently consumed.\n    if ((await this.backend.tombstonedSeqs(this._group)).has(incoming.serverSeq)) return;\n    const key = this.internalKey(incoming.serverSeq);\n    if (this.seenKeys.has(key)) return;\n    this.seenKeys.add(key);\n    let senderUser: string | null = null;\n    if (incoming.senderDeviceId) {\n      senderUser = await this.backend.userIdForDevice(this._group, incoming.senderDeviceId);\n    }\n    const direction: MessageDirection =\n      senderUser !== null && senderUser === this.backend.selfUserId ? 'outgoing' : 'incoming';\n\n    // Disappearing T10: a `timer_set` is a control envelope, NOT a bubble. Route it into\n    // the chat-default `TimerFold` (actor = the AUTHENTICATED sender, resolved device→user;\n    // own-send → self). An unresolvable actor DROPs it (no spoofable timer). Never appends\n    // a row, never notifies, never increments unread (mirrors iOS T5).\n    if (incoming.envelopeType === 'timer_set' && incoming.timer) {\n      const actorUserId = direction === 'outgoing' ? this.backend.selfUserId : senderUser;\n      if (actorUserId !== null) {\n        this.timerFold.ingest({\n          ttlSeconds: incoming.timer.ttlSeconds,\n          start: incoming.timer.start,\n          actorUserId,\n          epoch: incoming.epoch,\n          serverSeq: incoming.serverSeq,\n          eventClientMsgId: incoming.clientMsgId,\n        });\n      }\n      return; // no bubble, no unread, no push\n    }\n\n    // A reaction is NEVER a visible bubble — it folds into the target's tally and\n    // re-emits, so it also never notifies like a message (mirrors iOS T3).\n    if (incoming.envelopeType === 'reaction' && incoming.reaction) {\n      // actorUserId = the resolved sender (own-send → selfUserId). An unresolvable\n      // sender would yield a spoofable actor — drop it (no fold).\n      const actorUserId = direction === 'outgoing' ? this.backend.selfUserId : senderUser;\n      if (actorUserId !== null) {\n        this.reactionFold.ingest({\n          targetClientMsgId: incoming.reaction.targetClientMsgId,\n          actorUserId,\n          emoji: incoming.reaction.emoji,\n          op: incoming.reaction.op,\n          epoch: incoming.epoch,\n          serverSeq: incoming.serverSeq,\n          eventClientMsgId: incoming.clientMsgId,\n        });\n        this.recomputeReactions(incoming.reaction.targetClientMsgId);\n      }\n      return;\n    }\n\n    // An edit is NEVER a visible bubble — it folds the latest author edit's text\n    // onto the target in place and re-emits, so it also never notifies like a\n    // message (mirrors iOS T3). editorUserId = the resolved sender (own-send →\n    // selfUserId); null → the fold HOLDs until the roster resolves.\n    if (incoming.envelopeType === 'edit' && incoming.edit) {\n      const editorUserId = direction === 'outgoing' ? this.backend.selfUserId : senderUser;\n      this.editFold.ingest(\n        {\n          targetClientMsgId: incoming.edit.targetClientMsgId,\n          editorUserId,\n          newText: incoming.edit.newText,\n          epoch: incoming.epoch,\n          serverSeq: incoming.serverSeq,\n          eventClientMsgId: incoming.clientMsgId,\n          // Mentions T6: carry the edit's REPLACEMENT ranges so the edited message's\n          // mentions reflect them (recomputed against the new text on recomputeEdit).\n          bodyRanges: incoming.bodyRanges,\n        },\n        this.authorOfTarget,\n      );\n      this.recomputeEdit(incoming.edit.targetClientMsgId);\n      return;\n    }\n\n    // A delete-for-everyone is NEVER a visible bubble — it folds a tombstone onto\n    // its target (author-gated) and re-emits, so it also never notifies like a\n    // message (mirrors iOS T3). actorUserId = the resolved sender (own-send →\n    // selfUserId); null → the fold parks it in held until the roster resolves. The\n    // authorOfTarget closure resolves the TARGET message's author for the gate.\n    if (incoming.envelopeType === 'delete' && incoming.delete) {\n      const actorUserId = direction === 'outgoing' ? this.backend.selfUserId : senderUser;\n      this.deleteFold.ingest(\n        {\n          targetClientMsgId: incoming.delete.targetClientMsgId,\n          actorUserId,\n          epoch: incoming.epoch,\n          serverSeq: incoming.serverSeq,\n          eventClientMsgId: incoming.clientMsgId,\n        },\n        this.authorOfTarget,\n      );\n      // A tombstone that arrived BEFORE its target lands parked in pending; the\n      // target's own insert below re-checks it. Re-emit so an in-order scrub shows.\n      this.emit();\n      return;\n    }\n\n    // clientMsgId and replyRef are decoded by the delivery source (decodeEnvelope)\n    // and carried on IncomingMessage. Legacy/system messages carry empty string / null.\n    const incomingClientMsgId = incoming.clientMsgId;\n    const incomingReplyRef = incoming.replyRef;\n\n    // Resolve reply if present.\n    let resolvedReplyTo: ResolvedReply | null = null;\n    if (incomingReplyRef) {\n      resolvedReplyTo = resolveReply(incomingReplyRef, (id) => this.byClientMsgId.get(id) ?? null);\n    }\n\n    // Mentions T6: resolve the decode-time mention spans (normalize + roster name)\n    // for this NORMAL text bubble. A mention is carried on the message's own text (no\n    // fold) — the bubble renders normally with these spans for highlighting.\n    const mentions = this.resolveMentions(incoming.text, incoming.bodyRanges);\n\n    const msg: ChatMessage = {\n      id: this.publicId(incoming.serverSeq),\n      kind: this.kindOf(incoming),\n      direction,\n      senderUserId: senderUser,\n      text: incoming.text,\n      serverSeq: incoming.serverSeq,\n      sentAt: incoming.receivedAt,\n      clientMsgId: incomingClientMsgId,\n      replyTo: resolvedReplyTo,\n      // Attach any tally already folded for this message (a reaction that arrived\n      // BEFORE its target — the dangling case — renders the moment the target lands).\n      reactions: incomingClientMsgId ? this.reactionFold.tally(incomingClientMsgId) : {},\n      // Default false; applyEditOverlay below folds any edit that arrived first.\n      edited: false,\n      // Default false; surfaced() applies the tombstone scrub if a delete folded.\n      isDeleted: false,\n      mentions,\n      // Disappearing T10: the LOCAL deadline (own per-message expiry ELSE the chat default\n      // active AS OF arrival). null when this message is non-disappearing.\n      expiresAt: this.deadlineFor(this.toExpirySpec(incoming.expiry) ?? this.defaultExpiry()),\n    };\n\n    // Self-elevation decision (best-effort cooperative, dedup-once via the persisted\n    // set). Compute on the INCOMING bubble BEFORE projection — an edit never lands here\n    // (it routed to the EditFold above), satisfying the not-edit gate.\n    this.elevateIfMentioned(msg, mentions, senderUser, incoming.envelopeType);\n\n    // Index non-empty clientMsgId for future resolveReply lookups.\n    // Index ANY incoming message (senderUser may be null for peers); use '' for\n    // the senderUserId so resolveReply still returns state:'resolved' (real text\n    // wins over attacker-controlled preview). Spoof defense covers peer messages.\n    if (incomingClientMsgId && incoming.text !== null) {\n      this.byClientMsgId.set(incomingClientMsgId, {\n        text: incoming.text,\n        senderUserId: senderUser ?? '',\n      });\n    }\n\n    // Record this bubble's BASE text + AUTHOR for the edit fold BEFORE\n    // reevaluateHeld, so a dangling edit whose target just arrived author-gates\n    // correctly. Base text is seeded once (write-once) so a folded edit overlay\n    // never overwrites the original we render `edit ?? original` against.\n    if (incomingClientMsgId) {\n      this.seedEditBase(incomingClientMsgId, incoming.text, senderUser);\n      this.editFold.reevaluateHeld(this.authorOfTarget);\n      // A pending/held tombstone for this just-arrived target re-checks its\n      // deferred author-gate here — a forged early tombstone is discarded (the\n      // message renders), a genuine one scrubs (mirrors iOS T3 reevaluatePending).\n      this.deleteFold.reevaluatePending(\n        incomingClientMsgId,\n        this.authorOfTarget(incomingClientMsgId),\n      );\n    }\n\n    this.messageList.push(this.applyEditOverlay(msg));\n    this.messageList.sort((a, b) => a.serverSeq - b.serverSeq);\n    this.loadedEarliestSeq = Math.min(\n      this.loadedEarliestSeq ?? incoming.serverSeq,\n      incoming.serverSeq,\n    );\n    this.emit();\n    // Disappearing T10: a normal bubble carrying a per-message `expiry` arms its purge on\n    // first decrypt-and-display (the durable write-once anchor + the advisory timer); a\n    // bubble with NO per-message expiry falls back to the chat default (`timerFold`).\n    // own-expiry WINS over the default. Fire-and-forget — best-effort; never blocks ingest.\n    void this.armPurge(\n      this.toExpirySpec(incoming.expiry) ?? this.defaultExpiry(),\n      incoming.serverSeq,\n      incomingClientMsgId,\n    );\n  }\n\n  // ── Disappearing (TTL — T10) ──\n\n  /** Normalize a decoded `IncomingMessage.expiry` / `StoredMessage.expiry` into the\n   * `ExpirySpec` the arm path consumes (or null when absent). */\n  private toExpirySpec(\n    e:\n      | { v: number; ttlSeconds: number; start: 'send' | 'read'; senderSendTs: number | null }\n      | null\n      | undefined,\n  ): ExpirySpec | null {\n    return e\n      ? { v: e.v, ttlSeconds: e.ttlSeconds, start: e.start, senderSendTs: e.senderSendTs }\n      : null;\n  }\n\n  /** The chat-default expiry derived from the active `timer_set` fold, as an `ExpirySpec`\n   * so a bubble with no per-message expiry inherits it. null when no default is active or\n   * the default was explicitly DISABLED (`ttlSeconds === null`). `senderSendTs` is null —\n   * the default has no per-message sender clock; the arrival anchor drives the deadline\n   * (mirrors iOS `defaultExpiry()`). */\n  private defaultExpiry(): ExpirySpec | null {\n    const active = this.timerFold.active();\n    if (!active || active.ttlSeconds === null) return null;\n    return { v: 1, ttlSeconds: active.ttlSeconds, start: active.start, senderSendTs: null };\n  }\n\n  /** The surfaced display deadline for an effective expiry (a local, monotonic-derived\n   * value — the wall-clock projection of the TTL from now). null for a non-disappearing\n   * message. The durable purge is driven by `armPurge`'s write-once anchor; this is the\n   * UI countdown baseline. */\n  private deadlineFor(expiry: ExpirySpec | null): Date | null {\n    if (!expiry) return null;\n    return new Date(Date.now() + expiry.ttlSeconds * 1000);\n  }\n\n  /** Arm a message's TTL purge on first decrypt-and-display. Captures the WRITE-ONCE\n   * monotonic/wall/boot anchor (so the deadline survives a reload — a re-arm after relaunch\n   * reads back the ORIGINAL capture, never a fresh one → the deadline never resets),\n   * computes the remaining time via `remainingSeconds`, applies the send-anchor clamp\n   * `min(sender_send_ts+ttl, first_arrival+ttl)` (read-anchor uses the write-once first-read\n   * capture), then either purges immediately or schedules an advisory `setTimeout`. A null\n   * expiry / empty clientMsgId is a no-op. Mirrors iOS `armPurge`. */\n  private async armPurge(\n    expiry: ExpirySpec | null,\n    serverSeq: number,\n    clientMsgId: string,\n  ): Promise<void> {\n    if (!expiry || !clientMsgId || !this._group) return;\n    const group = this._group;\n    // Write-once arrival/first-read anchor (durable so the deadline survives a reload).\n    const fresh: AnchorTriple = {\n      mAnchorMs: MonotonicClock.nowMs(),\n      wAnchorEpochMs: MonotonicClock.nowWallEpochMs(),\n      bAnchorToken: MonotonicClock.bootToken(),\n    };\n    await this.backend.writeAnchorOnce(group, clientMsgId, fresh);\n    // Use the PERSISTED anchor (the write-once one) for the deadline math.\n    const effective = (await this.backend.anchor(group, clientMsgId)) ?? fresh;\n    const result = remainingSeconds({\n      ttlSeconds: expiry.ttlSeconds,\n      anchor: effective,\n      nowMonotonicMs: MonotonicClock.nowMs(),\n      nowWallEpochMs: MonotonicClock.nowWallEpochMs(),\n      nowBootToken: MonotonicClock.bootToken(),\n    });\n    // Send-anchor clamp: the sender's intended deadline is sender_send_ts + ttl; a\n    // clock-skew / late arrival can only SHORTEN, never extend, the message's life.\n    let purgeInSeconds: number | null;\n    if (result.kind === 'purgeNow') {\n      purgeInSeconds = 0;\n    } else if (expiry.start === 'send' && expiry.senderSendTs !== null) {\n      const sendRemaining =\n        expiry.senderSendTs + expiry.ttlSeconds - MonotonicClock.nowWallEpochMs() / 1000;\n      purgeInSeconds = sendRemaining <= 0 ? 0 : Math.min(result.seconds, sendRemaining);\n    } else {\n      purgeInSeconds = result.seconds;\n    }\n    // Cancel any prior timer for this seq (idempotent re-arm) before scheduling.\n    const prior = this.purgeTimers.get(serverSeq);\n    if (prior) clearTimeout(prior);\n    this.purgeTimers.delete(serverSeq);\n    if (purgeInSeconds <= 0) {\n      await this.purge(serverSeq, clientMsgId);\n      return;\n    }\n    const handle = setTimeout(() => {\n      void this.purge(serverSeq, clientMsgId);\n    }, purgeInSeconds * 1000);\n    this.purgeTimers.set(serverSeq, handle);\n  }\n\n  /** Re-arm a purge from a derived deadline (cold-launch hydrate path). The deadline is\n   * the projection's monotonic-derived `expiresAt`; schedule an advisory timer for the\n   * remaining time (purge immediately if the deadline has already passed). The durable\n   * tombstone is written by `purge` when it fires (the crash-safe commit point). */\n  private async armFromDeadline(\n    deadline: Date,\n    serverSeq: number,\n    clientMsgId: string,\n  ): Promise<void> {\n    if (!this._group) return;\n    const remainingMs = deadline.getTime() - Date.now();\n    const prior = this.purgeTimers.get(serverSeq);\n    if (prior) clearTimeout(prior);\n    this.purgeTimers.delete(serverSeq);\n    if (remainingMs <= 0) {\n      await this.purge(serverSeq, clientMsgId);\n      return;\n    }\n    const handle = setTimeout(() => {\n      void this.purge(serverSeq, clientMsgId);\n    }, remainingMs);\n    this.purgeTimers.set(serverSeq, handle);\n  }\n\n  /** Purge message M (TTL eviction). TOMBSTONE-FIRST (the crash-safe commit point):\n   * persist the `server_seq` tombstone + the `client_msg_id` purge id in ONE durable\n   * record, THEN drop M's body from `messageList` + `emit()`, then re-evaluate any HELD\n   * edit / PARKED delete targeting the now-purged cid so an orphan annotation DROPs/no-ops\n   * (the resolver now returns `'purged'`). Idempotent. Mirrors iOS `purge`. */\n  private async purge(serverSeq: number, clientMsgId: string): Promise<void> {\n    if (!this._group) return;\n    const prior = this.purgeTimers.get(serverSeq);\n    if (prior) clearTimeout(prior);\n    this.purgeTimers.delete(serverSeq);\n    // Tombstone FIRST (durable commit point) — records clientMsgId in purgedClientMsgIds.\n    await this.backend.tombstone(this._group, serverSeq, clientMsgId);\n    if (clientMsgId) this.purgedCids.add(clientMsgId); // live-mirror the purge set\n    // Drop the body from the transcript, then re-emit.\n    this.messageList = this.messageList.filter((m) => m.serverSeq !== serverSeq);\n    this.seenKeys.delete(this.internalKey(serverSeq));\n    this.emit();\n    // The purge now resolves this cid to 'purged' — re-evaluate any held edit / parked\n    // delete so an orphan annotation targeting the disappeared message DROPs/no-ops.\n    this.editFold.reevaluateHeld(this.authorOfTarget);\n    if (clientMsgId) {\n      this.deleteFold.reevaluatePending(clientMsgId, this.authorOfTarget(clientMsgId));\n    }\n  }\n\n  /** The Edit/Delete fold author-gate input via {@link AuthorResolution} (disappearing\n   * T10 — the orphan-aware resolver): `'purged'` when the target's clientMsgId is in the\n   * durable purge set (a late edit DROPs / a late delete no-ops — never resurrects a\n   * disappeared message); `'author'` when its author is locally known → run the\n   * author-gate; `'unknown'` otherwise → HOLD. The live twin of `projectHistory`'s\n   * resolver. Captured as a bound arrow so it can be passed to the pure folds. */\n  private readonly authorOfTarget = (targetClientMsgId: string): AuthorResolution => {\n    if (this.purgedCids.has(targetClientMsgId)) return { kind: 'purged' };\n    const a = this.authorByClientMsgId.get(targetClientMsgId);\n    return a !== undefined ? { kind: 'author', userId: a } : { kind: 'unknown' };\n  };\n\n  // ── Mentions (mentions T6) ──\n\n  /** Resolve a message's decode-time mention spans: NORMALIZE the raw `body_ranges`\n   * against `text` (the pinned `normalizeMentionRangesUtf16` cross-SDK contract) then\n   * resolve each surviving range's `mentionedUserId` to a roster display name. An id\n   * not in the roster resolves to `null` (the renderer falls back to the `text` slice).\n   * Pure over (text, bodyRanges, memberCache); never throws. Mirrors iOS T3. */\n  private resolveMentions(\n    text: string | null,\n    bodyRanges: MentionRange[] | null | undefined,\n  ): ResolvedMention[] {\n    if (text === null || !bodyRanges || bodyRanges.length === 0) return [];\n    const normalized = normalizeMentionRangesUtf16(bodyRanges, text);\n    if (normalized.length === 0) return [];\n    return normalized.map((r) => ({\n      start: r.start,\n      length: r.length,\n      mentionedUserId: r.mentionedUserId,\n      displayName: this.displayNameOf(r.mentionedUserId),\n    }));\n  }\n\n  /** Re-resolve the roster display name on already-NORMALIZED spans (the history\n   * projection produces them with null names — resolution is LIVE, not snapshotted).\n   * A member rename then reflects on old messages. Returns the message unchanged when\n   * it has no mentions (the common case) or no name changed. Mirrors iOS T3. */\n  private resolveMentionNames(m: ChatMessage): ChatMessage {\n    // Tolerate a row that predates the mentions field (an older persisted projection /\n    // a hand-built history row) — treat absent as `[]`, never throw.\n    if (!m.mentions || m.mentions.length === 0) {\n      return m.mentions ? m : { ...m, mentions: [] };\n    }\n    let changed = false;\n    const reresolved = m.mentions.map((span) => {\n      const name = this.displayNameOf(span.mentionedUserId);\n      if (name === span.displayName) return span;\n      changed = true;\n      return { ...span, displayName: name };\n    });\n    if (!changed) return m;\n    return { ...m, mentions: reresolved };\n  }\n\n  /** The WINNING edit's resolved mentions for a target (normalize its replacement\n   * ranges against the new text + roster names), or `[]` if no winning edit / no\n   * ranges. The edited message's mentions reflect the EDIT's ranges (mirrors iOS T3). */\n  private editMentions(targetClientMsgId: string, newText: string | null): ResolvedMention[] {\n    const ranges = this.editFold.bodyRanges(targetClientMsgId);\n    if (!ranges) return [];\n    return this.resolveMentions(newText, ranges);\n  }\n\n  /** Resolve a userId → its roster display name (null if not a known member). */\n  private displayNameOf(userId: string): string | null {\n    return this.memberCache.find((mm) => mm.userId === userId)?.displayName ?? null;\n  }\n\n  /** Compute the SELF-ELEVATION decision for a freshly-ingested INCOMING bubble and,\n   * when it fires, record the dedup key (persisted) + invoke `onMentionElevation`.\n   * Gate (mirrors iOS T3): a surviving mention targets THIS user AND the sender is not\n   * me AND it's NOT an edit AND the `(selfUserId, clientMsgId|seq)` key isn't already\n   * elevated. Dedup-once: the in-memory set gates the session, the persisted set\n   * survives reload. An EDIT never reaches here (it folds, not a bubble) — the\n   * `envelopeType !== 'edit'` guard is belt-and-braces. */\n  private elevateIfMentioned(\n    message: ChatMessage,\n    mentions: ResolvedMention[],\n    senderUserId: string | null,\n    envelopeType: string | undefined,\n  ): void {\n    const me = this.backend.selfUserId;\n    if (envelopeType === 'edit') return; // edits never elevate\n    if (senderUserId === me) return; // self-mention never buzzes me\n    if (!mentions.some((mm) => mm.mentionedUserId === me)) return; // not mentioned\n    const idPart = message.clientMsgId ? message.clientMsgId : `seq:${message.serverSeq}`;\n    const key = `${me}|${idPart}`;\n    if (this.elevated.has(key)) return; // already elevated → no re-buzz\n    this.elevated.add(key);\n    // Persist the dedup set (fire-and-forget — the in-memory record already gates this\n    // session; the write makes it survive a cold launch).\n    if (this._group) {\n      void this.backend.saveElevated(this._group, [...this.elevated]).catch(() => {});\n    }\n    this.onMentionElevation?.(message);\n  }\n\n  /** Seed the per-target base text + author for the edit fold. Base is write-once\n   * (a later own/peer edit must not overwrite the original we render against). The\n   * author is (re)recorded whenever a non-empty resolution is available. */\n  private seedEditBase(clientMsgId: string, text: string | null, author: string | null): void {\n    if (!this.originalTextByClientMsgId.has(clientMsgId)) {\n      this.originalTextByClientMsgId.set(clientMsgId, text);\n    }\n    if (author !== null) this.authorByClientMsgId.set(clientMsgId, author);\n  }\n\n  /**\n   * Rebuild the target message's `reactions` from the authoritative fold and\n   * re-emit. No-op when the target isn't present yet (its tally is attached the\n   * moment it lands, via the append/merge paths) or when the tally is unchanged.\n   */\n  private recomputeReactions(targetClientMsgId: string): void {\n    if (!targetClientMsgId) return;\n    const tally = this.reactionFold.tally(targetClientMsgId);\n    let changed = false;\n    this.messageList = this.messageList.map((m) => {\n      if (m.clientMsgId !== targetClientMsgId) return m;\n      if (sameReactions(m.reactions, tally)) return m;\n      changed = true;\n      return { ...m, reactions: tally };\n    });\n    if (changed) this.emit();\n  }\n\n  /**\n   * Overlay the authoritative fold's tally onto a message as it is appended/merged.\n   * The Chat fold WINS when it has a non-empty tally; otherwise the tally already\n   * attached upstream (the coordinator's page-local history fold) is preserved.\n   */\n  private applyReactionTally(m: ChatMessage): ChatMessage {\n    if (!m.clientMsgId) return m;\n    const tally = this.reactionFold.tally(m.clientMsgId);\n    if (Object.keys(tally).length === 0) return m; // fold has nothing — keep upstream tally\n    if (sameReactions(m.reactions, tally)) return m;\n    return { ...m, reactions: tally };\n  }\n\n  /**\n   * Rebuild the target message's rendered `text` + `edited` flag from the\n   * authoritative edit fold and re-emit, PRESERVING `.reactions` and `.replyTo`\n   * (the reaction-polish lesson — never clobber). text = `editFold.text(cid) ??\n   * base`; base is the seeded original so a forged/ignored edit leaves it intact.\n   * No-op when the target isn't present yet (the fold already recorded it; the\n   * overlay applies the moment the target lands) or when unchanged.\n   */\n  private recomputeEdit(targetClientMsgId: string): void {\n    if (!targetClientMsgId) return;\n    const editText = this.editFold.text(targetClientMsgId);\n    const foldEdited = this.editFold.isEdited(targetClientMsgId);\n    let changed = false;\n    this.messageList = this.messageList.map((m) => {\n      if (m.clientMsgId !== targetClientMsgId) return m;\n      const base = this.originalTextByClientMsgId.has(targetClientMsgId)\n        ? (this.originalTextByClientMsgId.get(targetClientMsgId) ?? null)\n        : m.text;\n      const text = editText ?? base;\n      // Write-once edited: the Chat fold OR an already-set flag (e.g. the\n      // coordinator's page-local history projection). Never downgrade true → false.\n      const edited = foldEdited || m.edited;\n      // Mentions T6: when an edit WINS, the edited message's mentions reflect the\n      // EDIT's replacement ranges (recomputed against the new text); otherwise keep\n      // the message's existing mentions.\n      const mentions = editText !== null ? this.editMentions(targetClientMsgId, text) : m.mentions;\n      if (m.text === text && m.edited === edited && sameMentions(m.mentions, mentions)) return m;\n      changed = true;\n      return { ...m, text, edited, mentions }; // PRESERVES reactions + replyTo (spread keeps them)\n    });\n    if (changed) this.emit();\n  }\n\n  /**\n   * Overlay the authoritative edit fold's winning text + flag onto a message as it\n   * is appended/merged. The fold WINS when it has an edit for this target;\n   * otherwise the upstream `text`/`edited` (e.g. the coordinator's page-local\n   * history fold) is preserved. PRESERVES reactions + replyTo.\n   */\n  private applyEditOverlay(m: ChatMessage): ChatMessage {\n    if (!m.clientMsgId) return m;\n    const editText = this.editFold.text(m.clientMsgId);\n    const foldEdited = this.editFold.isEdited(m.clientMsgId);\n    if (editText === null && !foldEdited) return m; // fold has nothing — keep upstream\n    const text = editText ?? m.text;\n    // Write-once: never downgrade an already-edited flag (the upstream projection).\n    const edited = foldEdited || m.edited;\n    // Mentions T6: when the LIVE fold has a winning edit for this target, the edited\n    // message's mentions come from that edit's replacement ranges; otherwise keep the\n    // mentions the message ALREADY carries (e.g. the coordinator's page-local overlay).\n    const mentions = editText !== null ? this.editMentions(m.clientMsgId, text) : m.mentions;\n    if (m.text === text && m.edited === edited && sameMentions(m.mentions, mentions)) return m;\n    return { ...m, text, edited, mentions };\n  }\n\n  /** @internal — called by the backend's conv subscription. */\n  applyConv(event: string, payload: Record<string, unknown>): void {\n    const userId = typeof payload.user_id === 'string' ? payload.user_id : null;\n    if (!userId || userId === this.backend.selfUserId) return;\n    if (event === 'typing') {\n      const isTyping = payload.typing === true;\n      const member = this.memberCache.find((m) => m.userId === userId) ?? {\n        id: userId,\n        userId,\n        displayName: null,\n        role: 'member' as const,\n        isSelf: false,\n      };\n      this.typingList = isTyping\n        ? [...this.typingList.filter((m) => m.userId !== userId), member]\n        : this.typingList.filter((m) => m.userId !== userId);\n      this.emit();\n    } else if (event === 'presence') {\n      const online = payload.online === true;\n      const ts = typeof payload.ts === 'number' ? payload.ts : null;\n      this.presenceStates.set(userId, {\n        userId,\n        isOnline: online,\n        lastSeenAt: ts ? new Date(ts * 1000) : null,\n      });\n      this.emit();\n    } else if (event === 'delivered' || event === 'read') {\n      // Server-metadata cluster — the double-tick fold (parity with iOS T11). A peer's\n      // `delivered`/`read` broadcast carries the acking device_id + an `up_to_server_seq`\n      // high-watermark. We fold it onto THIS user's OWN (outgoing) messages whose\n      // serverSeq is at or below the acked seq, USER-LEVEL (any peer/device counts) and\n      // MONOTONIC (`max` — a stale lower incoming tick NEVER lowers the displayed tick;\n      // the same guard the iOS `foldDeliveredTick` applies). `read` STAYS gated by the\n      // peer's share_receipts server-side (the broadcast simply never arrives when muted);\n      // the client fold is identical (delivered mirrors read).\n      const seq = typeof payload.up_to_server_seq === 'number' ? payload.up_to_server_seq : null;\n      if (seq === null) return;\n      let changed = false;\n      this.messageList = this.messageList.map((m) => {\n        if (m.direction !== 'outgoing' || m.serverSeq > seq) return m;\n        const cur = event === 'delivered' ? (m.deliveredUpTo ?? -1) : (m.readUpTo ?? -1);\n        if (seq <= cur) return m; // monotonic: a stale/equal tick never lowers it\n        changed = true;\n        return event === 'delivered' ? { ...m, deliveredUpTo: seq } : { ...m, readUpTo: seq };\n      });\n      if (changed) this.emit();\n    }\n  }\n\n  private kindOf(incoming: IncomingMessage): ChatMessageKind {\n    if (incoming.kind === 'commit' || incoming.kind === 'proposal' || incoming.kind === 'welcome')\n      return 'system';\n    return 'text';\n  }\n\n  private internalKey(serverSeq: number): string {\n    return this._group ? `${this._group.rfcGroupId}#${serverSeq}` : `draft#${serverSeq}`;\n  }\n  private publicId(serverSeq: number): string {\n    return `${this.id}#${serverSeq}`;\n  }\n\n  /** Page older messages in. Returns how many were prepended. */\n  async loadEarlier(limit = 50): Promise<number> {\n    if (!this._group) return 0;\n    const before = this.loadedEarliestSeq ?? undefined;\n    const older = await this.backend.history(this._group, limit, before);\n    const before0 = this.messageList.length;\n    this.mergeHistory(older);\n    return this.messageList.length - before0;\n  }\n\n  // ── Members ──\n\n  private async refreshMembers(): Promise<void> {\n    if (!this._group) return;\n    const m = await this.backend.members(this._group);\n    if (m.length > 0) {\n      this.memberCache = m;\n      this.emit();\n    }\n    // On a roster change a previously-unresolvable editor may now resolve — re-run\n    // held edits + recompute any target whose edit just landed (mirrors iOS T3's\n    // refreshMembers hook).\n    this.editFold.reevaluateHeld(this.authorOfTarget);\n    for (const cid of this.originalTextByClientMsgId.keys()) this.recomputeEdit(cid);\n    // Mentions T6: a member's display name may now be known — re-resolve mention names\n    // on every message (resolution is LIVE, never snapshotted; a rename reflects here).\n    this.reresolveAllMentionNames();\n  }\n\n  /** Re-resolve roster display names across the whole transcript (called on a roster\n   * change). Re-emits only if any name actually changed. */\n  private reresolveAllMentionNames(): void {\n    let changed = false;\n    this.messageList = this.messageList.map((m) => {\n      const reresolved = this.resolveMentionNames(m);\n      if (reresolved !== m) changed = true;\n      return reresolved;\n    });\n    if (changed) this.emit();\n  }\n\n  private seedMembersFromGroup(group: MessagingGroup): void {\n    const seed: ChatMember[] = [\n      {\n        id: this.backend.selfUserId,\n        userId: this.backend.selfUserId,\n        displayName: null,\n        role: 'owner',\n        isSelf: true,\n      },\n    ];\n    if (group.ownerUserId && group.ownerUserId !== this.backend.selfUserId) {\n      seed.push({\n        id: group.ownerUserId,\n        userId: group.ownerUserId,\n        displayName: null,\n        role: 'owner',\n        isSelf: false,\n      });\n    }\n    this.memberCache = seed;\n  }\n\n  private seedDraftMembers(draft: ChatDraft): void {\n    const seed: ChatMember[] = [\n      {\n        id: this.backend.selfUserId,\n        userId: this.backend.selfUserId,\n        displayName: null,\n        role: draft.mode.kind === 'group' ? 'owner' : 'member',\n        isSelf: true,\n      },\n    ];\n    if (draft.mode.kind === 'direct') {\n      seed.push({\n        id: draft.mode.peerUserId,\n        userId: draft.mode.peerUserId,\n        displayName: null,\n        role: 'member',\n        isSelf: false,\n      });\n    } else {\n      for (const uid of draft.mode.members) {\n        seed.push({ id: uid, userId: uid, displayName: null, role: 'member', isSelf: false });\n      }\n    }\n    this.memberCache = seed;\n  }\n\n  // ── Send (with WhatsApp lazy materialize) ──\n\n  async send(\n    text: string,\n    opts?: {\n      replyTo?: ChatMessage;\n      mentions?: MentionRange[];\n      expiresIn?: { ttlSeconds: number; start?: 'send' | 'read' };\n    },\n  ): Promise<SentReceipt> {\n    const group = await this.materializeIfNeeded();\n\n    // Build ReplyRef from the parent ChatMessage if provided (and replyable).\n    let replyRef: ReplyRef | null = null;\n    let resolvedReplyTo: ResolvedReply | null = null;\n    const parent = opts?.replyTo;\n    if (parent?.clientMsgId && parent.kind !== 'system') {\n      const [previewBody, wasTruncated] = parent.text ? truncateQuote(parent.text) : ['', false];\n      replyRef = {\n        v: 1,\n        client_msg_id: parent.clientMsgId,\n        preview: {\n          kind: 'text',\n          author_user_id: parent.senderUserId ?? '',\n          body: previewBody || undefined,\n          body_truncated: wasTruncated,\n        },\n      };\n      // Resolve the reply against local history immediately (the parent IS local).\n      resolvedReplyTo = resolveReply(replyRef, (id) => this.byClientMsgId.get(id) ?? null);\n    }\n\n    // Mentions T6: carry the caller's mention ranges onto the wire envelope (encoded\n    // as `body_ranges`). The own-sent bubble resolves them locally for its own render.\n    const bodyRanges = opts?.mentions ?? null;\n    // Disappearing T10: a per-message TTL rides INSIDE the ciphertext as an `expiry` spec\n    // — the server stays MLS-blind (no expires_at, no new route). `start === 'send'`\n    // (default) anchors the deadline to the sender's compose-time (stamps sender_send_ts,\n    // clamped on receipt by the local first-arrival); `read` anchors it to first-read.\n    //\n    // COMPOSE-TIME STAMPING (spec §\"Per-message vs per-chat\"): a message's effective TTL\n    // is its OWN explicit `expiresIn` IF present, ELSE the chat's active default timer\n    // STAMPED ONTO IT NOW. The per-message `expiry` field is the durable record — so a\n    // plain send under an active default carries the (frozen) default on the wire, making\n    // sender and receiver symmetric (both arm from the SAME stamped expiry, forward-only).\n    const effectiveExpiry = this.composeExpiry(opts?.expiresIn);\n    const { receipt, clientMsgId } = await this.backend.sendText(\n      group,\n      text,\n      replyRef,\n      bodyRanges,\n      effectiveExpiry,\n    );\n    this.appendOwnSend(text, receipt, clientMsgId, resolvedReplyTo, bodyRanges, effectiveExpiry);\n    // The own-send arms its OWN purge on the same rule (the stamped expiry is the basis).\n    // FIRE-AND-FORGET ADVISORY: we return on the LOCAL emit — there is NO peer-enforcement.\n    if (effectiveExpiry) void this.armPurge(effectiveExpiry, receipt.serverSeq, clientMsgId);\n    return receipt; // fire-and-forget advisory: local emit only, no peer-enforcement signal\n  }\n\n  /** Resolve a send's effective per-message expiry at COMPOSE TIME: the caller's explicit\n   * `expiresIn` if present, ELSE the chat's active default timer stamped onto the message\n   * NOW (the durable record per spec §\"Compose-time stamping\"). A `send`-anchored expiry\n   * (explicit or default-inherited) stamps `senderSendTs` = the sender's compose epoch\n   * seconds; a `read`-anchored one carries none (the deadline is the recipient's local\n   * first-read). Returns null when there is neither an explicit expiry nor an active\n   * default (a plain, non-disappearing send). Mirrors the iOS compose-time stamping. */\n  private composeExpiry(explicit?: {\n    ttlSeconds: number;\n    start?: 'send' | 'read';\n  }): ExpirySpec | null {\n    const base: ExpirySpec | null = explicit\n      ? {\n          v: 1,\n          ttlSeconds: explicit.ttlSeconds,\n          start: explicit.start ?? 'send',\n          senderSendTs: null,\n        }\n      : this.defaultExpiry();\n    if (!base) return null;\n    return {\n      ...base,\n      senderSendTs: base.start === 'send' ? Math.floor(Date.now() / 1000) : null,\n    };\n  }\n\n  /** Set (or DISABLE) this chat's DEFAULT disappearing timer. Emits a `timer_set` control\n   * envelope (server-blind — an opaque application message, NEVER a bubble) and folds the\n   * own-set locally so the default applies immediately to subsequent sends that carry no\n   * per-message expiry. `ttlSeconds === null` DISABLES the default. FIRE-AND-FORGET\n   * ADVISORY: returns on the LOCAL emit only; it exposes NO \"active for all peers\" signal.\n   * Mirrors iOS `setDisappearing(ttlSeconds:start:)`. */\n  async setDisappearing(opts: {\n    ttlSeconds: number | null;\n    start?: 'send' | 'read';\n  }): Promise<void> {\n    const group = await this.materializeIfNeeded();\n    const clientMsgId = mintClientMsgId();\n    const start = opts.start ?? 'send';\n    const { receipt } = await this.backend.sendTimerSet(group, {\n      clientMsgId,\n      ttlSeconds: opts.ttlSeconds,\n      start,\n    });\n    // Fold the own-set locally (actor = self) at the server-assigned order so the default\n    // applies immediately. The fold dedups on the event clientMsgId, so the durable echo on\n    // the next pump is a no-op. A timer_set is NOT a bubble.\n    this.timerFold.ingest({\n      ttlSeconds: opts.ttlSeconds,\n      start,\n      actorUserId: this.backend.selfUserId,\n      epoch: receipt.epoch,\n      serverSeq: receipt.serverSeq,\n      eventClientMsgId: clientMsgId,\n    });\n    // fire-and-forget advisory: returns on local emit; no \"active for all peers\" signal.\n  }\n\n  private appendOwnSend(\n    text: string,\n    receipt: SentReceipt,\n    clientMsgId: string,\n    resolvedReplyTo: ResolvedReply | null,\n    bodyRanges?: MentionRange[] | null,\n    expiry?: ExpirySpec | null,\n  ): void {\n    if (receipt.serverSeq <= 0) return;\n    const key = this.internalKey(receipt.serverSeq);\n    if (this.seenKeys.has(key)) return;\n    this.seenKeys.add(key);\n\n    // Index own-sent clientMsgId for future resolveReply lookups (self-reply support).\n    if (clientMsgId) {\n      this.byClientMsgId.set(clientMsgId, { text, senderUserId: this.backend.selfUserId });\n      // Seed the edit base + author (self) so a later own edit author-gates and the\n      // overlay renders `edit ?? original`.\n      this.seedEditBase(clientMsgId, text, this.backend.selfUserId);\n    }\n\n    this.messageList.push({\n      id: this.publicId(receipt.serverSeq),\n      kind: 'text',\n      direction: 'outgoing',\n      senderUserId: this.backend.selfUserId,\n      text,\n      serverSeq: receipt.serverSeq,\n      sentAt: new Date(),\n      clientMsgId,\n      replyTo: resolvedReplyTo,\n      // Attach any tally already folded for this own-sent message (rare, but keeps\n      // the dangling-target invariant uniform across every append path).\n      reactions: clientMsgId ? this.reactionFold.tally(clientMsgId) : {},\n      // Own-sent edits fold via edit() after the fact; new sends start unedited.\n      edited: false,\n      // Own-sent deletes fold via deleteForEveryone() after the fact; start live.\n      isDeleted: false,\n      // Mentions T6: resolve the own-sent bubble's mentions for its own render (the\n      // sender never gets a wire echo of its own message — this is the only local copy).\n      mentions: this.resolveMentions(text, bodyRanges),\n      // Disappearing T10: the surfaced deadline reflects the message's effective expiry\n      // (explicit `expiresIn` OR the chat default stamped at compose time). null only when\n      // this send is non-disappearing. armPurge re-derives the durable monotonic deadline;\n      // this is the immediate UI countdown baseline (own sender and receiver are symmetric).\n      expiresAt: this.deadlineFor(expiry ?? null),\n    });\n    this.messageList.sort((a, b) => a.serverSeq - b.serverSeq);\n    this.emit();\n  }\n\n  private async materializeIfNeeded(): Promise<MessagingGroup> {\n    if (this._group) return this._group;\n    if (!this._draft) throw new Error('messaging_not_configured');\n    const group = await this.backend.materialize(this._draft);\n    this._group = group;\n    this.id = group.displayId;\n    this._state = 'active';\n    this._draft = null;\n    this.backend.registerActive(group);\n    this.ensureWired();\n    this.emit();\n    return group;\n  }\n\n  // ── Membership (groups only) ──\n\n  async addMemberUser(userId: string): Promise<void> {\n    if (this.kind !== 'group') throw new Error('chat_is_direct');\n    const group = await this.materializeIfNeeded();\n    await this.backend.addMember(group, userId);\n    await this.refreshMembers();\n  }\n\n  async removeMemberUser(userId: string): Promise<void> {\n    if (this.kind !== 'group') throw new Error('chat_is_direct');\n    if (!this._group) throw new Error('messaging_not_configured');\n    await this.backend.removeMember(this._group, userId);\n    await this.refreshMembers();\n  }\n\n  async leave(): Promise<void> {\n    if (!this._group) return;\n    await this.backend.leave(this._group);\n    this.liveUnsub?.();\n    this.liveUnsub = null;\n  }\n\n  // ── Imperative ──\n\n  setTyping(isTyping: boolean): void {\n    if (this._group) this.backend.setTyping(this._group, isTyping);\n  }\n\n  async markRead(message: ChatMessage): Promise<void> {\n    if (!this._group) return;\n    await this.backend.markRead(this._group, message.serverSeq);\n    this.readWatermark = Math.max(this.readWatermark, message.serverSeq);\n    this.emit();\n  }\n\n  // ── Server-metadata cluster: notify scope (mute) + server unread ──\n\n  /** Set this chat's notify scope (the mute toggle). `'none'` mutes the push wake;\n   * `'all'` unmutes (the default). Materializes a draft first (the scope is a\n   * per-(user,group) server row), PUTs `/notify`, and returns the server-echoed scope.\n   * Mirrors iOS `Chat.setNotifyScope`. */\n  async setNotifyScope(scope: NotifyScope): Promise<NotifyScope> {\n    const group = await this.materializeIfNeeded();\n    return this.backend.setNotifyScope(group, scope);\n  }\n\n  /** Refresh + return this chat's notify scope from the server (fail-OPEN to `'all'`).\n   * Returns `'all'` for a draft chat (no server row yet). */\n  async getNotifyScope(): Promise<NotifyScope> {\n    if (!this._group) return 'all';\n    return this.backend.getNotifyScope(this._group);\n  }\n\n  /** Fetch the caller's authoritative SERVER unread count (opaque server metadata).\n   * Returns the clamped count (`max(0, …)`); `0` for a draft chat. The local computed\n   * `unreadCount` getter stays the instant, offline best-effort badge — this is the\n   * canonical count on demand. Named distinctly so it does not shadow the observable\n   * `unreadCount` snapshot getter. Mirrors iOS `Chat.refreshUnread`. */\n  async unreadCountFromServer(): Promise<number> {\n    if (!this._group) return 0;\n    const v = await this.backend.unread(this._group);\n    return Math.max(0, v.unreadCount);\n  }\n\n  // ── Reactions ──\n\n  /** Add an emoji reaction to a message. No-op if the message isn't reactable\n   * (empty clientMsgId — a legacy/system row). The reaction folds locally with\n   * the server receipt's `(epoch, serverSeq)` so the target's tally updates\n   * instantly; the durable echo on the next pump is a fold no-op (dedup on the\n   * SAME wire clientMsgId). Never appends a bubble. */\n  async react(message: ChatMessage, emoji: string): Promise<void> {\n    await this.sendReaction(message, emoji, 'add');\n  }\n\n  /** Remove this user's emoji reaction from a message (op:'remove'). */\n  async unreact(message: ChatMessage, emoji: string): Promise<void> {\n    await this.sendReaction(message, emoji, 'remove');\n  }\n\n  private async sendReaction(\n    message: ChatMessage,\n    emoji: string,\n    op: 'add' | 'remove',\n  ): Promise<void> {\n    if (!message.clientMsgId) return; // not reactable\n    const group = await this.materializeIfNeeded();\n    const clientMsgId = mintClientMsgId();\n    const { receipt } = await this.backend.sendReaction(group, {\n      clientMsgId,\n      targetClientMsgId: message.clientMsgId,\n      emoji,\n      op,\n    });\n    // Fold the own-send locally (actor = self) using the SAME wire clientMsgId so\n    // the durable echo dedups (no double-fold), ordered by the receipt's (epoch,\n    // serverSeq) for LWW. Then recompute the target's tally + emit.\n    this.reactionFold.ingest({\n      targetClientMsgId: message.clientMsgId,\n      actorUserId: this.backend.selfUserId,\n      emoji,\n      op,\n      epoch: receipt.epoch,\n      serverSeq: receipt.serverSeq,\n      eventClientMsgId: clientMsgId,\n    });\n    this.recomputeReactions(message.clientMsgId);\n  }\n\n  // ── Edit ──\n\n  /** Edit an own text message (edit-by-supersession). No-op if the message isn't\n   * editable (empty clientMsgId, or not a `text` kind). The edit folds locally\n   * with the server receipt's `(epoch, serverSeq)` so the target's text updates\n   * instantly; the durable echo on the next pump is a fold no-op (dedup on the\n   * SAME wire clientMsgId). Never appends a bubble; PRESERVES the target's\n   * reactions + reply context. Only the original author's edits count — for an own\n   * message self IS the author, so the author-gate passes. `opts.mentions` carries the\n   * edit's REPLACEMENT mention ranges → the edited message's mentions reflect them. */\n  async edit(\n    message: ChatMessage,\n    newText: string,\n    opts?: { mentions?: MentionRange[] },\n  ): Promise<void> {\n    if (!message.clientMsgId || message.kind !== 'text') return; // not editable\n    const group = await this.materializeIfNeeded();\n    const clientMsgId = mintClientMsgId();\n    const bodyRanges = opts?.mentions ?? null;\n    const { receipt } = await this.backend.sendEdit(group, {\n      clientMsgId,\n      targetClientMsgId: message.clientMsgId,\n      newText,\n      bodyRanges,\n    });\n    // Seed the base text + author (self) if not already recorded — a 2nd own edit\n    // must not corrupt the base (the seed is write-once). self IS the author of an\n    // own message, so authorOfTarget gates the own edit.\n    this.seedEditBase(message.clientMsgId, message.text, this.backend.selfUserId);\n    // Fold the own-send locally (editor = self) using the SAME wire clientMsgId so\n    // the durable echo dedups (no double-fold), ordered by the receipt's (epoch,\n    // serverSeq) for LWW. Carry the edit's replacement ranges so the edited message's\n    // mentions reflect them. Then recompute the target's text + edited in place.\n    this.editFold.ingest(\n      {\n        targetClientMsgId: message.clientMsgId,\n        editorUserId: this.backend.selfUserId,\n        newText,\n        epoch: receipt.epoch,\n        serverSeq: receipt.serverSeq,\n        eventClientMsgId: clientMsgId,\n        bodyRanges,\n      },\n      this.authorOfTarget,\n    );\n    this.recomputeEdit(message.clientMsgId);\n  }\n\n  // ── Delete ──\n\n  /** Delete a message for EVERYONE (a cooperative encrypted tombstone). Only the\n   * ORIGINAL SENDER can do this — for an own message self IS the author, so the\n   * author-gate passes. Legacy messages (empty clientMsgId) are DISABLED (a\n   * tombstone keys on the target's clientMsgId, which they lack) — no-op. Sends a\n   * `type:'delete'` envelope through the SAME MLS path as a text message (the\n   * server stays blind), folds the own delete locally so the target scrubs in\n   * place instantly (the durable echo dedups on the SAME wire clientMsgId), and\n   * re-emits. NEVER appends a bubble. delete-for-me'ing the target becomes moot. */\n  async deleteForEveryone(message: ChatMessage): Promise<void> {\n    if (!message.clientMsgId) return; // legacy → for-everyone disabled\n    const group = await this.materializeIfNeeded();\n    const clientMsgId = mintClientMsgId();\n    const { receipt } = await this.backend.sendDelete(group, {\n      clientMsgId,\n      targetClientMsgId: message.clientMsgId,\n    });\n    // Seed the author (self) so the own delete author-gates: self IS the author of\n    // an own message. The base text seed is write-once + harmless here.\n    this.seedEditBase(message.clientMsgId, message.text, this.backend.selfUserId);\n    // Fold the own delete locally (actor = self = author). Absorbing — the durable\n    // echo on the next pump dedups on the SAME wire clientMsgId.\n    this.deleteFold.ingest(\n      {\n        targetClientMsgId: message.clientMsgId,\n        actorUserId: this.backend.selfUserId,\n        epoch: receipt.epoch,\n        serverSeq: receipt.serverSeq,\n        eventClientMsgId: clientMsgId,\n      },\n      this.authorOfTarget,\n    );\n    this.emit(); // surfaced() re-reads the fold → the target renders \"deleted\"\n  }\n\n  /** Delete a message for ME only — a LOCAL, per-device suppression. NO wire, NO\n   * attribution, no server contact: the message is OMITTED from THIS view and the\n   * suppression key persists per chat (survives reload). The key is the message's\n   * clientMsgId when present, else `seq:<serverSeq>` for legacy messages. */\n  async deleteForMe(message: ChatMessage): Promise<void> {\n    const key = message.clientMsgId ? message.clientMsgId : `seq:${message.serverSeq}`;\n    if (this.suppressed.has(key)) return; // idempotent\n    this.suppressed.add(key);\n    this.emit(); // surfaced() omits it immediately (no wire — nothing sent)\n    // Persist the full set per chat (fire-and-forget; the omit already applied).\n    if (this._group) {\n      try {\n        await this.backend.saveSuppressed(this._group, [...this.suppressed]);\n      } catch {\n        // best-effort — the in-memory omit holds this session even if persist fails\n      }\n    }\n  }\n}\n\n/** Order-sensitive equality of two resolved-mention lists (normalize is deterministic,\n * so equal spans imply equal order). Cheap shortcut so the overlay paths can no-op. */\nfunction sameMentions(a: ResolvedMention[], b: ResolvedMention[]): boolean {\n  if (a.length !== b.length) return false;\n  for (let i = 0; i < a.length; i++) {\n    const x = a[i];\n    const y = b[i];\n    if (!x || !y) return false;\n    if (\n      x.start !== y.start ||\n      x.length !== y.length ||\n      x.mentionedUserId !== y.mentionedUserId ||\n      x.displayName !== y.displayName\n    ) {\n      return false;\n    }\n  }\n  return true;\n}\n\n/** Shallow-equal two reaction tallies (emoji → sorted userIds[]). */\nfunction sameReactions(a: Record<string, string[]>, b: Record<string, string[]>): boolean {\n  const ak = Object.keys(a);\n  const bk = Object.keys(b);\n  if (ak.length !== bk.length) return false;\n  for (const k of ak) {\n    const av = a[k];\n    const bv = b[k];\n    if (!bv || av === undefined || av.length !== bv.length) return false;\n    for (let i = 0; i < av.length; i++) if (av[i] !== bv[i]) return false;\n  }\n  return true;\n}\n","// The live delivery source — the web mirror of iOS MessageDeliverySource.\n// Subscribes the device wake topic `messaging:device:<id>` over pb.realtime\n// (new_message wake → pumpOnce), and on each pump drains:\n//\n//   1. welcomes  → engine.joinFromWelcome → register the group + emit `welcome`\n//   2. device queue → for each row:\n//        - COMMIT: processIncoming (applies), bump epoch, emit `commit`\n//        - APPLICATION: decrypt → persist plaintext → emit `message`\n//   3. ack everything consumed.\n//\n// The realtime wake is notification-only; the authoritative messages come from\n// the authenticated queue pull (never the broadcast payload), exactly as iOS.\n//\n// SERVER WIRE GAP (same as iOS): queue rows do NOT yet carry rfc_group_id or the\n// fanned declaration. When absent, route a blob to the SOLE known group (the\n// common 1:1/small-group case). The reconciliation-gate hook (describeIncoming)\n// is ready for the day the server fans the declaration — a pure server change.\n\nimport { palbeRequest } from '../request.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport {\n  type DeletePayload,\n  decodeEnvelope,\n  type EditPayload,\n  type ExpirySpec,\n  GroupMessaging,\n  type MentionRange,\n  type MessagingGroup,\n  type ReactionPayload,\n  type ReplyRef,\n} from './group-messaging.js';\nimport type { MessageStore, StoredMessage } from './history.js';\nimport type { MlsEngine } from './mls-engine.js';\nimport type { GroupRegistry } from './registry.js';\nimport type { NotifyScope, UnreadView } from './types.js';\nimport { decodeUtf8, fromBase64, toBase64 } from './util.js';\nimport {\n  ContentType,\n  MessagingPaths,\n  type QueuedMessage,\n  type QueuePage,\n  type WelcomePage,\n} from './wire.js';\n\n/** A decoded incoming message handed to chat listeners. */\nexport interface IncomingMessage {\n  kind: 'application' | 'commit' | 'proposal' | 'welcome';\n  group: MessagingGroup;\n  text: string | null;\n  senderDeviceId: string | null;\n  epoch: number;\n  serverSeq: number;\n  receivedAt: Date;\n  /** The client-minted idempotency id from the decoded envelope (empty string for legacy/system). */\n  clientMsgId: string;\n  /** The decoded reply reference, if present in the envelope. */\n  replyRef: ReplyRef | null;\n  /**\n   * The decoded envelope discriminator (`'text'`/`'reaction'`/`'media'`/…).\n   * Defaults to `'text'` at every existing call site — only the reaction branch\n   * sets `'reaction'`, so the Chat can route a reaction into its fold instead of\n   * appending a visible bubble. Optional for forward-compat with old emitters.\n   */\n  envelopeType?: string;\n  /** The decoded reaction payload, present only when `envelopeType === 'reaction'`. */\n  reaction?: ReactionPayload | null;\n  /** The decoded edit payload, present only when `envelopeType === 'edit'`. Lets\n   * the Chat route an edit into its EditFold instead of appending a visible bubble. */\n  edit?: EditPayload | null;\n  /** The decoded delete payload, present only when `envelopeType === 'delete'`. Lets\n   * the Chat route a delete-for-everyone tombstone into its DeleteFold instead of\n   * appending a visible bubble. */\n  delete?: DeletePayload | null;\n  /** The decoded mention ranges (raw, un-normalized). Present on a `'text'` bubble\n   * with `body_ranges` OR on an `'edit'` (the edit's replacement ranges). The Chat\n   * normalizes + resolves roster names → `ChatMessage.mentions` (mentions T6). */\n  bodyRanges?: MentionRange[] | null;\n  /** The decoded `timer_set` payload, present only when `envelopeType === 'timer_set'`\n   * (disappearing T10). Lets the Chat route a chat-default timer into its TimerFold\n   * instead of appending a visible bubble. */\n  timer?: { ttlSeconds: number | null; start: 'send' | 'read' } | null;\n  /** The decoded per-message TTL spec, present only on a `'text'` bubble that carried an\n   * `expiry` (disappearing T10). Lets the Chat arm the message's purge on first display. */\n  expiry?: ExpirySpec | null;\n}\n\ntype MessageListener = (m: IncomingMessage) => void;\ntype ConvEvent = { event: string; payload: Record<string, unknown> };\ntype ConvListener = (e: ConvEvent) => void;\n\n/** A tiny per-group fan-out hub (the web analogue of the iOS message/conv hubs). */\nexport class MessageHub {\n  private readonly messageListeners = new Map<string, Set<MessageListener>>();\n  private readonly convListeners = new Map<string, Set<ConvListener>>();\n\n  onMessage(displayId: string, fn: MessageListener): () => void {\n    return this.add(this.messageListeners, displayId, fn);\n  }\n  emitMessage(displayId: string, m: IncomingMessage): void {\n    for (const fn of this.messageListeners.get(displayId) ?? []) fn(m);\n  }\n  onConv(displayId: string, fn: ConvListener): () => void {\n    return this.add(this.convListeners, displayId, fn);\n  }\n  emitConv(displayId: string, e: ConvEvent): void {\n    for (const fn of this.convListeners.get(displayId) ?? []) fn(e);\n  }\n  /** How many live conv listeners a group still has — the census the LAST\n   * subscriber reads before tearing the conv topic (and its presence) down. */\n  convListenerCount(displayId: string): number {\n    return this.convListeners.get(displayId)?.size ?? 0;\n  }\n\n  private add<T>(map: Map<string, Set<T>>, key: string, fn: T): () => void {\n    let set = map.get(key);\n    if (!set) {\n      set = new Set();\n      map.set(key, set);\n    }\n    set.add(fn);\n    return () => {\n      set?.delete(fn);\n    };\n  }\n}\n\n/**\n * Decode the MLS-authenticated sender identity (`received.sender`) into the\n * `mdv_…` device id. The leaf-credential identity is exactly the SP-0 device id\n * UTF-8 bytes (see MlsEngine: `idBytes = utf8.encode(deviceId)`), so a plain\n * UTF-8 decode recovers it. Returns null for an empty/garbage identity so the\n * downstream `if (senderDeviceId)` guard stays sound (no spoofable empty actor).\n */\nfunction decodeSenderDeviceId(sender: Uint8Array): string | null {\n  if (sender.length === 0) return null;\n  const id = decodeUtf8(sender);\n  return id.length > 0 ? id : null;\n}\n\nexport class MessageDeliverySource {\n  private started = false;\n  private wakeUnsub: (() => void) | null = null;\n  // Per-observed-group conv subscription + heartbeat (presence/typing/read).\n  // `teardown` is the ONE departure path: it stops the heartbeat, broadcasts the\n  // offline frame and drops the subscriptions, so no caller can tear an\n  // observation down without saying goodbye (see observeConversation).\n  private readonly observed = new Map<string, { teardown: () => void }>();\n\n  constructor(\n    private readonly rt: PalbeRuntime,\n    private readonly engine: MlsEngine,\n    private readonly hub: MessageHub,\n    private readonly registry: GroupRegistry,\n    private readonly messageStore: MessageStore,\n    private readonly deviceId: string,\n    private readonly selfUserId: string,\n  ) {}\n\n  /** Subscribe the device wake topic + run an initial drain. Idempotent. */\n  async start(): Promise<void> {\n    if (this.started) return;\n    this.started = true;\n    try {\n      const channel = this.rt.realtime.channel(`messaging:device:${this.deviceId}`);\n      const sub = channel.on('new_message', () => {\n        void this.pumpOnce();\n      });\n      // Re-pump on every (re)connect to catch wakes missed while offline.\n      const offConn = this.rt.realtime.status.onChange((s) => {\n        if (s.state === 'connected') void this.pumpOnce();\n      });\n      this.wakeUnsub = () => {\n        sub.cancel();\n        offConn();\n      };\n    } catch {\n      // No WebSocket (SSR/Node) — the wake source is inert; explicit pumps still work.\n    }\n    await this.pumpOnce();\n  }\n\n  stop(): void {\n    this.wakeUnsub?.();\n    this.wakeUnsub = null;\n    for (const [, o] of this.observed) o.teardown();\n    this.observed.clear();\n    this.started = false;\n  }\n\n  /** One full drain: welcomes → queue (decrypt + emit) → ack. Never throws. */\n  async pumpOnce(): Promise<void> {\n    try {\n      await this.pullWelcomes();\n    } catch {\n      // transient — the next wake retries\n    }\n    try {\n      await this.pullQueue();\n    } catch {\n      // transient — the next wake retries\n    }\n  }\n\n  // ── Welcomes ──\n\n  private async pullWelcomes(): Promise<void> {\n    const page = await palbeRequest<WelcomePage>(\n      this.rt,\n      'GET',\n      MessagingPaths.deviceWelcomes(this.deviceId),\n    );\n    for (const w of page.welcomes) {\n      try {\n        const gidBytes = await this.engine.joinFromWelcome(fromBase64(w.welcome_b64));\n        // Register under the server-minted grp_ display_id (url-safe), NEVER the\n        // base64 rfc_group_id (which would 404 the members route — M3 #7).\n        const group: MessagingGroup = {\n          displayId: w.display_id,\n          rfcGroupId: toBase64(gidBytes),\n          currentEpoch: w.added_at_epoch,\n          ownerUserId: null,\n          directKey: null,\n          name: null,\n        };\n        this.registry.register(group);\n        this.hub.emitMessage(group.displayId, {\n          kind: 'welcome',\n          group,\n          text: null,\n          senderDeviceId: null,\n          epoch: w.added_at_epoch,\n          serverSeq: 0,\n          receivedAt: new Date(),\n          clientMsgId: '',\n          replyRef: null,\n        });\n      } catch {\n        // POISON-PILL GUARD: a re-served welcome whose one-time KeyPackage was\n        // already consumed (a duplicate for a membership we hold) fails join\n        // forever — skip quietly when the group is already known.\n        const known = this.registry.all().some((g) => g.displayId === w.display_id);\n        if (!known) {\n          // genuinely unknown group — swallow (best-effort pump); next wake retries\n        }\n      }\n    }\n  }\n\n  // ── Queue ──\n\n  private async pullQueue(): Promise<void> {\n    const page = await palbeRequest<QueuePage>(\n      this.rt,\n      'GET',\n      MessagingPaths.deviceQueue(this.deviceId),\n    );\n    const ackIds: string[] = [];\n    for (const row of page.messages) {\n      if (await this.process(row)) ackIds.push(row.id);\n    }\n    if (ackIds.length > 0) {\n      await palbeRequest<void>(this.rt, 'POST', MessagingPaths.deviceQueueAck(this.deviceId), {\n        body: { message_ids: ackIds },\n      });\n    }\n  }\n\n  /** Process one queue row; returns true if consumed (should ack). */\n  private async process(row: QueuedMessage): Promise<boolean> {\n    let blob: Uint8Array;\n    try {\n      blob = fromBase64(row.ciphertext_b64);\n    } catch {\n      return true; // junk → drop\n    }\n    // Resolve the target group: prefer the row's own rfc, else the sole group.\n    const group =\n      (row.rfc_group_id_b64 ? this.registry.group(row.rfc_group_id_b64) : undefined) ??\n      this.registry.soleGroup();\n    if (!group) return false; // unresolvable → leave unacked\n\n    try {\n      const received = await this.engine.processIncoming(fromBase64(group.rfcGroupId), blob);\n      if (received.type === 'application') {\n        const decoded = decodeEnvelope(received.data);\n        const { text, clientMsgId, replyTo } = decoded;\n        const isReaction = decoded.type === 'reaction' && decoded.reaction != null;\n        const isEdit = decoded.type === 'edit' && decoded.edit != null;\n        const isDelete = decoded.type === 'delete' && decoded.delete != null;\n        const isTimerSet = decoded.type === 'timer_set' && decoded.timer != null;\n        // SENDER ATTRIBUTION: prefer the server's `sender_device_id`, but the live\n        // server does NOT yet fan that field onto queue rows (same gap as\n        // `rfc_group_id` — see QueuedMessage). So fall back to the MLS-decrypted\n        // sender (`received.sender`), which IS the device's leaf-credential\n        // identity bytes (`mdv_…`, the SP-0 device id). This is the\n        // cryptographically authenticated sender — strictly stronger than a\n        // server-asserted field, and unspoofable. Without it, a peer's reaction\n        // arrives with a null sender → the Chat fold can't resolve the actor and\n        // SILENTLY DROPS it (text still renders, reactions vanish — the live bug).\n        const senderDeviceId = row.sender_device_id ?? decodeSenderDeviceId(received.sender);\n        const stored: StoredMessage = {\n          id: `${group.rfcGroupId}#${row.server_seq}`,\n          direction: 'incoming',\n          text,\n          senderDeviceId,\n          epoch: row.epoch,\n          serverSeq: row.server_seq,\n          at: Date.now(),\n          clientMsgId: clientMsgId || undefined,\n          replyTo: replyTo\n            ? {\n                clientMsgId: replyTo.client_msg_id,\n                previewBody: replyTo.preview?.body ?? null,\n                previewAuthorUserId: replyTo.preview?.author_user_id ?? null,\n                previewKind: replyTo.preview?.kind ?? 'text',\n              }\n            : null,\n          // Thread the reaction discriminator + fields through the persisted row so\n          // a reaction folded LIVE re-folds onto its target after a reload (the\n          // reload-parity boundary — mirrors iOS T3). Omitted for non-reactions →\n          // old rows hydrate as `'text'`/no-reaction (backward-compat).\n          ...(isReaction && decoded.reaction\n            ? {\n                envelopeType: 'reaction' as const,\n                reaction: {\n                  targetClientMsgId: decoded.reaction.targetClientMsgId,\n                  emoji: decoded.reaction.emoji,\n                  op: decoded.reaction.op,\n                },\n              }\n            : {}),\n          // Thread the edit discriminator + new text through the persisted row so an\n          // edit folded LIVE re-folds onto its target after a reload (the reload-parity\n          // boundary — mirrors iOS T3). Omitted for non-edits → old rows hydrate as\n          // `'text'`/no-edit (backward-compat). The edit's replacement body_ranges ride\n          // along so the edited message's mentions re-resolve on cold launch (T6).\n          ...(isEdit && decoded.edit\n            ? {\n                envelopeType: 'edit' as const,\n                edit: {\n                  targetClientMsgId: decoded.edit.targetClientMsgId,\n                  newText: decoded.edit.newText,\n                  ...(decoded.bodyRanges ? { bodyRanges: decoded.bodyRanges } : {}),\n                },\n              }\n            : {}),\n          // Thread the TEXT bubble's mention ranges (raw) through the persisted row so a\n          // mention surfaced LIVE re-resolves onto its bubble after a reload (the\n          // reload-parity boundary for mentions — T6, mirrors iOS T3). Only on a text\n          // bubble (not a reaction/edit/delete row); omitted when absent (backward-compat).\n          ...(!isReaction && !isEdit && !isDelete && decoded.bodyRanges\n            ? { bodyRanges: decoded.bodyRanges }\n            : {}),\n          // Thread the delete discriminator + target through the persisted row so a\n          // delete-for-everyone tombstone folded LIVE re-folds onto its target after\n          // a reload (the reload-parity boundary — the iOS-review CRITICAL lesson;\n          // the projection's `.delete` branch re-folds it so it never leaks a blank\n          // bubble). Omitted for non-deletes → old rows hydrate as `'text'`/no-delete.\n          ...(isDelete && decoded.delete\n            ? {\n                envelopeType: 'delete' as const,\n                delete: {\n                  targetClientMsgId: decoded.delete.targetClientMsgId,\n                  scope: decoded.delete.scope,\n                },\n              }\n            : {}),\n          // Disappearing T10: thread the timer_set discriminator + payload through the\n          // persisted row so the chat default re-folds on cold launch (the page-local\n          // TimerFold in projectHistory). Omitted for non-timer_set rows (backward-compat).\n          ...(isTimerSet && decoded.timer\n            ? {\n                envelopeType: 'timer_set' as const,\n                timer: { ttlSeconds: decoded.timer.ttlSeconds, start: decoded.timer.start },\n              }\n            : {}),\n          // Disappearing T10: thread a TEXT bubble's per-message expiry through the persisted\n          // row so the message re-arms its purge on cold launch (the projection derives the\n          // deadline from this). Only on a text bubble; omitted when absent (backward-compat).\n          ...(!isReaction && !isEdit && !isDelete && !isTimerSet && decoded.expiry\n            ? { expiry: decoded.expiry }\n            : {}),\n        };\n        try {\n          await this.messageStore.append(group.rfcGroupId, stored);\n        } catch {\n          return false; // persist failed → NOT acked, re-served next pump\n        }\n        this.hub.emitMessage(group.displayId, {\n          kind: 'application',\n          group,\n          text,\n          senderDeviceId,\n          epoch: row.epoch,\n          serverSeq: row.server_seq,\n          receivedAt: new Date(),\n          clientMsgId,\n          replyRef: replyTo,\n          envelopeType: decoded.type ?? 'text',\n          reaction: isReaction ? decoded.reaction : null,\n          edit: isEdit ? decoded.edit : null,\n          delete: isDelete ? decoded.delete : null,\n          // The raw mention ranges (text bubble or the edit's replacement ranges); the\n          // Chat normalizes + resolves names → ChatMessage.mentions (T6).\n          bodyRanges: decoded.bodyRanges ?? null,\n          // Disappearing T10: the decoded timer_set payload (chat default control) + a text\n          // bubble's per-message expiry. The Chat routes timer_set into its TimerFold and\n          // arms a bubble's purge from the expiry (or the active default).\n          timer: isTimerSet ? decoded.timer : null,\n          expiry:\n            !isReaction && !isEdit && !isDelete && !isTimerSet ? (decoded.expiry ?? null) : null,\n        });\n        return true;\n      }\n      if (received.type === 'commitApplied') {\n        const newEpoch = Math.max(row.epoch, group.currentEpoch + 1);\n        this.registry.bumpEpoch(group.rfcGroupId, newEpoch);\n        const fresh = this.registry.group(group.rfcGroupId) ?? group;\n        this.hub.emitMessage(group.displayId, {\n          kind: 'commit',\n          group: fresh,\n          text: null,\n          senderDeviceId: row.sender_device_id ?? null,\n          epoch: newEpoch,\n          serverSeq: 0,\n          receivedAt: new Date(),\n          clientMsgId: '',\n          replyRef: null,\n        });\n        return true;\n      }\n      return true; // proposal / other — consumed\n    } catch (e) {\n      // Own-sent echo or consumed-key: mls-rs refuses to decrypt own ciphertext /\n      // a replayed generation. ACK + skip (the durable copy is the send path's).\n      if (isOwnEchoOrConsumed(e)) return true;\n      return false; // decode/transient → leave unacked for retry\n    }\n  }\n\n  // ── Conv topic (presence / typing / read) ──\n\n  /** Begin observing a group's conv topic; fans events into the hub. Idempotent. */\n  observeConversation(group: MessagingGroup): void {\n    if (this.observed.has(group.displayId)) return;\n    try {\n      const channel = this.rt.realtime.channel(`messaging:conv:${group.rfcGroupId}`);\n      // Server-metadata cluster: subscribe `delivered` alongside `read` (its exact 3-key\n      // twin `{user_id, device_id, up_to_server_seq}`) so the sender's \"delivered\" tick\n      // advances. The Chat consumes both via applyConv → the per-message user-level\n      // monotonic watermark fold (mirrors iOS MessageDeliverySource's delivered case).\n      const subs = ['presence', 'typing', 'read', 'delivered'].map((ev) =>\n        channel.on(ev, (payload) => {\n          this.hub.emitConv(group.displayId, { event: ev, payload });\n        }),\n      );\n      // Announce online + heartbeat every 25s.\n      const emitPresence = (online: boolean) =>\n        channel.send('presence', {\n          user_id: this.selfUserId,\n          device_id: this.deviceId,\n          online,\n          ts: Date.now() / 1000,\n        });\n      emitPresence(true);\n      const heartbeat = setInterval(() => emitPresence(true), 25_000);\n      this.observed.set(group.displayId, {\n        teardown: () => {\n          // Stop the heartbeat BEFORE the goodbye so no beat can land after it.\n          clearInterval(heartbeat);\n          // The departure frame. Presence is broadcast-only — a peer's light is\n          // lit and unlit solely by these frames, and the server keeps no\n          // expiry that would time this device out — so leaving without it\n          // leaves every peer showing us online for the rest of their session.\n          try {\n            emitPresence(false);\n          } catch {\n            // socket already gone — nothing left to say goodbye through\n          }\n          for (const s of subs) s.cancel();\n        },\n      });\n    } catch {\n      // no socket (SSR) — presence/typing simply unavailable\n    }\n  }\n\n  /** Stop observing a group's conv topic: announce OFFLINE, stop the heartbeat\n   * and drop the subscriptions. Idempotent — an unobserved group is a no-op. */\n  unobserveConversation(group: MessagingGroup): void {\n    const o = this.observed.get(group.displayId);\n    if (!o) return;\n    this.observed.delete(group.displayId);\n    o.teardown();\n  }\n\n  /** Announce typing on a group's conv topic (the app calls per keystroke). */\n  setTyping(group: MessagingGroup, isTyping: boolean): void {\n    this.observeConversation(group);\n    try {\n      this.rt.realtime.channel(`messaging:conv:${group.rfcGroupId}`).send('typing', {\n        user_id: this.selfUserId,\n        device_id: this.deviceId,\n        typing: isTyping,\n      });\n    } catch {\n      // no socket\n    }\n  }\n\n  /** Advance this device's read cursor (idempotent; the server clamps). */\n  async markRead(group: MessagingGroup, upToServerSeq: number): Promise<void> {\n    await palbeRequest<void>(this.rt, 'POST', MessagingPaths.groupRead(group.displayId), {\n      body: { read_seq: upToServerSeq, read_epoch: group.currentEpoch, is_private: false },\n    });\n  }\n\n  // ── Server-metadata cluster: notify scope (mute) + unread (HTTP) ──\n\n  /** PUT `/v1/messaging/groups/{gid}/notify` — set the caller's per-(user,group) notify\n   * scope (`'all'`|`'none'`). The server stores the opaque enum verbatim and stays blind.\n   * Returns the server-echoed scope (fail-OPEN to `'all'` on an unknown value). */\n  async setNotifyScope(group: MessagingGroup, scope: NotifyScope): Promise<NotifyScope> {\n    const res = await palbeRequest<{ notify_scope: string }>(\n      this.rt,\n      'PUT',\n      MessagingPaths.groupNotify(group.displayId),\n      { body: { notify_scope: scope } },\n    );\n    return res.notify_scope === 'none' ? 'none' : 'all';\n  }\n\n  /** GET `/v1/messaging/groups/{gid}/notify` — the caller's notify scope. An absent\n   * server row / unknown value reads as `'all'` (fail-OPEN — never silently mutes). */\n  async getNotifyScope(group: MessagingGroup): Promise<NotifyScope> {\n    const res = await palbeRequest<{ notify_scope: string }>(\n      this.rt,\n      'GET',\n      MessagingPaths.groupNotify(group.displayId),\n    );\n    return res.notify_scope === 'none' ? 'none' : 'all';\n  }\n\n  /** GET `/v1/messaging/groups/{gid}/unread` — the caller's OWN unread view (opaque\n   * server metadata). Maps the snake_case wire → the camelCase `UnreadView`. */\n  async unread(group: MessagingGroup): Promise<UnreadView> {\n    const res = await palbeRequest<{\n      group_max_seq: number;\n      last_read_seq: number;\n      delivered_seq: number;\n      unread_count: number;\n    }>(this.rt, 'GET', MessagingPaths.groupUnread(group.displayId));\n    return {\n      groupMaxSeq: res.group_max_seq,\n      lastReadSeq: res.last_read_seq,\n      deliveredSeq: res.delivered_seq,\n      unreadCount: res.unread_count,\n    };\n  }\n}\n\n/** mls-rs own-echo (\"message from self can't be processed\") or consumed-key\n * (\"key not available, invalid generation\") — both ACK-and-skip on the receiver. */\nfunction isOwnEchoOrConsumed(e: unknown): boolean {\n  const msg = e instanceof Error ? e.message : String(e);\n  return msg.includes('message from self') || msg.includes('key not available, invalid generation');\n}\n\n// keep GroupMessaging/ContentType referenced for the wire-gap declaration hook\nvoid GroupMessaging;\nvoid ContentType;\n","// The disappearing/TTL durable store — the web mirror of iOS `DisappearingStore`.\n//\n// Holds the crash-safe purge state for disappearing messages, sealed at rest by the\n// same durable KV (IndexedDB + WebCrypto AES-GCM in the browser) that seals the\n// message store, so it survives a cold launch / mid-purge crash.\n//\n// TWO SEPARATE persistent purge sets, two key namespaces that CANNOT collide:\n//   (a) `tombstonedSeqs` — an INTEGER `server_seq` tombstone. Written FIRST (the purge\n//       commit point), it drives transcript exclusion (rebuilt-from-store skips a\n//       tombstoned seq) + redelivery drop (a redelivered tombstoned seq is dropped on\n//       arrival). A mid-purge crash AFTER this write resurrects the tombstone on reload.\n//   (b) `purgedClientMsgIds` — a STRING `client_msg_id` set. It drives the orphan-fold\n//       resolver (`authorOfTarget → 'purged'`) so a late edit DROPs and a late delete\n//       no-ops against a TTL-purged target.\n// The int seq and the string id live in distinct JSON fields; one is NEVER keyed off\n// the other (per the TTL global constraint).\n//\n// Anchors are WRITE-ONCE per `(device, clientMsgId)`: the first arrival captures the\n// monotonic/wall/boot anchor triple; a later re-arm for the same clientMsgId is a\n// no-op, so the deadline never resets.\n\nimport type { AnchorTriple } from './deadline-calculator.js';\nimport type { DurableKV } from './storage.js';\nimport { decodeUtf8, encodeUtf8 } from './util.js';\n\ninterface DisappearingRecord {\n  tombstonedSeqs: number[];\n  purgedClientMsgIds: string[];\n  anchors: Record<string, AnchorTriple>;\n}\n\n/**\n * Per-chat IndexedDB-backed store for disappearing durable state (keyed by\n * `disappear:<rfcGroupId>`). Mirrors `SuppressionStore`'s DurableKV/JSON pattern.\n */\nexport class DisappearingStore {\n  constructor(private readonly kv: DurableKV) {}\n\n  private key(rfc: string): string {\n    return `disappear:${rfc}`;\n  }\n\n  private async load(rfc: string): Promise<DisappearingRecord> {\n    const raw = await this.kv.get(this.key(rfc));\n    if (!raw) return { tombstonedSeqs: [], purgedClientMsgIds: [], anchors: {} };\n    try {\n      const r = JSON.parse(decodeUtf8(raw)) as Partial<DisappearingRecord>;\n      return {\n        tombstonedSeqs: r.tombstonedSeqs ?? [],\n        purgedClientMsgIds: r.purgedClientMsgIds ?? [],\n        anchors: r.anchors ?? {},\n      };\n    } catch {\n      return { tombstonedSeqs: [], purgedClientMsgIds: [], anchors: {} };\n    }\n  }\n\n  private async save(rfc: string, rec: DisappearingRecord): Promise<void> {\n    await this.kv.set(this.key(rfc), encodeUtf8(JSON.stringify(rec)));\n  }\n\n  /** The persisted INTEGER `server_seq` tombstone set for a chat (transcript exclusion + redelivery drop). */\n  async tombstonedSeqs(rfc: string): Promise<Set<number>> {\n    return new Set((await this.load(rfc)).tombstonedSeqs);\n  }\n\n  /** The persisted STRING `client_msg_id` purge set for a chat (orphan-fold → `'purged'`). */\n  async purgedClientMsgIds(rfc: string): Promise<Set<string>> {\n    return new Set((await this.load(rfc)).purgedClientMsgIds);\n  }\n\n  /**\n   * Tombstone-first commit point: the INTEGER seq and the STRING client_msg_id are\n   * written together in ONE durable record. Idempotent (re-tombstoning the same seq /\n   * id is a no-op). This write is THE purge commit — once it lands, a transcript rebuilt\n   * from the store excludes the seq and a redelivery is dropped, even across a crash.\n   */\n  async tombstone(rfc: string, serverSeq: number, clientMsgId: string): Promise<void> {\n    const rec = await this.load(rfc);\n    if (!rec.tombstonedSeqs.includes(serverSeq)) rec.tombstonedSeqs.push(serverSeq);\n    if (clientMsgId && !rec.purgedClientMsgIds.includes(clientMsgId)) {\n      rec.purgedClientMsgIds.push(clientMsgId);\n    }\n    await this.save(rfc, rec);\n  }\n\n  /** The persisted write-once anchor triple for a `clientMsgId`, or null if none. */\n  async anchor(rfc: string, clientMsgId: string): Promise<AnchorTriple | null> {\n    return (await this.load(rfc)).anchors[clientMsgId] ?? null;\n  }\n\n  /** Write-once: a second call for the same `clientMsgId` is a no-op (deadline never resets). */\n  async writeAnchorOnce(rfc: string, clientMsgId: string, a: AnchorTriple): Promise<void> {\n    const rec = await this.load(rfc);\n    if (rec.anchors[clientMsgId]) return;\n    rec.anchors[clientMsgId] = a;\n    await this.save(rfc, rec);\n  }\n}\n","// Local decrypted-message history + the group catalog — the web mirror of iOS\n// MessageStore + GroupCatalog. MLS decrypt-once means a received message's key\n// is erased on first decrypt, so you can NEVER refetch+redecrypt it from the\n// server: the decrypted plaintext MUST be persisted locally (sealed at rest by\n// the durable KV — IndexedDB+WebCrypto-AES-GCM in the browser). The own-sent\n// copy is likewise the only durable form (the sender can't decrypt its own\n// ciphertext).\n\nimport type { MentionRange } from './group-messaging.js';\nimport type { DurableKV } from './storage.js';\nimport type { MessageDirection } from './types.js';\nimport { decodeUtf8, encodeUtf8 } from './util.js';\n\n/** A durable stored message (one row in the local sealed transcript). */\nexport interface StoredMessage {\n  /** Stable across reloads: `<rfcGroupId>#<serverSeq>`. */\n  id: string;\n  direction: MessageDirection;\n  text: string | null;\n  senderDeviceId: string | null;\n  epoch: number;\n  serverSeq: number;\n  /** ms since epoch. */\n  at: number;\n  /**\n   * Client-minted idempotency id from the decoded envelope.\n   * Optional for backward-compat: old persisted rows without this key\n   * are treated as '' (no id) on read.\n   */\n  clientMsgId?: string;\n  /**\n   * The decoded reply reference, if the message was a reply.\n   * Optional for backward-compat: old persisted rows without this key\n   * are treated as null on read.\n   */\n  replyTo?: {\n    clientMsgId: string;\n    previewBody: string | null;\n    previewAuthorUserId: string | null;\n    previewKind: string;\n  } | null;\n  /**\n   * The decoded envelope discriminator (`'text'`/`'reaction'`/…).\n   * Optional for backward-compat: old persisted rows without this key are treated\n   * as `'text'` (a non-reaction) on read, so a pre-reactions row never re-folds.\n   */\n  envelopeType?: string;\n  /**\n   * The decoded reaction payload, present only when `envelopeType === 'reaction'`.\n   * Optional + backward-compat (old rows → undefined → no re-fold). Threading this\n   * through the persisted shape is the reload-parity boundary: a reaction folded\n   * LIVE re-folds onto its target after a cold launch.\n   */\n  reaction?: {\n    targetClientMsgId: string;\n    emoji: string;\n    op: 'add' | 'remove';\n  } | null;\n  /**\n   * The decoded edit payload, present only when `envelopeType === 'edit'`.\n   * Optional + backward-compat (old rows → undefined → no re-fold). Threading this\n   * through the persisted shape is the reload-parity boundary for edits: an edit\n   * folded LIVE re-folds onto its target's text after a cold launch.\n   */\n  edit?: {\n    targetClientMsgId: string;\n    newText: string;\n    /**\n     * The edit's REPLACEMENT mention ranges (raw, un-normalized). Optional +\n     * backward-compat (old rows → undefined). Threaded so an edited message's\n     * mentions re-resolve from the WINNING edit's ranges after a reload (mentions T6).\n     */\n    bodyRanges?: MentionRange[] | null;\n  } | null;\n  /**\n   * The decoded mention ranges on a TEXT/media bubble (raw, un-normalized — the\n   * Chat/projection normalizes + resolves names). Present only on `'text'` rows that\n   * carried `body_ranges`. Optional + backward-compat (old rows → undefined → no\n   * mentions). Threading this through the persisted shape is the reload-parity\n   * boundary for mentions: a mention surfaced LIVE re-resolves onto its bubble after a\n   * cold launch (mentions T6, mirrors iOS T3).\n   */\n  bodyRanges?: MentionRange[] | null;\n  /**\n   * The decoded delete payload, present only when `envelopeType === 'delete'`.\n   * Optional + backward-compat (old rows → undefined → no re-fold). Threading this\n   * through the persisted shape is the reload-parity boundary for deletes: a\n   * delete-for-everyone tombstone folded LIVE re-folds onto its target after a\n   * cold launch (and never leaks as a blank bubble — the iOS-review CRITICAL\n   * lesson: the projection MUST have a `.delete` branch).\n   */\n  delete?: {\n    targetClientMsgId: string;\n    scope: string;\n  } | null;\n  /**\n   * The decoded per-message TTL spec (own-sent / decoded), present only on a text/media\n   * row that carried an `expiry` (disappearing T10). Optional + backward-compat (old rows\n   * → undefined → no re-arm). Threaded so an own-send TTL re-arms its purge after a cold\n   * launch, and so the cold-launch `projectHistory` derives the message's effective TTL.\n   */\n  expiry?: {\n    v: number;\n    ttlSeconds: number;\n    start: 'send' | 'read';\n    senderSendTs: number | null;\n  } | null;\n  /**\n   * The decoded `timer_set` payload, present only when `envelopeType === 'timer_set'`\n   * (disappearing T10). Optional + backward-compat (old rows → undefined → no re-fold).\n   * Threaded so the chat default disappearing timer re-folds on a cold launch (the\n   * page-local `TimerFold` in `projectHistory`). `ttlSeconds === null` disables the default.\n   */\n  timer?: {\n    ttlSeconds: number | null;\n    start: 'send' | 'read';\n  } | null;\n}\n\n/** Persist decrypted messages per group, newest-last, deduped by id. */\nexport class MessageStore {\n  constructor(private readonly kv: DurableKV) {}\n\n  private key(rfcGroupId: string): string {\n    return `msgs:${rfcGroupId}`;\n  }\n\n  /** Append (idempotent on id) and persist the group's transcript. */\n  async append(rfcGroupId: string, msg: StoredMessage): Promise<void> {\n    const list = await this.load(rfcGroupId);\n    if (list.some((m) => m.id === msg.id)) return; // dedup by stable id\n    list.push(msg);\n    list.sort((a, b) => a.serverSeq - b.serverSeq);\n    await this.save(rfcGroupId, list);\n  }\n\n  /** True if a message id is already durable (the consumed-key recovery check). */\n  async contains(rfcGroupId: string, id: string): Promise<boolean> {\n    const list = await this.load(rfcGroupId);\n    return list.some((m) => m.id === id);\n  }\n\n  /**\n   * Read history for a group, newest-last. `before` pages older: returns up to\n   * `limit` rows with serverSeq < before. nil `before` returns the newest page.\n   */\n  async history(rfcGroupId: string, limit: number, before?: number): Promise<StoredMessage[]> {\n    const list = await this.load(rfcGroupId);\n    const filtered = before == null ? list : list.filter((m) => m.serverSeq < before);\n    return filtered.slice(Math.max(0, filtered.length - limit));\n  }\n\n  async load(rfcGroupId: string): Promise<StoredMessage[]> {\n    const raw = await this.kv.get(this.key(rfcGroupId));\n    if (!raw) return [];\n    try {\n      return JSON.parse(decodeUtf8(raw)) as StoredMessage[];\n    } catch {\n      return [];\n    }\n  }\n\n  private async save(rfcGroupId: string, list: StoredMessage[]): Promise<void> {\n    await this.kv.set(this.key(rfcGroupId), encodeUtf8(JSON.stringify(list)));\n  }\n\n  async wipe(): Promise<void> {\n    for (const k of await this.kv.keys('msgs:')) await this.kv.delete(k);\n  }\n}\n\n/** A persisted group entry (the catalog row — survives reloads). */\nexport interface CatalogGroup {\n  displayId: string;\n  rfcGroupId: string;\n  currentEpoch: number;\n  ownerUserId: string | null;\n  directKey: string | null;\n  name: string | null;\n}\n\n/** Durable list of known groups (the web mirror of iOS GroupCatalog), so a\n * reload hydrates the chat list + lets queue rows route before the first pump. */\nexport class GroupCatalog {\n  constructor(private readonly kv: DurableKV) {}\n\n  async upsert(g: CatalogGroup): Promise<void> {\n    await this.kv.set(`cat:${g.rfcGroupId}`, encodeUtf8(JSON.stringify(g)));\n  }\n\n  async remove(rfcGroupId: string): Promise<void> {\n    await this.kv.delete(`cat:${rfcGroupId}`);\n  }\n\n  async all(): Promise<CatalogGroup[]> {\n    const keys = await this.kv.keys('cat:');\n    const out: CatalogGroup[] = [];\n    for (const k of keys) {\n      const raw = await this.kv.get(k);\n      if (!raw) continue;\n      try {\n        out.push(JSON.parse(decodeUtf8(raw)) as CatalogGroup);\n      } catch {\n        // skip a corrupt row\n      }\n    }\n    return out;\n  }\n\n  async wipe(): Promise<void> {\n    for (const k of await this.kv.keys('cat:')) await this.kv.delete(k);\n  }\n}\n","// The self-elevation dedup store — the web mirror of iOS `MentionElevationStore`.\n//\n// WHY THIS EXISTS (mentions design §\"Self-elevation idempotency\"): when an INCOMING\n// message mentions THIS device's user (and the sender isn't me, and it isn't an edit),\n// the Chat fires `onMentionElevation` exactly ONCE. Re-delivery (a reconnect re-pump),\n// a backfill, and a cold-launch relaunch must NOT re-fire. The in-memory set gates a\n// session; this persisted set makes the dedup survive reload — a re-delivered mention\n// after a cold launch finds its key already set and is a no-op.\n//\n// POSTURE — identical to `SuppressionStore`: a persisted per-chat `Set<elevationKey>`\n// (keyed by rfcGroupId) where `elevationKey` is `\"<selfUserId>|<idPart>\"` (idPart =\n// the mention message's client_msg_id, or `seq:<serverSeq>` for a legacy message). The\n// `selfUserId` scoping means a multi-account device never crosses dedup sets. Sealed at\n// rest by the same durable KV (IndexedDB + WebCrypto AES-GCM in the browser) that seals\n// the message store — so \"which messages buzzed me\" stays private (a soft mention-graph\n// signal) and the dedup survives a cold launch.\n\nimport type { DurableKV } from './storage.js';\nimport { decodeUtf8, encodeUtf8 } from './util.js';\n\n/** Persist a per-chat self-elevation dedup key set (keyed by rfcGroupId). */\nexport class MentionElevationStore {\n  constructor(private readonly kv: DurableKV) {}\n\n  private key(rfcGroupId: string): string {\n    return `elev:${rfcGroupId}`;\n  }\n\n  /** Load the persisted elevation keys for a chat (empty array if none). */\n  async load(rfcGroupId: string): Promise<string[]> {\n    const raw = await this.kv.get(this.key(rfcGroupId));\n    if (!raw) return [];\n    try {\n      const parsed = JSON.parse(decodeUtf8(raw));\n      return Array.isArray(parsed) ? (parsed as string[]) : [];\n    } catch {\n      return [];\n    }\n  }\n\n  /** Persist the full elevation key set for a chat (deterministic, deduped order). */\n  async save(rfcGroupId: string, keys: string[]): Promise<void> {\n    const sorted = [...new Set(keys)].sort();\n    await this.kv.set(this.key(rfcGroupId), encodeUtf8(JSON.stringify(sorted)));\n  }\n\n  async wipe(): Promise<void> {\n    for (const k of await this.kv.keys('elev:')) await this.kv.delete(k);\n  }\n}\n","/**\n * Browser binding of [`PalbeMlsClient`]. Holds the same `Arc<PalbeMlsClient>`\n * the native FFI would; every method delegates to the engine.\n */\nexport class MlsClient {\n    static __wrap(ptr) {\n        const obj = Object.create(MlsClient.prototype);\n        obj.__wbg_ptr = ptr;\n        MlsClientFinalization.register(obj, obj.__wbg_ptr, obj);\n        return obj;\n    }\n    __destroy_into_raw() {\n        const ptr = this.__wbg_ptr;\n        this.__wbg_ptr = 0;\n        MlsClientFinalization.unregister(this);\n        return ptr;\n    }\n    free() {\n        const ptr = this.__destroy_into_raw();\n        wasm.__wbg_mlsclient_free(ptr, 0);\n    }\n    /**\n     * The MLS Capabilities wire bytes (the keydir's `capabilities`).\n     * @returns {Uint8Array}\n     */\n    capabilities() {\n        const ret = wasm.mlsclient_capabilities(this.__wbg_ptr);\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n    /**\n     * Create a new group at epoch 0. `groupId` `undefined`/`null` lets mls-rs\n     * mint a globally-unique id (the rfc_group_id routing key).\n     * @param {Uint8Array | null} [group_id]\n     * @returns {MlsGroup}\n     */\n    createGroup(group_id) {\n        var ptr0 = isLikeNone(group_id) ? 0 : passArray8ToWasm0(group_id, wasm.__wbindgen_malloc);\n        var len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsclient_createGroup(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return MlsGroup.__wrap(ret[0]);\n    }\n    /**\n     * The MLS Credential wire bytes (the keydir's `credential`).\n     * @returns {Uint8Array}\n     */\n    credential() {\n        const ret = wasm.mlsclient_credential(this.__wbg_ptr);\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n    /**\n     * The MLS-encoded enrollment material `{ signatureKey, credential,\n     * capabilities }` (byte fields as arrays-of-numbers — wrap in Uint8Array as\n     * needed). Base64 these into the SP-0 keydir enroll body.\n     * @returns {any}\n     */\n    enrollmentMaterial() {\n        const ret = wasm.mlsclient_enrollmentMaterial(this.__wbg_ptr);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * Mint a one-use KeyPackage (RAW RFC 9420 §10 bytes) — uploaded to the\n     * keydir, consumed by an adder's `addMember`.\n     * @returns {Uint8Array}\n     */\n    generateKeyPackage() {\n        const ret = wasm.mlsclient_generateKeyPackage(this.__wbg_ptr);\n        if (ret[3]) {\n            throw takeFromExternrefTable0(ret[2]);\n        }\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n    /**\n     * Join a group from a Welcome (opaque MLSMessage bytes).\n     * @param {Uint8Array} welcome\n     * @returns {MlsGroup}\n     */\n    joinGroup(welcome) {\n        const ptr0 = passArray8ToWasm0(welcome, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsclient_joinGroup(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return MlsGroup.__wrap(ret[0]);\n    }\n    /**\n     * Re-hydrate a previously-persisted group by its `groupId` (restart-safe\n     * reload of an already-joined group).\n     * @param {Uint8Array} group_id\n     * @returns {MlsGroup}\n     */\n    loadGroup(group_id) {\n        const ptr0 = passArray8ToWasm0(group_id, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsclient_loadGroup(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return MlsGroup.__wrap(ret[0]);\n    }\n    /**\n     * The serialized STABLE signature keypair (secret-bearing). Persist sealed\n     * and pass back as `signatureKeypair` on restart so the device keeps the\n     * SAME MLS signing identity.\n     * @returns {Uint8Array}\n     */\n    signatureKeypair() {\n        const ret = wasm.mlsclient_signatureKeypair(this.__wbg_ptr);\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n    /**\n     * The device's STABLE signature PUBLIC key bytes (the keydir's\n     * `signature_key`).\n     * @returns {Uint8Array}\n     */\n    signaturePublicKey() {\n        const ret = wasm.mlsclient_signaturePublicKey(this.__wbg_ptr);\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n}\nif (Symbol.dispose) MlsClient.prototype[Symbol.dispose] = MlsClient.prototype.free;\n\n/**\n * Browser binding of [`PalbeMlsGroup`].\n */\nexport class MlsGroup {\n    static __wrap(ptr) {\n        const obj = Object.create(MlsGroup.prototype);\n        obj.__wbg_ptr = ptr;\n        MlsGroupFinalization.register(obj, obj.__wbg_ptr, obj);\n        return obj;\n    }\n    __destroy_into_raw() {\n        const ptr = this.__wbg_ptr;\n        this.__wbg_ptr = 0;\n        MlsGroupFinalization.unregister(this);\n        return ptr;\n    }\n    free() {\n        const ptr = this.__destroy_into_raw();\n        wasm.__wbg_mlsgroup_free(ptr, 0);\n    }\n    /**\n     * Stage a member add. Returns `{ commit, welcome?, addedLeafIndices }`\n     * (byte fields as arrays-of-numbers). The group is PENDING after this.\n     * @param {Uint8Array} key_package_msg\n     * @returns {any}\n     */\n    addMember(key_package_msg) {\n        const ptr0 = passArray8ToWasm0(key_package_msg, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_addMember(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * Apply the staged commit (advances the local epoch). Call ONLY after the\n     * server accepted the commit.\n     */\n    applyPendingCommit() {\n        const ret = wasm.mlsgroup_applyPendingCommit(this.__wbg_ptr);\n        if (ret[1]) {\n            throw takeFromExternrefTable0(ret[0]);\n        }\n    }\n    /**\n     * Discard the staged commit without advancing (the 409-rebase path).\n     */\n    clearPendingCommit() {\n        wasm.mlsgroup_clearPendingCommit(this.__wbg_ptr);\n    }\n    /**\n     * Stage a SINGLE atomic add+remove commit. `addKeyPackages` is an\n     * `Array<Uint8Array>` of one-use key packages; `removeMemberIds` an\n     * `Array<Uint8Array>` of member identity bytes. Returns the same\n     * `AddResult` shape as `addMember`. PENDING after this.\n     * @param {Uint8Array[]} add_key_packages\n     * @param {Uint8Array[]} remove_member_ids\n     * @returns {any}\n     */\n    commitChanges(add_key_packages, remove_member_ids) {\n        const ptr0 = passArrayJsValueToWasm0(add_key_packages, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ptr1 = passArrayJsValueToWasm0(remove_member_ids, wasm.__wbindgen_malloc);\n        const len1 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_commitChanges(this.__wbg_ptr, ptr0, len0, ptr1, len1);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * The current (applied) epoch as a JS BigInt (u64 exceeds safe-integer).\n     * @returns {bigint}\n     */\n    currentEpoch() {\n        const ret = wasm.mlsgroup_currentEpoch(this.__wbg_ptr);\n        return BigInt.asUintN(64, ret);\n    }\n    /**\n     * Inspect an incoming Commit and return the membership delta it WOULD\n     * effect WITHOUT applying it (the reconciliation gate's crypto-truth).\n     * Returns `{ kind, addedIdentities, removedIdentities }`.\n     * @param {Uint8Array} commit_msg\n     * @returns {any}\n     */\n    describeIncomingCommit(commit_msg) {\n        const ptr0 = passArray8ToWasm0(commit_msg, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_describeIncomingCommit(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * Encrypt an application message at the current epoch. Returns the opaque\n     * MLSMessage bytes (PrivateMessage).\n     * @param {Uint8Array} plaintext\n     * @returns {Uint8Array}\n     */\n    encryptApplicationMessage(plaintext) {\n        const ptr0 = passArray8ToWasm0(plaintext, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_encryptApplicationMessage(this.__wbg_ptr, ptr0, len0);\n        if (ret[3]) {\n            throw takeFromExternrefTable0(ret[2]);\n        }\n        var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v2;\n    }\n    /**\n     * Derive the group's current-epoch exporter secret (RFC 9420 §8.5) — the SAME\n     * engine call iOS uses (uniffi `exportSecret`), so a cross-platform call/group\n     * derives a byte-identical key. The SP-4 web call sets this as the LiveKit\n     * frame key (server + SFU stay blind); also group-name/media sealing.\n     * @param {Uint8Array} label\n     * @param {Uint8Array} context\n     * @param {bigint} len\n     * @returns {Uint8Array}\n     */\n    exportSecret(label, context, len) {\n        const ptr0 = passArray8ToWasm0(label, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ptr1 = passArray8ToWasm0(context, wasm.__wbindgen_malloc);\n        const len1 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_exportSecret(this.__wbg_ptr, ptr0, len0, ptr1, len1, len);\n        if (ret[3]) {\n            throw takeFromExternrefTable0(ret[2]);\n        }\n        var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v3;\n    }\n    /**\n     * The MLS group id (the rfc_group_id routing key / storage key).\n     * @returns {Uint8Array}\n     */\n    groupId() {\n        const ret = wasm.mlsgroup_groupId(this.__wbg_ptr);\n        var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n        wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n        return v1;\n    }\n    /**\n     * True while a staged (unapplied) commit exists.\n     * @returns {boolean}\n     */\n    hasPendingCommit() {\n        const ret = wasm.mlsgroup_hasPendingCommit(this.__wbg_ptr);\n        return ret !== 0;\n    }\n    /**\n     * Process an incoming MLSMessage and apply its effect. Returns a\n     * `ReceivedMessage` plain object (serde-tagged enum): e.g.\n     * `{ Application: { sender, data } }`, `{ CommitApplied: { epoch,\n     * removedSelf } }`, `\"Proposal\"`, or `\"Other\"`.\n     * @param {Uint8Array} message\n     * @returns {any}\n     */\n    processIncomingMessage(message) {\n        const ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_processIncomingMessage(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * Stage a member remove (by the member's identity bytes). Returns\n     * `{ commit }`. PENDING after this.\n     * @param {Uint8Array} member_id\n     * @returns {any}\n     */\n    removeMember(member_id) {\n        const ptr0 = passArray8ToWasm0(member_id, wasm.__wbindgen_malloc);\n        const len0 = WASM_VECTOR_LEN;\n        const ret = wasm.mlsgroup_removeMember(this.__wbg_ptr, ptr0, len0);\n        if (ret[2]) {\n            throw takeFromExternrefTable0(ret[1]);\n        }\n        return takeFromExternrefTable0(ret[0]);\n    }\n    /**\n     * Persist the current group state through the JS group storage callback.\n     */\n    writeToStorage() {\n        const ret = wasm.mlsgroup_writeToStorage(this.__wbg_ptr);\n        if (ret[1]) {\n            throw takeFromExternrefTable0(ret[0]);\n        }\n    }\n}\nif (Symbol.dispose) MlsGroup.prototype[Symbol.dispose] = MlsGroup.prototype.free;\n\n/**\n * Mint a device MLS client (browser binding of [`engine::generate_client`]).\n *\n * - `id`: the member identity bytes (the SP-0 device id `mdv_`).\n * - `group_storage`: a JS object implementing `IGroupStateStorage`.\n * - `key_package_storage`: a JS object implementing `IKeyPackageStorage`.\n * - `signature_keypair`: `undefined`/`null` on first run (a fresh keypair is\n *   minted), or the previously-persisted serialized secret-key bytes on restart.\n * @param {Uint8Array} id\n * @param {IGroupStateStorage} group_storage\n * @param {IKeyPackageStorage} key_package_storage\n * @param {Uint8Array | null} [signature_keypair]\n * @returns {MlsClient}\n */\nexport function generateClient(id, group_storage, key_package_storage, signature_keypair) {\n    const ptr0 = passArray8ToWasm0(id, wasm.__wbindgen_malloc);\n    const len0 = WASM_VECTOR_LEN;\n    var ptr1 = isLikeNone(signature_keypair) ? 0 : passArray8ToWasm0(signature_keypair, wasm.__wbindgen_malloc);\n    var len1 = WASM_VECTOR_LEN;\n    const ret = wasm.generateClient(ptr0, len0, group_storage, key_package_storage, ptr1, len1);\n    if (ret[2]) {\n        throw takeFromExternrefTable0(ret[1]);\n    }\n    return MlsClient.__wrap(ret[0]);\n}\n\n/**\n * Install the browser console panic hook so a Rust panic shows a readable\n * stack in the devtools console instead of an opaque `unreachable`. Idempotent;\n * the TS facade calls this once at module init.\n */\nexport function setPanicHook() {\n    wasm.setPanicHook();\n}\nexport function __wbg_BigInt_231999d28f899902() { return handleError(function (arg0) {\n    const ret = BigInt(arg0);\n    return ret;\n}, arguments); }\nexport function __wbg_Error_fdd633d4bb5dd76a(arg0, arg1) {\n    const ret = Error(getStringFromWasm0(arg0, arg1));\n    return ret;\n}\nexport function __wbg_String_8564e559799eccda(arg0, arg1) {\n    const ret = String(arg1);\n    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n    const len1 = WASM_VECTOR_LEN;\n    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n}\nexport function __wbg___wbindgen_bigint_get_as_i64_d9e915702856f831(arg0, arg1) {\n    const v = arg1;\n    const ret = typeof(v) === 'bigint' ? v : undefined;\n    getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);\n}\nexport function __wbg___wbindgen_debug_string_8a447059637473e2(arg0, arg1) {\n    const ret = debugString(arg1);\n    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n    const len1 = WASM_VECTOR_LEN;\n    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n}\nexport function __wbg___wbindgen_is_function_acc5528be2b923f2(arg0) {\n    const ret = typeof(arg0) === 'function';\n    return ret;\n}\nexport function __wbg___wbindgen_is_null_6d937fbfb6478470(arg0) {\n    const ret = arg0 === null;\n    return ret;\n}\nexport function __wbg___wbindgen_is_object_0beba4a1980d3eea(arg0) {\n    const val = arg0;\n    const ret = typeof(val) === 'object' && val !== null;\n    return ret;\n}\nexport function __wbg___wbindgen_is_string_1fca8072260dd261(arg0) {\n    const ret = typeof(arg0) === 'string';\n    return ret;\n}\nexport function __wbg___wbindgen_is_undefined_721f8decd50c87a3(arg0) {\n    const ret = arg0 === undefined;\n    return ret;\n}\nexport function __wbg___wbindgen_jsval_eq_4e8c38722cb8ff51(arg0, arg1) {\n    const ret = arg0 === arg1;\n    return ret;\n}\nexport function __wbg___wbindgen_memory_9751d9a3017e7c25() {\n    const ret = wasm.memory;\n    return ret;\n}\nexport function __wbg___wbindgen_number_get_1cc01dd708740256(arg0, arg1) {\n    const obj = arg1;\n    const ret = typeof(obj) === 'number' ? obj : undefined;\n    getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);\n}\nexport function __wbg___wbindgen_string_get_71bb4348194e31f0(arg0, arg1) {\n    const obj = arg1;\n    const ret = typeof(obj) === 'string' ? obj : undefined;\n    var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n    var len1 = WASM_VECTOR_LEN;\n    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n}\nexport function __wbg___wbindgen_throw_ea4887a5f8f9a9db(arg0, arg1) {\n    throw new Error(getStringFromWasm0(arg0, arg1));\n}\nexport function __wbg_buffer_7447b9cc2267a9e5(arg0) {\n    const ret = arg0.buffer;\n    return ret;\n}\nexport function __wbg_call_67f43c91d09298f2() { return handleError(function (arg0, arg1, arg2) {\n    const ret = arg0.call(arg1, arg2);\n    return ret;\n}, arguments); }\nexport function __wbg_call_b51415974987aa44() { return handleError(function (arg0, arg1) {\n    const ret = arg0.call(arg1);\n    return ret;\n}, arguments); }\nexport function __wbg_crypto_38df2bab126b63dc(arg0) {\n    const ret = arg0.crypto;\n    return ret;\n}\nexport function __wbg_delete_21fafcbc7bb82c85() { return handleError(function (arg0, arg1) {\n    arg0.delete(arg1);\n}, arguments); }\nexport function __wbg_epoch_15c000ffe3004541() { return handleError(function (arg0, arg1, arg2) {\n    const ret = arg0.epoch(arg1, BigInt.asUintN(64, arg2));\n    return ret;\n}, arguments); }\nexport function __wbg_error_a6fa202b58aa1cd3(arg0, arg1) {\n    let deferred0_0;\n    let deferred0_1;\n    try {\n        deferred0_0 = arg0;\n        deferred0_1 = arg1;\n        console.error(getStringFromWasm0(arg0, arg1));\n    } finally {\n        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n    }\n}\nexport function __wbg_getRandomValues_c44a50d8cfdaebeb() { return handleError(function (arg0, arg1) {\n    arg0.getRandomValues(arg1);\n}, arguments); }\nexport function __wbg_get_615446055a48103f() { return handleError(function (arg0, arg1) {\n    const ret = arg0.get(arg1);\n    return ret;\n}, arguments); }\nexport function __wbg_globalThis_6d268067835e6709() { return handleError(function () {\n    const ret = globalThis.globalThis;\n    return ret;\n}, arguments); }\nexport function __wbg_global_3fe6c6c8ad6e6fb2() { return handleError(function () {\n    const ret = global.global;\n    return ret;\n}, arguments); }\nexport function __wbg_insert_2d611f2bf9b60fee() { return handleError(function (arg0, arg1, arg2) {\n    arg0.insert(arg1, arg2);\n}, arguments); }\nexport function __wbg_instanceof_Error_38f854307ecab4ce(arg0) {\n    let result;\n    try {\n        result = arg0 instanceof Error;\n    } catch (_) {\n        result = false;\n    }\n    const ret = result;\n    return ret;\n}\nexport function __wbg_length_c552db98817b9523(arg0) {\n    const ret = arg0.length;\n    return ret;\n}\nexport function __wbg_maxEpochId_0b176768b2f352fb() { return handleError(function (arg0, arg1) {\n    const ret = arg0.maxEpochId(arg1);\n    return ret;\n}, arguments); }\nexport function __wbg_message_a05fcf872473ffc5(arg0) {\n    const ret = arg0.message;\n    return ret;\n}\nexport function __wbg_msCrypto_bd5a034af96bcba6(arg0) {\n    const ret = arg0.msCrypto;\n    return ret;\n}\nexport function __wbg_new_227d7c05414eb861() {\n    const ret = new Error();\n    return ret;\n}\nexport function __wbg_new_32de5cbf49ca7dcb(arg0) {\n    const ret = new Uint8Array(arg0);\n    return ret;\n}\nexport function __wbg_new_364c96143b8f3496() {\n    const ret = new Object();\n    return ret;\n}\nexport function __wbg_new_b8b71ca8104fc178(arg0, arg1) {\n    const ret = new Error(getStringFromWasm0(arg0, arg1));\n    return ret;\n}\nexport function __wbg_new_d9762fd75876aafe() {\n    const ret = new Array();\n    return ret;\n}\nexport function __wbg_new_no_args_4010ad257320fa4f(arg0, arg1) {\n    const ret = new Function(getStringFromWasm0(arg0, arg1));\n    return ret;\n}\nexport function __wbg_new_with_byte_offset_and_length_8b21e3b1308deb48(arg0, arg1, arg2) {\n    const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0);\n    return ret;\n}\nexport function __wbg_new_with_length_5fdafe029be917a5(arg0) {\n    const ret = new Uint8Array(arg0 >>> 0);\n    return ret;\n}\nexport function __wbg_node_84ea875411254db1(arg0) {\n    const ret = arg0.node;\n    return ret;\n}\nexport function __wbg_process_44c7a14e11e9f69e(arg0) {\n    const ret = arg0.process;\n    return ret;\n}\nexport function __wbg_push_1303ce035391aed3(arg0, arg1) {\n    const ret = arg0.push(arg1);\n    return ret;\n}\nexport function __wbg_randomFillSync_6c25eac9869eb53c() { return handleError(function (arg0, arg1) {\n    arg0.randomFillSync(arg1);\n}, arguments); }\nexport function __wbg_require_b4edbdcf3e2a1ef0() { return handleError(function () {\n    const ret = module.require;\n    return ret;\n}, arguments); }\nexport function __wbg_self_1035a7cbd1b0d959() { return handleError(function () {\n    const ret = self.self;\n    return ret;\n}, arguments); }\nexport function __wbg_set_047d1ea37bb67c19(arg0, arg1, arg2) {\n    arg0.set(arg1, arg2 >>> 0);\n}\nexport function __wbg_set_1ddc4b8cd44d0da4() { return handleError(function (arg0, arg1, arg2) {\n    const ret = Reflect.set(arg0, arg1, arg2);\n    return ret;\n}, arguments); }\nexport function __wbg_set_28cba565792ec75f(arg0, arg1, arg2) {\n    arg0[arg1 >>> 0] = arg2;\n}\nexport function __wbg_set_6be42768c690e380(arg0, arg1, arg2) {\n    arg0[arg1] = arg2;\n}\nexport function __wbg_set_name_b4c29a3a72ebbddc(arg0, arg1, arg2) {\n    arg0.name = getStringFromWasm0(arg1, arg2);\n}\nexport function __wbg_stack_3b0d974bbf31e44f(arg0, arg1) {\n    const ret = arg1.stack;\n    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n    const len1 = WASM_VECTOR_LEN;\n    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n}\nexport function __wbg_state_bd20456c0f3efbc9() { return handleError(function (arg0, arg1) {\n    const ret = arg0.state(arg1);\n    return ret;\n}, arguments); }\nexport function __wbg_subarray_e0162dcdea48eb3a(arg0, arg1, arg2) {\n    const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n    return ret;\n}\nexport function __wbg_versions_276b2795b1c6a219(arg0) {\n    const ret = arg0.versions;\n    return ret;\n}\nexport function __wbg_window_9c17850b5e99c0ab() { return handleError(function () {\n    const ret = window.window;\n    return ret;\n}, arguments); }\nexport function __wbg_write_56b1cf5bb0e780d6() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {\n    arg0.write(arg1, arg2, arg3, arg4);\n}, arguments); }\nexport function __wbindgen_cast_0000000000000001(arg0) {\n    // Cast intrinsic for `F64 -> Externref`.\n    const ret = arg0;\n    return ret;\n}\nexport function __wbindgen_cast_0000000000000002(arg0, arg1) {\n    // Cast intrinsic for `Ref(String) -> Externref`.\n    const ret = getStringFromWasm0(arg0, arg1);\n    return ret;\n}\nexport function __wbindgen_cast_0000000000000003(arg0) {\n    // Cast intrinsic for `U64 -> Externref`.\n    const ret = BigInt.asUintN(64, arg0);\n    return ret;\n}\nexport function __wbindgen_init_externref_table() {\n    const table = wasm.__wbindgen_externrefs;\n    const offset = table.grow(4);\n    table.set(0, undefined);\n    table.set(offset + 0, undefined);\n    table.set(offset + 1, null);\n    table.set(offset + 2, true);\n    table.set(offset + 3, false);\n}\nconst MlsClientFinalization = (typeof FinalizationRegistry === 'undefined')\n    ? { register: () => {}, unregister: () => {} }\n    : new FinalizationRegistry(ptr => wasm.__wbg_mlsclient_free(ptr, 1));\nconst MlsGroupFinalization = (typeof FinalizationRegistry === 'undefined')\n    ? { register: () => {}, unregister: () => {} }\n    : new FinalizationRegistry(ptr => wasm.__wbg_mlsgroup_free(ptr, 1));\n\nfunction addToExternrefTable0(obj) {\n    const idx = wasm.__externref_table_alloc();\n    wasm.__wbindgen_externrefs.set(idx, obj);\n    return idx;\n}\n\nfunction debugString(val) {\n    // primitive types\n    const type = typeof val;\n    if (type == 'number' || type == 'boolean' || val == null) {\n        return  `${val}`;\n    }\n    if (type == 'string') {\n        return `\"${val}\"`;\n    }\n    if (type == 'symbol') {\n        const description = val.description;\n        if (description == null) {\n            return 'Symbol';\n        } else {\n            return `Symbol(${description})`;\n        }\n    }\n    if (type == 'function') {\n        const name = val.name;\n        if (typeof name == 'string' && name.length > 0) {\n            return `Function(${name})`;\n        } else {\n            return 'Function';\n        }\n    }\n    // objects\n    if (Array.isArray(val)) {\n        const length = val.length;\n        let debug = '[';\n        if (length > 0) {\n            debug += debugString(val[0]);\n        }\n        for(let i = 1; i < length; i++) {\n            debug += ', ' + debugString(val[i]);\n        }\n        debug += ']';\n        return debug;\n    }\n    // Test for built-in\n    const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n    let className;\n    if (builtInMatches && builtInMatches.length > 1) {\n        className = builtInMatches[1];\n    } else {\n        // Failed to match the standard '[object ClassName]'\n        return toString.call(val);\n    }\n    if (className == 'Object') {\n        // we're a user defined class or Object\n        // JSON.stringify avoids problems with cycles, and is generally much\n        // easier than looping through ownProperties of `val`.\n        try {\n            return 'Object(' + JSON.stringify(val) + ')';\n        } catch (_) {\n            return 'Object';\n        }\n    }\n    // errors\n    if (val instanceof Error) {\n        return `${val.name}: ${val.message}\\n${val.stack}`;\n    }\n    // TODO we could test for more things here, like `Set`s and `Map`s.\n    return className;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n    ptr = ptr >>> 0;\n    return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nlet cachedDataViewMemory0 = null;\nfunction getDataViewMemory0() {\n    if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n        cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n    }\n    return cachedDataViewMemory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n    return decodeText(ptr >>> 0, len);\n}\n\nlet cachedUint8ArrayMemory0 = null;\nfunction getUint8ArrayMemory0() {\n    if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n        cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n    }\n    return cachedUint8ArrayMemory0;\n}\n\nfunction handleError(f, args) {\n    try {\n        return f.apply(this, args);\n    } catch (e) {\n        const idx = addToExternrefTable0(e);\n        wasm.__wbindgen_exn_store(idx);\n    }\n}\n\nfunction isLikeNone(x) {\n    return x === undefined || x === null;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n    const ptr = malloc(arg.length * 1, 1) >>> 0;\n    getUint8ArrayMemory0().set(arg, ptr / 1);\n    WASM_VECTOR_LEN = arg.length;\n    return ptr;\n}\n\nfunction passArrayJsValueToWasm0(array, malloc) {\n    const ptr = malloc(array.length * 4, 4) >>> 0;\n    for (let i = 0; i < array.length; i++) {\n        const add = addToExternrefTable0(array[i]);\n        getDataViewMemory0().setUint32(ptr + 4 * i, add, true);\n    }\n    WASM_VECTOR_LEN = array.length;\n    return ptr;\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n    if (realloc === undefined) {\n        const buf = cachedTextEncoder.encode(arg);\n        const ptr = malloc(buf.length, 1) >>> 0;\n        getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n        WASM_VECTOR_LEN = buf.length;\n        return ptr;\n    }\n\n    let len = arg.length;\n    let ptr = malloc(len, 1) >>> 0;\n\n    const mem = getUint8ArrayMemory0();\n\n    let offset = 0;\n\n    for (; offset < len; offset++) {\n        const code = arg.charCodeAt(offset);\n        if (code > 0x7F) break;\n        mem[ptr + offset] = code;\n    }\n    if (offset !== len) {\n        if (offset !== 0) {\n            arg = arg.slice(offset);\n        }\n        ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n        const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n        const ret = cachedTextEncoder.encodeInto(arg, view);\n\n        offset += ret.written;\n        ptr = realloc(ptr, len, offset, 1) >>> 0;\n    }\n\n    WASM_VECTOR_LEN = offset;\n    return ptr;\n}\n\nfunction takeFromExternrefTable0(idx) {\n    const value = wasm.__wbindgen_externrefs.get(idx);\n    wasm.__externref_table_dealloc(idx);\n    return value;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\ncachedTextDecoder.decode();\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n    numBytesDecoded += len;\n    if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n        cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n        cachedTextDecoder.decode();\n        numBytesDecoded = len;\n    }\n    return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n    cachedTextEncoder.encodeInto = function (arg, view) {\n        const buf = cachedTextEncoder.encode(arg);\n        view.set(buf);\n        return {\n            read: arg.length,\n            written: buf.length\n        };\n    };\n}\n\nlet WASM_VECTOR_LEN = 0;\n\n\nlet wasm;\nexport function __wbg_set_wasm(val) {\n    wasm = val;\n}\n","\nexport function date_now() {\n  return Date.now();\n}","// Portable WASM loader for the palbe-mls engine — works in browser bundles and\n// Node without filesystem paths, public URLs, or runtime network requests.\n//\n// Why not just `import * as wasm from './palbe_mls_bg.wasm'` (the bundler\n// target's own entry, `palbe_mls.js`)? Because that import form only works in\n// bundlers that special-case `.wasm` (webpack/Vite with config) and NEVER in\n// Node — so the two-client crypto smoke (vitest, Node) could not run the real\n// engine. Instead we replicate what the wasm-pack `web`/`nodejs` targets do\n// internally: build the import object from the glue module's named exports +\n// the inline snippet, then `WebAssembly.instantiate` the bytes ourselves. The\n// bytes live in a private, lazily imported JavaScript package target, so a\n// consumer bundler can code-split them without needing a `.wasm` loader.\n//\n// init is idempotent + races-safe: concurrent callers share one in-flight\n// promise, and a second call after success is a no-op returning the same glue.\n\n// The glue exports every user-facing binding (MlsClient/MlsGroup/generateClient/\n// setPanicHook) AND all the `__wbg_*` import functions the `.wasm` needs, plus\n// `__wbg_set_wasm` (hand the instantiated exports back to the glue) and\n// `__wbindgen_start` (run wasm-bindgen's start section). We import it as a\n// namespace so we can both call the bindings and assemble the import object.\nimport * as glue from './pkg/palbe_mls_bg.js';\n// The single inline snippet the `.wasm` imports directly (Date.now()).\nimport * as snippet from './pkg/snippets/mls-rs-core-f99cdecbb456b09c/inline0.js';\n\n/** The subset of the glue surface the bridge calls. */\nexport interface MlsGlue {\n  generateClient: typeof glue.generateClient;\n  setPanicHook: typeof glue.setPanicHook;\n  MlsClient: typeof glue.MlsClient;\n  MlsGroup: typeof glue.MlsGroup;\n}\n\n// The two import-module specifiers the `.wasm` declares (verified via\n// WebAssembly.Module.imports — './palbe_mls_bg.js' + the inline snippet).\nconst GLUE_MODULE = './palbe_mls_bg.js';\nconst SNIPPET_MODULE = './snippets/mls-rs-core-f99cdecbb456b09c/inline0.js';\n\nlet inflight: Promise<MlsGlue> | null = null;\nlet ready: MlsGlue | null = null;\n\nfunction decodeBase64(encoded: unknown): ArrayBuffer {\n  if (\n    typeof encoded !== 'string' ||\n    encoded.length === 0 ||\n    typeof globalThis.atob !== 'function'\n  ) {\n    throw new Error('palbe-mls WASM asset is invalid');\n  }\n\n  let binary: string;\n  try {\n    binary = globalThis.atob(encoded);\n  } catch {\n    throw new Error('palbe-mls WASM asset is invalid');\n  }\n\n  const bytes = new Uint8Array(binary.length);\n  for (let index = 0; index < binary.length; index += 1) {\n    bytes[index] = binary.charCodeAt(index);\n  }\n  return bytes.buffer;\n}\n\nasync function loadWasmModule(): Promise<WebAssembly.Module> {\n  const asset = await import('#palbase-mls-wasm');\n  return WebAssembly.compile(decodeBase64(asset.default));\n}\n\n/** Assemble the import object the `.wasm` expects from the glue + snippet. */\nfunction buildImports(): WebAssembly.Imports {\n  return {\n    [GLUE_MODULE]: glue as unknown as WebAssembly.ModuleImports,\n    [SNIPPET_MODULE]: snippet as unknown as WebAssembly.ModuleImports,\n  };\n}\n\n/**\n * Initialize the MLS WASM engine. Idempotent — call it once before any\n * messaging crypto op (the facade does this on `pb.messaging.start()` and\n * before the first chat op). Returns the glue surface (the bridge uses it).\n */\nexport function initMls(): Promise<MlsGlue> {\n  if (ready) return Promise.resolve(ready);\n  if (inflight) return inflight;\n  const attempt = (async () => {\n    const module = await loadWasmModule();\n    const instance = await WebAssembly.instantiate(module, buildImports());\n    // Hand the instance's exports back to the glue (its module-level `wasm`)…\n    const setWasm = (glue as unknown as { __wbg_set_wasm: (e: unknown) => void }).__wbg_set_wasm;\n    setWasm(instance.exports);\n    // …then run wasm-bindgen's start section (sets up the heap, etc).\n    (instance.exports as { __wbindgen_start?: () => void }).__wbindgen_start?.();\n    const g: MlsGlue = {\n      generateClient: glue.generateClient,\n      setPanicHook: glue.setPanicHook,\n      MlsClient: glue.MlsClient,\n      MlsGroup: glue.MlsGroup,\n    };\n    // Surface Rust panics as readable console errors in the browser.\n    try {\n      g.setPanicHook();\n    } catch {\n      // best-effort: a missing console_error_panic_hook must not fail init\n    }\n    ready = g;\n    return g;\n  })();\n  inflight = attempt;\n  void attempt.catch(() => {\n    if (inflight === attempt) inflight = null;\n  });\n  return attempt;\n}\n\n/** True once `initMls()` has completed (the engine is usable synchronously). */\nexport function isMlsReady(): boolean {\n  return ready !== null;\n}\n\n/** The initialized glue, or throw if `initMls()` has not completed. */\nexport function requireMls(): MlsGlue {\n  if (!ready) {\n    throw new Error('palbe-mls WASM not initialized — await initMls() first');\n  }\n  return ready;\n}\n","// Typed bridge over the raw WASM `MlsClient`/`MlsGroup`. It normalizes the two\n// byte conventions the engine uses and presents clean TS records:\n//\n//  · Direct byte methods (signaturePublicKey, generateKeyPackage,\n//    encryptApplicationMessage, groupId, …) already return `Uint8Array`.\n//  · serde records/enums (enrollmentMaterial, addMember/commitChanges result,\n//    processIncomingMessage, describeIncomingCommit) cross via\n//    serde-wasm-bindgen, where `Vec<u8>` fields serialize as ARRAYS OF NUMBERS\n//    (documented in src/wasm.rs §Records). We wrap those back into Uint8Array.\n//\n// Field names are camelCase (the engine derives `serde(rename_all =\n// \"camelCase\")`). The `ReceivedMessage` enum is externally tagged:\n//   { Application: { sender, data } } | { CommitApplied: { epoch, removedSelf } }\n//   | \"Proposal\" | \"Other\"\n//\n// Everything here is SYNC — the engine methods are synchronous (mls-rs storage\n// is sync in this build). Serialization of state happens through the JS storage\n// callbacks the host supplies (see ../storage.ts).\n\nimport { requireMls } from './loader.js';\nimport type {\n  IGroupStateStorage,\n  IKeyPackageStorage,\n  MlsClient as RawClientType,\n  MlsGroup as RawGroup,\n} from './pkg/palbe_mls.types.d.ts';\n\nexport type { IGroupStateStorage, IKeyPackageStorage };\n\n/** Coerce a serde byte field (array-of-numbers OR Uint8Array) to Uint8Array. */\nfunction toBytes(v: unknown): Uint8Array {\n  if (v instanceof Uint8Array) return v;\n  if (Array.isArray(v)) return Uint8Array.from(v as number[]);\n  if (v == null) return new Uint8Array(0);\n  // ArrayBuffer / typed-array view fallthrough.\n  if (ArrayBuffer.isView(v)) return new Uint8Array((v as ArrayBufferView).buffer);\n  throw new Error('expected byte field (Uint8Array | number[])');\n}\n\nfunction optBytes(v: unknown): Uint8Array | undefined {\n  if (v == null) return undefined;\n  return toBytes(v);\n}\n\n// ─── Record types (normalized) ───────────────────────────────────────────────\n\n/** `{ signatureKey, credential, capabilities }` — the SP-0 enroll material. */\nexport interface EnrollmentMaterial {\n  signatureKey: Uint8Array;\n  credential: Uint8Array;\n  capabilities: Uint8Array;\n}\n\n/** Result of staging an add/commit-changes: commit + optional welcome + leaves. */\nexport interface AddResult {\n  commit: Uint8Array;\n  welcome?: Uint8Array;\n  addedLeafIndices: number[];\n}\n\n/** Result of staging a remove: just the commit. */\nexport interface RemoveResult {\n  commit: Uint8Array;\n}\n\nexport type CommitKind = 'Add' | 'Remove' | 'Update' | 'Mixed' | 'Other';\n\n/** The membership delta a commit WOULD effect (the reconciliation gate truth). */\nexport interface CommitDescription {\n  kind: CommitKind;\n  addedIdentities: Uint8Array[];\n  removedIdentities: Uint8Array[];\n}\n\n/** What `processIncomingMessage` decoded (the normalized form of the serde enum). */\nexport type ReceivedMessage =\n  | { type: 'application'; sender: Uint8Array; data: Uint8Array }\n  | { type: 'commitApplied'; epoch: number; removedSelf: boolean }\n  | { type: 'proposal' }\n  | { type: 'other' };\n\n// ─── Group wrapper ───────────────────────────────────────────────────────────\n\n/** Typed wrapper over a raw `MlsGroup`. */\nexport class MlsGroupHandle {\n  /** @internal */\n  constructor(private readonly raw: RawGroup) {}\n\n  /** The MLS rfc_group_id (routing key / storage key) bytes. */\n  groupId(): Uint8Array {\n    return this.raw.groupId();\n  }\n\n  /** Current applied epoch (BigInt → number; epochs stay well under 2^53). */\n  currentEpoch(): number {\n    return Number(this.raw.currentEpoch());\n  }\n\n  /** Stage a member add (PENDING after). */\n  addMember(keyPackageMsg: Uint8Array): AddResult {\n    return normalizeAddResult(this.raw.addMember(keyPackageMsg));\n  }\n\n  /** Stage a member remove by identity bytes (PENDING after). */\n  removeMember(memberId: Uint8Array): RemoveResult {\n    const r = this.raw.removeMember(memberId) as { commit: unknown };\n    return { commit: toBytes(r.commit) };\n  }\n\n  /** Stage a SINGLE atomic add+remove commit (PENDING after). */\n  commitChanges(addKeyPackages: Uint8Array[], removeMemberIds: Uint8Array[]): AddResult {\n    return normalizeAddResult(this.raw.commitChanges(addKeyPackages, removeMemberIds));\n  }\n\n  /** Apply the staged commit (advance the local epoch). Only after server-accept. */\n  applyPendingCommit(): void {\n    this.raw.applyPendingCommit();\n  }\n\n  /** Discard the staged commit without advancing (the 409-rebase path). */\n  clearPendingCommit(): void {\n    this.raw.clearPendingCommit();\n  }\n\n  /** True while a staged (unapplied) commit exists. */\n  hasPendingCommit(): boolean {\n    return this.raw.hasPendingCommit();\n  }\n\n  /** Encrypt an application message at the current epoch → PrivateMessage bytes. */\n  encryptApplicationMessage(plaintext: Uint8Array): Uint8Array {\n    return this.raw.encryptApplicationMessage(plaintext);\n  }\n\n  /** Process an incoming MLSMessage and apply its effect (normalized result). */\n  processIncomingMessage(message: Uint8Array): ReceivedMessage {\n    return normalizeReceived(this.raw.processIncomingMessage(message));\n  }\n\n  /** Inspect an incoming Commit WITHOUT applying it (the gate's crypto-truth). */\n  describeIncomingCommit(commitMsg: Uint8Array): CommitDescription {\n    const d = this.raw.describeIncomingCommit(commitMsg) as {\n      kind: CommitKind;\n      addedIdentities: unknown[];\n      removedIdentities: unknown[];\n    };\n    return {\n      kind: d.kind,\n      addedIdentities: d.addedIdentities.map(toBytes),\n      removedIdentities: d.removedIdentities.map(toBytes),\n    };\n  }\n\n  /** Persist the current group state through the JS group-storage callback. */\n  writeToStorage(): void {\n    this.raw.writeToStorage();\n  }\n}\n\nfunction normalizeAddResult(v: unknown): AddResult {\n  const r = v as { commit: unknown; welcome?: unknown; addedLeafIndices?: unknown[] };\n  return {\n    commit: toBytes(r.commit),\n    welcome: optBytes(r.welcome),\n    addedLeafIndices: (r.addedLeafIndices ?? []).map((n) => Number(n)),\n  };\n}\n\nfunction normalizeReceived(v: unknown): ReceivedMessage {\n  // Unit variants serialize as the bare string (\"Proposal\" / \"Other\").\n  if (v === 'Proposal') return { type: 'proposal' };\n  if (v === 'Other') return { type: 'other' };\n  const obj = v as Record<string, unknown>;\n  if (obj.Application) {\n    const a = obj.Application as { sender: unknown; data: unknown };\n    return { type: 'application', sender: toBytes(a.sender), data: toBytes(a.data) };\n  }\n  if (obj.CommitApplied) {\n    const c = obj.CommitApplied as { epoch: unknown; removedSelf: unknown };\n    return { type: 'commitApplied', epoch: Number(c.epoch), removedSelf: Boolean(c.removedSelf) };\n  }\n  return { type: 'other' };\n}\n\n// ─── Client wrapper ──────────────────────────────────────────────────────────\n\n/** Typed wrapper over a raw `MlsClient`. */\nexport class MlsClientHandle {\n  /** @internal */\n  constructor(private readonly raw: RawClientType) {}\n\n  /** The SP-0 keydir enroll material (`{ signatureKey, credential, capabilities }`). */\n  enrollmentMaterial(): EnrollmentMaterial {\n    const m = this.raw.enrollmentMaterial() as {\n      signatureKey: unknown;\n      credential: unknown;\n      capabilities: unknown;\n    };\n    return {\n      signatureKey: toBytes(m.signatureKey),\n      credential: toBytes(m.credential),\n      capabilities: toBytes(m.capabilities),\n    };\n  }\n\n  /** The device's STABLE signature PUBLIC key bytes (the keydir `signature_key`). */\n  signaturePublicKey(): Uint8Array {\n    return this.raw.signaturePublicKey();\n  }\n\n  /** The MLS Credential wire bytes (the keydir `credential`). */\n  credential(): Uint8Array {\n    return this.raw.credential();\n  }\n\n  /** The MLS Capabilities wire bytes (the keydir `capabilities`). */\n  capabilities(): Uint8Array {\n    return this.raw.capabilities();\n  }\n\n  /** The serialized STABLE signature keypair (secret-bearing — persist sealed). */\n  signatureKeypair(): Uint8Array {\n    return this.raw.signatureKeypair();\n  }\n\n  /** Mint a one-use KeyPackage (RAW RFC 9420 §10 bytes). */\n  generateKeyPackage(): Uint8Array {\n    return this.raw.generateKeyPackage();\n  }\n\n  /** Create a new group at epoch 0 (engine mints the rfc_group_id). */\n  createGroup(groupId?: Uint8Array): MlsGroupHandle {\n    return new MlsGroupHandle(this.raw.createGroup(groupId ?? undefined));\n  }\n\n  /** Join a group from a Welcome (opaque MLSMessage bytes). */\n  joinGroup(welcome: Uint8Array): MlsGroupHandle {\n    return new MlsGroupHandle(this.raw.joinGroup(welcome));\n  }\n\n  /** Re-hydrate an already-joined group by its rfc_group_id bytes. */\n  loadGroup(groupId: Uint8Array): MlsGroupHandle {\n    return new MlsGroupHandle(this.raw.loadGroup(groupId));\n  }\n}\n\n/**\n * Mint a device MLS client. `initMls()` MUST have completed first\n * (the facade enforces this). `signatureKeypair` is undefined on first run, or\n * the previously-persisted sealed keypair bytes on restart (same MLS identity).\n */\nexport function generateClient(\n  id: Uint8Array,\n  groupStorage: IGroupStateStorage,\n  keyPackageStorage: IKeyPackageStorage,\n  signatureKeypair?: Uint8Array,\n): MlsClientHandle {\n  const { generateClient: gen } = requireMls();\n  return new MlsClientHandle(\n    gen(id, groupStorage, keyPackageStorage, signatureKeypair ?? undefined),\n  );\n}\n","// The web mirror of iOS `MLSEngine` — a single serialized owner of the WASM\n// MlsClient + the per-group MlsGroup handles. Every public method runs through\n// a promise-chain mutex (`enqueue`) so the synchronous engine critical section\n// is never re-entered concurrently (the engine is single-threaded; two awaited\n// ops interleaving would corrupt the storage write-through cache).\n//\n// DURABILITY BOUNDARY: a mutating engine op (create / join / commit / encrypt /\n// process / applyPending) is followed by an awaited storage flush before the\n// host treats the op as done — so an acked message / applied commit is always\n// durable (the engine erases a message key on first decrypt; the durable copy\n// is the only recoverable form, mirroring the iOS D3/D5 ordering).\n//\n// IDENTITY: the MLS credential identity is the SP-0 device id (`mdv_`), passed\n// as the `id` bytes to generateClient (SP-1.6 per-device leaf identity).\n\nimport type { GroupStateStorage, KeyPackageStorage, SignatureKeyStore } from './storage.js';\nimport { bytesToHex } from './util.js';\nimport {\n  type AddResult,\n  type CommitDescription,\n  generateClient,\n  type MlsClientHandle,\n  type MlsGroupHandle,\n  type ReceivedMessage,\n} from './wasm/bridge.js';\nimport { initMls } from './wasm/loader.js';\n\nconst utf8 = new TextEncoder();\n\n/** The rfc_group_id keyed by its hex form (the per-group handle cache key). */\nconst gidHex = bytesToHex;\n\nexport interface EngineEnrollmentMaterial {\n  signatureKey: Uint8Array;\n  credential: Uint8Array;\n  capabilities: Uint8Array;\n}\n\n/**\n * The serialized MLS engine. Built once per (userId, deviceId). All crypto +\n * storage flows through here; `GroupMessaging` and `MessageDeliverySource` hold\n * the SAME instance so one MLS identity backs enroll + group ops + delivery.\n */\nexport class MlsEngine {\n  private readonly groups = new Map<string, MlsGroupHandle>();\n  private chain: Promise<unknown> = Promise.resolve();\n\n  private constructor(\n    readonly userId: string,\n    readonly deviceId: string,\n    private readonly client: MlsClientHandle,\n    private readonly groupStore: GroupStateStorage,\n    private readonly kpStore: KeyPackageStorage,\n  ) {}\n\n  /**\n   * Build the engine: init the WASM, hydrate the durable stores into the sync\n   * caches, generate (or restore) the device client. Idempotent restore: the\n   * persisted signature keypair keeps the SAME MLS signing identity across\n   * reloads; the group-state cache makes already-joined groups reloadable.\n   */\n  static async create(opts: {\n    userId: string;\n    deviceId: string;\n    groupStore: GroupStateStorage;\n    kpStore: KeyPackageStorage;\n    sigStore: SignatureKeyStore;\n  }): Promise<MlsEngine> {\n    await initMls();\n    // Hydrate the durable state into the sync caches BEFORE generateClient so a\n    // restart sees its persisted groups + key-package secrets.\n    await Promise.all([opts.groupStore.hydrate(), opts.kpStore.hydrate()]);\n    const persistedKeypair = await opts.sigStore.load(opts.userId);\n    const idBytes = utf8.encode(opts.deviceId);\n    const client = generateClient(idBytes, opts.groupStore, opts.kpStore, persistedKeypair);\n    // Persist the (possibly freshly minted) signature keypair so the next reload\n    // restores the SAME identity.\n    if (!persistedKeypair) {\n      await opts.sigStore.save(opts.userId, client.signatureKeypair());\n    }\n    return new MlsEngine(opts.userId, opts.deviceId, client, opts.groupStore, opts.kpStore);\n  }\n\n  /** Serialize an engine op onto the chain so the critical section is exclusive. */\n  private enqueue<T>(fn: () => T | Promise<T>): Promise<T> {\n    const run = this.chain.then(fn, fn);\n    // Keep the chain alive but swallow rejections so one failure doesn't poison\n    // every later op (each caller still sees its own rejection via `run`).\n    this.chain = run.then(\n      () => undefined,\n      () => undefined,\n    );\n    return run;\n  }\n\n  /** Flush both storage caches durably (the post-mutation durability boundary). */\n  private async flush(): Promise<void> {\n    await Promise.all([this.groupStore.flush(), this.kpStore.flush()]);\n  }\n\n  // ── Enroll material / key packages ──\n\n  enrollmentMaterial(): Promise<EngineEnrollmentMaterial> {\n    return this.enqueue(() => this.client.enrollmentMaterial());\n  }\n\n  signaturePublicKey(): Promise<Uint8Array> {\n    return this.enqueue(() => this.client.signaturePublicKey());\n  }\n\n  generateKeyPackage(): Promise<Uint8Array> {\n    return this.enqueue(async () => {\n      const kp = this.client.generateKeyPackage();\n      // A generated key package stores its private bits via the kp store — flush.\n      await this.flush();\n      return kp;\n    });\n  }\n\n  // ── Group create / join / reload ──\n\n  /** Create a group; returns its rfc_group_id (the routing key). */\n  createGroup(): Promise<Uint8Array> {\n    return this.enqueue(async () => {\n      const group = this.client.createGroup();\n      const gid = group.groupId();\n      this.groups.set(gidHex(gid), group);\n      group.writeToStorage();\n      await this.flush();\n      return gid;\n    });\n  }\n\n  /** Join from a Welcome; returns the joined group's rfc_group_id. */\n  joinFromWelcome(welcome: Uint8Array): Promise<Uint8Array> {\n    return this.enqueue(async () => {\n      const group = this.client.joinGroup(welcome);\n      const gid = group.groupId();\n      this.groups.set(gidHex(gid), group);\n      group.writeToStorage();\n      await this.flush();\n      return gid;\n    });\n  }\n\n  /** The current applied epoch for a group (0 if unknown). */\n  epoch(rfcGroupId: Uint8Array): Promise<number> {\n    return this.enqueue(() => {\n      const g = this.handle(rfcGroupId);\n      return g ? g.currentEpoch() : 0;\n    });\n  }\n\n  // ── Membership commits (staged → applied/cleared by the rebase loop) ──\n\n  /** Stage a SINGLE atomic add+remove commit. Returns the AddResult (PENDING). */\n  commitChanges(\n    rfcGroupId: Uint8Array,\n    adds: Uint8Array[],\n    removeMemberIds: Uint8Array[],\n  ): Promise<AddResult> {\n    return this.enqueue(() => {\n      const g = this.requireHandle(rfcGroupId);\n      return g.commitChanges(adds, removeMemberIds);\n    });\n  }\n\n  /** Apply the staged commit (advance the epoch). Only after a server-accept. */\n  applyPendingCommit(rfcGroupId: Uint8Array): Promise<void> {\n    return this.enqueue(async () => {\n      const g = this.requireHandle(rfcGroupId);\n      g.applyPendingCommit();\n      g.writeToStorage();\n      await this.flush();\n    });\n  }\n\n  /** Discard the staged commit (the 409-rebase path). */\n  clearPendingCommit(rfcGroupId: Uint8Array): Promise<void> {\n    return this.enqueue(() => {\n      const g = this.handle(rfcGroupId);\n      if (g?.hasPendingCommit()) g.clearPendingCommit();\n    });\n  }\n\n  // ── Application messages ──\n\n  /** Encrypt a plaintext at the current epoch → PrivateMessage bytes. */\n  encryptApplication(rfcGroupId: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array> {\n    return this.enqueue(async () => {\n      const g = this.requireHandle(rfcGroupId);\n      const ct = g.encryptApplicationMessage(plaintext);\n      // The sender ratchet advanced — checkpoint.\n      g.writeToStorage();\n      await this.flush();\n      return ct;\n    });\n  }\n\n  /**\n   * Process an incoming MLSMessage (decrypt application / apply commit). Returns\n   * the normalized ReceivedMessage. `describeIncomingCommit` could gate a commit\n   * before applying when the server fans a declaration; today the live server\n   * does not, so we process directly (parity with the iOS nil-declaration path).\n   */\n  processIncoming(rfcGroupId: Uint8Array, blob: Uint8Array): Promise<ReceivedMessage> {\n    return this.enqueue(async () => {\n      const g = this.requireHandle(rfcGroupId);\n      const received = g.processIncomingMessage(blob);\n      // A commit/decrypt mutated state — checkpoint before the host acks.\n      g.writeToStorage();\n      await this.flush();\n      return received;\n    });\n  }\n\n  /** Inspect a commit WITHOUT applying (the reconciliation gate's crypto-truth). */\n  describeIncomingCommit(rfcGroupId: Uint8Array, commit: Uint8Array): Promise<CommitDescription> {\n    return this.enqueue(() => this.requireHandle(rfcGroupId).describeIncomingCommit(commit));\n  }\n\n  /** Persist the current group state (explicit checkpoint). */\n  writeToStorage(rfcGroupId: Uint8Array): Promise<void> {\n    return this.enqueue(async () => {\n      const g = this.handle(rfcGroupId);\n      if (g) {\n        g.writeToStorage();\n        await this.flush();\n      }\n    });\n  }\n\n  // ── Handle resolution ──\n\n  /** Resolve (or reload from storage) the handle for a group, or undefined. */\n  private handle(rfcGroupId: Uint8Array): MlsGroupHandle | undefined {\n    const key = gidHex(rfcGroupId);\n    const cached = this.groups.get(key);\n    if (cached) return cached;\n    // Try to reload from the hydrated group-state cache (restart-safe).\n    try {\n      const g = this.client.loadGroup(rfcGroupId);\n      this.groups.set(key, g);\n      return g;\n    } catch {\n      return undefined;\n    }\n  }\n\n  private requireHandle(rfcGroupId: Uint8Array): MlsGroupHandle {\n    const g = this.handle(rfcGroupId);\n    if (!g) throw new Error(`MLS group not loaded: ${gidHex(rfcGroupId)}`);\n    return g;\n  }\n}\n","// The group registry — maps rfc_group_id ↔ the resolved MessagingGroup and\n// drives the observable chat list. Web mirror of the iOS GroupRegistry: a SET\n// change (register-new / remove / hydrate) publishes a fresh [Chat] snapshot;\n// an in-place epoch bump does NOT (a chatty group must not invalidate the list).\n\nimport type { Chat } from './chat.js';\nimport type { MessagingGroup } from './group-messaging.js';\nimport type { GroupCatalog } from './history.js';\n\n/** A pointer-stable Chat factory: one Chat per rfc_group_id. */\nexport type ChatFactory = (group: MessagingGroup) => Chat;\n\nexport class GroupRegistry {\n  private readonly byRfc = new Map<string, MessagingGroup>();\n  private catalog: GroupCatalog | null = null;\n  private chatFactory: ChatFactory | null = null;\n  private onListChange: ((chats: Chat[]) => void) | null = null;\n\n  /** Wire the observable chat-list sink + the pointer-stable Chat factory, then\n   * replay the current set so a sink attached after groups loaded reflects them. */\n  attachChatList(onListChange: (chats: Chat[]) => void, factory: ChatFactory): void {\n    this.onListChange = onListChange;\n    this.chatFactory = factory;\n    this.publish();\n  }\n\n  /** Hydrate from the durable catalog (live entries win — fresher epoch). */\n  async attachCatalog(catalog: GroupCatalog): Promise<void> {\n    this.catalog = catalog;\n    let changed = false;\n    for (const c of await catalog.all()) {\n      if (!this.byRfc.has(c.rfcGroupId)) {\n        this.byRfc.set(c.rfcGroupId, {\n          displayId: c.displayId,\n          rfcGroupId: c.rfcGroupId,\n          currentEpoch: c.currentEpoch,\n          ownerUserId: c.ownerUserId,\n          directKey: c.directKey,\n          name: c.name,\n        });\n        changed = true;\n      }\n    }\n    if (changed) this.publish();\n  }\n\n  register(group: MessagingGroup): void {\n    const isNew = !this.byRfc.has(group.rfcGroupId);\n    this.byRfc.set(group.rfcGroupId, group);\n    void this.persist(group);\n    if (isNew) this.publish();\n  }\n\n  remove(rfcGroupId: string): void {\n    if (!this.byRfc.has(rfcGroupId)) return;\n    this.byRfc.delete(rfcGroupId);\n    if (this.catalog) void this.catalog.remove(rfcGroupId);\n    this.publish();\n  }\n\n  group(rfcGroupId: string): MessagingGroup | undefined {\n    return this.byRfc.get(rfcGroupId);\n  }\n\n  /** The single known group, if exactly one (the wire-gap routing fallback). */\n  soleGroup(): MessagingGroup | undefined {\n    return this.byRfc.size === 1 ? this.byRfc.values().next().value : undefined;\n  }\n\n  all(): MessagingGroup[] {\n    return [...this.byRfc.values()];\n  }\n\n  /** Advance a cached epoch (after a processed commit). Does NOT publish (the\n   * group SET is unchanged — only metadata). */\n  bumpEpoch(rfcGroupId: string, epoch: number): void {\n    const g = this.byRfc.get(rfcGroupId);\n    if (!g) return;\n    const bumped = { ...g, currentEpoch: epoch };\n    this.byRfc.set(rfcGroupId, bumped);\n    void this.persist(bumped);\n  }\n\n  private publish(): void {\n    const factory = this.chatFactory;\n    if (!this.onListChange || !factory) return;\n    const chats = this.all().map((g) => factory(g));\n    this.onListChange(chats);\n  }\n\n  private async persist(group: MessagingGroup): Promise<void> {\n    if (!this.catalog) return;\n    try {\n      await this.catalog.upsert({\n        displayId: group.displayId,\n        rfcGroupId: group.rfcGroupId,\n        currentEpoch: group.currentEpoch,\n        ownerUserId: group.ownerUserId,\n        directKey: group.directKey,\n        name: group.name,\n      });\n    } catch {\n      // best-effort persistence — never blocks the live path\n    }\n  }\n}\n","// The persistence layer for web messaging — the web mirror of the iOS\n// Keychain-sealed MLS stores (MessagingGroupStateStorage / KeyPackageStorage /\n// MessagingDeviceIDStore / MessagingSignatureKeyStore / MessageStore /\n// GroupCatalog).\n//\n// The CRITICAL contract (src/wasm.rs §Storage): mls-rs calls IGroupStateStorage\n// / IKeyPackageStorage methods SYNCHRONOUSLY inside the engine's locked\n// critical section. So those are backed by an in-memory write-through cache\n// (sync reads/writes) and flushed to a durable, encrypted-at-rest backend\n// (IndexedDB + WebCrypto AES-GCM) ASYNCHRONOUSLY, OUTSIDE the engine call. The\n// engine never awaits I/O; the host (the engine wrapper) awaits the flush after\n// each mutating op so an acked message is always durable.\n//\n// At-rest encryption: a per-device AES-GCM key, non-extractable, kept in\n// IndexedDB as a CryptoKey (browsers persist CryptoKey objects in IDB without\n// exposing raw bytes — the web analogue of the iOS Keychain seal key). In Node\n// (vitest / SSR) there is no IndexedDB; a pure in-memory durable backend stands\n// in (the crypto smoke needs durability WITHIN a process, not across reloads).\n\nimport { bytesToHex } from './util.js';\nimport type { IGroupStateStorage, IKeyPackageStorage } from './wasm/bridge.js';\n\n// ─── Durable KV backend (IndexedDB in browser, memory in Node) ──────────────\n\n/** A namespaced async key→bytes store. Values are sealed before write. */\nexport interface DurableKV {\n  get(key: string): Promise<Uint8Array | undefined>;\n  set(key: string, value: Uint8Array): Promise<void>;\n  delete(key: string): Promise<void>;\n  /** All keys under a prefix (for hydrating a store on launch). */\n  keys(prefix: string): Promise<string[]>;\n}\n\nconst hasIndexedDB = (): boolean =>\n  typeof indexedDB !== 'undefined' && typeof crypto !== 'undefined' && !!crypto.subtle;\n\n/** A tight, non-shared ArrayBuffer copy of a byte view (WebCrypto BufferSource). */\nfunction copyToArrayBuffer(view: Uint8Array): ArrayBuffer {\n  const out = new ArrayBuffer(view.byteLength);\n  new Uint8Array(out).set(view);\n  return out;\n}\n\n// ── In-memory backend (Node/SSR/tests) ──────────────────────────────────────\n\nclass MemoryKV implements DurableKV {\n  private readonly map = new Map<string, Uint8Array>();\n  get(key: string): Promise<Uint8Array | undefined> {\n    return Promise.resolve(this.map.get(key));\n  }\n  set(key: string, value: Uint8Array): Promise<void> {\n    this.map.set(key, value.slice());\n    return Promise.resolve();\n  }\n  delete(key: string): Promise<void> {\n    this.map.delete(key);\n    return Promise.resolve();\n  }\n  keys(prefix: string): Promise<string[]> {\n    return Promise.resolve([...this.map.keys()].filter((k) => k.startsWith(prefix)));\n  }\n}\n\n// ── IndexedDB backend (browser) with WebCrypto AES-GCM seal at rest ─────────\n\nconst DB_NAME = 'palbe.messaging';\nconst STORE = 'kv';\nconst KEY_STORE = 'keys';\nconst SEAL_KEY_ID = 'seal-key-v1';\n\nfunction openDb(): Promise<IDBDatabase> {\n  return new Promise((resolve, reject) => {\n    const req = indexedDB.open(DB_NAME, 1);\n    req.onupgradeneeded = () => {\n      const db = req.result;\n      if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE);\n      if (!db.objectStoreNames.contains(KEY_STORE)) db.createObjectStore(KEY_STORE);\n    };\n    req.onsuccess = () => resolve(req.result);\n    req.onerror = () => reject(req.error);\n  });\n}\n\nfunction idbReq<T>(req: IDBRequest<T>): Promise<T> {\n  return new Promise((resolve, reject) => {\n    req.onsuccess = () => resolve(req.result);\n    req.onerror = () => reject(req.error);\n  });\n}\n\n/** Get-or-create the non-extractable AES-GCM seal key (persisted as a CryptoKey). */\nasync function getSealKey(db: IDBDatabase): Promise<CryptoKey> {\n  const existing = await idbReq(\n    db.transaction(KEY_STORE, 'readonly').objectStore(KEY_STORE).get(SEAL_KEY_ID),\n  );\n  if (existing) return existing as CryptoKey;\n  const key = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, [\n    'encrypt',\n    'decrypt',\n  ]);\n  // Storing a non-extractable CryptoKey keeps the raw bytes inside the browser's\n  // key store — the page can use it to seal/open but can never read it out.\n  await idbReq(db.transaction(KEY_STORE, 'readwrite').objectStore(KEY_STORE).put(key, SEAL_KEY_ID));\n  return key;\n}\n\nclass IndexedDbKV implements DurableKV {\n  private dbPromise: Promise<IDBDatabase> | null = null;\n  private keyPromise: Promise<CryptoKey> | null = null;\n\n  private db(): Promise<IDBDatabase> {\n    if (!this.dbPromise) this.dbPromise = openDb();\n    return this.dbPromise;\n  }\n  private async sealKey(): Promise<CryptoKey> {\n    if (!this.keyPromise) this.keyPromise = this.db().then(getSealKey);\n    return this.keyPromise;\n  }\n\n  private async seal(plain: Uint8Array): Promise<Uint8Array> {\n    const key = await this.sealKey();\n    const iv = crypto.getRandomValues(new Uint8Array(12));\n    const ct = new Uint8Array(\n      await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, copyToArrayBuffer(plain)),\n    );\n    const out = new Uint8Array(iv.length + ct.length);\n    out.set(iv, 0);\n    out.set(ct, iv.length);\n    return out;\n  }\n\n  private async open(sealed: Uint8Array): Promise<Uint8Array> {\n    const key = await this.sealKey();\n    const iv = copyToArrayBuffer(sealed.subarray(0, 12));\n    const ct = copyToArrayBuffer(sealed.subarray(12));\n    const pt = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct);\n    return new Uint8Array(pt);\n  }\n\n  async get(k: string): Promise<Uint8Array | undefined> {\n    const db = await this.db();\n    const sealed = (await idbReq(db.transaction(STORE, 'readonly').objectStore(STORE).get(k))) as\n      | Uint8Array\n      | undefined;\n    if (!sealed) return undefined;\n    return this.open(sealed);\n  }\n  async set(k: string, v: Uint8Array): Promise<void> {\n    const db = await this.db();\n    const sealed = await this.seal(v);\n    await idbReq(db.transaction(STORE, 'readwrite').objectStore(STORE).put(sealed, k));\n  }\n  async delete(k: string): Promise<void> {\n    const db = await this.db();\n    await idbReq(db.transaction(STORE, 'readwrite').objectStore(STORE).delete(k));\n  }\n  async keys(prefix: string): Promise<string[]> {\n    const db = await this.db();\n    const all = (await idbReq(\n      db.transaction(STORE, 'readonly').objectStore(STORE).getAllKeys(),\n    )) as IDBValidKey[];\n    return all.map(String).filter((k) => k.startsWith(prefix));\n  }\n}\n\n/** Build the durable KV for this environment (IndexedDB in browser, memory else). */\nexport function createDurableKV(): DurableKV {\n  return hasIndexedDB() ? new IndexedDbKV() : new MemoryKV();\n}\n\n// ─── Byte / hex helpers ──────────────────────────────────────────────────────\n\nfunction bytesKey(prefix: string, id: Uint8Array): string {\n  // Hex the id bytes so any blob can be a string key.\n  return prefix + bytesToHex(id);\n}\n\n// ─── Sync write-through cache (the IGroupStateStorage / IKeyPackageStorage seam)\n\n/**\n * The synchronous group-state storage mls-rs calls inside the engine. Reads/\n * writes hit an in-memory cache (sync); a durable flush to the encrypted KV is\n * scheduled and awaited by the engine wrapper OUTSIDE the engine call.\n *\n * Layout per group (keyed by hex(groupId)):\n *   state:<gid>            → latest serialized group state\n *   epoch:<gid>:<epochId>  → a stored prior-epoch record\n *   maxEpoch:<gid>         → highest stored prior-epoch id (decimal string bytes)\n */\nexport class GroupStateStorage implements IGroupStateStorage {\n  // In-memory authoritative cache (the engine reads/writes this synchronously).\n  private readonly stateCache = new Map<string, Uint8Array>();\n  private readonly epochCache = new Map<string, Uint8Array>();\n  private readonly maxEpochCache = new Map<string, bigint>();\n  // Keys touched since the last flush (durable write queue).\n  private readonly dirty = new Set<string>();\n\n  constructor(private readonly kv: DurableKV) {}\n\n  // ── sync engine seam ──\n  state(groupId: Uint8Array): Uint8Array | undefined {\n    return this.stateCache.get(bytesKey('', groupId));\n  }\n  epoch(groupId: Uint8Array, epochId: bigint): Uint8Array | undefined {\n    return this.epochCache.get(`${bytesKey('', groupId)}:${epochId}`);\n  }\n  write(\n    groupId: Uint8Array,\n    groupState: Uint8Array,\n    epochInserts: { id: bigint; data: Uint8Array }[],\n    epochUpdates: { id: bigint; data: Uint8Array }[],\n  ): void {\n    const gid = bytesKey('', groupId);\n    this.stateCache.set(gid, groupState.slice());\n    this.dirty.add(`state:${gid}`);\n    let max = this.maxEpochCache.get(gid) ?? -1n;\n    for (const rec of [...epochInserts, ...epochUpdates]) {\n      this.epochCache.set(`${gid}:${rec.id}`, rec.data.slice());\n      this.dirty.add(`epoch:${gid}:${rec.id}`);\n      if (rec.id > max) max = rec.id;\n    }\n    if (max >= 0n) {\n      this.maxEpochCache.set(gid, max);\n      this.dirty.add(`maxEpoch:${gid}`);\n    }\n  }\n  maxEpochId(groupId: Uint8Array): bigint | undefined {\n    return this.maxEpochCache.get(bytesKey('', groupId));\n  }\n\n  // ── async durable flush (called by the engine wrapper after a mutating op) ──\n  async flush(): Promise<void> {\n    if (this.dirty.size === 0) return;\n    const pending = [...this.dirty];\n    this.dirty.clear();\n    await Promise.all(\n      pending.map(async (key) => {\n        if (key.startsWith('state:')) {\n          const gid = key.slice('state:'.length);\n          const v = this.stateCache.get(gid);\n          if (v) await this.kv.set(`gss:state:${gid}`, v);\n        } else if (key.startsWith('epoch:')) {\n          const rest = key.slice('epoch:'.length);\n          const v = this.epochCache.get(rest);\n          if (v) await this.kv.set(`gss:epoch:${rest}`, v);\n        } else if (key.startsWith('maxEpoch:')) {\n          const gid = key.slice('maxEpoch:'.length);\n          const max = this.maxEpochCache.get(gid);\n          if (max != null) await this.kv.set(`gss:maxEpoch:${gid}`, encodeBigint(max));\n        }\n      }),\n    );\n  }\n\n  /** Hydrate the in-memory cache from the durable KV (call before generateClient). */\n  async hydrate(): Promise<void> {\n    const keys = await this.kv.keys('gss:');\n    for (const k of keys) {\n      const v = await this.kv.get(k);\n      if (!v) continue;\n      if (k.startsWith('gss:state:')) {\n        this.stateCache.set(k.slice('gss:state:'.length), v);\n      } else if (k.startsWith('gss:epoch:')) {\n        this.epochCache.set(k.slice('gss:epoch:'.length), v);\n      } else if (k.startsWith('gss:maxEpoch:')) {\n        this.maxEpochCache.set(k.slice('gss:maxEpoch:'.length), decodeBigint(v));\n      }\n    }\n  }\n\n  async wipe(): Promise<void> {\n    this.stateCache.clear();\n    this.epochCache.clear();\n    this.maxEpochCache.clear();\n    this.dirty.clear();\n    for (const k of await this.kv.keys('gss:')) await this.kv.delete(k);\n  }\n}\n\n/**\n * The synchronous key-package secret storage mls-rs calls. Secret-bearing (HPKE\n * private keys) — sealed at rest by the KV. Same sync-cache + async-flush shape.\n */\nexport class KeyPackageStorage implements IKeyPackageStorage {\n  private readonly cache = new Map<string, Uint8Array>();\n  private readonly dirtySet = new Set<string>();\n  private readonly dirtyDelete = new Set<string>();\n\n  constructor(private readonly kv: DurableKV) {}\n\n  // ── sync engine seam ──\n  delete(id: Uint8Array): void {\n    const k = bytesKey('', id);\n    this.cache.delete(k);\n    this.dirtyDelete.add(k);\n    this.dirtySet.delete(k);\n  }\n  insert(id: Uint8Array, data: Uint8Array): void {\n    const k = bytesKey('', id);\n    this.cache.set(k, data.slice());\n    this.dirtySet.add(k);\n    this.dirtyDelete.delete(k);\n  }\n  get(id: Uint8Array): Uint8Array | undefined {\n    return this.cache.get(bytesKey('', id));\n  }\n\n  // ── async durable flush ──\n  async flush(): Promise<void> {\n    if (this.dirtySet.size === 0 && this.dirtyDelete.size === 0) return;\n    const sets = [...this.dirtySet];\n    const dels = [...this.dirtyDelete];\n    this.dirtySet.clear();\n    this.dirtyDelete.clear();\n    await Promise.all([\n      ...sets.map((k) => {\n        const v = this.cache.get(k);\n        return v ? this.kv.set(`kps:${k}`, v) : Promise.resolve();\n      }),\n      ...dels.map((k) => this.kv.delete(`kps:${k}`)),\n    ]);\n  }\n\n  async hydrate(): Promise<void> {\n    for (const k of await this.kv.keys('kps:')) {\n      const v = await this.kv.get(k);\n      if (v) this.cache.set(k.slice('kps:'.length), v);\n    }\n  }\n\n  async wipe(): Promise<void> {\n    this.cache.clear();\n    this.dirtySet.clear();\n    this.dirtyDelete.clear();\n    for (const k of await this.kv.keys('kps:')) await this.kv.delete(k);\n  }\n}\n\nfunction encodeBigint(n: bigint): Uint8Array {\n  return new TextEncoder().encode(n.toString());\n}\nfunction decodeBigint(b: Uint8Array): bigint {\n  return BigInt(new TextDecoder().decode(b));\n}\n\n// ─── Device-id + signature-keypair stores (small singletons) ────────────────\n\nconst enc = new TextEncoder();\nconst dec = new TextDecoder();\n\n/** Persisted server-minted device id, keyed by user id (enroll idempotency). */\nexport class DeviceIdStore {\n  constructor(private readonly kv: DurableKV) {}\n  async load(userId: string): Promise<string | undefined> {\n    const v = await this.kv.get(`devid:${userId}`);\n    return v ? dec.decode(v) : undefined;\n  }\n  async save(userId: string, deviceId: string): Promise<void> {\n    await this.kv.set(`devid:${userId}`, enc.encode(deviceId));\n  }\n  async clear(userId: string): Promise<void> {\n    await this.kv.delete(`devid:${userId}`);\n  }\n}\n\n/** Persisted STABLE signature keypair bytes, keyed by user id (same MLS identity). */\nexport class SignatureKeyStore {\n  constructor(private readonly kv: DurableKV) {}\n  async load(userId: string): Promise<Uint8Array | undefined> {\n    return this.kv.get(`sigkey:${userId}`);\n  }\n  async save(userId: string, keypair: Uint8Array): Promise<void> {\n    await this.kv.set(`sigkey:${userId}`, keypair);\n  }\n}\n","// The delete-for-me suppression store — the web mirror of iOS `SuppressionStore`.\n//\n// delete-for-me is a PURELY LOCAL, per-device, unsynced \"hide this message\"\n// intent: NO wire, NO attribution, no server contact. It is a persisted per-chat\n// `Set<suppressionKey>` where `suppressionKey` is the message's `client_msg_id`\n// when present, else `seq:<server_seq>` for legacy messages (which lack a\n// client_msg_id but are always server-acked, so `server_seq` is stable). At\n// render time a message whose key is in the set is OMITTED from the transcript.\n//\n// Sealed at rest by the same durable KV (IndexedDB + WebCrypto AES-GCM in the\n// browser) that seals the message store — so the suppression intent survives a\n// cold launch and a for-me'd message stays hidden after reload (the reload-parity\n// boundary for delete-for-me, mirroring the message store's reaction/edit/delete\n// re-fold parity).\n\nimport type { DurableKV } from './storage.js';\nimport { decodeUtf8, encodeUtf8 } from './util.js';\n\n/** Persist a per-chat delete-for-me suppression key set (keyed by rfcGroupId). */\nexport class SuppressionStore {\n  constructor(private readonly kv: DurableKV) {}\n\n  private key(rfcGroupId: string): string {\n    return `supp:${rfcGroupId}`;\n  }\n\n  /** Load the persisted suppression keys for a chat (empty array if none). */\n  async load(rfcGroupId: string): Promise<string[]> {\n    const raw = await this.kv.get(this.key(rfcGroupId));\n    if (!raw) return [];\n    try {\n      const parsed = JSON.parse(decodeUtf8(raw));\n      return Array.isArray(parsed) ? (parsed as string[]) : [];\n    } catch {\n      return [];\n    }\n  }\n\n  /** Persist the full suppression key set for a chat (deterministic order). */\n  async save(rfcGroupId: string, keys: string[]): Promise<void> {\n    const sorted = [...new Set(keys)].sort();\n    await this.kv.set(this.key(rfcGroupId), encodeUtf8(JSON.stringify(sorted)));\n  }\n\n  async wipe(): Promise<void> {\n    for (const k of await this.kv.keys('supp:')) await this.kv.delete(k);\n  }\n}\n","// The messaging coordinator — the web mirror of iOS MessagingCoordinator +\n// MessagingGroupState. Builds the engine/storage/delivery-source ONCE (lazily,\n// on first chat op after sign-in), implements the ChatBackend seam, mints\n// pointer-stable Chats (one per rfc id), and owns the observable chat list.\n//\n// Process-shared singleton (one runtime per browser tab), like the iOS shared\n// holder. Bound to ONE PalbeRuntime (the configured pb).\n\nimport type { PalbeRuntime } from '../runtime.js';\nimport { Chat, type ChatBackend, type ChatDraft, DELETED_DESCRIPTOR } from './chat.js';\nimport type { AnchorTriple } from './deadline-calculator.js';\nimport { DeleteFold } from './delete-fold.js';\nimport { type IncomingMessage, MessageDeliverySource, MessageHub } from './delivery-source.js';\nimport { DisappearingStore } from './disappearing.js';\nimport { type AuthorResolution, EditFold } from './edit-fold.js';\nimport {\n  type ExpirySpec,\n  GroupMessaging,\n  type MentionRange,\n  type MessagingGroup,\n  type ReplyRef,\n  resolveReply,\n} from './group-messaging.js';\nimport { GroupCatalog, MessageStore, type StoredMessage } from './history.js';\nimport { enrollDevice, listDevices } from './keydir.js';\nimport { MentionElevationStore } from './mention-elevation.js';\nimport { normalizeMentionRangesUtf16 } from './mention-ranges.js';\nimport { MlsEngine } from './mls-engine.js';\nimport { ReactionFold } from './reaction-fold.js';\nimport { GroupRegistry } from './registry.js';\nimport {\n  createDurableKV,\n  DeviceIdStore,\n  type DurableKV,\n  GroupStateStorage,\n  KeyPackageStorage,\n  SignatureKeyStore,\n} from './storage.js';\nimport { SuppressionStore } from './suppression.js';\nimport { TimerFold } from './timer-fold.js';\nimport type {\n  ChatMember,\n  ChatMessage,\n  NotifyScope,\n  ResolvedMention,\n  ResolvedReply,\n  SentReceipt,\n  UnreadView,\n  Unsubscribe,\n} from './types.js';\nimport { directKey as makeDirectKey, mintDeviceId } from './util.js';\n\ninterface Resolved {\n  engine: MlsEngine;\n  groups: GroupMessaging;\n  source: MessageDeliverySource;\n  hub: MessageHub;\n  messageStore: MessageStore;\n  catalog: GroupCatalog;\n  registry: GroupRegistry;\n  deviceId: string;\n  userId: string;\n}\n\nexport class MessagingCoordinator implements ChatBackend {\n  private readonly kv: DurableKV;\n  private readonly deviceStore: DeviceIdStore;\n  private readonly sigStore: SignatureKeyStore;\n  private readonly groupStore: GroupStateStorage;\n  private readonly kpStore: KeyPackageStorage;\n  private readonly suppressionStore: SuppressionStore;\n  private readonly elevationStore: MentionElevationStore;\n  private readonly disappearingStore: DisappearingStore;\n  private readonly registry = new GroupRegistry();\n\n  private resolved: Resolved | null = null;\n  private resolvePromise: Promise<Resolved> | null = null;\n\n  // Pointer-stable Chat cache (one per rfc id) + the observable chat list.\n  private readonly chatByRfc = new Map<string, Chat>();\n  private chatList: Chat[] = [];\n  private readonly listListeners = new Set<() => void>();\n\n  constructor(private readonly rt: PalbeRuntime) {\n    this.kv = createDurableKV();\n    this.deviceStore = new DeviceIdStore(this.kv);\n    this.sigStore = new SignatureKeyStore(this.kv);\n    this.groupStore = new GroupStateStorage(this.kv);\n    this.kpStore = new KeyPackageStorage(this.kv);\n    // The delete-for-me suppression store is durable-only (no engine) — build it\n    // eagerly so loadSuppressed/saveSuppressed work without forcing MLS resolution.\n    this.suppressionStore = new SuppressionStore(this.kv);\n    // The self-elevation dedup store is durable-only (no engine) — build it eagerly so\n    // loadElevated/saveElevated work without forcing MLS resolution (mirrors suppression).\n    this.elevationStore = new MentionElevationStore(this.kv);\n    // The disappearing/TTL purge store is durable-only (no engine) — build it eagerly so\n    // the tombstone/purge/anchor seam works without forcing MLS resolution (T10).\n    this.disappearingStore = new DisappearingStore(this.kv);\n    // Wire the registry → observable chat list with the pointer-stable factory.\n    this.registry.attachChatList(\n      (chats) => {\n        this.chatList = chats;\n        this.emitList();\n      },\n      (group) => this.chatFor(group),\n    );\n  }\n\n  // ── ChatBackend identity ──\n\n  get selfUserId(): string {\n    const u = this.rt.auth.currentUser;\n    if (!u) throw new Error('not_signed_in');\n    return u.id;\n  }\n\n  // ── Public surface (used by the facade) ──\n\n  /** Self-enroll + start the delivery source (idempotent). The first chat op\n   * calls this implicitly; pb.messaging.start() is the opt-in warm-at-sign-in. */\n  async ensureEnrolled(): Promise<void> {\n    await this.resolve();\n  }\n\n  /** Open the ONE direct chat with userId. INSTANT + LOCAL (no network); the\n   * group materializes on the first send. Pointer-stable per peer pair. */\n  directChat(peerUserId: string): Chat {\n    const selfId = this.selfUserId;\n    const dk = makeDirectKey(selfId, peerUserId);\n    // If an active direct chat with this key already exists, return it.\n    for (const chat of this.chatByRfc.values()) {\n      if (chat.isDirect && chat.state === 'active') {\n        // best-effort: match the active group's direct key via the registry\n        const g = this.registry.all().find((x) => x.displayId === chat.id);\n        if (g?.directKey === dk) return chat;\n      }\n    }\n    const draft: ChatDraft = {\n      mode: { kind: 'direct', peerUserId },\n      reservedId: `draft:${dk}`,\n    };\n    // Cache the draft under its reserved id so two opens converge.\n    const cached = this.chatByRfc.get(draft.reservedId);\n    if (cached) return cached;\n    const chat = new Chat({ draft, kind: 'direct', backend: this });\n    this.chatByRfc.set(draft.reservedId, chat);\n    // Fire-and-forget enroll so a peer's DM/Welcome can drain in.\n    void this.ensureEnrolled().catch(() => {});\n    return chat;\n  }\n\n  /** Open a multi-party group chat (LOCAL + LAZY; created on first send). */\n  groupChat(members: string[] = []): Chat {\n    const draft: ChatDraft = {\n      mode: { kind: 'group', members },\n      reservedId: `draft:group:${crypto.randomUUID()}`,\n    };\n    const chat = new Chat({ draft, kind: 'group', backend: this });\n    this.chatByRfc.set(draft.reservedId, chat);\n    void this.ensureEnrolled().catch(() => {});\n    return chat;\n  }\n\n  /** Look up an active chat by id (grp_ display id). */\n  chatById(id: string): Chat | null {\n    const g = this.registry.all().find((x) => x.displayId === id);\n    return g ? this.chatFor(g) : (this.chatByRfc.get(id) ?? null);\n  }\n\n  /** The observable chat list (active chats only). */\n  get chats(): readonly Chat[] {\n    void this.ensureEnrolled().catch(() => {});\n    return this.chatList;\n  }\n\n  onChatsChange(cb: () => void): Unsubscribe {\n    this.listListeners.add(cb);\n    void this.ensureEnrolled().catch(() => {});\n    return () => this.listListeners.delete(cb);\n  }\n\n  private emitList(): void {\n    for (const cb of this.listListeners) cb();\n  }\n\n  /** Pointer-stable Chat for a group (one per rfc id). */\n  private chatFor(group: MessagingGroup): Chat {\n    const existing = this.chatByRfc.get(group.rfcGroupId);\n    if (existing) return existing;\n    const chat = new Chat({\n      group,\n      kind: group.directKey ? 'direct' : 'group',\n      backend: this,\n    });\n    this.chatByRfc.set(group.rfcGroupId, chat);\n    return chat;\n  }\n\n  // ── Resolution (build-once) ──\n\n  private resolve(): Promise<Resolved> {\n    if (this.resolved) return Promise.resolve(this.resolved);\n    if (this.resolvePromise) return this.resolvePromise;\n    this.resolvePromise = this.buildResolved();\n    return this.resolvePromise;\n  }\n\n  private async buildResolved(): Promise<Resolved> {\n    const userId = this.selfUserId;\n    // Resolve (or mint + persist) the device id BEFORE building the engine — the\n    // engine's MLS credential identity IS the device id (SP-1.6).\n    const deviceId = (await this.deviceStore.load(userId)) ?? mintDeviceId();\n\n    const engine = await MlsEngine.create({\n      userId,\n      deviceId,\n      groupStore: this.groupStore,\n      kpStore: this.kpStore,\n      sigStore: this.sigStore,\n    });\n\n    const messageStore = new MessageStore(this.kv);\n    const catalog = new GroupCatalog(this.kv);\n    const hub = new MessageHub();\n    const groups = new GroupMessaging(this.rt, engine, userId, deviceId, messageStore);\n    const source = new MessageDeliverySource(\n      this.rt,\n      engine,\n      hub,\n      this.registry,\n      messageStore,\n      deviceId,\n      userId,\n    );\n\n    // Enroll this device (idempotent — persists the id, publishes key packages).\n    await enrollDevice(this.rt, engine, this.deviceStore, {});\n\n    // Hydrate the registry from the durable catalog BEFORE the first pump.\n    await this.registry.attachCatalog(catalog);\n\n    const resolved: Resolved = {\n      engine,\n      groups,\n      source,\n      hub,\n      messageStore,\n      catalog,\n      registry: this.registry,\n      deviceId,\n      userId,\n    };\n    this.resolved = resolved;\n\n    // Start the live delivery source (subscribe wake + initial drain).\n    await source.start();\n    return resolved;\n  }\n\n  // ── ChatBackend impl ──\n\n  async materialize(draft: ChatDraft): Promise<MessagingGroup> {\n    const r = await this.resolve();\n    let group: MessagingGroup;\n    if (draft.mode.kind === 'direct') {\n      group = await r.groups.getOrCreateDirect(draft.mode.peerUserId);\n    } else {\n      group = await r.groups.createGroup();\n      for (const userId of draft.mode.members) {\n        await r.groups.addMember(group, userId);\n      }\n    }\n    void r.catalog.upsert({\n      displayId: group.displayId,\n      rfcGroupId: group.rfcGroupId,\n      currentEpoch: group.currentEpoch,\n      ownerUserId: group.ownerUserId,\n      directKey: group.directKey,\n      name: group.name,\n    });\n    return group;\n  }\n\n  async sendText(\n    group: MessagingGroup,\n    text: string,\n    replyTo?: ReplyRef | null,\n    bodyRanges?: MentionRange[] | null,\n    expiry?: ExpirySpec | null,\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const r = await this.resolve();\n    // Disappearing T10: forward the per-message/default-stamped `expiry` to the wire.\n    // Dropping it here (the facade declared only 4 params) silently stripped the\n    // per-message TTL from the ciphertext, so a recipient decoded a plain text and\n    // never armed — invisible on the sender's own screen (it arms from effectiveExpiry\n    // directly) and missed by unit tests that drove groups.sendText directly. Caught by\n    // the live 2-browser A↔B gate; locked by the coordinator-forwarding regression test.\n    return r.groups.sendText(group, text, replyTo, bodyRanges, expiry);\n  }\n\n  async sendReaction(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string; emoji: string; op: 'add' | 'remove' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const r = await this.resolve();\n    return r.groups.sendReaction(group, args);\n  }\n\n  async sendEdit(\n    group: MessagingGroup,\n    args: {\n      clientMsgId: string;\n      targetClientMsgId: string;\n      newText: string;\n      bodyRanges?: MentionRange[] | null;\n    },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const r = await this.resolve();\n    return r.groups.sendEdit(group, args);\n  }\n\n  async sendDelete(\n    group: MessagingGroup,\n    args: { clientMsgId: string; targetClientMsgId: string },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const r = await this.resolve();\n    return r.groups.sendDelete(group, args);\n  }\n\n  async sendTimerSet(\n    group: MessagingGroup,\n    args: { clientMsgId: string; ttlSeconds: number | null; start: 'send' | 'read' },\n  ): Promise<{ receipt: SentReceipt; clientMsgId: string }> {\n    const r = await this.resolve();\n    return r.groups.sendTimerSet(group, args);\n  }\n\n  /** Load this chat's persisted delete-for-me suppression keys (durable-only). */\n  loadSuppressed(group: MessagingGroup): Promise<string[]> {\n    return this.suppressionStore.load(group.rfcGroupId);\n  }\n\n  /** Persist this chat's delete-for-me suppression keys (durable-only, no wire). */\n  saveSuppressed(group: MessagingGroup, keys: string[]): Promise<void> {\n    return this.suppressionStore.save(group.rfcGroupId, keys);\n  }\n\n  /** Load this chat's persisted self-elevation dedup keys (durable-only). */\n  loadElevated(group: MessagingGroup): Promise<string[]> {\n    return this.elevationStore.load(group.rfcGroupId);\n  }\n\n  /** Persist this chat's self-elevation dedup keys (durable-only, no wire). */\n  saveElevated(group: MessagingGroup, keys: string[]): Promise<void> {\n    return this.elevationStore.save(group.rfcGroupId, keys);\n  }\n\n  // ── Disappearing / TTL seam (durable-only, no wire) ──\n\n  tombstonedSeqs(group: MessagingGroup): Promise<Set<number>> {\n    return this.disappearingStore.tombstonedSeqs(group.rfcGroupId);\n  }\n\n  purgedClientMsgIds(group: MessagingGroup): Promise<Set<string>> {\n    return this.disappearingStore.purgedClientMsgIds(group.rfcGroupId);\n  }\n\n  anchor(group: MessagingGroup, clientMsgId: string): Promise<AnchorTriple | null> {\n    return this.disappearingStore.anchor(group.rfcGroupId, clientMsgId);\n  }\n\n  writeAnchorOnce(group: MessagingGroup, clientMsgId: string, a: AnchorTriple): Promise<void> {\n    return this.disappearingStore.writeAnchorOnce(group.rfcGroupId, clientMsgId, a);\n  }\n\n  tombstone(group: MessagingGroup, serverSeq: number, clientMsgId: string): Promise<void> {\n    return this.disappearingStore.tombstone(group.rfcGroupId, serverSeq, clientMsgId);\n  }\n\n  async history(group: MessagingGroup, limit: number, before?: number): Promise<ChatMessage[]> {\n    const r = await this.resolve();\n    const rows = await r.messageStore.history(group.rfcGroupId, limit, before);\n    // Disappearing T10: the REAL cold-launch path passes the durable per-chat purge state\n    // so projectHistory excludes tombstoned seqs + resolves purged orphans + arms the chat\n    // default — the SAME pure function the reload-parity test drives (the M1 shared helper).\n    const tombstoned = await this.disappearingStore.tombstonedSeqs(group.rfcGroupId);\n    const purged = await this.disappearingStore.purgedClientMsgIds(group.rfcGroupId);\n    return projectHistory(group.displayId, rows, this.selfUserId, undefined, tombstoned, purged);\n  }\n\n  async members(group: MessagingGroup): Promise<ChatMember[]> {\n    const r = await this.resolve();\n    try {\n      const rows = await r.groups.listMembers(group.displayId);\n      // Dedup device rows → users.\n      const byUser = new Map<string, ChatMember>();\n      for (const row of rows) {\n        if (!byUser.has(row.user_id)) {\n          byUser.set(row.user_id, {\n            id: row.user_id,\n            userId: row.user_id,\n            displayName: null,\n            role: row.role,\n            isSelf: row.user_id === this.selfUserId,\n          });\n        }\n      }\n      return [...byUser.values()];\n    } catch {\n      return [];\n    }\n  }\n\n  async addMember(group: MessagingGroup, userId: string): Promise<void> {\n    const r = await this.resolve();\n    await r.groups.addMember(group, userId);\n  }\n\n  async removeMember(group: MessagingGroup, userId: string): Promise<void> {\n    const r = await this.resolve();\n    await r.groups.removeMember(group, userId);\n  }\n\n  async leave(group: MessagingGroup): Promise<void> {\n    const r = await this.resolve();\n    await r.groups.leaveGroup(group);\n    r.registry.remove(group.rfcGroupId);\n  }\n\n  registerActive(group: MessagingGroup): void {\n    this.registry.register(group);\n  }\n\n  setTyping(group: MessagingGroup, isTyping: boolean): void {\n    void this.resolve().then((r) => r.source.setTyping(group, isTyping));\n  }\n\n  async markRead(group: MessagingGroup, upToServerSeq: number): Promise<void> {\n    const r = await this.resolve();\n    await r.source.markRead(group, upToServerSeq);\n  }\n\n  // ── Server-metadata cluster: notify scope (mute) + unread ──\n\n  async setNotifyScope(group: MessagingGroup, scope: NotifyScope): Promise<NotifyScope> {\n    const r = await this.resolve();\n    return r.source.setNotifyScope(group, scope);\n  }\n\n  async getNotifyScope(group: MessagingGroup): Promise<NotifyScope> {\n    const r = await this.resolve();\n    return r.source.getNotifyScope(group);\n  }\n\n  async unread(group: MessagingGroup): Promise<UnreadView> {\n    const r = await this.resolve();\n    return r.source.unread(group);\n  }\n\n  subscribeLive(group: MessagingGroup, chat: Chat): Unsubscribe {\n    let offMsg: (() => void) | null = null;\n    let offConv: (() => void) | null = null;\n    let resolved: Resolved | null = null;\n    // The runtime resolves on a promise, so a component that mounts and unmounts\n    // inside one tick unsubscribes BEFORE this body runs. Wiring it up anyway\n    // would leave listeners nobody can drop and — the whole point of the\n    // departure frame — a device announcing itself on a topic no Chat is\n    // holding, with no unsubscribe left to take it down.\n    let cancelled = false;\n    void this.resolve().then((r) => {\n      if (cancelled) return;\n      resolved = r;\n      offMsg = r.hub.onMessage(group.displayId, (m: IncomingMessage) => {\n        void chat.ingestLive(m);\n      });\n      r.source.observeConversation(group);\n      offConv = r.hub.onConv(group.displayId, (e) => chat.applyConv(e.event, e.payload));\n    });\n    return () => {\n      cancelled = true;\n      offMsg?.();\n      offConv?.();\n      // The conv topic (and the presence heartbeat riding it) belongs to the\n      // group, not to one Chat — so it comes down only when the LAST live\n      // subscriber has left. Presence is broadcast-only with no server-side\n      // expiry: without this the departing device stays lit for every peer.\n      if (resolved && resolved.hub.convListenerCount(group.displayId) === 0) {\n        resolved.source.unobserveConversation(group);\n      }\n    };\n  }\n\n  async userIdForDevice(group: MessagingGroup, deviceId: string): Promise<string | null> {\n    const r = await this.resolve();\n    try {\n      const rows = await r.groups.listMembers(group.displayId);\n      return rows.find((m) => m.device_id === deviceId)?.user_id ?? null;\n    } catch {\n      return null;\n    }\n  }\n\n  // ── Trust (chat-scoped) ──\n\n  /** List a user's devices (used by safety-number computation). */\n  async listUserDevices(userId: string): Promise<string[]> {\n    const res = await listDevices(this.rt, userId);\n    return res.devices.map((d) => d.device_id);\n  }\n}\n\n/**\n * Project a page of stored rows → surfaced `ChatMessage[]`, page-local-folding\n * reaction rows into their targets' tallies (the web mirror of the iOS\n * `MessagingCoordinator.history()` reaction-vs-bubble loop).\n *\n * A `'reaction'`/`'edit'`/`'delete'` row NEVER becomes a bubble — each folds into a\n * page-local `ReactionFold`/`EditFold`/`DeleteFold` and is skipped. Every surfaced\n * message carries its tally + the winning edit text, UNLESS a valid tombstone folded\n * onto it — then it renders the neutral \"deleted\" descriptor with reactions/reply/edit\n * HIDDEN (the render precedence: delete DOMINATES edit). Backward-compat: old rows (no\n * `envelopeType`) project as ordinary messages. Actor attribution at the store layer:\n * outgoing rows = self; incoming rows use `resolveActor(senderDeviceId)` when provided\n * (the live Chat fold, which resolves device→user, remains authoritative cross-page).\n *\n * Exported so the reaction/edit/delete reload-parity boundary is testable with a REAL\n * `MessageStore` (real persist → unseal → project → re-fold), not a bypass — and so the\n * REAL cold-launch path folds deletes (the iOS-review CRITICAL `.delete` branch lives\n * HERE, the same function `coordinator.history()` calls, so a persisted tombstone can\n * never leak as a blank bubble).\n */\nexport function projectHistory(\n  displayId: string,\n  rows: StoredMessage[],\n  selfUserId: string,\n  resolveActor?: (senderDeviceId: string | null) => string | null,\n  tombstonedSeqs: Set<number> = new Set(),\n  purgedClientMsgIds: Set<string> = new Set(),\n): ChatMessage[] {\n  // Disappearing T10 (the M1-trap cold-launch parity): drop every row whose serverSeq is\n  // in `tombstonedSeqs` BEFORE any fold sees it — a TTL-purged message is NEVER\n  // re-projected (the transcript-reader half of the live `ingestLive` redelivery-drop).\n  const visible = rows.filter((s) => !tombstonedSeqs.has(s.serverSeq));\n\n  // Page-local fold: ingest every reaction row before projecting, so a surfaced\n  // message in the same page renders its tally on cold launch.\n  const fold = new ReactionFold();\n  for (const s of visible) {\n    if (s.envelopeType !== 'reaction' || !s.reaction) continue;\n    const actor =\n      s.direction === 'outgoing' ? selfUserId : (resolveActor?.(s.senderDeviceId ?? null) ?? null);\n    if (actor === null) continue; // unresolvable peer actor — leave to the live fold\n    fold.ingest({\n      targetClientMsgId: s.reaction.targetClientMsgId,\n      actorUserId: actor,\n      emoji: s.reaction.emoji,\n      op: s.reaction.op,\n      epoch: s.epoch,\n      serverSeq: s.serverSeq,\n      eventClientMsgId: s.clientMsgId ?? `${s.id}`,\n    });\n  }\n\n  // Page-local edit fold: an `'edit'` row NEVER becomes a bubble — it folds the\n  // latest author edit's text onto its target in place. The author-gate resolves\n  // each bubble's author from a page map (outgoing = self; incoming = resolveActor,\n  // else unresolved → unknown so the edit HOLDs). A target in `purgedClientMsgIds`\n  // resolves to 'purged' so a late edit DROPs (never resurrects). After the batch,\n  // reevaluateHeld handles an out-of-order page (an edit row before its target).\n  const editFold = new EditFold();\n  // Page-local delete fold: a `'delete'` row NEVER becomes a bubble — it folds a\n  // delete-for-everyone tombstone onto its target (author-gated). After the batch\n  // a tombstoned target is mapped to the neutral \"deleted\" descriptor with\n  // reactions/reply/edit HIDDEN (delete DOMINATES edit). This is the iOS-review\n  // CRITICAL branch: the REAL projection MUST fold deletes, else a persisted\n  // tombstone leaks as a blank bubble + never scrubs on cold launch. The reload\n  // test drives THIS exact function (the same one coordinator.history() calls), so\n  // the boundary is genuinely locked, not a test-local re-implementation.\n  const deleteFold = new DeleteFold();\n  // Disappearing T10 (the M1-trap cold-launch chat-default arming): a `'timer_set'` row is\n  // NEVER a bubble — fold it into a page-local TimerFold so a bubble with no per-message\n  // expiry inherits the chat default active AS OF its order. Because we iterate\n  // oldest-first and fold each timer_set BEFORE reaching a later bubble, `active()` at a\n  // bubble reflects only timer_set events at a LOWER (epoch, serverSeq) order → FORWARD-ONLY\n  // (a message ordered BEFORE the governing timer_set inherits nothing).\n  const pageTimerFold = new TimerFold();\n  const authorByClientMsgId = new Map<string, string>();\n  for (const s of visible) {\n    // A non-bubble row (reaction/edit/delete/timer_set) is not itself a target — only the\n    // surfaced text/media rows author-gate the folds.\n    if (\n      s.envelopeType === 'reaction' ||\n      s.envelopeType === 'edit' ||\n      s.envelopeType === 'delete' ||\n      s.envelopeType === 'timer_set'\n    )\n      continue;\n    const cid = s.clientMsgId ?? '';\n    if (!cid) continue;\n    const author =\n      s.direction === 'outgoing' ? selfUserId : resolveActor?.(s.senderDeviceId ?? null);\n    if (author != null) authorByClientMsgId.set(cid, author);\n  }\n  // Disappearing T10: the orphan-aware resolver — a target whose clientMsgId is in\n  // `purgedClientMsgIds` resolves to 'purged' (a late edit DROPs / a late delete no-ops),\n  // else 'author' from the page map, else 'unknown' (HOLD). Same shape the live\n  // `Chat.authorOfTarget` uses, so the cold-launch fold and the live fold never diverge.\n  const authorOfTarget = (cid: string): AuthorResolution => {\n    if (purgedClientMsgIds.has(cid)) return { kind: 'purged' };\n    const a = authorByClientMsgId.get(cid);\n    return a !== undefined ? { kind: 'author', userId: a } : { kind: 'unknown' };\n  };\n  for (const s of visible) {\n    if (s.envelopeType !== 'edit' || !s.edit) continue;\n    const editor =\n      s.direction === 'outgoing' ? selfUserId : (resolveActor?.(s.senderDeviceId ?? null) ?? null);\n    editFold.ingest(\n      {\n        targetClientMsgId: s.edit.targetClientMsgId,\n        editorUserId: editor,\n        newText: s.edit.newText,\n        epoch: s.epoch,\n        serverSeq: s.serverSeq,\n        eventClientMsgId: s.clientMsgId ?? `${s.id}`,\n        // Mentions T6: the edit's replacement ranges ride the fold so the WINNING\n        // edit's ranges drive the edited message's mentions on cold launch.\n        bodyRanges: s.edit.bodyRanges ?? null,\n      },\n      authorOfTarget,\n    );\n  }\n  editFold.reevaluateHeld(authorOfTarget);\n  // Fold every delete row through the same author-gate (actor = resolved sender;\n  // outgoing = self). A pending/held tombstone whose target sits later in the page\n  // is re-evaluated by the post-loop sweep below.\n  for (const s of visible) {\n    if (s.envelopeType !== 'delete' || !s.delete) continue;\n    const actor =\n      s.direction === 'outgoing' ? selfUserId : (resolveActor?.(s.senderDeviceId ?? null) ?? null);\n    deleteFold.ingest(\n      {\n        targetClientMsgId: s.delete.targetClientMsgId,\n        actorUserId: actor,\n        epoch: s.epoch,\n        serverSeq: s.serverSeq,\n        eventClientMsgId: s.clientMsgId ?? `${s.id}`,\n      },\n      authorOfTarget,\n    );\n  }\n  // Sweep: re-evaluate any pending/held tombstone now that every target's author\n  // is known (an out-of-order tombstone before its target in the same page).\n  for (const [cid] of authorByClientMsgId) deleteFold.reevaluatePending(cid, authorOfTarget(cid));\n\n  // Reply lookup over the surfaced (non-fold) rows.\n  const lookup = new Map<string, { text: string; senderUserId: string }>();\n  for (const s of visible) {\n    if (\n      s.envelopeType === 'reaction' ||\n      s.envelopeType === 'edit' ||\n      s.envelopeType === 'delete' ||\n      s.envelopeType === 'timer_set'\n    )\n      continue;\n    const cid = s.clientMsgId ?? '';\n    if (cid && s.text !== null) {\n      // selfUserId for outgoing rows; '' for incoming (peer user unresolved at\n      // history time — the empty string still yields state:'resolved').\n      const senderUserId = s.direction === 'outgoing' ? selfUserId : '';\n      lookup.set(cid, { text: s.text, senderUserId });\n    }\n  }\n\n  const out: ChatMessage[] = [];\n  // The page-local timer fold is consumed INLINE as we iterate oldest-first (so a bubble\n  // sees only the chat default at a LOWER order — forward-only). A timer_set row never\n  // becomes a bubble; it folds + is skipped.\n  for (const s of visible) {\n    if (s.envelopeType === 'timer_set') {\n      // Fold the chat default (no bubble) — actor = the resolved sender USER; an\n      // unresolvable actor drops it (no spoofable timer). own-send (outgoing) → self.\n      const actor =\n        s.direction === 'outgoing'\n          ? selfUserId\n          : (resolveActor?.(s.senderDeviceId ?? null) ?? null);\n      if (actor !== null && s.timer) {\n        pageTimerFold.ingest({\n          ttlSeconds: s.timer.ttlSeconds,\n          start: s.timer.start,\n          actorUserId: actor,\n          epoch: s.epoch,\n          serverSeq: s.serverSeq,\n          eventClientMsgId: s.clientMsgId ?? `${s.id}`,\n        });\n      }\n      continue; // never projected as a row\n    }\n    if (s.envelopeType === 'reaction' || s.envelopeType === 'edit' || s.envelopeType === 'delete')\n      continue; // folded, never a bubble\n    const clientMsgId = s.clientMsgId ?? '';\n    // RENDER PRECEDENCE (history side; suppression is applied later by the Chat):\n    // (1) tombstoned → the neutral \"deleted\" descriptor, HIDE reactions/reply/edit\n    // (delete DOMINATES edit — short-circuit the overlay); (2) else edit overlay +\n    // reactions + reply. Identical to the live Chat composition so a cold launch\n    // and a live delete render the same.\n    const isDeleted = clientMsgId ? deleteFold.isTombstoned(clientMsgId) : false;\n    if (isDeleted) {\n      out.push({\n        id: `${displayId}#${s.serverSeq}`,\n        kind: 'text',\n        direction: s.direction,\n        senderUserId: s.direction === 'outgoing' ? selfUserId : null,\n        text: DELETED_DESCRIPTOR,\n        serverSeq: s.serverSeq,\n        sentAt: new Date(s.at),\n        clientMsgId,\n        replyTo: null,\n        reactions: {},\n        edited: false,\n        isDeleted: true,\n        // Mentions T6: delete DOMINATES mentions too — a tombstoned message has none.\n        mentions: [],\n        // delete DOMINATES disappearing too — a tombstoned message carries no deadline.\n        expiresAt: null,\n      });\n      continue;\n    }\n    // Disappearing T10 (cold-launch arming): the message's EFFECTIVE TTL = its OWN\n    // per-message `expiry` if present, ELSE the chat default active AS OF this message's\n    // order (forward-only — `pageTimerFold.active()` reflects only timer_set events at a\n    // LOWER (epoch, serverSeq) order because we fold them inline oldest-first). own-expiry\n    // WINS. The deadline is derived purely from the row's send time `s.at` + the TTL — a\n    // monotonic-derived local value, never a wire field; the Chat re-arms the durable\n    // write-once anchor + the advisory purge timer off it on merge.\n    let expiresAt: Date | null = null;\n    if (s.expiry) {\n      expiresAt = new Date(s.at + s.expiry.ttlSeconds * 1000);\n    } else {\n      const active = pageTimerFold.active();\n      if (active && active.ttlSeconds !== null) {\n        expiresAt = new Date(s.at + active.ttlSeconds * 1000);\n      }\n    }\n    let replyTo: ResolvedReply | null = null;\n    if (s.replyTo) {\n      const ref: ReplyRef = {\n        v: 1,\n        client_msg_id: s.replyTo.clientMsgId,\n        preview: {\n          kind: s.replyTo.previewKind,\n          author_user_id: s.replyTo.previewAuthorUserId ?? '',\n          body: s.replyTo.previewBody ?? undefined,\n          body_truncated: false,\n        },\n      };\n      replyTo = resolveReply(ref, (id) => lookup.get(id) ?? null);\n    }\n    // Overlay the winning edit's text + flag onto the row in place: the ORIGINAL\n    // decrypted text stays on the persisted row; the projection computes\n    // `text = edit ?? original` + `edited` so a cold-launched screen renders the\n    // edited text without a new bubble (mirrors iOS T3 history projection).\n    const editText = clientMsgId ? editFold.text(clientMsgId) : null;\n    const edited = clientMsgId ? editFold.isEdited(clientMsgId) : false;\n    const text = editText ?? s.text;\n    // Mentions T6: NORMALIZE the row's raw body_ranges against the SURFACED text → spans\n    // with a null displayName (name resolution is LIVE — the Chat re-resolves on merge,\n    // the projection has no roster). When an edit WON, the surfaced mentions come from the\n    // WINNING edit's replacement ranges (against the edited text); else the bubble's own.\n    const rawRanges = editText !== null ? editFold.bodyRanges(clientMsgId) : s.bodyRanges;\n    const mentions = normalizeMentionsNullNames(rawRanges, text);\n    out.push({\n      id: `${displayId}#${s.serverSeq}`,\n      kind: s.text != null ? 'text' : 'system',\n      direction: s.direction,\n      senderUserId: s.direction === 'outgoing' ? selfUserId : null,\n      text,\n      serverSeq: s.serverSeq,\n      sentAt: new Date(s.at),\n      clientMsgId,\n      replyTo,\n      reactions: clientMsgId ? fold.tally(clientMsgId) : {},\n      edited,\n      isDeleted: false,\n      mentions,\n      expiresAt,\n    });\n  }\n  return out;\n}\n\n/** NORMALIZE raw mention ranges against `text` → `ResolvedMention[]` with `displayName:\n * null` (the history projection has no roster — names are resolved LIVE by the Chat on\n * merge). Returns `[]` when there is no text or no surviving range. */\nfunction normalizeMentionsNullNames(\n  raw: MentionRange[] | null | undefined,\n  text: string | null,\n): ResolvedMention[] {\n  if (text === null || !raw || raw.length === 0) return [];\n  return normalizeMentionRangesUtf16(raw, text).map((r) => ({\n    start: r.start,\n    length: r.length,\n    mentionedUserId: r.mentionedUserId,\n    displayName: null,\n  }));\n}\n","// `pb.messaging` — the chat-centric E2E-encrypted messaging surface (Web-MLS\n// Phase 2). The web mirror of the iOS `pb.messaging`: the dev's mental model is\n// a CHAT (a DM or a group), so the top-level noun is `Chat`, bundling its own\n// messages + typing + presence + members.\n//\n//   const dm = pb.messaging.directChat(peerUserId);   // INSTANT, LOCAL, no network\n//   await dm.send('hi');                               // first send MATERIALIZES it\n//   const off = pb.messaging.onChatsChange(() => render(pb.messaging.chats));\n//\n// The MLS protocol underneath (keydir enroll/claim, group commits, queue pull)\n// is INTERNAL — the first chat op self-enrolls. `messaging` is a reserved\n// namespace (no backend endpoint may be named `messaging`).\n\nimport type { PalbeRuntime } from '../runtime.js';\nimport type { Chat } from './chat.js';\nimport { MessagingCoordinator } from './coordinator.js';\nimport type { Unsubscribe } from './types.js';\n\nexport class PalbeMessaging {\n  private readonly coordinator: MessagingCoordinator;\n\n  constructor(rt: PalbeRuntime) {\n    this.coordinator = new MessagingCoordinator(rt);\n  }\n\n  /**\n   * Warm messaging at sign-in (optional). Enrolls this device + starts the live\n   * delivery source so incoming DMs/Welcomes drain before the chat list opens.\n   * Never REQUIRED — any chat op self-enrolls. Idempotent.\n   */\n  async start(): Promise<void> {\n    await this.coordinator.ensureEnrolled();\n  }\n\n  /**\n   * Open the ONE direct chat with `userId`. INSTANT + LOCAL — no network, nothing\n   * created yet. Returns a draft `Chat` to show immediately; the server group +\n   * MLS material materialize LAZILY on the first `chat.send`. Idempotent + stable:\n   * the same two users always resolve to the SAME Chat.\n   */\n  directChat(userId: string): Chat {\n    return this.coordinator.directChat(userId);\n  }\n\n  /**\n   * Open a multi-party group chat. LOCAL + LAZY like `directChat`: pick the\n   * members, get a draft Chat, the group is created on the FIRST `chat.send`.\n   */\n  groupChat(opts: { members?: string[] } = {}): Chat {\n    return this.coordinator.groupChat(opts.members ?? []);\n  }\n\n  /** Look up a chat by id (e.g. from a push payload / deep link). null if unknown. */\n  chat(id: string): Chat | null {\n    return this.coordinator.chatById(id);\n  }\n\n  /** The observable chat list (DMs + groups, active only). Read it after an\n   * `onChatsChange` subscription to render the inbox. */\n  get chats(): readonly Chat[] {\n    return this.coordinator.chats;\n  }\n\n  /** Subscribe to chat-list changes (a chat added/removed/hydrated). */\n  onChatsChange(cb: () => void): Unsubscribe {\n    return this.coordinator.onChatsChange(cb);\n  }\n}\n","// Web cold-start measurement (§2.8: app-start). The web equivalent of iOS's\n// prewarm-discard (AppStartTracker.measure): iOS may PREWARM a process, so it\n// must discard those launches; the web has no prewarm, so a browser load is\n// ALWAYS a real cold start — `measureAppStart` therefore measures whenever the\n// First Contentful Paint timestamp is available, returning `null` only when FCP\n// is missing (no paint yet / unsupported) or the delta is non-positive (clock\n// skew). `value` is milliseconds from navigation start to FCP.\n//\n// PURE by design (mirrors iOS): the FCP/navigation timestamps come in as\n// parameters so the measurement is unit-testable in isolation. The\n// PerformanceObserver wiring (reading `first-contentful-paint` + navigation\n// startTime, firing once) lives in `runtime.ts`'s browser branch, which calls\n// `rt.perf.record(measureAppStart(...))`.\n//\n// The `app_start` trace_type + `cold_start` name match the iOS emitter exactly,\n// so a row from either platform tags identically server-side.\n\nimport type { PerfItem } from './perf-wire.js';\n\n/** First Contentful Paint relative to navigation start (the two `PerformanceEntry`\n * timestamps the browser branch reads). Both are `DOMHighResTimeStamp` ms. */\nexport interface AppStartTimings {\n  /** Navigation start time (a `PerformanceNavigationTiming.startTime`, usually 0). */\n  startTime: number;\n  /** First Contentful Paint `startTime`; `0` when no paint has been recorded. */\n  fcp: number;\n}\n\n/**\n * Build a `cold_start` `app_start` PerfItem from the navigation→FCP timings, or\n * `null` when FCP is unavailable (`fcp <= 0`) or the delta is non-positive.\n * `value` is `fcp - startTime` in milliseconds.\n */\nexport function measureAppStart(nav: AppStartTimings): PerfItem | null {\n  if (!(nav.fcp > 0)) return null;\n  const value = nav.fcp - nav.startTime;\n  if (value <= 0) return null;\n  return {\n    row_id: crypto.randomUUID(),\n    trace_type: 'app_start',\n    name: 'cold_start',\n    value,\n    timestamp: Date.now(),\n  };\n}\n","// Remote perf sampling (the SDK half). The server owns the sample rate via\n// `GET /v1/analytics/perf/config` `{ sample_pct, flush_at, flush_interval_ms }`\n// (modules/analytics, Faz-2 B1). The SDK fetches it (ETag-cached) and applies\n// `sample_pct` as a CLIENT-SIDE ceiling so it only uploads ~sample_pct% of\n// distinct rows — saving bandwidth — while the server STILL re-samples\n// authoritatively at ingest (defense-in-depth, invariant 3). The SDK never\n// raises its own rate above the fetched value.\n//\n// Cross-boundary wire contract (mutation-evident): `perfSampleBucket` below is a\n// byte-for-byte mirror of the Go `service.SampleDecision`\n// (modules/analytics/internal/service/perf_sampling.go) — FNV-1a-32 over the\n// UTF-8 bytes of `row_id`, mod 100, sampled iff the bucket is strictly below\n// `sample_pct`. Because the decision is DETERMINISTIC per row_id, the client and\n// the server pick the SAME rows: there is no client/server drift, and a row\n// redelivered after an offline-queue reconnect samples identically (idempotency\n// under ReplacingMergeTree). Changing this algorithm here without changing it\n// there breaks the contract — that is why both sides golden-test it.\n\nimport type { PalbeRuntime } from '../runtime.js';\n\n/** The config endpoint the SDK consults for the server-controlled sample rate. */\nconst PERF_CONFIG_PATH = '/v1/analytics/perf/config';\n\n/** FNV-1a 32-bit constants (RFC / Go `hash/fnv`). */\nconst FNV_OFFSET_BASIS_32 = 0x811c9dc5;\nconst FNV_PRIME_32 = 0x01000193;\n\nconst utf8 =\n  typeof TextEncoder !== 'undefined'\n    ? new TextEncoder()\n    : { encode: (s: string): Uint8Array => Uint8Array.from(Buffer.from(s, 'utf-8')) };\n\n/**\n * Deterministic sampling bucket (0..99) for a `row_id`, identical to the Go\n * `service.SampleDecision`: FNV-1a-32 over the row_id's UTF-8 bytes, mod 100.\n * An item is sampled-in iff `perfSampleBucket(row_id) < sample_pct`.\n *\n * Implemented in 32-bit unsigned arithmetic via `Math.imul` (the multiply must\n * wrap exactly like Go's `uint32`); `>>> 0` keeps every intermediate unsigned.\n */\nexport function perfSampleBucket(rowId: string): number {\n  let hash = FNV_OFFSET_BASIS_32;\n  // Iterate values (not indices) so `noUncheckedIndexedAccess` keeps each byte a\n  // definite `number`.\n  for (const byte of utf8.encode(rowId)) {\n    hash ^= byte;\n    hash = Math.imul(hash, FNV_PRIME_32);\n  }\n  // `>>> 0` coerces to the unsigned 32-bit value before the mod, matching\n  // Go's `h.Sum32() % 100` on a `uint32`.\n  return (hash >>> 0) % 100;\n}\n\n/** The server config body. snake_case = wire shape (see B1's `perfConfigResponse`). */\ninterface PerfConfig {\n  sample_pct: number;\n  flush_at: number;\n  flush_interval_ms: number;\n}\n\nfunction isPerfConfig(value: unknown): value is PerfConfig {\n  if (typeof value !== 'object' || value === null) return false;\n  const o = value as Record<string, unknown>;\n  return typeof o.sample_pct === 'number';\n}\n\n/** The shape `rt.http.request` resolves to — `{ data, error, status, headers }`. */\ninterface RawResponse {\n  data: unknown;\n  error: { status: number } | null;\n  status?: number;\n  headers?: Record<string, string>;\n}\n\nfunction isRawResponse(value: unknown): value is RawResponse {\n  return typeof value === 'object' && value !== null && 'data' in value;\n}\n\nfunction headerValue(\n  headers: Record<string, string> | undefined,\n  name: string,\n): string | undefined {\n  if (!headers) return undefined;\n  const lower = name.toLowerCase();\n  for (const [k, v] of Object.entries(headers)) {\n    if (k.toLowerCase() === lower) return v;\n  }\n  return undefined;\n}\n\n/**\n * Fetches the server-controlled perf config and applies its `sample_pct` to the\n * facade's client-side sampling. ETag-aware: it remembers the last ETag and\n * sends `If-None-Match`, so a steady SDK gets a 304 and skips re-applying an\n * unchanged config.\n *\n * The fetch goes through `rt.http.request` directly (NOT `palbeRequest`'s\n * unwrap) so a 304 — which has no body — is observable instead of throwing, and\n * because the config GET is one of the `/v1/analytics/*` paths the network-trace\n * choke point self-excludes (no self-measurement loop).\n */\nexport class PerfConfigClient {\n  private etag: string | undefined;\n\n  async fetchConfig(rt: PalbeRuntime, perf: { setSamplePct(pct: number): void }): Promise<void> {\n    const headers: Record<string, string> = {};\n    if (this.etag) headers['If-None-Match'] = this.etag;\n    try {\n      const res: unknown = await rt.http.request('GET', PERF_CONFIG_PATH, { headers });\n      if (!isRawResponse(res)) return;\n\n      // 304 Not Modified: config unchanged — keep the applied pct and the cached\n      // ETag. Mutation-evident: if we re-applied here, a 304 would clobber pct.\n      if (res.status === 304 || (res.error && res.error.status === 304)) return;\n      if (res.error) return; // any other error: keep the current (default 100) pct\n\n      const newEtag = headerValue(res.headers, 'etag');\n      if (newEtag) this.etag = newEtag;\n\n      if (isPerfConfig(res.data)) {\n        perf.setSamplePct(res.data.sample_pct);\n      }\n    } catch {\n      // Network/transport failure — fire-and-forget: the SDK keeps its current\n      // sample rate (defaults to 100 before the first successful fetch).\n    }\n  }\n}\n","// Opt-in app-level network capture. By default the SDK only traces ITS OWN\n// fetches (the `request.ts` choke point). An app that wants every `fetch(...)`\n// it makes timed as a `network` perf item can opt in with `installFetchSwizzle`\n// — it wraps the global `fetch`, records a redacted trace per call, and hands\n// back an `uninstall` that restores the original `fetch`. It is OFF by default\n// (the embedder calls this explicitly) because swizzling a global is a\n// page-wide side effect.\n//\n// Self-exclusion: the wrapper skips the `/v1/analytics/*` ingest paths, exactly\n// like the `request.ts` network trace — otherwise the perf-flush POST (which an\n// app could route through the global `fetch`) would emit another `network` item\n// that the next flush ships, an item-amplifying self-measurement loop. This is\n// the SAME prefix guard the SDK uses internally (mutation-evident: drop it and\n// the self-loop test goes red).\n\nimport { redactUrl } from './url-redactor.js';\n\n/** The minimal perf surface the swizzle needs — `recordNetwork`, as on PalbePerf. */\ninterface NetworkPerfSink {\n  recordNetwork(\n    method: string,\n    url: string,\n    status: number,\n    durationMs: number,\n    requestId?: string,\n  ): void;\n}\n\n/** The same ingest prefix `request.ts` self-excludes — keep them identical so\n * the wrapper never traces a perf/analytics POST routed through global fetch. */\nconst PERF_EXCLUDED_PREFIX = '/v1/analytics/';\n\n/** Monotonic clock — `performance.now()` when present, else `Date.now()`. */\nfunction nowMs(): number {\n  return typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now();\n}\n\n/** Pull the request URL + method out of the `fetch` argument tuple without a\n * cast: `fetch(input, init)` where input is a string, URL, or Request. */\nfunction describeRequest(\n  input: RequestInfo | URL,\n  init?: RequestInit,\n): { url: string; method: string } {\n  let url: string;\n  let method = 'GET';\n  if (typeof input === 'string') {\n    url = input;\n  } else if (input instanceof URL) {\n    url = input.href;\n  } else {\n    // Request object: it carries both url and method.\n    url = input.url;\n    method = input.method;\n  }\n  if (init?.method) method = init.method;\n  return { url, method: method.toUpperCase() };\n}\n\n/** Resolve the path portion of a URL for the self-exclusion check (absolute or\n * relative). Returns the raw input on a parse failure so the guard still works\n * on a bare `/v1/analytics/...` relative path. */\nfunction pathOf(url: string): string {\n  try {\n    return new URL(url, 'http://_local').pathname;\n  } catch {\n    return url;\n  }\n}\n\n/**\n * Wrap the global `fetch` to record a redacted `network` perf item per app-level\n * request. Returns an `uninstall` that restores the original `fetch`. No-op (and\n * a no-op uninstall) when there is no global `fetch` (some server runtimes).\n */\nexport function installFetchSwizzle(perf: NetworkPerfSink): () => void {\n  if (typeof fetch !== 'function') return () => {};\n  const original = fetch;\n\n  const wrapped = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n    const { url, method } = describeRequest(input, init);\n    const traced = !pathOf(url).startsWith(PERF_EXCLUDED_PREFIX);\n    const startedAt = traced ? nowMs() : 0;\n    try {\n      const res = await original(input, init);\n      if (traced) perf.recordNetwork(method, redactUrl(url), res.status, nowMs() - startedAt);\n      return res;\n    } catch (err) {\n      // A transport failure is still a completed-with-error call (status 0),\n      // mirroring the `request.ts` trace; rethrow so the caller sees the error.\n      if (traced) perf.recordNetwork(method, redactUrl(url), 0, nowMs() - startedAt);\n      throw err;\n    }\n  };\n\n  globalThis.fetch = wrapped as typeof fetch;\n  return () => {\n    globalThis.fetch = original;\n  };\n}\n","// A bounded, FIFO-evicting durability buffer for perf items that failed to\n// flush. It mirrors the iOS offline queue (persist-on-fail, drain-on-reconnect):\n// when `flush()` cannot reach `/v1/analytics/perf` (offline / transport error),\n// the facade hands the failed slice here instead of dropping it; the next flush\n// (size/timer, or the `online` reconnect event) drains it oldest-first.\n//\n// Durability: in the browser the queue persists to `localStorage` under a fixed\n// key, so items survive a page reload while the device is offline. On the server\n// (no `localStorage`) it degrades to pure in-memory — the Faz-1 \"no leak into\n// RSC/route handlers\" rule holds (no timers, no I/O beyond the in-memory array).\n//\n// Bounded + counted: a device offline for days must not grow `localStorage`\n// unbounded. The queue caps at `maxItems` (default 500) and FIFO-evicts the\n// OLDEST items on overflow; every eviction increments `dropped` so the loss is\n// observable, never silent corruption.\n//\n// Idempotency: items are stored VERBATIM — their original `row_id` (client\n// UUIDv7) is preserved, never re-minted. A re-delivered item after reconnect\n// therefore dedups server-side (ClickHouse ReplacingMergeTree keyed on row_id).\n\nimport type { PerfItem } from './perf-wire.js';\n\n/** localStorage key for the persisted perf offline queue (one per origin). */\nexport const PERF_QUEUE_KEY = 'palbe.perf.queue';\n\n/** Default item cap — bounds memory/disk for a long-offline device. */\nconst DEFAULT_MAX_ITEMS = 500;\n\n/** True iff this is a browser with a usable `localStorage`. Gated on `document`\n * too (the SAME \"browser\" test the facade uses): a server runtime must be PURE\n * in-memory — no `localStorage` read/write — even if a `localStorage` global is\n * polyfilled/stubbed there (the \"no I/O leak into RSC/route handlers\" rule). The\n * offline queue's durability (reload survival, reconnect drain) only has meaning\n * in the browser anyway. */\nfunction canPersist(): boolean {\n  return typeof document !== 'undefined' && typeof localStorage !== 'undefined';\n}\n\n/**\n * Narrow `unknown` (parsed JSON) into a `PerfItem`. Only the wire-required\n * fields are checked; this is a defensive parse of persisted bytes that another\n * tab / a corrupt write may have left — a malformed entry is skipped, never\n * cast. Keeps the queue typed end-to-end with no `any`.\n */\nfunction isPerfItem(value: unknown): value is PerfItem {\n  if (typeof value !== 'object' || value === null) return false;\n  const o = value as Record<string, unknown>;\n  return (\n    typeof o.row_id === 'string' &&\n    typeof o.trace_type === 'string' &&\n    typeof o.name === 'string' &&\n    typeof o.value === 'number' &&\n    typeof o.timestamp === 'number'\n  );\n}\n\n/** Read the persisted items, dropping any malformed entries. Never throws. */\nfunction readPersisted(): PerfItem[] {\n  if (!canPersist()) return [];\n  try {\n    const raw = localStorage.getItem(PERF_QUEUE_KEY);\n    if (!raw) return [];\n    const parsed: unknown = JSON.parse(raw);\n    if (!Array.isArray(parsed)) return [];\n    return parsed.filter(isPerfItem);\n  } catch {\n    // Corrupt JSON / quota read error — degrade to empty, never break the\n    // request path.\n    return [];\n  }\n}\n\n/**\n * Bounded FIFO perf-item queue. `enqueue` appends and evicts the oldest on\n * overflow; `drainAll` returns everything (oldest-first) and clears the store;\n * `count` is the current depth; `dropped` is the cumulative eviction counter.\n *\n * When `localStorage` is present the queue is read-through / write-through to a\n * fixed key, so a fresh instance after a reload sees the persisted items. With\n * no `localStorage` it is purely in-memory.\n */\nexport class PerfOfflineQueue {\n  private items: PerfItem[];\n  private _dropped = 0;\n  private readonly maxItems: number;\n\n  constructor(maxItems: number = DEFAULT_MAX_ITEMS) {\n    this.maxItems = Math.max(1, maxItems);\n    // Hydrate from the persisted store (browser) so durability survives reload.\n    this.items = readPersisted();\n    // A persisted store larger than the cap (e.g. a smaller cap after an\n    // upgrade) is trimmed on construction, counting the eviction.\n    this.trim();\n  }\n\n  /** Append items; FIFO-evict the oldest when over `maxItems`. */\n  enqueue(items: PerfItem[]): void {\n    if (items.length === 0) return;\n    this.items.push(...items);\n    this.trim();\n    this.persist();\n  }\n\n  /** Return all queued items (oldest-first) and clear the queue + store. */\n  drainAll(): PerfItem[] {\n    if (this.items.length === 0) return [];\n    const out = this.items;\n    this.items = [];\n    this.clearStore();\n    return out;\n  }\n\n  /** Current queue depth. */\n  get count(): number {\n    return this.items.length;\n  }\n\n  /** Cumulative count of FIFO-evicted items (a `dropped` metric, not silent). */\n  get dropped(): number {\n    return this._dropped;\n  }\n\n  /** Drop the oldest items until at most `maxItems` remain, counting each. */\n  private trim(): void {\n    const overflow = this.items.length - this.maxItems;\n    if (overflow > 0) {\n      this.items.splice(0, overflow);\n      this._dropped += overflow;\n    }\n  }\n\n  private persist(): void {\n    if (!canPersist()) return;\n    try {\n      localStorage.setItem(PERF_QUEUE_KEY, JSON.stringify(this.items));\n    } catch {\n      // Quota exceeded / SSR — non-fatal: durability degrades to in-memory.\n    }\n  }\n\n  private clearStore(): void {\n    if (!canPersist()) return;\n    try {\n      localStorage.removeItem(PERF_QUEUE_KEY);\n    } catch {\n      // ignore\n    }\n  }\n}\n","// Runtime-scoped PalPerf buffer + test-device flag. Kept separate from the\n// facade (PalbePerf) for the same reason AnalyticsState is split out: the\n// buffer/flag identity outlives the lazy facade, and `pb.setTestDevice` /\n// `request.ts`'s network hook need to reach the flag and the buffer without\n// forcing the facade to construct. State is intentionally dumb — no I/O, no\n// timers; the facade owns flush policy.\n\nimport type { PerfItem } from './perf-wire.js';\n\n/** Server hard cap: `POST /v1/analytics/perf` rejects > 100 items per request. */\nexport const MAX_PERF_BATCH = 100;\n\n/**\n * The mutable PalPerf state shared between the facade and the network hook.\n * `testDevice` is signalled to the server via the `X-Palbase-Test-Device: 1`\n * request header (server-authoritative tagging — the SDK only flips the bit).\n */\nexport class PerfState {\n  /** Pending, un-flushed perf items (FIFO). */\n  readonly buffer: PerfItem[] = [];\n  /** When true, every flush carries `X-Palbase-Test-Device: 1`. */\n  testDevice = false;\n\n  enqueue(item: PerfItem): void {\n    this.buffer.push(item);\n  }\n\n  /** Detach up to `MAX_PERF_BATCH` items for one POST (FIFO order preserved). */\n  take(limit: number = MAX_PERF_BATCH): PerfItem[] {\n    return this.buffer.splice(0, limit);\n  }\n\n  get size(): number {\n    return this.buffer.length;\n  }\n}\n","// Wire model for the PalPerf ingest contract (§8.3/§8.6). The live backend\n// (`POST /v1/analytics/perf`, modules/analytics) decodes each item with\n// snake_case json tags — `trace_type`, `request_id`, `row_id`. These property\n// names ARE the wire format: a camelCase key would silently zero-value\n// server-side. distinct_id/app_id/geo and Environment identity are\n// server-derived, so the client MUST NOT send them — they are absent from\n// `PerfItem` by design.\n\n/** The Faz-1 trace kinds plus the Faz-1.5 web-vital family. */\nexport type PerfTraceType = 'network' | 'app_start' | 'custom' | 'web_vital';\n\n/**\n * One perf measurement, shaped EXACTLY as the ingest wire expects. Keys are\n * snake_case to match the Go decode tags — do not rename to camelCase.\n */\nexport interface PerfItem {\n  /** Client-generated UUIDv7 — server dedup key. */\n  row_id: string;\n  trace_type: PerfTraceType;\n  name: string;\n  /** Duration in milliseconds. */\n  value: number;\n  counters?: Record<string, number>;\n  attrs?: Record<string, string>;\n  request_id?: string;\n  /** Unix milliseconds. */\n  timestamp: number;\n}\n\n/** The `POST /v1/analytics/perf` request body shape (≤100 / ≤512 KB per call). */\nexport interface PerfBatch {\n  items: PerfItem[];\n}\n\n/** Wraps items in the ingest request-body envelope. */\nexport function encodePerfBatch(items: PerfItem[]): PerfBatch {\n  return { items };\n}\n","// `pb.perf` — the stateful PalPerf surface. Mirrors `analytics-facade.ts`\n// (same buffer + size/timer flush in the browser, immediate flush on the\n// server where there is no `document`) and the iOS `pb.perf.*` API\n// (startTrace/putAttribute/incrementMetric/stop). Transport is the SAME seam\n// as analytics event send: `palbeRequest(rt, 'POST', '/v1/analytics/perf', …)`,\n// which wraps `rt.http.request` and unwraps the `{ data, error }` envelope.\n//\n// The live ingest contract (proven E2E against modules/analytics):\n//\n//   POST /v1/analytics/perf   {\"items\":[PerfItem…]}   → 202 {accepted,dropped}\n//\n// distinct_id / app_id / geo and Environment identity are server-derived — the\n// SDK sends raw measurements only (§8.3/§8.6). Test traffic is signalled with the\n// `X-Palbase-Test-Device: 1` header, which the server reads to tag the rows;\n// the SDK only flips the bit via `setTestDevice`.\n//\n// Ingestion is fire-and-forget: `flush()` is the only awaited surface and it\n// NEVER rejects — a failed slice is dropped with one warn per flush. `record`\n// and `recordNetwork` never throw into the caller.\n\nimport { palbeRequest } from '../request.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport { installFetchSwizzle } from './fetch-swizzle.js';\nimport { PerfOfflineQueue } from './offline-queue.js';\nimport { perfSampleBucket } from './perf-config-client.js';\nimport { MAX_PERF_BATCH, PerfState } from './perf-state.js';\nimport { encodePerfBatch, type PerfItem, type PerfTraceType } from './perf-wire.js';\n\nconst FLUSH_AT = 20;\nconst FLUSH_INTERVAL_MS = 10_000;\nconst TEST_DEVICE_HEADER = 'X-Palbase-Test-Device';\n\n/** Monotonic millisecond clock — `performance.now()` when present (browser and\n * modern Node), else `Date.now()`. Used to time custom traces; the wall clock\n * is only used for the wire `timestamp`. */\nfunction nowMs(): number {\n  return typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now();\n}\n\n/**\n * A running custom trace. `putAttribute`/`incrementMetric` accumulate metadata;\n * `stop()` records ONE `custom` PerfItem whose `value` is the elapsed\n * milliseconds since `startTrace`. Idempotent: a second `stop()` is a no-op.\n */\nexport class PerfTrace {\n  private readonly attrs: Record<string, string> = {};\n  private readonly counters: Record<string, number> = {};\n  private readonly startedAt = nowMs();\n  private stopped = false;\n\n  constructor(\n    private readonly name: string,\n    private readonly onStop: (item: PerfItem) => void,\n  ) {}\n\n  putAttribute(key: string, value: string): void {\n    this.attrs[key] = value;\n  }\n\n  incrementMetric(name: string, by = 1): void {\n    this.counters[name] = (this.counters[name] ?? 0) + by;\n  }\n\n  stop(): void {\n    if (this.stopped) return;\n    this.stopped = true;\n    const item: PerfItem = {\n      row_id: crypto.randomUUID(),\n      trace_type: 'custom',\n      name: this.name,\n      value: Math.max(0, nowMs() - this.startedAt),\n      timestamp: Date.now(),\n    };\n    if (Object.keys(this.attrs).length > 0) item.attrs = this.attrs;\n    if (Object.keys(this.counters).length > 0) item.counters = this.counters;\n    this.onStop(item);\n  }\n}\n\nexport class PalbePerf {\n  private flushTimer: ReturnType<typeof setTimeout> | null = null;\n  /** Browser → buffer + size/timer flush. Server (no document) → immediate\n   * per-item flush, zero timers (nothing leaks into RSC/route handlers). */\n  private readonly browser = typeof document !== 'undefined';\n  /** Bound `online` handler so it can be removed on `dispose()` (no leak). */\n  private readonly onOnline = (): void => {\n    void this.flush();\n  };\n  /** Server-controlled client-side sample rate (0..100). 100 until the config\n   * client fetches `/v1/analytics/perf/config` — the SDK obeys this ceiling and\n   * never raises its own rate (invariant 3). `record` drops an item whose\n   * deterministic `row_id` bucket is >= this pct, mirroring the server's\n   * `SampleDecision` so client + server keep the SAME rows. */\n  private samplePct = 100;\n\n  constructor(\n    private readonly rt: PalbeRuntime,\n    private readonly state: PerfState = new PerfState(),\n    /** Durable offline buffer for failed flushes (persist-on-fail). Browser →\n     * localStorage-backed; server → in-memory. */\n    private readonly queue: PerfOfflineQueue = new PerfOfflineQueue(),\n  ) {\n    // Drain-on-reconnect: when the browser comes back online, flush — this ships\n    // whatever the offline queue persisted while the network was down. Server\n    // (no `window`) wires nothing (the no-timers/no-listeners rule holds).\n    if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n      window.addEventListener('online', this.onOnline);\n    }\n  }\n\n  /** Remove the `online` listener. Called when the runtime is replaced so the\n   * handler does not outlive this facade. No-op outside the browser. */\n  dispose(): void {\n    if (typeof window !== 'undefined' && typeof window.removeEventListener === 'function') {\n      window.removeEventListener('online', this.onOnline);\n    }\n  }\n\n  /** Mark (or unmark) this client's traffic as test — the server tags the rows\n   * when the `X-Palbase-Test-Device: 1` header rides along on flush. */\n  setTestDevice(on: boolean): void {\n    this.state.testDevice = on;\n  }\n\n  /** Apply the server-resolved client-side sample rate (0..100), clamped. Called\n   * by `PerfConfigClient` after fetching `/v1/analytics/perf/config`. The SDK\n   * OBEYS this value — it is a ceiling, never raised locally. */\n  setSamplePct(pct: number): void {\n    this.samplePct = Math.max(0, Math.min(100, Math.trunc(pct)));\n  }\n\n  /** Pending (un-flushed) buffer depth. Test-only visibility into the buffer so\n   * the remote-sampling tests can assert how many items were sampled in. */\n  get bufferSizeForTest(): number {\n    return this.state.size;\n  }\n\n  /** Opt-in: wrap the global `fetch` so every app-level request is recorded as a\n   * redacted `network` perf item (the `/v1/analytics/*` ingest paths are\n   * self-excluded). OFF by default — swizzling a global is a page-wide side\n   * effect. Returns an `uninstall` that restores the original `fetch`. */\n  enableFetchCapture(): () => void {\n    return installFetchSwizzle(this);\n  }\n\n  /** Start a custom trace; the returned handle records a `custom` item on\n   * `.stop()`. */\n  startTrace(name: string): PerfTrace {\n    return new PerfTrace(name, (item) => this.record(item));\n  }\n\n  /** Buffer one perf item. In the browser, flush on size/timer; on the server\n   * flush immediately (no timers). Never throws.\n   *\n   * Client-side remote sampling: an item whose deterministic `row_id` bucket is\n   * NOT below the server-controlled `samplePct` is dropped before buffering —\n   * the SAME FNV-1a-mod-100 decision the server applies at ingest, so the two\n   * keep identical rows and the SDK saves the upload (defense-in-depth: the\n   * server re-samples authoritatively). */\n  record(item: PerfItem): void {\n    if (perfSampleBucket(item.row_id) >= this.samplePct) return;\n    this.state.enqueue(item);\n    if (!this.browser) {\n      void this.flush();\n      return;\n    }\n    if (this.state.size >= FLUSH_AT) void this.flush();\n    else this.startTimer();\n  }\n\n  /** Buffer a network trace — called by `request.ts` around `rt.http.request`\n   * (the analytics ingest path is excluded by the caller to avoid recursion). */\n  recordNetwork(\n    method: string,\n    url: string,\n    status: number,\n    durationMs: number,\n    requestId?: string,\n  ): void {\n    const item: PerfItem = {\n      row_id: crypto.randomUUID(),\n      trace_type: 'network' satisfies PerfTraceType,\n      name: `${method} ${url}`,\n      value: durationMs,\n      attrs: { status: String(status) },\n      timestamp: Date.now(),\n    };\n    if (requestId) item.request_id = requestId;\n    this.record(item);\n  }\n\n  /** Drain the offline queue (oldest-first) and the live buffer to\n   * `/v1/analytics/perf` (≤100 items per request, sequential). Resolves when\n   * delivery finished; NEVER rejects. A failed slice is NOT dropped — it goes\n   * to the offline queue (persist-on-fail) so the next flush (size/timer or the\n   * `online` reconnect event) retries it. Items keep their original `row_id`,\n   * so a redelivery dedups server-side (ReplacingMergeTree). */\n  async flush(): Promise<void> {\n    this.cancelTimer();\n    // Previously-failed items drain FIRST (oldest-first), prepended ahead of the\n    // current buffer so the queue cannot starve.\n    const pending = this.queue.drainAll();\n    if (pending.length === 0 && this.state.size === 0) return;\n    const headers = this.state.testDevice ? { [TEST_DEVICE_HEADER]: '1' } : undefined;\n    const remaining = [...pending];\n    while (this.state.size > 0) remaining.push(...this.state.take(MAX_PERF_BATCH));\n\n    for (let i = 0; i < remaining.length; i += MAX_PERF_BATCH) {\n      const slice = remaining.slice(i, i + MAX_PERF_BATCH);\n      try {\n        await palbeRequest<{ accepted?: number; dropped?: number }>(\n          this.rt,\n          'POST',\n          '/v1/analytics/perf',\n          { body: encodePerfBatch(slice), headers },\n        );\n      } catch {\n        // Offline / transport error: persist this slice for a later drain\n        // instead of dropping it. Re-enqueueing a drained slice is safe — the\n        // bounded queue caps growth and the row_id dedups any redelivery.\n        this.queue.enqueue(slice);\n      }\n    }\n  }\n\n  private startTimer(): void {\n    if (this.flushTimer !== null) return;\n    this.flushTimer = setTimeout(() => {\n      this.flushTimer = null;\n      void this.flush();\n    }, FLUSH_INTERVAL_MS);\n  }\n\n  private cancelTimer(): void {\n    if (this.flushTimer !== null) {\n      clearTimeout(this.flushTimer);\n      this.flushTimer = null;\n    }\n  }\n}\n","// Web Vitals capture (PalPerf Faz 1.5). Each Core Web Vital is ONE `web_vital`\n// perf row: name = the vital (LCP/CLS/INP/FCP/TTFB), value = the metric. They\n// ride the SAME ingest + `perf_agg_daily_mv` percentile rollup as every other\n// perf family — no new wire shape, no new CH table. distinct_id/app_id/geo are\n// server-derived (§8.6); the SDK sends raw measurements only.\n//\n// Strict TS, no `any`/cast: PerformanceObserver entry types are narrowed via\n// typed predicates, never coerced. We avoid the `web-vitals` npm dep (the SDK\n// ships zero runtime deps for perf) and read the raw PerformanceObserver\n// entries directly — CLS is summed across `layout-shift` entries without recent\n// input, LCP/INP take the latest, FCP/TTFB are one-shot.\n\nimport type { PerfItem } from './perf-wire.js';\n\n/** The Core Web Vitals we capture. FID is intentionally omitted — it is\n * deprecated in favour of INP. Closed union → exhaustive, no `any`. */\nexport type WebVitalName = 'LCP' | 'CLS' | 'INP' | 'FCP' | 'TTFB';\n\n/** Build a `web_vital` PerfItem. `value` is the metric (ms for timing vitals,\n * a unitless score ×1000-free for CLS). Negative values clamp to 0. PURE. */\nexport function webVitalItem(name: WebVitalName, value: number): PerfItem {\n  return {\n    row_id: crypto.randomUUID(),\n    trace_type: 'web_vital',\n    name,\n    value: Math.max(0, value),\n    timestamp: Date.now(),\n  };\n}\n\n// --- typed PerformanceObserver entry narrowing (no `any`) -------------------\n\ninterface LayoutShiftEntry extends PerformanceEntry {\n  value: number;\n  hadRecentInput: boolean;\n}\nfunction isLayoutShift(e: PerformanceEntry): e is LayoutShiftEntry {\n  return e.entryType === 'layout-shift' && 'value' in e && 'hadRecentInput' in e;\n}\n\ninterface EventTimingEntry extends PerformanceEntry {\n  duration: number;\n  interactionId?: number;\n}\nfunction isEventTiming(e: PerformanceEntry): e is EventTimingEntry {\n  return e.entryType === 'event' || e.entryType === 'first-input';\n}\n\n/** Safely create + start a PerformanceObserver for one entry type, swallowing\n * unsupported-type errors (Safari lacks `layout-shift`/`event`). Returns the\n * observer or null. */\nfunction safeObserve(\n  type: string,\n  cb: (entries: PerformanceEntryList) => void,\n): PerformanceObserver | null {\n  if (typeof PerformanceObserver === 'undefined') return null;\n  try {\n    const obs = new PerformanceObserver((list) => cb(list.getEntries()));\n    obs.observe({ type, buffered: true } as PerformanceObserverInit);\n    return obs;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Wire the Core Web Vitals observers, recording one `web_vital` PerfItem per\n * settled vital. Returns a disconnect fn (call on teardown). No-op outside the\n * browser. LCP/INP record the LATEST observed value on disconnect/pagehide; CLS\n * sums layout shifts without recent input; FCP/TTFB are one-shot. Best-effort —\n * a missing observer type is silently skipped, never thrown.\n */\nexport function observeWebVitals(record: (item: PerfItem) => void): () => void {\n  // No-op outside a real browser. We require the exact DOM/timing methods we\n  // call below — a partial/non-standard `document` (e.g. an SSR shim, or a test\n  // fake that only sets `window`) must NOT crash runtime construction. This is\n  // the same defensiveness `recordColdStart` applies.\n  if (\n    typeof document === 'undefined' ||\n    typeof document.addEventListener !== 'function' ||\n    typeof document.removeEventListener !== 'function' ||\n    typeof performance === 'undefined' ||\n    typeof performance.getEntriesByType !== 'function'\n  ) {\n    return () => {};\n  }\n\n  let cls = 0;\n  let lcp = 0;\n  let inp = 0;\n\n  const observers: Array<PerformanceObserver | null> = [\n    // LCP: keep the largest/last reported render.\n    safeObserve('largest-contentful-paint', (entries) => {\n      for (const e of entries) lcp = Math.max(lcp, e.startTime);\n    }),\n    // CLS: sum shift values that weren't caused by recent input.\n    safeObserve('layout-shift', (entries) => {\n      for (const e of entries) if (isLayoutShift(e) && !e.hadRecentInput) cls += e.value;\n    }),\n    // INP: approximate as the worst interaction duration observed.\n    safeObserve('event', (entries) => {\n      for (const e of entries) if (isEventTiming(e)) inp = Math.max(inp, e.duration);\n    }),\n    // FCP: one-shot.\n    safeObserve('paint', (entries) => {\n      for (const e of entries)\n        if (e.name === 'first-contentful-paint') record(webVitalItem('FCP', e.startTime));\n    }),\n  ];\n\n  // TTFB from the navigation entry (one-shot, available immediately).\n  const nav = performance.getEntriesByType('navigation')[0] as\n    | PerformanceNavigationTiming\n    | undefined;\n  if (nav && nav.responseStart > 0) record(webVitalItem('TTFB', nav.responseStart));\n\n  // Flush the running aggregates (LCP/CLS/INP) once, when the page is hidden or\n  // torn down — that's when the values have settled.\n  let flushed = false;\n  const flush = (): void => {\n    if (flushed) return;\n    flushed = true;\n    if (lcp > 0) record(webVitalItem('LCP', lcp));\n    record(webVitalItem('CLS', cls));\n    if (inp > 0) record(webVitalItem('INP', inp));\n  };\n  const onHide = (): void => {\n    if (document.visibilityState === 'hidden') flush();\n  };\n  document.addEventListener('visibilitychange', onHide);\n\n  return () => {\n    flush();\n    document.removeEventListener('visibilitychange', onHide);\n    for (const o of observers) o?.disconnect();\n  };\n}\n","const APP_METADATA_HEADER = 'X-Palbase-Bundle';\n\n/**\n * Stamp the live browser origin metadata on an app-key request. Final headers\n * are inspected case-insensitively so an explicit caller/config value wins.\n * The authenticated app identity is the app-bound API key plus its app_id;\n * this header is diagnostic metadata, not an authorization proof. Server\n * runtimes have no browser origin and intentionally add nothing.\n */\nexport function applyBrowserOriginHeader(headers: Record<string, string>): void {\n  if (Object.keys(headers).some((key) => key.toLowerCase() === 'x-palbase-bundle')) return;\n  const origin =\n    typeof window !== 'undefined' && typeof window.location !== 'undefined'\n      ? window.location.origin\n      : '';\n  if (origin !== '') headers[APP_METADATA_HEADER] = origin;\n}\n","// Anonymous-token minting for the realtime WebSocket — a port of the iOS\n// `AnonTokenProvider` actor (palbackend-ios-src Sources/Palbe/Realtime/\n// AnonTokenProvider.swift).\n//\n// Why this exists: Realtime validates every connection's token against the\n// tenant's JWKS (palauth's ES256 signing key). A signed-in user already has a\n// palauth-issued Bearer that validates there. An anonymous caller only holds\n// the Environment's publishable API key (`pb_<environmentRef>_c…`) — NOT a JWT, so Realtime\n// rejects it with MalformedJWT. `POST /auth/anonymous` mints the missing\n// piece: a role=anon ES256 JWT signed by the same key Realtime trusts.\n//\n// Deliberately SEPARATE from TokenManager (which owns the user-session\n// lifecycle and auth-state events): an anonymous token has no user, no\n// refresh token, and emits no auth events. The provider memoises one token\n// and re-mints it shortly before expiry.\n\nimport { BackendError, fromEnvelope } from '../errors.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport { applyBrowserOriginHeader } from '../runtime-metadata.js';\n\ninterface AnonToken {\n  accessToken: string;\n  expiresAt: number; // epoch ms\n}\n\n/** Re-mint this long before real expiry so a long-lived socket never presents\n * an expired token on reconnect/join (iOS refreshSkew = 60s). */\nconst REFRESH_SKEW_MS = 60_000;\n\nexport class AnonTokenProvider {\n  private readonly rt: PalbeRuntime;\n  private cached: AnonToken | null = null;\n  private inFlight: Promise<string> | null = null;\n\n  constructor(rt: PalbeRuntime) {\n    this.rt = rt;\n  }\n\n  /**\n   * Return a valid anonymous access token, minting (or re-minting) one when\n   * the cache is empty or within the skew of expiry. Concurrent callers\n   * collapse onto a single in-flight mint.\n   */\n  token(): Promise<string> {\n    if (this.cached && Date.now() < this.cached.expiresAt - REFRESH_SKEW_MS) {\n      return Promise.resolve(this.cached.accessToken);\n    }\n    if (this.inFlight) return this.inFlight;\n    const mint = this.mint().then(\n      (token) => {\n        this.cached = token;\n        this.inFlight = null;\n        return token.accessToken;\n      },\n      (e: unknown) => {\n        this.inFlight = null; // a failed mint must not poison future attempts\n        throw e;\n      },\n    );\n    this.inFlight = mint;\n    return mint;\n  }\n\n  /**\n   * Raw fetch, deliberately NOT through HttpClient/palbeRequest: the mint\n   * must carry the Environment API key and NEVER a Bearer (iOS keeps\n   * `/auth/anonymous` on the unauthenticated-path list), and HttpClient's\n   * pre-flight would try to refresh a stale session before an anon mint —\n   * exactly the entanglement this provider exists to avoid.\n   */\n  private async mint(): Promise<AnonToken> {\n    const base = this.rt.config.url.replace(/\\/+$/, '');\n    const headers: Record<string, string> = {\n      apikey: this.rt.config.apiKey,\n      ...this.rt.config.headers,\n    };\n    applyBrowserOriginHeader(headers);\n    let response: Response;\n    try {\n      response = await fetch(`${base}/auth/anonymous`, {\n        method: 'POST',\n        headers,\n      });\n    } catch (e) {\n      throw new BackendError('network', {\n        code: 'network_error',\n        message: e instanceof Error ? e.message : 'Network request failed',\n      });\n    }\n    const body: unknown = await response.json().catch(() => null);\n    if (!response.ok) throw fromEnvelope(response.status, body);\n    // Wire shape: { access_token, token_type: \"Bearer\", expires_in: seconds }.\n    const obj = (typeof body === 'object' && body !== null ? body : {}) as Record<string, unknown>;\n    const accessToken = obj.access_token;\n    const expiresIn = obj.expires_in;\n    if (typeof accessToken !== 'string' || accessToken === '' || typeof expiresIn !== 'number') {\n      throw new BackendError('decode', {\n        code: 'decode_error',\n        message:\n          'POST /auth/anonymous returned an unexpected shape (expected {access_token, expires_in}).',\n      });\n    }\n    return { accessToken, expiresAt: Date.now() + expiresIn * 1000 };\n  }\n}\n\n/**\n * The realtime connection's token closure (iOS PalBackend.swift parity):\n * 1. the signed-in user Bearer when present and unexpired (user-override\n *    flag topics + private channels authorize);\n * 2. else an anonymous palauth JWT (role=anon);\n * 3. else — ONLY when the mint fails — the bare Environment API key. Realtime\n *    would reject it, but it keeps the closure total: the connect proceeds,\n *    fails, and the backoff loop retries the mint on the next attempt.\n */\nexport function realtimeTokenProvider(\n  rt: PalbeRuntime,\n  anon: AnonTokenProvider,\n): () => Promise<string> {\n  return async () => {\n    const bearer = rt.tokenManager.getAccessToken();\n    if (bearer && !rt.tokenManager.isExpired()) return bearer;\n    try {\n      return await anon.token();\n    } catch {\n      return rt.config.apiKey;\n    }\n  };\n}\n","// Phoenix Channels v2 frame codec — the realtime wire format.\n//\n// Every shape here is byte-locked to the iOS encoder (palbackend-ios-src\n// Sources/Palbe/Realtime/RealtimeConnection.swift), the proven-live ground\n// truth against the platform's Supabase Realtime (Elixir/Phoenix):\n//\n//   join:      [join_ref, ref, \"realtime:<topic>\", \"phx_join\", {access_token, config}]\n//   reply:     [join_ref, ref, \"realtime:<topic>\", \"phx_reply\", {status, response}]\n//   heartbeat: [null, ref, \"phoenix\", \"heartbeat\", {}]\n//   leave:     [null, ref, \"realtime:<topic>\", \"phx_leave\", {}]\n//   broadcast: [join_ref, ref, \"realtime:<topic>\", \"broadcast\", {type, event, payload}]\n//\n// Refs are stringified monotonic ints. Topics are bare sub-topics in the API\n// (\"room:42\"); the codec adds the \"realtime:\" prefix on the way out and strips\n// it on the way in. Goldens: __tests__/realtime-frames.test.ts.\n\nexport const REALTIME_PREFIX = 'realtime:';\n\n/** A decoded Phoenix v2 frame. Only topic/event/payload matter for routing. */\nexport interface PhoenixFrame {\n  joinRef: unknown;\n  ref: unknown;\n  topic: string;\n  event: string;\n  payload: unknown;\n}\n\n/** An inbound broadcast routed to channel handlers: bare topic + inner event/payload. */\nexport interface RealtimeInbound {\n  topic: string;\n  event: string;\n  payload: Record<string, unknown>;\n}\n\n/**\n * Join a topic. join_ref = ref (iOS sends the same ref in both slots). The\n * config mirrors iOS exactly: broadcast self=false, no presence key, public\n * channel, no postgres_changes.\n */\nexport function encodeJoin(ref: number, topic: string, accessToken: string): string {\n  const r = String(ref);\n  return JSON.stringify([\n    r,\n    r,\n    REALTIME_PREFIX + topic,\n    'phx_join',\n    {\n      access_token: accessToken,\n      config: {\n        broadcast: { self: false },\n        presence: { key: '' },\n        private: false,\n        postgres_changes: [],\n      },\n    },\n  ]);\n}\n\nexport function encodeLeave(ref: number, topic: string): string {\n  return JSON.stringify([null, String(ref), REALTIME_PREFIX + topic, 'phx_leave', {}]);\n}\n\nexport function encodeHeartbeat(ref: number): string {\n  return JSON.stringify([null, String(ref), 'phoenix', 'heartbeat', {}]);\n}\n\n/**\n * Client-side broadcast push (web addition — iOS is receive-only). The payload\n * envelope {type:\"broadcast\", event, payload} matches what the server fans out\n * to other subscribers (Realtime's BroadcastHandler re-broadcasts it verbatim),\n * so receivers unwrap pushes from peers and from the backend identically.\n * joinRef is the topic's CURRENT join ref — Phoenix drops channel messages\n * whose join_ref does not match the live channel instance.\n */\nexport function encodeBroadcast(\n  joinRef: string,\n  ref: number,\n  topic: string,\n  event: string,\n  payload: Record<string, unknown>,\n): string {\n  return JSON.stringify([\n    joinRef,\n    String(ref),\n    REALTIME_PREFIX + topic,\n    'broadcast',\n    { type: 'broadcast', event, payload },\n  ]);\n}\n\n/** Decode a Phoenix v2 frame; null when the text is not a valid 5-slot array. */\nexport function decodeFrame(text: string): PhoenixFrame | null {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(text);\n  } catch {\n    return null;\n  }\n  if (!Array.isArray(parsed)) return null;\n  const [joinRef, ref, topic, event, payload] = parsed as unknown[];\n  if (typeof topic !== 'string' || typeof event !== 'string') return null;\n  return { joinRef, ref, topic, event, payload };\n}\n\nfunction asObject(value: unknown): Record<string, unknown> | null {\n  if (typeof value !== 'object' || value === null || Array.isArray(value)) return null;\n  return value as Record<string, unknown>;\n}\n\n/**\n * Route an inbound frame: only `broadcast` events carry channel traffic\n * (replies/acks/presence are connection bookkeeping — iOS ignores them the\n * same way; reconnect re-joins every topic, so socket health drives recovery).\n * Missing inner event defaults to '' and a non-object payload to {} — exact\n * iOS decoder behavior.\n */\nexport function unwrapBroadcast(frame: PhoenixFrame): RealtimeInbound | null {\n  if (frame.event !== 'broadcast') return null;\n  const body = asObject(frame.payload);\n  if (!body) return null;\n  const event = typeof body.event === 'string' ? body.event : '';\n  const payload = asObject(body.payload) ?? {};\n  return { topic: stripRealtimePrefix(frame.topic), event, payload };\n}\n\nexport function stripRealtimePrefix(topic: string): string {\n  return topic.startsWith(REALTIME_PREFIX) ? topic.slice(REALTIME_PREFIX.length) : topic;\n}\n\n// ── the state vocabulary ─────────────────────────────────────────────────────\n//\n// New event names on the SAME 5-slot envelope, byte-locked to the server's\n// goldens (internal/modules/rt/frames_state_test.go). A client that speaks only\n// broadcast is unaffected.\n\n/** Write one entry on a channel's shared state. */\nexport function encodeStateSet(\n  joinRef: string,\n  ref: number,\n  topic: string,\n  key: string,\n  value: unknown,\n  life: 'ephemeral' | 'durable',\n): string {\n  return JSON.stringify([\n    joinRef,\n    String(ref),\n    REALTIME_PREFIX + topic,\n    'state_set',\n    { key, value, life },\n  ]);\n}\n\n/** Remove one entry. The server refuses a key this connection does not own. */\nexport function encodeStateDel(joinRef: string, ref: number, topic: string, key: string): string {\n  return JSON.stringify([joinRef, String(ref), REALTIME_PREFIX + topic, 'state_del', { key }]);\n}\n\n/** Ask for a fresh snapshot — the answer to a detected gap. */\nexport function encodeStateResync(joinRef: string, ref: number, topic: string): string {\n  return JSON.stringify([joinRef, String(ref), REALTIME_PREFIX + topic, 'state_resync', {}]);\n}\n\n/** Present a fresher credential for the SAME principal without rejoining.\n * A rejoin would reset presence and force a full resync; this does not. */\nexport function encodeAccessToken(\n  joinRef: string,\n  ref: number,\n  topic: string,\n  token: string,\n): string {\n  return JSON.stringify([\n    joinRef,\n    String(ref),\n    REALTIME_PREFIX + topic,\n    'access_token',\n    { access_token: token },\n  ]);\n}\n","// The Phoenix-Channels WebSocket transport for Palbase Realtime — a port of\n// the proven-live iOS `RealtimeConnection` actor (palbackend-ios-src\n// Sources/Palbe/Realtime/RealtimeConnection.swift), the wire ground truth\n// against the platform's Supabase Realtime (Elixir/Phoenix):\n//\n//   connect:   wss://<host>/realtime/v1/websocket?apikey=<jwt>&vsn=2.0.0\n//   join:      [join_ref, ref, \"realtime:<topic>\", \"phx_join\", {access_token, config}]\n//   heartbeat: [null, ref, \"phoenix\", \"heartbeat\", {}]            (~every 25s)\n//   recv:      [null, null, \"realtime:<topic>\", \"broadcast\", {type, event, payload}]\n//\n// ONE socket is shared by every subscribed channel (the Supabase model —\n// multiplex all topics over a single connection). This class is a generic\n// frame pump; the facade (facade.ts) owns per-channel handlers and refcounts.\n//\n// DEVIATION from iOS (documented): iOS sends the auth token in the\n// `x-api-key` HTTP header on the WS upgrade. Browsers cannot set headers on\n// a WebSocket handshake, so the web client uses the server's query fallback —\n// Realtime's user_socket.ex reads `x-api-key` first, then `params[\"apikey\"]`.\n//\n// Resilience mirrors iOS: a dropped socket reconnects with exponential\n// backoff (1,2,4…s capped at 30s + deterministic ref jitter); on reconnect\n// every previously-joined topic is re-joined with a FRESH token and fresh\n// refs. The 25s heartbeat keeps Kong's idle WS timeout (180s) from closing\n// the connection. One behavioral adaptation: iOS promotes to `connected` on\n// the first RECEIVED frame because `URLSessionWebSocketTask.resume()` does\n// not signal handshake completion — a browser WebSocket's `open` event fires\n// only after a successful HTTP-101 handshake, so promotion happens there.\n\nimport {\n  decodeFrame,\n  encodeAccessToken,\n  encodeBroadcast,\n  encodeHeartbeat,\n  encodeJoin,\n  encodeLeave,\n  encodeStateDel,\n  encodeStateResync,\n  encodeStateSet,\n  type RealtimeInbound,\n  stripRealtimePrefix,\n  unwrapBroadcast,\n} from './frames.js';\nimport type { DiffBody, SnapshotBody } from './state.js';\n\n/**\n * The connection state of the shared realtime WebSocket (iOS enum parity), plus\n * `'error'` — surfaced when a channel could not be recovered after a\n * token-expiry close exhausted its rejoin attempts (the socket itself may still\n * be up; the app should stop expecting events on the dead channel).\n */\nexport type RealtimeConnectionState = 'idle' | 'connected' | 'reconnecting' | 'error';\n\n/** Connection-level callbacks the owner (the realtime facade) installs once. */\nexport interface RealtimeSocketHandlers {\n  /** A broadcast arrived for a topic (bare sub-topic, inner event/payload). */\n  onInbound: (inbound: RealtimeInbound) => void;\n  /** The socket (re)connected — fires on EVERY successful open, first included. */\n  onReconnect: () => void;\n  /** The socket's connection state changed (idle/connected/reconnecting). */\n  onStateChange: (state: RealtimeConnectionState) => void;\n  /** A channel's whole state arrived — on join, and in answer to a resync. */\n  onStateSnapshot: (topic: string, body: SnapshotBody) => void;\n  /** A change to a channel's state. The owner applies it and, when it reports a\n   * gap, asks for a snapshot. */\n  onStateDiff: (topic: string, body: DiffBody) => void;\n  /** The join was acked, carrying who this connection is ON THAT CHANNEL.\n   * Presence is keyed by it, so nothing can be written until it is known. */\n  onJoinInfo: (\n    topic: string,\n    info: { conn?: string; occupancy?: number; state_seq?: number },\n  ) => void;\n  /**\n   * A single channel died for good (token-expiry rejoin exhausted N attempts).\n   * The socket is still up; the owner surfaces this on the channel's status so\n   * the app stops expecting events on that topic. Distinct from onStateChange,\n   * which is connection-global — one bad channel must not flag the whole socket.\n   */\n  onChannelError: (topic: string) => void;\n  /**\n   * The server REFUSED a join, and said why.\n   *\n   * Distinct from onChannelError, which reports a channel that died after\n   * having worked. This one never started: `unauthorized` is the authorization\n   * model answering \"you may not\", `unavailable` is it answering \"I could not\n   * ask\". The owner has to keep those apart, because they demand opposite\n   * things of the caller — one says stop, the other says try again.\n   */\n  onChannelRefused: (topic: string, reason: string) => void;\n}\n\n/**\n * Refusals that asking again can still answer differently.\n *\n * `unavailable` is the project not being reachable to decide. The two ceilings\n * belong here too and did not: they are sent on the JOIN path, so they carry the\n * join's ref and pass the correlation gate as channel refusals — and being\n * treated as FINAL meant a client caught in a reconnect storm dropped the topic\n * from its rejoin set and never came back to it. The server's own ratelimit\n * comment is explicit that these two are \"slow down\" and \"you are holding too\n * much\", which are the two things a client can act on and recover from.\n */\nconst RETRYABLE_REFUSALS = new Set(['unavailable', 'rate_limited', 'too_many_channels']);\n\n/** The structural slice of the DOM WebSocket the transport needs (injectable). */\nexport interface WebSocketLike {\n  readonly readyState: number;\n  send(data: string): void;\n  close(code?: number): void;\n  onopen: (() => void) | null;\n  onmessage: ((event: { data: unknown }) => void) | null;\n  onclose: (() => void) | null;\n  onerror: (() => void) | null;\n}\n\nexport type WebSocketCtor = new (url: string) => WebSocketLike;\n\nexport interface RealtimeSocketOptions {\n  /** https base, e.g. https://ref.dev.palbase.studio (PalbeConfig.url). */\n  baseUrl: string;\n  /**\n   * Resolves the token used as the WS `apikey` query + per-join `access_token`.\n   * Bearer when signed in, else anon JWT, else the Environment API key (see\n   * anon-token.ts). Re-invoked on every connect AND every join, so a token\n   * rotated while offline is picked up by the next reconnect.\n   */\n  tokenProvider: () => Promise<string>;\n  /** Injectable for non-DOM hosts; defaults to globalThis.WebSocket, resolved per connect. */\n  webSocket?: WebSocketCtor;\n  /** Heartbeat cadence; default 25s (under Kong's 180s idle WS cap). */\n  heartbeatIntervalMs?: number;\n  /** Reconnect backoff cap; default 30s. */\n  maxBackoffSeconds?: number;\n}\n\nconst WS_OPEN = 1;\nconst DEFAULT_HEARTBEAT_MS = 25_000;\nconst DEFAULT_MAX_BACKOFF_SECONDS = 30;\n// How many times a single channel may be rejoined after a token-expiry close\n// before we give up on it (the rejoin-storm guard). A genuinely-bad token (not\n// just expired) would close every rejoin immediately; capping turns that into a\n// surfaced channel error instead of a tight loop. The first rejoin is attempt 0.\nconst MAX_CHANNEL_REJOIN_ATTEMPTS = 3;\n\n/**\n * Build the Phoenix WS URL: https→wss (http→ws), trailing slashes stripped,\n * Kong's `/realtime/v1/websocket` path, `apikey` + `vsn=2.0.0` query.\n * Port of iOS `websocketURL` — plus the browser apikey-query deviation\n * documented in the file header.\n */\nexport function websocketUrl(base: string, token: string): string {\n  let s = base;\n  if (s.startsWith('https://')) {\n    s = `wss://${s.slice('https://'.length)}`;\n  } else if (s.startsWith('http://')) {\n    s = `ws://${s.slice('http://'.length)}`;\n  }\n  while (s.endsWith('/')) s = s.slice(0, -1);\n  return `${s}/realtime/v1/websocket?apikey=${encodeURIComponent(token)}&vsn=2.0.0`;\n}\n\n/**\n * Exponential reconnect backoff: 2^attempt seconds capped at `cap`, plus up\n * to 1s of deterministic jitter derived from the ref counter (iOS formula —\n * nondeterministic RNG is banned, and ref-based jitter is enough to de-sync\n * reconnect storms). Pure so growth/cap are unit-testable without sleeping.\n */\nexport function backoffDelaySeconds(attempt: number, refCounter: number, cap: number): number {\n  const base = Math.min(2 ** attempt, cap);\n  const jitter = (refCounter % 1000) / 1000;\n  return base + jitter;\n}\n\ninterface PendingBroadcast {\n  topic: string;\n  event: string;\n  payload: Record<string, unknown>;\n}\n\nexport class RealtimeSocket {\n  private readonly options: RealtimeSocketOptions;\n  private handlers: RealtimeSocketHandlers | null = null;\n\n  private ws: WebSocketLike | null = null;\n  // Membership intent (bare sub-topics): re-joined on every (re)connect. A\n  // topic stays in this set from joinTopic() until leaveTopic().\n  private readonly joinedTopics = new Set<string>();\n  // topic → join_ref of the LIVE join on the current socket. Phoenix drops\n  // channel messages whose join_ref doesn't match, so broadcasts carry this.\n  // Cleared on disconnect (the next socket gets fresh joins/refs).\n  private readonly joinRefs = new Map<string, string>();\n  // Broadcasts pushed before the topic's join is live — flushed right after it.\n  private pendingBroadcasts: PendingBroadcast[] = [];\n  // Per-topic rejoin attempt counter for the token-expiry channel-death guard.\n  // Bumped on every channel rejoin; reset to 0 when the topic delivers a live\n  // broadcast (proof the channel recovered). At MAX_CHANNEL_REJOIN_ATTEMPTS the\n  // channel is given up on (onChannelError) instead of looping forever.\n  private readonly channelRejoinAttempts = new Map<string, number>();\n  // Pending per-topic rejoin backoff timers — separate from the socket-level\n  // reconnectTimer so a channel backoff never clobbers socket reconnection.\n  private readonly channelRejoinTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n  // Monotonic Phoenix message ref. Every outbound frame carries a unique ref.\n  private refCounter = 0;\n  private connected = false;\n  private started = false;\n  private stopped = false;\n  // Reset ONLY on a genuine open, so a never-opening socket walks\n  // attempt 0,1,2,… → delays 1,2,4,…,cap instead of hammering (iOS parity).\n  private reconnectAttempt = 0;\n  // Invalidates async continuations (token awaits) from a superseded connect.\n  private connectEpoch = 0;\n\n  private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n  constructor(options: RealtimeSocketOptions) {\n    this.options = options;\n  }\n\n  // MARK: lifecycle\n\n  /** Install handlers and open the socket. Idempotent while started. */\n  start(handlers: RealtimeSocketHandlers): void {\n    this.handlers = handlers;\n    if (this.started) return;\n    this.started = true;\n    this.stopped = false;\n    void this.connect();\n  }\n\n  /** Tear down the socket, stop reconnecting, emit `idle`. Idempotent. */\n  stop(): void {\n    this.stopped = true;\n    this.started = false;\n    this.connected = false;\n    this.connectEpoch += 1; // invalidate in-flight connect continuations\n    this.stopHeartbeat();\n    if (this.reconnectTimer !== null) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n    this.clearAllChannelRejoins();\n    const ws = this.ws;\n    this.ws = null;\n    this.joinRefs.clear();\n    ws?.close(1000);\n    this.handlers?.onStateChange('idle');\n  }\n\n  // MARK: topic membership\n\n  /**\n   * Join a topic (bare sub-topic, no \"realtime:\" prefix). Idempotent. Sent\n   * immediately when the socket is up, else on the next (re)connect.\n   */\n  joinTopic(topic: string): void {\n    if (this.joinedTopics.has(topic)) return;\n    this.joinedTopics.add(topic);\n    if (this.connected) void this.sendJoin(topic);\n  }\n\n  /**\n   * Leave a topic: sends `phx_leave` when connected and always drops it from\n   * the re-join set (a future reconnect won't restore it). Pending broadcasts\n   * for the topic are discarded.\n   */\n  leaveTopic(topic: string): void {\n    if (!this.joinedTopics.delete(topic)) return;\n    this.joinRefs.delete(topic);\n    this.pendingBroadcasts = this.pendingBroadcasts.filter((p) => p.topic !== topic);\n    this.clearChannelRejoin(topic); // cancel any pending token-expiry rejoin\n    if (this.isOpen()) this.send(encodeLeave(this.nextRef(), topic));\n  }\n\n  /**\n   * Push a broadcast onto a topic (web addition — iOS is receive-only). Sent\n   * synchronously when the topic's join is live on the current socket;\n   * otherwise queued and flushed right after the join goes out.\n   */\n  sendBroadcast(topic: string, event: string, payload: Record<string, unknown>): void {\n    const joinRef = this.joinRefs.get(topic);\n    if (joinRef !== undefined && this.isOpen()) {\n      this.send(encodeBroadcast(joinRef, this.nextRef(), topic, event, payload));\n    } else {\n      this.pendingBroadcasts.push({ topic, event, payload });\n    }\n  }\n\n  // MARK: connect / reconnect\n\n  private async connect(): Promise<void> {\n    if (this.stopped) return;\n    const epoch = ++this.connectEpoch;\n    let token: string;\n    try {\n      token = await this.options.tokenProvider();\n    } catch {\n      // The provider is total by design (apikey fallback) — but a throw must\n      // not kill the reconnect loop.\n      this.scheduleReconnect();\n      return;\n    }\n    if (this.stopped || epoch !== this.connectEpoch) return;\n\n    // Resolved per attempt (not cached) so an environment that gains a\n    // WebSocket later (test stubs, polyfill load order) recovers on retry.\n    const Ctor = this.options.webSocket ?? (globalThis as { WebSocket?: WebSocketCtor }).WebSocket;\n    if (!Ctor) {\n      this.scheduleReconnect();\n      return;\n    }\n\n    const ws = new Ctor(websocketUrl(this.options.baseUrl, token));\n    this.ws = ws;\n    // Every callback gates on `ws === this.ws` so events from a superseded\n    // socket (replaced during reconnect) can't corrupt the live one's state.\n    ws.onopen = () => {\n      if (ws === this.ws) void this.handleOpen();\n    };\n    ws.onmessage = (event) => {\n      if (ws === this.ws) this.handleMessage(event.data);\n    };\n    ws.onclose = () => {\n      if (ws === this.ws) this.handleClose();\n    };\n    // Browsers always follow `error` with `close` — onclose drives recovery.\n    ws.onerror = () => {};\n  }\n\n  /**\n   * The browser `open` event proves the HTTP-101 handshake completed (the\n   * analogue of iOS promoteToConnected): flip connected, announce, then\n   * (re)join every topic with a fresh token + fresh refs. Backoff is NOT\n   * reset here — it resets on the first inbound frame (iOS parity), so a\n   * server that opens but immediately closes still grows the backoff.\n   */\n  private async handleOpen(): Promise<void> {\n    if (this.stopped) return;\n    this.connected = true;\n    this.handlers?.onStateChange('connected');\n    this.handlers?.onReconnect();\n    this.startHeartbeat();\n    for (const topic of this.joinedTopics) {\n      await this.sendJoin(topic);\n    }\n  }\n\n  private handleClose(): void {\n    if (this.stopped) return;\n    this.ws = null;\n    this.joinRefs.clear();\n    // The socket reconnect rejoins ALL topics fresh — drop per-channel rejoin\n    // state so a pending channel backoff doesn't race the rejoin-all.\n    this.clearAllChannelRejoins();\n    this.stopHeartbeat();\n    this.scheduleReconnect();\n  }\n\n  private scheduleReconnect(): void {\n    if (this.stopped || !this.started) return;\n    this.connected = false;\n    this.handlers?.onStateChange('reconnecting');\n    const attempt = this.reconnectAttempt;\n    this.reconnectAttempt += 1;\n    const cap = this.options.maxBackoffSeconds ?? DEFAULT_MAX_BACKOFF_SECONDS;\n    const delaySeconds = backoffDelaySeconds(attempt, this.refCounter, cap);\n    this.reconnectTimer = setTimeout(() => {\n      this.reconnectTimer = null;\n      void this.connect();\n    }, delaySeconds * 1000);\n  }\n\n  // MARK: frames out\n\n  /**\n   * Join carries a freshly-resolved token (iOS parity — `sendJoin` awaits the\n   * provider), so a Bearer rotated while offline rides the next rejoin.\n   */\n  private async sendJoin(topic: string): Promise<void> {\n    const token = await this.options.tokenProvider();\n    // Re-validate after the await: the socket may have dropped or the topic\n    // may have been left while the token resolved.\n    if (!this.isOpen() || !this.joinedTopics.has(topic)) return;\n    const ref = this.nextRef();\n    this.joinRefs.set(topic, String(ref));\n    this.send(encodeJoin(ref, topic, token));\n    this.flushPending(topic);\n  }\n\n  private flushPending(topic: string): void {\n    const ready = this.pendingBroadcasts.filter((p) => p.topic === topic);\n    if (ready.length === 0) return;\n    this.pendingBroadcasts = this.pendingBroadcasts.filter((p) => p.topic !== topic);\n    for (const p of ready) this.sendBroadcast(p.topic, p.event, p.payload);\n  }\n\n  private startHeartbeat(): void {\n    this.stopHeartbeat();\n    const interval = this.options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_MS;\n    this.heartbeatTimer = setInterval(() => {\n      if (this.isOpen()) this.send(encodeHeartbeat(this.nextRef()));\n    }, interval);\n  }\n\n  private stopHeartbeat(): void {\n    if (this.heartbeatTimer !== null) {\n      clearInterval(this.heartbeatTimer);\n      this.heartbeatTimer = null;\n    }\n  }\n\n  /** Drop-if-not-open: a send racing a disconnect is recovered by the rejoin-all on reconnect. */\n  private send(text: string): void {\n    if (this.ws && this.ws.readyState === WS_OPEN) this.ws.send(text);\n  }\n\n  // MARK: frames in\n\n  private handleMessage(data: unknown): void {\n    if (typeof data !== 'string') return;\n    const frame = decodeFrame(data);\n    if (!frame) return;\n    // Any valid inbound frame proves the server is actually delivering data\n    // (not just completing the TCP handshake). Reset backoff here — iOS parity:\n    // iOS promotes to connected on the first frame because URLSession does not\n    // surface a separate handshake-complete signal. A server that opens then\n    // immediately closes does NOT trigger this, so backoff keeps growing.\n    this.reconnectAttempt = 0;\n    // Token-expiry channel death (the cross-SDK P4 bug): at JWT TTL the server\n    // kills just THIS channel (`{:stop, :normal}`) while the socket stays up\n    // (heartbeats hold it past Kong's idle cap). Phoenix v2 pushes a per-topic\n    // phx_close carrying the channel's join_ref ([<joinRef>,null,topic,\"phx_close\",{}];\n    // phx_error on a crash). We rejoin that one topic with a FRESH token rather\n    // than letting it silently die. Socket-level reconnect rejoins ALL topics —\n    // this handles the case where only ONE channel was killed.\n    if (frame.event === 'phx_close' || frame.event === 'phx_error') {\n      this.handleChannelClose(frame);\n      return;\n    }\n    // State frames are routed by NAME, before the broadcast unwrap: they are a\n    // different vocabulary on the same envelope, and unwrapBroadcast does not\n    // recognise them.\n    if (frame.event === 'state_snapshot') {\n      this.handlers?.onStateSnapshot(\n        stripRealtimePrefix(frame.topic),\n        frame.payload as SnapshotBody,\n      );\n      return;\n    }\n    if (frame.event === 'state_diff') {\n      this.handlers?.onStateDiff(stripRealtimePrefix(frame.topic), frame.payload as DiffBody);\n      return;\n    }\n    // A join ack carries this connection's identity ON THAT CHANNEL. It is the\n    // only place that identity exists, and presence cannot be written without it.\n    if (frame.event === 'phx_reply') {\n      const body = frame.payload as {\n        status?: string;\n        response?: Record<string, unknown>;\n      } | null;\n      const topic = stripRealtimePrefix(frame.topic);\n      if (body && body.status === 'ok' && body.response && typeof body.response === 'object') {\n        this.handlers?.onJoinInfo(topic, body.response);\n        return;\n      }\n      // A refusal — but of WHAT?\n      //\n      // The server answers a refused PUSH with exactly the same envelope as a\n      // refused join: a handler that threw, a state key you do not own, a rate\n      // limit. Reading every error reply as a channel refusal tears down a\n      // working channel from ordinary app code — one bid the project rejects\n      // would drop every handler on `auction:7` and stop the socket ever\n      // rejoining it.\n      //\n      // The ref separates them. A join's reply carries the join's own ref\n      // (encodeJoin puts it in both slots); a push's reply carries the push's.\n      // Anything that is not the live join's ref is one operation being\n      // refused, and the channel is untouched.\n      if (body && body.status === 'error' && String(frame.ref) === this.joinRefs.get(topic)) {\n        const reason =\n          typeof body.response?.['reason'] === 'string'\n            ? (body.response['reason'] as string)\n            : 'unauthorized';\n        // A final refusal stops being a subscription: leaving the topic in the\n        // set would rejoin it on every reconnect, forever, against a decision\n        // that will not change. A transient one stays — the reconnect IS the\n        // retry it asks for.\n        if (!RETRYABLE_REFUSALS.has(reason)) {\n          this.joinedTopics.delete(topic);\n          this.joinRefs.delete(topic);\n        }\n        this.handlers?.onChannelRefused(topic, reason);\n      }\n      return;\n    }\n    // Only `broadcast` events carry channel traffic; replies/acks/presence\n    // are bookkeeping (iOS ignores them identically).\n    const inbound = unwrapBroadcast(frame);\n    if (inbound) {\n      // A live broadcast proves the channel recovered — reset its rejoin guard.\n      this.channelRejoinAttempts.delete(inbound.topic);\n      this.handlers?.onInbound(inbound);\n    }\n  }\n\n  /**\n   * Recover (or give up on) a single channel the server closed for token\n   * reasons. Ignored unless the close targets a topic we still intend to be\n   * joined AND its join_ref matches the LIVE join — so a stale close from a\n   * superseded join, or a close arriving after our OWN phx_leave (the topic is\n   * already dropped from joinedTopics/joinRefs), does NOT trigger a rejoin.\n   */\n  private handleChannelClose(frame: { topic: string; joinRef: unknown }): void {\n    const topic = stripRealtimePrefix(frame.topic);\n    // Intentional-leave / stale-close guard: leaveTopic() removes the topic\n    // from joinedTopics and its joinRefs entry, so neither check passes here.\n    if (!this.joinedTopics.has(topic)) return;\n    if (this.joinRefs.get(topic) !== frame.joinRef) return;\n    // The current join is dead; drop its ref so a queued send won't use it.\n    this.joinRefs.delete(topic);\n\n    const attempt = this.channelRejoinAttempts.get(topic) ?? 0;\n    if (attempt >= MAX_CHANNEL_REJOIN_ATTEMPTS) {\n      // A genuinely-bad token (not just expired) closes every rejoin at once —\n      // give up on this channel instead of tight-looping.\n      this.joinedTopics.delete(topic);\n      this.channelRejoinAttempts.delete(topic);\n      this.handlers?.onChannelError(topic);\n      return;\n    }\n    this.channelRejoinAttempts.set(topic, attempt + 1);\n    if (attempt === 0) {\n      // First close: rejoin immediately (the common case — token simply expired).\n      void this.sendJoin(topic);\n      return;\n    }\n    // Repeated closes: back off (reuse the socket reconnect curve) so a flapping\n    // channel doesn't hammer the server. Replaces any pending rejoin for the topic.\n    const cap = this.options.maxBackoffSeconds ?? DEFAULT_MAX_BACKOFF_SECONDS;\n    const delayMs = backoffDelaySeconds(attempt, this.refCounter, cap) * 1000;\n    const existing = this.channelRejoinTimers.get(topic);\n    if (existing !== undefined) clearTimeout(existing);\n    const timer = setTimeout(() => {\n      this.channelRejoinTimers.delete(topic);\n      if (this.joinedTopics.has(topic)) void this.sendJoin(topic);\n    }, delayMs);\n    this.channelRejoinTimers.set(topic, timer);\n  }\n\n  // MARK: state\n\n  /** Write one entry on a joined channel's state. Dropped when the topic has no\n   * live join: the server refuses state on a channel this socket is not on, and\n   * the reconnect's join brings a fresh snapshot anyway. */\n  sendStateSet(topic: string, key: string, value: unknown, life: 'ephemeral' | 'durable'): void {\n    const joinRef = this.joinRefs.get(topic);\n    if (joinRef === undefined || !this.isOpen()) return;\n    this.send(encodeStateSet(joinRef, this.nextRef(), topic, key, value, life));\n  }\n\n  /** Remove one entry. The server refuses a key this connection does not own. */\n  sendStateDel(topic: string, key: string): void {\n    const joinRef = this.joinRefs.get(topic);\n    if (joinRef === undefined || !this.isOpen()) return;\n    this.send(encodeStateDel(joinRef, this.nextRef(), topic, key));\n  }\n\n  /** Ask for a fresh snapshot — the answer to a detected gap. */\n  sendStateResync(topic: string): void {\n    const joinRef = this.joinRefs.get(topic);\n    if (joinRef === undefined || !this.isOpen()) return;\n    this.send(encodeStateResync(joinRef, this.nextRef(), topic));\n  }\n\n  /**\n   * Present a fresher credential on every joined channel WITHOUT rejoining.\n   *\n   * The alternative — dropping and rejoining — reaps this connection's\n   * ephemeral entries (its presence) and forces a full resync on every channel.\n   * A token rotation is not a reconnection and must not look like one.\n   */\n  sendAccessToken(token: string): void {\n    if (!this.isOpen()) return;\n    for (const [topic, joinRef] of this.joinRefs) {\n      this.send(encodeAccessToken(joinRef, this.nextRef(), topic, token));\n    }\n  }\n\n  // MARK: helpers\n\n  /** Drop a single topic's token-expiry rejoin state (cancel its pending timer). */\n  private clearChannelRejoin(topic: string): void {\n    const timer = this.channelRejoinTimers.get(topic);\n    if (timer !== undefined) {\n      clearTimeout(timer);\n      this.channelRejoinTimers.delete(topic);\n    }\n    this.channelRejoinAttempts.delete(topic);\n  }\n\n  /** Drop all per-channel rejoin state (socket teardown / full reconnect). */\n  private clearAllChannelRejoins(): void {\n    for (const timer of this.channelRejoinTimers.values()) clearTimeout(timer);\n    this.channelRejoinTimers.clear();\n    this.channelRejoinAttempts.clear();\n  }\n\n  private isOpen(): boolean {\n    return this.connected && this.ws !== null && this.ws.readyState === WS_OPEN;\n  }\n\n  private nextRef(): number {\n    this.refCounter += 1;\n    return this.refCounter;\n  }\n}\n","// state.ts — the client half of the channel state primitive.\n//\n// The server keeps a keyed, last-writer-wins map per channel and hands it out\n// two ways: a SNAPSHOT (the whole picture, on join and on resync) and DIFFS\n// (what changed, after that). This applies both to a local map and — the part\n// that matters — DETECTS when a diff cannot be applied.\n//\n// That detection is the reason state can travel over a transport that is\n// allowed to drop frames. A diff carries the sequence it moves the channel\n// FROM as well as the one it moves it TO, so a client holding less than\n// `from_seq` knows it missed something. It says so instead of guessing, and the\n// caller answers by asking for a fresh snapshot. Without it a dropped frame\n// would leave a client quietly, permanently wrong — which looks exactly like a\n// frame that never arrived.\n\n/** One entry as it travels: the value, and whether it outlives its writer. */\nexport interface StateEntryWire {\n  v: unknown;\n  life: string;\n}\n\nexport interface SnapshotBody {\n  seq: number;\n  entries: Record<string, StateEntryWire>;\n}\n\nexport interface DiffBody {\n  from_seq: number;\n  seq: number;\n  set: Record<string, StateEntryWire>;\n  del: string[];\n}\n\n/** What applying a diff did. `gap` means the caller must resync. */\nexport type DiffResult = 'applied' | 'gap';\n\n/** The key prefix presence entries use. One per connection, and the connection\n * id is the suffix — which is how a client tells its own entry from everyone\n * else's. */\nexport const PRESENCE_PREFIX = '$p:';\n\nexport class ChannelState {\n  /** The sequence this local copy is current as of. */\n  seq = 0;\n  /** key → value. Lifetimes are the server's business; a reader only needs the\n   * values, and presence is derived from the key shape. */\n  readonly entries = new Map<string, unknown>();\n\n  /** Replace everything. A snapshot is the WHOLE picture, never a merge —\n   * merging one would keep entries the server has since removed. */\n  applySnapshot(body: SnapshotBody): void {\n    this.entries.clear();\n    for (const [k, e] of Object.entries(body.entries ?? {})) {\n      this.entries.set(k, e.v);\n    }\n    this.seq = body.seq;\n  }\n\n  /**\n   * Apply a diff, or report that it cannot be applied.\n   *\n   * `gap` when this copy is behind the diff's starting point: frames were\n   * missed, and applying anyway would produce a state that never existed on the\n   * server. The state is left untouched so the caller can resync from something\n   * consistent.\n   *\n   * A diff at or below the current sequence is already applied — a resend after\n   * a retry — and is silently accepted so duplicates are harmless.\n   */\n  applyDiff(body: DiffBody): DiffResult {\n    if (this.seq < body.from_seq) return 'gap';\n    if (body.seq <= this.seq) return 'applied';\n\n    for (const [k, e] of Object.entries(body.set ?? {})) this.entries.set(k, e.v);\n    for (const k of body.del ?? []) this.entries.delete(k);\n    this.seq = body.seq;\n    return 'applied';\n  }\n\n  /**\n   * Everyone else's presence.\n   *\n   * `selfConn` is this connection's id, as the join reply reported it. Its own\n   * entry is excluded because an app rendering \"who else is here\" would\n   * otherwise always show one extra face — itself.\n   */\n  presence(selfConn: string | undefined): unknown[] {\n    const own = selfConn === undefined ? undefined : PRESENCE_PREFIX + selfConn;\n    const out: unknown[] = [];\n    for (const [k, v] of this.entries) {\n      if (!k.startsWith(PRESENCE_PREFIX) || k === own) continue;\n      out.push(v);\n    }\n    return out;\n  }\n}\n","// `pb.realtime` — the public, customer-facing realtime surface. Mirrors the\n// iOS `Facade+Realtime` + `RealtimeClient` pair (palbackend-ios-src\n// Sources/Palbe/Realtime/): a channel/handler manager multiplexing every\n// subscription over ONE shared, auto-reconnecting WebSocket (connection.ts).\n//\n//     const channel = pb.realtime.channel('room:42');\n//     const sub = channel.on('message', (payload) => { ... });\n//     channel.send('message', { text: 'hi' });   // web addition — iOS is receive-only\n//     // later: sub.cancel()  (last cancel on the channel → phx_leave)\n//\n// Channel names are app-defined bare sub-topics — do NOT prefix with\n// \"realtime:\" (that's internal to the transport). `realtime` is a reserved\n// namespace: a backend endpoint cannot be named `realtime` (namespaces.ts\n// RESERVED, alongside auth/flags).\n//\n// Realtime is CLIENT-ONLY: on a host with no WebSocket (SSR/RSC/route\n// handlers), `channel()` throws a guided validation error. Reading\n// `status` is always safe (it just reports `idle`).\n\nimport type { Unsubscribe } from '../auth-facade.js';\nimport { BackendError } from '../errors.js';\nimport type { PalbeRuntime } from '../runtime.js';\nimport { AnonTokenProvider, realtimeTokenProvider } from './anon-token.js';\nimport { type RealtimeConnectionState, RealtimeSocket } from './connection.js';\nimport type { RealtimeInbound } from './frames.js';\nimport { ChannelState, type DiffBody, type SnapshotBody } from './state.js';\n\nexport type { RealtimeConnectionState } from './connection.js';\n\n/** An inbound broadcast payload (the inner `payload` of the Phoenix envelope). */\nexport type RealtimePayload = Record<string, unknown>;\nexport type RealtimeHandler = (payload: RealtimePayload) => void;\n\n/** A cancellable realtime subscription. `cancel()` removes the handler and,\n * when it was the channel's last, leaves the channel on the shared socket.\n * Cancelling twice is a no-op. */\nexport interface RealtimeSubscription {\n  cancel(): void;\n}\n\nexport interface RealtimeStatusSnapshot {\n  state: RealtimeConnectionState;\n  lastEventAt: Date | null;\n}\n\n/**\n * The observable connection status (`pb.realtime.status`) — the plain-JS\n * analogue of the iOS `@Observable RealtimeStatusStore`. `state` drives a\n * live \"connected\" badge; `lastEventAt` proves a push actually arrived.\n * `onChange` fires on state transitions and on every recorded event.\n */\nexport interface RealtimeStatus {\n  readonly state: RealtimeConnectionState;\n  readonly lastEventAt: Date | null;\n  onChange(callback: (status: RealtimeStatusSnapshot) => void): Unsubscribe;\n}\n\nclass StatusStore implements RealtimeStatus {\n  private currentState: RealtimeConnectionState = 'idle';\n  private lastEvent: Date | null = null;\n  private readonly listeners = new Set<(status: RealtimeStatusSnapshot) => void>();\n\n  get state(): RealtimeConnectionState {\n    return this.currentState;\n  }\n\n  get lastEventAt(): Date | null {\n    return this.lastEvent;\n  }\n\n  onChange(callback: (status: RealtimeStatusSnapshot) => void): Unsubscribe {\n    this.listeners.add(callback);\n    return () => {\n      this.listeners.delete(callback);\n    };\n  }\n\n  /** No-op on equal state (iOS setState guard) — listeners see transitions only. */\n  setState(state: RealtimeConnectionState): void {\n    if (state === this.currentState) return;\n    this.currentState = state;\n    this.emit();\n  }\n\n  recordEvent(at: Date): void {\n    this.lastEvent = at;\n    this.emit();\n  }\n\n  private emit(): void {\n    const snapshot: RealtimeStatusSnapshot = {\n      state: this.currentState,\n      lastEventAt: this.lastEvent,\n    };\n    for (const listener of this.listeners) listener(snapshot);\n  }\n}\n\ninterface HandlerEntry {\n  topic: string;\n  event: string;\n  handler: RealtimeHandler;\n}\n\n/**\n * Refusals worth asking about again — the same set the transport uses to decide\n * whether to keep a topic in its rejoin list. `unavailable` is the project being\n * unreachable; the two ceilings are \"slow down\" and \"you are holding too much\",\n * both of which pass with time.\n */\nconst RETRYABLE_REASONS = new Set(['unavailable', 'rate_limited', 'too_many_channels']);\n\n/** Why the server refused a channel. */\nexport interface RealtimeChannelError {\n  /** The channel this is about. */\n  topic: string;\n  /** Exactly what the server said: `\"unauthorized\"` or `\"unavailable\"`. */\n  reason: string;\n  /**\n   * Whether asking again could succeed. `unavailable` (the project could not be\n   * reached to decide) is retryable and the socket retries it on reconnect;\n   * `unauthorized` is a settled answer and is not.\n   */\n  retryable: boolean;\n}\n\ninterface ErrorHandlerEntry {\n  topic: string;\n  handler: (error: RealtimeChannelError) => void;\n}\n\n/**\n * A subscription handle for one realtime channel (returned by\n * `pb.realtime.channel(name)` — the SAME instance per name). A channel is\n * joined on the shared socket when its first handler is added (or on the\n * first `send`) and left when its last handler cancels.\n */\nexport class RealtimeChannel {\n  /** The app-defined channel name (bare sub-topic, no \"realtime:\" prefix). */\n  readonly name: string;\n  private readonly owner: PalbeRealtime;\n\n  /** @internal — obtain channels via `pb.realtime.channel(name)`. */\n  constructor(name: string, owner: PalbeRealtime) {\n    this.name = name;\n    this.owner = owner;\n  }\n\n  /**\n   * Subscribe `handler` to `event` on this channel. Fire-and-forget: the\n   * join rides the shared socket asynchronously. Hold the returned\n   * subscription and `cancel()` it to stop.\n   */\n  on(event: string, handler: RealtimeHandler): RealtimeSubscription {\n    return this.owner.subscribe(this.name, event, handler);\n  }\n\n  /**\n   * Called when the server REFUSES this channel.\n   *\n   * A join is an authorization decision, and a decision the app never hears is\n   * the same as no decision at all: silence looks exactly like a slow network.\n   * This is where a refusal arrives, carrying the server's own distinction —\n   * `retryable: false` means \"you may not\" and asking again will not help;\n   * `retryable: true` means the project could not be asked, and the socket's\n   * next reconnect retries on its own.\n   *\n   *     pb.realtime.channel('room:42').onError((err) => {\n   *       if (!err.retryable) showJoinDenied()\n   *     })\n   */\n  onError(handler: (error: RealtimeChannelError) => void): RealtimeSubscription {\n    return this.owner.subscribeError(this.name, handler);\n  }\n\n  /**\n   * Broadcast `payload` to the channel's other subscribers (web addition —\n   * iOS is receive-only). Joins the channel if it isn't already; queued\n   * until the join is live on the socket.\n   */\n  send(event: string, payload: RealtimePayload = {}): void {\n    this.owner.send(this.name, event, payload);\n  }\n\n  /**\n   * Watch one key of the channel's shared state.\n   *\n   * The handler is called with the CURRENT value straight away when there is\n   * one, and again on every change. That is the difference from `on()`: a\n   * subscriber to an event learns nothing until the next one, while state is\n   * already there when you ask.\n   */\n  onState(key: string, handler: (value: unknown) => void): RealtimeSubscription {\n    return this.owner.subscribeState(this.name, key, handler);\n  }\n\n  /** Read one key without subscribing. */\n  stateValue(key: string): unknown {\n    return this.owner.stateOf(this.name).entries.get(key);\n  }\n\n  /** Write one key. `durable` outlives this connection; `ephemeral` is reaped\n   * when it closes, which is what presence is built on. */\n  setState(key: string, value: unknown, opts: { life?: 'ephemeral' | 'durable' } = {}): void {\n    this.owner.writeState(this.name, key, value, opts.life ?? 'durable');\n  }\n\n  /** Remove a key this connection wrote. */\n  clearState(key: string): void {\n    this.owner.clearState(this.name, key);\n  }\n\n  /**\n   * Announce this client on the channel. `meta` is whatever other participants\n   * should see — a name, an avatar, a cursor.\n   *\n   * It is ephemeral state keyed by this connection, so it disappears when the\n   * socket does. Nothing has to be un-announced on a crash.\n   */\n  presenceEnter(meta: RealtimePayload): void {\n    this.owner.presenceWrite(this.name, meta);\n  }\n\n  /** Replace the announced value — a cursor moving is this, at whatever rate\n   * the app likes: the server conflates writes it cannot deliver fast enough. */\n  presenceUpdate(meta: RealtimePayload): void {\n    this.owner.presenceWrite(this.name, meta);\n  }\n\n  /** Leave early. Closing the socket does this on its own. */\n  presenceLeave(): void {\n    this.owner.presenceClear(this.name);\n  }\n\n  /** Everyone else currently announced, this client excluded. */\n  presenceOthers(): unknown[] {\n    return this.owner.presenceOthers(this.name);\n  }\n\n  /** Watch the announced set. Called on every change. */\n  onPresence(handler: (others: unknown[]) => void): RealtimeSubscription {\n    return this.owner.subscribePresence(this.name, handler);\n  }\n}\n\nexport class PalbeRealtime {\n  private readonly rt: PalbeRuntime;\n  private socket: RealtimeSocket | null = null;\n  private readonly channels = new Map<string, RealtimeChannel>();\n  private readonly statusStore = new StatusStore();\n  // Per-(topic, event) handlers — an event may have multiple handlers\n  // (multiple .on calls); entry identity is the unsubscribe token.\n  private readonly handlers = new Set<HandlerEntry>();\n  // Per-topic refusal handlers. Kept apart from `handlers` because they are not\n  // refcounted: registering one must not join a channel, and cancelling the\n  // last one must not leave a channel that still has event handlers on it.\n  private readonly errorHandlers = new Set<ErrorHandlerEntry>();\n  // Joins are refcounted per topic so the socket only leaves a topic when\n  // its last handler cancels (iOS RealtimeClient parity).\n  private readonly topicRefcount = new Map<string, number>();\n  // Per-topic shared state, and this connection's identity on each topic (from\n  // the join ack). Presence is keyed by that identity, so a write before the\n  // ack has nowhere to go and is queued until it arrives.\n  private readonly states = new Map<string, ChannelState>();\n  private readonly connIds = new Map<string, string>();\n  private readonly pendingPresence = new Map<string, RealtimePayload>();\n  private readonly stateWatchers = new Set<{\n    topic: string;\n    key: string;\n    handler: (v: unknown) => void;\n  }>();\n  private readonly presenceWatchers = new Set<{\n    topic: string;\n    handler: (others: unknown[]) => void;\n  }>();\n\n  constructor(rt: PalbeRuntime) {\n    this.rt = rt;\n  }\n\n  /**\n   * Get the handle for an app-defined channel (e.g. \"room:42\"). The same\n   * name returns the SAME instance. Throws a guided error on server-side\n   * hosts (SSR/RSC/Node) — realtime is client-only.\n   */\n  channel(name: string): RealtimeChannel {\n    // Primary: detect server environment by the absence of the browser globals\n    // `document` and `window`. Node ≥22 ships a global WebSocket, so the old\n    // `typeof WebSocket === 'undefined'` check is no-op there — server code\n    // would silently open real sockets.\n    if (typeof document === 'undefined' && typeof window === 'undefined') {\n      throw new BackendError('validation', {\n        code: 'realtime_unavailable',\n        message:\n          'pb.realtime requires a browser environment: document and window are not defined ' +\n          '(server/SSR/RSC). Subscribe from browser code instead — e.g. a client component or useEffect.',\n      });\n    }\n    // Secondary: browser polyfill may be missing even with document/window present.\n    if (typeof WebSocket === 'undefined') {\n      throw new BackendError('validation', {\n        code: 'realtime_unavailable',\n        message:\n          'pb.realtime is client-only: this environment has no WebSocket. ' +\n          'Subscribe from browser code instead — e.g. a client component or useEffect.',\n      });\n    }\n    let channel = this.channels.get(name);\n    if (!channel) {\n      channel = new RealtimeChannel(name, this);\n      this.channels.set(name, channel);\n    }\n    return channel;\n  }\n\n  /**\n   * Tear down the shared socket and clear all channel state. Called by\n   * `__configure` and `__reset` when the runtime is replaced, so old sockets\n   * are not left open and heartbeat timers do not leak.\n   */\n  destroy(): void {\n    this.socket?.stop();\n    this.socket = null;\n    this.channels.clear();\n  }\n\n  /** The observable connection status. Safe to read anywhere (reports `idle` until a socket exists). */\n  get status(): RealtimeStatus {\n    return this.statusStore;\n  }\n\n  /**\n   * Hand the socket a fresher credential for the SAME user, without rejoining.\n   *\n   * Called when the app's token rotates. The alternative — letting the channels\n   * die at expiry and rejoining — reaps this connection's ephemeral entries\n   * (its presence, on every channel) and forces a full state resync. A token\n   * getting older is not a disconnection and must not cost one.\n   *\n   * A no-op before a socket exists: the first connect resolves a fresh token\n   * on its own.\n   */\n  refreshToken(token: string): void {\n    this.socket?.sendAccessToken(token);\n  }\n\n  /** @internal */\n  subscribe(topic: string, event: string, handler: RealtimeHandler): RealtimeSubscription {\n    const socket = this.ensureSocket();\n    const entry: HandlerEntry = { topic, event, handler };\n    this.handlers.add(entry);\n    const count = (this.topicRefcount.get(topic) ?? 0) + 1;\n    this.topicRefcount.set(topic, count);\n    if (count === 1) socket.joinTopic(topic);\n\n    let cancelled = false;\n    return {\n      cancel: () => {\n        if (cancelled) return;\n        cancelled = true;\n        this.handlers.delete(entry);\n        // A count that is GONE means this topic was already torn down — by a\n        // final refusal, which deletes the count while the app still holds live\n        // cancel handles. Reading a missing count as 1 and decrementing it to 0\n        // then leaves the channel: an app that re-subscribed after\n        // re-authenticating, and only afterwards tidied up its old handle, had\n        // the new subscription silently severed. iOS guards this; this did not.\n        const held = this.topicRefcount.get(topic);\n        if (held === undefined) return;\n        const next = held - 1;\n        if (next <= 0) {\n          this.topicRefcount.delete(topic);\n          socket.leaveTopic(topic);\n        } else {\n          this.topicRefcount.set(topic, next);\n        }\n      },\n    };\n  }\n\n  /**\n   * Register a refusal handler for one topic. Does NOT join: watching for a\n   * refusal is not a subscription, and an app that registers one before its\n   * first `.on()` should not be joining anything yet.\n   *\n   * @internal\n   */\n  subscribeError(\n    topic: string,\n    handler: (error: RealtimeChannelError) => void,\n  ): RealtimeSubscription {\n    const entry: ErrorHandlerEntry = { topic, handler };\n    this.errorHandlers.add(entry);\n    let cancelled = false;\n    return {\n      cancel: () => {\n        if (cancelled) return;\n        cancelled = true;\n        this.errorHandlers.delete(entry);\n      },\n    };\n  }\n\n  /** @internal */\n  send(topic: string, event: string, payload: RealtimePayload): void {\n    const socket = this.ensureSocket();\n    // Phoenix only accepts pushes on joined topics. Idempotent when already\n    // joined; a send-only channel stays joined until its handlers (if any\n    // are ever added) all cancel.\n    socket.joinTopic(topic);\n    socket.sendBroadcast(topic, event, payload);\n  }\n\n  /** Lazily build + start the shared socket on first subscription/send. */\n  private ensureSocket(): RealtimeSocket {\n    if (!this.socket) {\n      const anon = new AnonTokenProvider(this.rt);\n      this.socket = new RealtimeSocket({\n        baseUrl: this.rt.config.url,\n        tokenProvider: realtimeTokenProvider(this.rt, anon),\n      });\n      this.socket.start({\n        onInbound: (inbound) => this.route(inbound),\n        // Rejoin-all already happens inside the socket; nothing to refresh\n        // here (no managed flags-sync on web yet — pb.flags polls).\n        onReconnect: () => {},\n        onStateChange: (state) => this.statusStore.setState(state),\n        onChannelError: (topic) => this.handleChannelError(topic),\n        onChannelRefused: (topic, reason) => this.handleChannelRefused(topic, reason),\n        onStateSnapshot: (topic, body) => this.applySnapshot(topic, body),\n        onStateDiff: (topic, body) => this.applyDiff(topic, body),\n        onJoinInfo: (topic, info) => this.applyJoinInfo(topic, info),\n      });\n    }\n    return this.socket;\n  }\n\n  private route(inbound: RealtimeInbound): void {\n    // Any inbound broadcast counts as a \"live event\" (iOS parity) — even one\n    // without a matching handler proves the socket is delivering.\n    this.statusStore.recordEvent(new Date());\n    for (const entry of this.handlers) {\n      if (entry.topic === inbound.topic && entry.event === inbound.event) {\n        entry.handler(inbound.payload);\n      }\n    }\n  }\n\n  /**\n  /**\n   * The server refused a channel. Tell whoever asked, and — when the answer is\n   * final — stop pretending the app is subscribed to it.\n   *\n   * `unavailable` leaves everything in place: the project could not be reached\n   * to decide, the socket rejoins on its next reconnect, and dropping the app's\n   * handlers would make a momentary outage look like a permanent denial.\n   */\n  private handleChannelRefused(topic: string, reason: string): void {\n    const retryable = RETRYABLE_REASONS.has(reason);\n    for (const entry of this.errorHandlers) {\n      if (entry.topic === topic) entry.handler({ topic, reason, retryable });\n    }\n    if (retryable) return;\n    // A final refusal ends every kind of subscription on this channel, not just\n    // the event handlers. A state or presence watcher left registered here would\n    // wait forever: no snapshot or diff can arrive for a channel the server has\n    // refused, so the app sits on a callback that will never fire again and has\n    // nothing telling it why.\n    this.forgetTopic(topic);\n  }\n\n  /**\n   * A channel died for good — a token-expiry rejoin that exhausted its attempts.\n   * The app must stop expecting anything on it, and the status observable flips\n   * to `'error'` (the React `useChannel` hook reports that).\n   *\n   * It clears the SAME registries a final refusal clears, and used to clear only\n   * the event handlers. A state or presence watcher left behind here waits\n   * forever for a snapshot that cannot arrive, and fires twice if the app ever\n   * re-subscribes — the identical failure its sibling three functions up\n   * describes, on a channel that was given up on rather than refused.\n   */\n  private handleChannelError(topic: string): void {\n    this.forgetTopic(topic);\n    this.statusStore.setState('error');\n  }\n\n  /** Drop every registration this topic holds. One place, because \"which\n   *  registries\" is a question two callers must never answer differently. */\n  private forgetTopic(topic: string): void {\n    for (const entry of this.handlers) {\n      if (entry.topic === topic) this.handlers.delete(entry);\n    }\n    for (const entry of this.stateWatchers) {\n      if (entry.topic === topic) this.stateWatchers.delete(entry);\n    }\n    for (const entry of this.presenceWatchers) {\n      if (entry.topic === topic) this.presenceWatchers.delete(entry);\n    }\n    this.pendingPresence.delete(topic);\n    this.states.delete(topic);\n    this.connIds.delete(topic);\n    this.topicRefcount.delete(topic);\n  }\n\n  // ── state ──────────────────────────────────────────────────────────────────\n\n  /** @internal */\n  stateOf(topic: string): ChannelState {\n    let st = this.states.get(topic);\n    if (!st) {\n      st = new ChannelState();\n      this.states.set(topic, st);\n    }\n    return st;\n  }\n\n  /** @internal */\n  subscribeState(\n    topic: string,\n    key: string,\n    handler: (value: unknown) => void,\n  ): RealtimeSubscription {\n    const socket = this.ensureSocket();\n    const entry = { topic, key, handler };\n    this.stateWatchers.add(entry);\n    this.retainTopic(topic, socket);\n    // The current value, if there is one: state is already there when you ask,\n    // and making the caller wait for a change would defeat the point.\n    const known = this.stateOf(topic).entries.get(key);\n    if (known !== undefined) handler(known);\n\n    let cancelled = false;\n    return {\n      cancel: () => {\n        if (cancelled) return;\n        cancelled = true;\n        this.stateWatchers.delete(entry);\n        this.releaseTopic(topic, socket);\n      },\n    };\n  }\n\n  /** @internal */\n  subscribePresence(topic: string, handler: (others: unknown[]) => void): RealtimeSubscription {\n    const socket = this.ensureSocket();\n    const entry = { topic, handler };\n    this.presenceWatchers.add(entry);\n    this.retainTopic(topic, socket);\n    handler(this.presenceOthers(topic));\n\n    let cancelled = false;\n    return {\n      cancel: () => {\n        if (cancelled) return;\n        cancelled = true;\n        this.presenceWatchers.delete(entry);\n        this.releaseTopic(topic, socket);\n      },\n    };\n  }\n\n  /** @internal */\n  writeState(topic: string, key: string, value: unknown, life: 'ephemeral' | 'durable'): void {\n    const socket = this.ensureSocket();\n    socket.joinTopic(topic);\n    socket.sendStateSet(topic, key, value, life);\n  }\n\n  /** @internal */\n  clearState(topic: string, key: string): void {\n    this.ensureSocket().sendStateDel(topic, key);\n  }\n\n  /** @internal */\n  presenceWrite(topic: string, meta: RealtimePayload): void {\n    const socket = this.ensureSocket();\n    socket.joinTopic(topic);\n    const conn = this.connIds.get(topic);\n    if (conn === undefined) {\n      // The join ack has not arrived, so this connection has no identity on the\n      // channel yet and the entry would have no key. Held, and written the\n      // moment the ack lands — announcing under a guessed key would leave a\n      // ghost nothing ever reaps.\n      this.pendingPresence.set(topic, meta);\n      return;\n    }\n    socket.sendStateSet(topic, PRESENCE_KEY(conn), meta, 'ephemeral');\n  }\n\n  /** @internal */\n  presenceClear(topic: string): void {\n    this.pendingPresence.delete(topic);\n    const conn = this.connIds.get(topic);\n    if (conn === undefined) return;\n    this.ensureSocket().sendStateDel(topic, PRESENCE_KEY(conn));\n  }\n\n  /** @internal */\n  presenceOthers(topic: string): unknown[] {\n    return this.stateOf(topic).presence(this.connIds.get(topic));\n  }\n\n  private retainTopic(topic: string, socket: RealtimeSocket): void {\n    const count = (this.topicRefcount.get(topic) ?? 0) + 1;\n    this.topicRefcount.set(topic, count);\n    if (count === 1) socket.joinTopic(topic);\n  }\n\n  private releaseTopic(topic: string, socket: RealtimeSocket): void {\n    const next = (this.topicRefcount.get(topic) ?? 1) - 1;\n    if (next <= 0) {\n      this.topicRefcount.delete(topic);\n      socket.leaveTopic(topic);\n      return;\n    }\n    this.topicRefcount.set(topic, next);\n  }\n\n  private applySnapshot(topic: string, body: SnapshotBody): void {\n    this.stateOf(topic).applySnapshot(body);\n    this.notifyState(topic);\n  }\n\n  private applyDiff(topic: string, body: DiffBody): void {\n    if (this.stateOf(topic).applyDiff(body) === 'gap') {\n      // Frames were missed. Asking for the whole picture is the only honest\n      // recovery: applying the diff anyway would produce a state that never\n      // existed on the server.\n      this.socket?.sendStateResync(topic);\n      return;\n    }\n    this.notifyState(topic);\n  }\n\n  private applyJoinInfo(topic: string, info: { conn?: string; state_seq?: number }): void {\n    if (typeof info.conn !== 'string' || info.conn === '') return;\n    this.connIds.set(topic, info.conn);\n\n    // ADOPT THE SERVER'S SEQUENCE. The ack says which sequence the state we are\n    // about to receive describes, and until now nothing read it.\n    //\n    // It matters because the server's sequence can go BACKWARDS between our\n    // joins: a channel everybody left and that held nothing is forgotten, and\n    // the next write starts again at 1. A client that kept its old local\n    // sequence — say 11 — then reads the fresh `state_diff{from_seq:0, seq:1}`\n    // as one it has already applied (`seq <= this.seq`) and silently discards\n    // it, along with every change after it until the server passes 11. Its\n    // picture is wrong and nothing ever heals it, which is the exact failure\n    // the store's own eviction guard exists to prevent — reached by another\n    // door.\n    //\n    // Behind the server means our copy is stale, not ahead: drop it and take\n    // what arrives. A snapshot follows when there is anything to send, and when\n    // there is not, empty IS the truth.\n    const seq = info.state_seq;\n    if (typeof seq === 'number' && seq < this.stateOf(topic).seq) {\n      this.stateOf(topic).applySnapshot({ seq, entries: {} });\n    }\n    const held = this.pendingPresence.get(topic);\n    if (held !== undefined) {\n      this.pendingPresence.delete(topic);\n      this.socket?.sendStateSet(topic, PRESENCE_KEY(info.conn), held, 'ephemeral');\n    }\n    this.notifyState(topic);\n  }\n\n  private notifyState(topic: string): void {\n    this.statusStore.recordEvent(new Date());\n    const st = this.stateOf(topic);\n    for (const w of this.stateWatchers) {\n      if (w.topic === topic) w.handler(st.entries.get(w.key));\n    }\n    if (this.presenceWatchers.size > 0) {\n      const others = this.presenceOthers(topic);\n      for (const w of this.presenceWatchers) {\n        if (w.topic === topic) w.handler(others);\n      }\n    }\n  }\n}\n\n/** Presence is state keyed by the connection that announced it. */\nconst PRESENCE_KEY = (conn: string) => `$p:${conn}`;\n","import { PalbaseError, type Session, type TokenManager } from '@palbase/core';\nimport type { PersistedSession, SessionStorageAdapter } from './storage.js';\n\nconst asSession = (stored: PersistedSession): Session => ({\n  accessToken: stored.accessToken ?? '',\n  refreshToken: stored.refreshToken,\n  expiresAt: stored.expiresAt ?? 0,\n});\n\n/** Read, rotate, and persist under one lock; never erase a newer login. */\nexport class SessionCoordinator {\n  private persistedRefresh: string | null;\n  private committedRefresh: string | null = null;\n\n  constructor(\n    private readonly storage: SessionStorageAdapter,\n    private readonly manager: TokenManager,\n  ) {\n    this.persistedRefresh = storage.load()?.refreshToken ?? null;\n  }\n\n  readonly refresh = async (\n    refreshToken: string,\n    exchange: (token: string) => Promise<Session>,\n  ): Promise<Session> => {\n    const run = async () => {\n      const localToken = this.manager.getRefreshToken();\n      if (!localToken || localToken !== refreshToken) {\n        throw new PalbaseError('session_changed', 'Session changed while waiting to refresh', 0);\n      }\n      const before = this.storage.load();\n      if (!before && this.persistedRefresh !== null) return this.adopt(null);\n\n      // A tab that waited for the lock, or resumed later, reuses the result\n      // already written by its neighbour instead of replaying a consumed token.\n      if (\n        before &&\n        before.refreshToken !== refreshToken &&\n        before.accessToken &&\n        (before.expiresAt ?? 0) > Date.now()\n      ) {\n        return this.adopt(before);\n      }\n\n      let result: Session;\n      try {\n        result = await exchange(before?.refreshToken ?? refreshToken);\n      } catch (error) {\n        const after = this.storage.load();\n        // A login/logout in another tab may have completed during the request.\n        // Its state wins even when the old request returns a terminal error.\n        if (\n          this.manager.getRefreshToken() === localToken &&\n          after?.refreshToken !== before?.refreshToken\n        ) {\n          return this.adopt(after);\n        }\n        throw error;\n      }\n\n      if (this.manager.getRefreshToken() !== localToken) {\n        throw new PalbaseError('session_changed', 'Session changed during refresh', 0);\n      }\n      const after = this.storage.load();\n      if (after?.refreshToken !== before?.refreshToken) return this.adopt(after);\n\n      // Persist before releasing the lock. TokenManager will announce the\n      // session after this returns; persist() must not write it a second time.\n      this.storage.save(result);\n      this.persistedRefresh = this.storage.load()?.refreshToken ?? null;\n      this.committedRefresh = result.refreshToken;\n      return result;\n    };\n    return this.storage.withLock ? this.storage.withLock(run) : run();\n  };\n\n  persist(session: Session | null): void {\n    if (session && session.refreshToken === this.committedRefresh) {\n      this.committedRefresh = null;\n      return;\n    }\n    if (session) {\n      this.committedRefresh = null;\n      // An explicit sign-in deliberately replaces the current stored session.\n      this.storage.save(session);\n      this.persistedRefresh = this.storage.load()?.refreshToken ?? null;\n    } else {\n      // An old tab's rejected session must not delete another tab's new login.\n      if ((this.storage.load()?.refreshToken ?? null) === this.persistedRefresh)\n        this.storage.clear();\n      this.persistedRefresh = null;\n      this.committedRefresh = null;\n    }\n  }\n\n  private adopt(stored: PersistedSession | null): Session {\n    if (!stored) {\n      this.manager.clearSession();\n      throw new PalbaseError('session_changed', 'Session ended in another context', 0);\n    }\n    this.persistedRefresh = stored.refreshToken;\n    this.committedRefresh = stored.refreshToken;\n    return asSession(stored);\n  }\n}\n","/**\n * Persisted session. The refresh token is the durable credential; access\n * token + expiry ride along (when available) so a reload — or a server-side\n * cookie read — can reuse a still-fresh access token instead of burning a\n * refresh per hydration (rotation storm under SSR).\n */\nexport interface PersistedSession {\n  refreshToken: string;\n  accessToken?: string;\n  /** ms epoch */\n  expiresAt?: number;\n}\n\nexport interface SessionStorageAdapter {\n  load(): PersistedSession | null;\n  save(session: PersistedSession): void;\n  clear(): void;\n  /** Serialize refresh read/exchange/write across users of this store. */\n  withLock?<T>(operation: () => Promise<T>): Promise<T>;\n}\n\ntype SessionLock = NonNullable<SessionStorageAdapter['withLock']>;\n\nfunction serialLock(): SessionLock {\n  let tail: Promise<unknown> = Promise.resolve();\n  return (operation) => {\n    const result = tail.then(operation);\n    tail = result.then(\n      () => undefined,\n      () => undefined,\n    );\n    return result;\n  };\n}\n\nexport function memorySessionStorage(): SessionStorageAdapter {\n  let current: PersistedSession | null = null;\n  return {\n    withLock: serialLock(),\n    load: () => current,\n    save: (s) => {\n      current = s;\n    },\n    clear: () => {\n      current = null;\n    },\n  };\n}\n\nconst DEFAULT_KEY = 'palbe.session';\nconst realmLocks = new Map<string, SessionLock>();\n\nexport function localStorageSessionStorage(key: string = DEFAULT_KEY): SessionStorageAdapter {\n  let fallback = realmLocks.get(key);\n  if (!fallback) {\n    fallback = serialLock();\n    realmLocks.set(key, fallback);\n  }\n  const realmLock = fallback;\n  return {\n    withLock: async (operation) => {\n      // Web Locks covers other same-origin tabs, including a newly reloaded\n      // tab. The fallback only coordinates runtimes in this JS realm.\n      const locks = typeof navigator !== 'undefined' ? navigator.locks : undefined;\n      return await (locks\n        ? locks.request(`palbase:${key}:refresh`, operation)\n        : realmLock(operation));\n    },\n    load: () => {\n      try {\n        const raw = localStorage.getItem(key);\n        if (!raw) return null;\n        const parsed: unknown = JSON.parse(raw);\n        if (typeof parsed === 'object' && parsed !== null) {\n          const obj = parsed as Record<string, unknown>;\n          if (typeof obj.refreshToken === 'string') {\n            // Optional fields are validated as a PAIR: a wrong-typed (or lone)\n            // access token / expiry degrades to the legacy {refreshToken}\n            // shape — never null the whole session over the optional part.\n            if (typeof obj.accessToken === 'string' && typeof obj.expiresAt === 'number') {\n              return {\n                refreshToken: obj.refreshToken,\n                accessToken: obj.accessToken,\n                expiresAt: obj.expiresAt,\n              };\n            }\n            return { refreshToken: obj.refreshToken };\n          }\n        }\n        return null;\n      } catch {\n        return null;\n      }\n    },\n    save: (s) => {\n      try {\n        localStorage.setItem(key, JSON.stringify(s));\n      } catch {\n        // quota/SSR — non-fatal: session just won't survive reload\n      }\n    },\n    clear: () => {\n      try {\n        localStorage.removeItem(key);\n      } catch {\n        // ignore\n      }\n    },\n  };\n}\n\n/**\n * Browser → localStorage, else memory. Pass an environment-scoped key\n * (`palbe.session.<environmentRef>`) — the bare default key would collide\n * between two Palbase environments served from the same origin.\n */\nexport function defaultSessionStorage(key?: string): SessionStorageAdapter {\n  if (typeof localStorage !== 'undefined') return localStorageSessionStorage(key);\n  return memorySessionStorage();\n}\n","// AUTO-GENERATED from package.json — do not edit\nexport const VERSION = '11.2.2';\n","import { AuthClient, type OAuthTransactionStorage, parseOAuthConfig } from '@palbase/auth';\nimport { HttpClient, TokenManager } from '@palbase/core';\nimport { AnalyticsState, PalbeAnalytics } from './analytics-facade.js';\nimport { environmentRefFromPublishableApiKey } from './api-key.js';\nimport { PalbeAuth } from './auth-facade.js';\nimport { PalbeCalls } from './calls/facade.js';\nimport type { PalbeConfig } from './config.js';\nimport { PalbeFlags } from './flags-facade.js';\nimport { PalbeMessaging } from './messaging/facade.js';\nimport { measureAppStart } from './perf/app-start.js';\nimport { PerfConfigClient } from './perf/perf-config-client.js';\nimport { PalbePerf } from './perf/perf-facade.js';\nimport { observeWebVitals } from './perf/web-vitals.js';\nimport { PalbeRealtime } from './realtime/facade.js';\nimport { applyBrowserOriginHeader } from './runtime-metadata.js';\nimport { SessionCoordinator } from './session-coordinator.js';\nimport { defaultSessionStorage, type SessionStorageAdapter } from './storage.js';\nimport { VERSION } from './version.js';\n\nexport interface PalbeRuntime {\n  config: PalbeConfig;\n  /**\n   * The project this runtime talks to, read from the publishable key.\n   *\n   * Exposed here so every consumer takes it from ONE derivation. It used to be\n   * a field on the config that had to equal the key's — see buildRuntime.\n   */\n  projectRef: string;\n  http: HttpClient;\n  tokenManager: TokenManager;\n  authClient: AuthClient;\n  auth: PalbeAuth;\n  flags: PalbeFlags;\n  realtime: PalbeRealtime;\n  analytics: PalbeAnalytics;\n  calls: PalbeCalls;\n  messaging: PalbeMessaging;\n  /**\n   * PalPerf surface. EAGER (like analytics identity): `request.ts` records a\n   * `network` trace around EVERY SDK fetch, so the facade must exist from the\n   * first request — never lazy. The buffer/timer it owns is inert until the\n   * first item is recorded.\n   */\n  perf: PalbePerf;\n  storage: SessionStorageAdapter;\n  /**\n   * Destroy the realtime facade if it was already constructed (no-op otherwise).\n   * Called by `__configure` / `__reset` when the runtime is replaced so the old\n   * socket is closed and heartbeat timers do not leak.\n   */\n  destroyRealtime(): void;\n}\n\nexport function buildRuntime(\n  config: PalbeConfig,\n  options?: { oauthStorage?: OAuthTransactionStorage },\n): PalbeRuntime {\n  // THE project identity, and there is one source for it: the publishable key\n  // carries it (`pb_<ref>_c<random>`), so anything holding the key holds the ref.\n  //\n  // It used to be a second field beside the key, cross-checked against it — and\n  // the cross-check was the whole reason it existed, which is the tell. A copy\n  // that must equal its original is not a fact, it is an opportunity to\n  // disagree: measured on 2026-08-16, `palbase link` wrote one value and minted\n  // a key carrying another, and this generator refused to run at all.\n  const projectRef = environmentRefFromPublishableApiKey(config.apiKey);\n  if (projectRef === '') {\n    throw new Error('PalbeConfig.apiKey does not contain a valid publishable project identity');\n  }\n  try {\n    // Yalnız AYRIŞTIRILABİLİRLİK sınanıyor; sonucuna ihtiyaç yok.\n    new URL(config.url);\n  } catch {\n    throw new Error('PalbeConfig.url must be a valid URL');\n  }\n  // NO HOST-FROM-KEY CHECK. A publishable key does not name its own address on\n  // v2: a stack's identity is a compile-time constant, so every tenant's key\n  // reads `pb_project_…` while its address is the tenant's own ref. The rule\n  // that used to live here refused every correct v2 config. See the same note\n  // in gen/generate.ts.\n  const http = new HttpClient(config.apiKey, {\n    url: config.url,\n    sealed: config.sealed,\n    headers: { 'X-Client-Info': `palbe-web/${VERSION}`, ...config.headers },\n  });\n  // One transport-level default covers direct AuthClient/HttpClient calls as\n  // well as palbeRequest. It runs after global + per-request header merging,\n  // so an explicit caller value wins and the live origin is read per request.\n  http.addInterceptor(({ headers }) => applyBrowserOriginHeader(headers));\n  const tokenManager = new TokenManager();\n  http.tokenManager = tokenManager;\n  const storage = config.storage ?? defaultSessionStorage(`palbe.session.${projectRef}`);\n  const sessionCoordinator = new SessionCoordinator(storage, tokenManager);\n  const oauth = config.oauth === undefined ? undefined : parseOAuthConfig(config.oauth, projectRef);\n  const authClient = new AuthClient(http, tokenManager, config.apiKey, config.url, {\n    oauth,\n    oauthStorage: options?.oauthStorage,\n    coordinateRefresh: sessionCoordinator.refresh,\n  });\n\n  // Hydrate. Two paths:\n  //\n  // 1. FULL session persisted and still fresh → adopt it as a REAL session\n  //    (setTokens with the remaining TTL). The first request goes out with\n  //    the persisted Bearer and NO pre-flight refresh — this is what keeps\n  //    per-request server runtimes (palbe/next) from burning a token\n  //    rotation per request.\n  //\n  // 2. Legacy {refreshToken}-only shape, or an expired/invalid full session\n  //    → the expired-trick: the refresh token becomes an already-expired\n  //    session so HttpClient's pre-flight refresh runs before the first\n  //    real request. setTokens wires refreshFunction but sets\n  //    expiresAt=now+1h — we then override expiresAt to 0 so isExpired()\n  //    returns true immediately.\n  //\n  // Two implicit consequences, relied upon downstream (BOTH paths):\n  // (a) setTokens marks AuthClient.hasSession=true, so the first successful\n  //     refresh after restore emits TOKEN_REFRESHED (not SIGNED_IN) — the\n  //     auth facade relies on this distinction.\n  // (b) In the expired-trick path the transient session is\n  //     {accessToken:'', expiresAt:0} = \"pending refresh\" — never usable\n  //     directly, it only exists to arm pre-flight.\n  const persisted = storage.load();\n  if (persisted) {\n    const { accessToken, expiresAt } = persisted;\n    if (accessToken && expiresAt && expiresAt > Date.now()) {\n      authClient.setTokens(\n        accessToken,\n        persisted.refreshToken,\n        Math.floor((expiresAt - Date.now()) / 1000),\n      );\n    } else {\n      authClient.setTokens('', persisted.refreshToken); // wires refreshFunction\n      tokenManager.setSession({\n        accessToken: '',\n        refreshToken: persisted.refreshToken,\n        expiresAt: 0,\n      });\n    }\n  }\n\n  // Persist token changes — the FULL session (access+expiry ride along so the\n  // next hydration can skip the refresh); clear storage on sign-out.\n  // AuthClient's own session mirror is registered first (its constructor), so\n  // getSession() here already reflects the change that triggered us.\n  authClient.onTokenChange(() => sessionCoordinator.persist(authClient.getSession().data));\n\n  // Lazy getter resolves the rt↔PalbeAuth construction cycle without a cast:\n  // PalbeAuth needs rt, and `auth` stays non-optional on the interface.\n  let auth: PalbeAuth | undefined;\n  let flags: PalbeFlags | undefined;\n  let realtime: PalbeRealtime | undefined;\n  let analytics: PalbeAnalytics | undefined;\n  let calls: PalbeCalls | undefined;\n  let messaging: PalbeMessaging | undefined;\n  let perf: PalbePerf | undefined;\n  const rt: PalbeRuntime = {\n    config,\n    projectRef,\n    http,\n    tokenManager,\n    authClient,\n    storage,\n    get auth() {\n      if (!auth) auth = new PalbeAuth(rt);\n      return auth;\n    },\n    // Same lazy pattern as `auth`: the pool is constructed (and, in the\n    // browser, started) only when `pb.flags` is actually touched — a pbServer\n    // request that never reads flags pays nothing.\n    get flags() {\n      if (!flags) flags = new PalbeFlags(rt);\n      return flags;\n    },\n    // Lazy like `auth`/`flags` — but constructing PalbeRealtime is itself\n    // inert: the WebSocket only opens on the first channel subscription/send.\n    get realtime() {\n      if (!realtime) realtime = new PalbeRealtime(rt);\n      return realtime;\n    },\n    // PalbeCalls is lazy + stateless per instance (no timer/socket to destroy).\n    get calls() {\n      if (!calls) calls = new PalbeCalls(rt);\n      return calls;\n    },\n    // Lazy like the others — constructing PalbeMessaging is inert (no enroll /\n    // socket / WASM load until the first chat op or pb.messaging.start()).\n    get messaging() {\n      if (!messaging) messaging = new PalbeMessaging(rt);\n      return messaging;\n    },\n    destroyRealtime() {\n      // Runtime teardown hook (called by __configure/__reset on replace). Tear\n      // down everything that holds a global listener/socket/timer so the old\n      // runtime doesn't leak across a swap.\n      // Only destroy if the lazy getter was already accessed (memo is set).\n      // Do NOT touch `rt.realtime` here — that would construct it just to destroy.\n      realtime?.destroy();\n      realtime = undefined;\n      // PalPerf is eager (below), so it always holds the `online` reconnect\n      // listener — remove it so a __configure swap doesn't accumulate handlers.\n      perf?.dispose();\n    },\n    // The buffering facade is lazy; its identity state is NOT (below).\n    get analytics() {\n      if (!analytics) analytics = new PalbeAnalytics(rt, analyticsState);\n      return analytics;\n    },\n    // PalPerf is constructed up front (touched below): `request.ts` records a\n    // network trace on EVERY fetch, so it can't be lazy. The memo here only\n    // guards against re-construction.\n    get perf() {\n      if (!perf) perf = new PalbePerf(rt);\n      return perf;\n    },\n  };\n\n  // Analytics identity state is EAGER (cheap: listener wiring, no I/O): the\n  // X-Distinct-Id interceptor must stamp EVERY request from the first one,\n  // even when pb.analytics is never touched (iOS wires the resolver at\n  // PalBackend init). Subscribing to auth events here constructs PalbeAuth\n  // up front — acceptable, its constructor only attaches listeners.\n  const analyticsState = new AnalyticsState(rt);\n  http.addInterceptor((request) => {\n    // Caller-supplied X-Distinct-Id wins (iOS applyDistinctId parity).\n    const hasOwn = Object.keys(request.headers).some((k) => k.toLowerCase() === 'x-distinct-id');\n    if (!hasOwn) request.headers['X-Distinct-Id'] = analyticsState.distinctId();\n  });\n\n  // Eagerly materialize the perf facade so `request.ts` can record a network\n  // trace from the very first SDK fetch (the facade buffer stays inert until\n  // an item is actually recorded).\n  void rt.perf;\n\n  // Browser-only: fetch the server-controlled perf sample rate once at init and\n  // apply it to the facade's client-side sampling (remote sampling). Server\n  // (no `document`) skips this — a per-request runtime must not fire an extra\n  // GET per request. Fire-and-forget: a failed fetch leaves the default 100%.\n  if (typeof document !== 'undefined') {\n    void new PerfConfigClient().fetchConfig(rt, rt.perf);\n    // A session restored from the cookie above rehydrated the TOKENS but not the\n    // user object (the access-token JWT carries no emailVerified/createdAt), so\n    // fetch GET /auth/user once and announce `signedIn` — the app no longer has\n    // to `await pb.auth.refreshUser()` on boot. Browser-only (SSR must not fetch;\n    // it renders SIGNED_OUT and the client hydrates), idempotent, non-throwing.\n    rt.auth.hydrateUser();\n  }\n\n  // Browser-only cold-start trace. The web has no prewarm (unlike iOS), so a\n  // load is always a real cold start: read First Contentful Paint relative to\n  // navigation start and record ONE `app_start` item. The measurement itself is\n  // the pure `measureAppStart`; this is just the untestable observer glue.\n  recordColdStart(rt);\n\n  // Browser-only Core Web Vitals. Records one `web_vital` perf item per settled\n  // vital (LCP/CLS/INP/FCP/TTFB) through the same buffer as every perf family.\n  // Best-effort — unsupported observer types are skipped, never thrown.\n  observeWebVitals((item) => rt.perf.record(item));\n\n  return rt;\n}\n\n/**\n * Wire the browser cold-start measurement. Records exactly one `app_start` perf\n * item once First Contentful Paint is known. No-op outside the browser (no\n * `document`/`PerformanceObserver`) or when navigation timing is unavailable.\n * Failures are swallowed — a perf hook must never break runtime construction.\n */\nfunction recordColdStart(rt: PalbeRuntime): void {\n  if (typeof document === 'undefined' || typeof performance === 'undefined') return;\n  try {\n    const navEntry = performance.getEntriesByType('navigation')[0] as\n      | PerformanceNavigationTiming\n      | undefined;\n    const startTime = navEntry?.startTime ?? 0;\n\n    const recordFromFcp = (fcp: number): void => {\n      const item = measureAppStart({ startTime, fcp });\n      if (item) rt.perf.record(item);\n    };\n\n    // FCP may already have happened by the time the SDK is configured — read\n    // the existing paint entry first.\n    const existing = performance\n      .getEntriesByName('first-contentful-paint')\n      .find((e) => e.startTime > 0);\n    if (existing) {\n      recordFromFcp(existing.startTime);\n      return;\n    }\n\n    // Otherwise observe paint entries and record on the first FCP, then stop.\n    if (typeof PerformanceObserver === 'undefined') return;\n    const observer = new PerformanceObserver((list) => {\n      for (const entry of list.getEntries()) {\n        if (entry.name === 'first-contentful-paint') {\n          observer.disconnect();\n          recordFromFcp(entry.startTime);\n          return;\n        }\n      }\n    });\n    observer.observe({ type: 'paint', buffered: true });\n  } catch {\n    // PerformanceObserver/navigation timing not supported — cold-start trace is\n    // best-effort, never fatal.\n  }\n}\n","import { BackendError } from './errors.js';\nimport { type CallOptions, palbeRequest } from './request.js';\nimport type { PalbeRuntime } from './runtime.js';\n\n/**\n * Runtime resolution is deferred behind `resolveRt` (global pb passes\n * `getRuntime`, bound clients pass `() => rt`) — but name validation runs\n * FIRST so an empty name fails as `validation` even before `notConfigured`.\n */\nexport async function callEndpoint<O>(\n  resolveRt: () => PalbeRuntime,\n  name: string,\n  input?: unknown,\n  options?: CallOptions,\n): Promise<O> {\n  if (!name || name === '/') {\n    throw new BackendError('validation', {\n      code: 'invalid_endpoint_name',\n      message: 'Endpoint name must be a non-empty path like \"todos/create\"',\n    });\n  }\n  const rt = resolveRt();\n  const path = name.startsWith('/') ? name : `/${name}`;\n  return palbeRequest<O>(rt, 'POST', path, {\n    body: input,\n    headers: options?.headers,\n    signal: options?.signal,\n  });\n}\n","// room.ts — the TYPED cap over a realtime channel, on the web side.\n//\n// Realtime arrives untyped today: a handler is given `Record<string, unknown>`\n// and every field is a cast. A room changes that — the backend DECLARES its\n// events and its messages, the generator emits them as real types, and this file\n// is where those types meet the socket.\n//\n// What this file deliberately does NOT do is manage membership. `PalbeRealtime`\n// already joins a channel on its first handler and leaves on its last, so FR-016\n// is satisfied by DELEGATING to that count. A second refcount here would be a\n// second thing to get wrong, and the two would disagree the first time an app\n// mixed `pb.join` with `pb.realtime.channel`.\n\nimport type { RealtimePayload, RealtimeSubscription } from './realtime/facade.js';\n\n/** What a room needs from the socket. `PalbeRealtime` provides it; a test\n *  supplies its own, so the typed layer can be measured without a connection. */\nexport interface RoomTransport {\n  /** Subscribe to one event on one topic. Returns the undo. */\n  subscribe(topic: string, event: string, handler: (payload: RealtimePayload) => void): () => void;\n  /** Push one client frame. */\n  send(topic: string, event: string, payload: RealtimePayload): void;\n}\n\n/**\n * A room, as the generator emits one. An app never writes this by hand.\n *\n * `send` and `event` are TYPE CARRIERS — their values are never read. They exist\n * so `room.send('say', {...})` checks the payload against the right shape\n * without the app ever naming that shape.\n */\nexport interface RoomDescriptor<\n  E extends { event: string; payload: unknown },\n  S,\n  P extends readonly string[] = readonly string[],\n> {\n  /** The channel pattern the backend declared: `ai:{sessionId}`. */\n  pattern: string;\n  /** The `{param}` names, in pattern order.\n   *\n   *  Typed as a literal tuple (the generator emits `as const`) so `join` can\n   *  demand EXACTLY these keys. Without that, `params` is `Record<string,\n   *  string>` and a typo'd key type-checks — it then builds a topic with an\n   *  unfilled `{param}`, which matches no room on the server and fails as\n   *  SILENCE. Measured: the runtime guard caught it, the compiler did not. */\n  params: P;\n  /** The declared event names — what the handle subscribes to. Without the list\n   *  it would have to guess, and a room's events are what it must not guess. */\n  events: readonly string[];\n  /** The declared message names. `send` is a TYPE carrier with no runtime keys,\n   *  so this is the half a JavaScript caller can be checked against. */\n  messages: readonly string[];\n  send: S;\n  event: E;\n}\n\n/** A live room. Hold it for as long as the view is on screen. */\nexport interface RoomHandle<E extends { event: string; payload: unknown }, S> {\n  /** The topic this handle is attached to. An app never has to build it. */\n  readonly topic: string;\n  /** Start receiving. Returns a token for `off`. */\n  on(handler: (event: E) => void): RoomToken;\n  /** Stop one callback. */\n  off(token: RoomToken): void;\n  /** Send one declared message. The event name comes from the descriptor. */\n  send<K extends keyof S & string>(name: K, payload: S[K]): void;\n  /** Drop every callback this handle registered. */\n  leave(): void;\n}\n\n/** Opaque handle to one registration. Callback + token, deliberately: a room\n *  routinely has several interested parties (a transcript, a badge, a logger),\n *  and an async iterator has exactly one consumer. */\nexport type RoomToken = { readonly __room: unique symbol } | symbol;\n\n/**\n * Attach to a room.\n *\n *     const room = pb.join(AiSessionIdRoom, { sessionId })\n *     const token = room.on((e) => {\n *       switch (e.event) {\n *         case 'token': transcript.push(e.payload.text); break\n *         case 'done':  finish(e.payload.reason); break\n *       }\n *     })\n *     room.send('say', { text: 'hello' })\n *     room.off(token)\n *\n * `switch` is exhaustive: when the backend adds an event, the compiler points at\n * every place that has to handle it.\n */\nexport function joinRoom<\n  E extends { event: string; payload: unknown },\n  S,\n  P extends readonly string[],\n>(\n  descriptor: RoomDescriptor<E, S, P>,\n  params: Record<P[number], string>,\n  transport: RoomTransport,\n): RoomHandle<E, S> {\n  const topic = fillPattern(descriptor.pattern, params as Record<string, string>);\n  // One app-facing callback holds several socket unsubscribes — one per declared\n  // event — so `off` has to undo all of them together.\n  const registrations = new Map<symbol, (() => void)[]>();\n\n  return {\n    topic,\n\n    on(handler) {\n      const token = Symbol('room');\n      const undos: (() => void)[] = [];\n      for (const name of descriptor.events) {\n        undos.push(\n          transport.subscribe(topic, name, (payload) => {\n            handler({ event: name, payload } as E);\n          }),\n        );\n      }\n      registrations.set(token, undos);\n      return token;\n    },\n\n    off(token) {\n      const undos = registrations.get(token as symbol);\n      if (!undos) return;\n      registrations.delete(token as symbol);\n      for (const undo of undos) undo();\n    },\n\n    send(name, payload) {\n      if (!descriptor.messages.includes(name)) {\n        // NAMED, and before the socket is touched. TypeScript already refuses\n        // this, but a JavaScript caller has no compiler — and a message the room\n        // never declared is dropped server-side with nothing said, which is the\n        // hardest failure shape to trace back.\n        throw new Error(\n          `room \"${descriptor.pattern}\" declares no message \"${String(name)}\" — ` +\n            `check the backend's @OnMessage names and re-run the generator.`,\n        );\n      }\n      transport.send(topic, name, payload as RealtimePayload);\n    },\n\n    leave() {\n      for (const undos of registrations.values()) {\n        for (const undo of undos) undo();\n      }\n      registrations.clear();\n    },\n  };\n}\n\n/** Build the live topic. A `{param}` left unfilled would produce a topic that\n *  matches no room on the server and fails as SILENCE — the hardest failure to\n *  trace — so it is refused here, by name. */\nfunction fillPattern(pattern: string, params: Record<string, string>): string {\n  return pattern\n    .split(':')\n    .map((seg) => {\n      if (!seg.startsWith('{') || !seg.endsWith('}')) return seg;\n      const name = seg.slice(1, -1);\n      const value = params[name];\n      if (value === undefined || value === '') {\n        throw new Error(`room \"${pattern}\" needs a value for \"${name}\".`);\n      }\n      return value;\n    })\n    .join(':');\n}\n\nexport type { RealtimeSubscription };\n","import { asPalbaseError, BackendError, fromEnvelope, fromPalbaseError } from './errors.js';\nimport type { PalbeRuntime } from './runtime.js';\nimport { applyBrowserOriginHeader } from './runtime-metadata.js';\nimport { VERSION } from './version.js';\n\nexport interface UploadProgress {\n  /** Bytes sent so far. */\n  sent: number;\n  /**\n   * Total bytes. Always > 0 when delivered — progress events whose length is\n   * not computable are skipped entirely.\n   */\n  total: number;\n}\n\nexport interface UploadOptions {\n  file: Blob;\n  filename?: string;\n  contentType?: string;\n  /**\n   * The request body sent beside the file. Folded into the single `body` part\n   * storage reads and handed to the route's schema — pass a pre-encoded JSON\n   * string as `body` to own the envelope yourself.\n   */\n  fields?: Record<string, string>;\n  onProgress?: (progress: UploadProgress) => void;\n  signal?: AbortSignal;\n  headers?: Record<string, string>;\n  /** Client-side pre-send validation (iOS parity). */\n  constraints?: { maxSize?: number; allowedTypes?: string[] };\n}\n\n/** Storage's client-facing door: `POST /v1/storage/upload/{route...}`. */\nconst UPLOAD_PATH = '/v1/storage/upload';\n\nfunction abortError(): BackendError {\n  return new BackendError('network', { code: 'aborted', message: 'Upload aborted' });\n}\n\nfunction checkConstraints(options: UploadOptions): void {\n  const c = options.constraints;\n  if (!c) return;\n  if (c.maxSize !== undefined && options.file.size > c.maxSize) {\n    const message = `File size ${options.file.size} exceeds max ${c.maxSize} bytes`;\n    throw new BackendError('validation', {\n      code: 'file_too_large',\n      message,\n      fields: [{ field: 'file', message }],\n    });\n  }\n  // Empty allowedTypes = no type check (iOS contract). Validate the EFFECTIVE\n  // type: a contentType override wins over file.type (it is what gets sent).\n  const effType = options.contentType ?? options.file.type;\n  if (c.allowedTypes && c.allowedTypes.length > 0 && !c.allowedTypes.includes(effType)) {\n    const message = `File type '${effType}' is not allowed`;\n    throw new BackendError('validation', {\n      code: 'file_type_not_allowed',\n      message,\n      fields: [{ field: 'file', message }],\n    });\n  }\n}\n\nasync function buildHeaders(\n  rt: PalbeRuntime,\n  extra?: Record<string, string>,\n): Promise<Record<string, string>> {\n  // Pre-flight refresh: mirrors the pattern in request.ts / HttpClient.\n  if (\n    rt.tokenManager.isExpired() &&\n    rt.tokenManager.getRefreshToken() &&\n    rt.tokenManager.refreshFunction\n  ) {\n    try {\n      await rt.tokenManager.refreshSession();\n    } catch (e) {\n      const pe = asPalbaseError(e);\n      const status = pe?.status ?? 0;\n      if (status === 400 || status === 401 || status === 403) {\n        rt.tokenManager.clearSession(); // terminal — proceed unauthenticated\n      } else {\n        throw pe ? fromPalbaseError(pe) : e;\n      }\n    }\n  }\n\n  // Uploads bypass @palbase/core to stream multipart bodies. Kong derives the\n  // Environment identity from the API key, matching the iOS upload path.\n  const headers: Record<string, string> = {\n    apikey: rt.config.apiKey,\n    'X-Client-Info': `palbe-web/${VERSION}`,\n    ...rt.config.headers,\n  };\n  const token = rt.tokenManager.getAccessToken();\n  if (token) headers.Authorization = `Bearer ${token}`;\n  // Case-insensitive scan (mirrors request.ts): a caller-supplied\n  // `idempotency-key` in any casing must suppress generation.\n  const callerHasKey = Object.keys(extra ?? {}).some((k) => k.toLowerCase() === 'idempotency-key');\n  if (!callerHasKey) headers['Idempotency-Key'] = crypto.randomUUID();\n  // extra spreads LAST so a caller-pinned Authorization wins (HttpClient/iOS precedence).\n  const merged = { ...headers, ...extra };\n  applyBrowserOriginHeader(merged);\n  return merged;\n}\n\nfunction buildForm(options: UploadOptions): FormData {\n  const form = new FormData();\n  // The handler's own body travels as a SINGLE `body` part carrying JSON, not\n  // as loose form fields: storage reads exactly `r.FormValue(\"body\")` and hands\n  // that to the route's schema (`upload.go`, receiveUpload). One part per field\n  // was appended here and every one of them was dropped on the other side — the\n  // upload still answered 200 and the handler's `@Body` was `undefined`.\n  // Same folding as the iOS SDK (BackendUpload.swift): a caller who supplies\n  // `body` themselves has already encoded the envelope, so it is sent verbatim.\n  const { body, ...loose } = options.fields ?? {};\n  if (body !== undefined) form.append('body', body);\n  else if (Object.keys(loose).length > 0) form.append('body', JSON.stringify(loose));\n  const file =\n    options.contentType && options.file.type !== options.contentType\n      ? new Blob([options.file], { type: options.contentType })\n      : options.file;\n  const filename =\n    options.filename ??\n    (typeof File !== 'undefined' && options.file instanceof File ? options.file.name : 'file');\n  form.append('file', file, filename);\n  return form;\n}\n\nfunction decode<O>(status: number, text: string): O {\n  let body: unknown;\n  try {\n    body = text === '' ? null : JSON.parse(text);\n  } catch {\n    if (status >= 200 && status < 300) {\n      throw new BackendError('decode', {\n        code: 'decode_error',\n        message: 'Invalid JSON in response',\n        status,\n      });\n    }\n    body = text;\n  }\n  if (status < 200 || status >= 300) throw fromEnvelope(status, body);\n  return body as O;\n}\n\nfunction uploadViaXHR<O>(\n  url: string,\n  form: FormData,\n  headers: Record<string, string>,\n  options: UploadOptions,\n): Promise<O> {\n  return new Promise<O>((resolve, reject) => {\n    // Pre-aborted signal: never send. (xhr.abort() before send() fires no\n    // abort event per spec, so routing this through onabort would hang.)\n    if (options.signal?.aborted) {\n      reject(abortError());\n      return;\n    }\n    const xhr = new XMLHttpRequest();\n    xhr.open('POST', url);\n    for (const [k, v] of Object.entries(headers)) xhr.setRequestHeader(k, v);\n    xhr.upload.onprogress = (e: { lengthComputable: boolean; loaded: number; total: number }) => {\n      if (!e.lengthComputable) return;\n      options.onProgress?.({ sent: e.loaded, total: e.total });\n    };\n    const onAbort = () => xhr.abort();\n    const cleanup = () => options.signal?.removeEventListener('abort', onAbort);\n    xhr.onload = () => {\n      cleanup();\n      try {\n        resolve(decode<O>(xhr.status, xhr.responseText));\n      } catch (err) {\n        reject(err);\n      }\n    };\n    xhr.onerror = () => {\n      cleanup();\n      reject(new BackendError('network', { code: 'network_error', message: 'Upload failed' }));\n    };\n    xhr.onabort = () => {\n      cleanup();\n      reject(abortError());\n    };\n    options.signal?.addEventListener('abort', onAbort, { once: true });\n    xhr.send(form);\n  });\n}\n\nasync function uploadViaFetch<O>(\n  url: string,\n  form: FormData,\n  headers: Record<string, string>,\n  options: UploadOptions,\n): Promise<O> {\n  let res: Response;\n  try {\n    res = await fetch(url, { method: 'POST', body: form, headers, signal: options.signal });\n  } catch (e) {\n    // DOMException extends Error in modern runtimes — name check covers both.\n    if (e instanceof Error && e.name === 'AbortError') throw abortError();\n    throw new BackendError('network', {\n      code: 'network_error',\n      message: e instanceof Error ? e.message : 'Upload failed',\n    });\n  }\n  return decode<O>(res.status, await res.text());\n}\n\n/** Runtime resolution deferred behind `resolveRt` — see call.ts for the pattern. */\nexport async function uploadEndpoint<O>(\n  resolveRt: () => PalbeRuntime,\n  name: string,\n  options: UploadOptions,\n): Promise<O> {\n  const rt = resolveRt();\n  checkConstraints(options); // pre-send guard — rejects before any network I/O\n  // `name` is the tenant ROUTE, and the door is STORAGE's — storage authorizes\n  // against the route's own `@Upload` declaration, writes the bytes, renders\n  // the variants and only then calls the handler. Posting the multipart\n  // straight at the route is what the runtime refuses (\"this endpoint accepts\n  // uploads through storage, not directly\"), so every upload from a browser was\n  // a 401 no app could act on. Mirrors the iOS path (BackendUpload.swift).\n  const route = name.startsWith('/') ? name : `/${name}`;\n  const url = `${rt.config.url}${UPLOAD_PATH}${route}`;\n  const headers = await buildHeaders(rt, options.headers);\n  const form = buildForm(options);\n  const useXHR = options.onProgress !== undefined && typeof XMLHttpRequest !== 'undefined';\n  return useXHR\n    ? uploadViaXHR<O>(url, form, headers, options)\n    : uploadViaFetch<O>(url, form, headers, options);\n}\n","import type { PalbeAnalytics } from './analytics-facade.js';\nimport type { PalbeAuth } from './auth-facade.js';\nimport { callEndpoint } from './call.js';\nimport type { PalbeCalls } from './calls/facade.js';\nimport type { PalbeFlags } from './flags-facade.js';\nimport { getRuntime } from './internal.js';\nimport type { PalbeMessaging } from './messaging/facade.js';\nimport { boundNamespaceAccessor, getNamespace, getRegistry } from './namespaces.js';\nimport type { PalbePerf } from './perf/perf-facade.js';\nimport type { PalbeRealtime } from './realtime/facade.js';\nimport type { CallOptions } from './request.js';\nimport { joinRoom, type RoomDescriptor, type RoomHandle } from './room.js';\nimport type { PalbeRuntime } from './runtime.js';\nimport type { UploadOptions } from './upload.js';\nimport { uploadEndpoint } from './upload.js';\n\n/**\n * The Palbe surface. Codegen augments this interface with typed endpoint\n * namespaces:  declare module '@palbase/web' { interface PB { rooms: ... } }\n */\nexport interface PB {\n  call<O = unknown>(name: string, input?: unknown, options?: CallOptions): Promise<O>;\n  upload<O = unknown>(name: string, options: UploadOptions): Promise<O>;\n  readonly auth: PalbeAuth;\n  readonly flags: PalbeFlags;\n  readonly realtime: PalbeRealtime;\n  /**\n   * Join a room the backend declared with `@Room`.\n   *\n   *     const room = pb.join(AiSessionIdRoom, { sessionId })\n   *     const token = room.on((e) => { … })\n   *     room.send('say', { text: 'hello' })\n   *\n   * The descriptor is GENERATED: the pattern, the event names and the message\n   * names all come from the backend's declaration, so the app writes no channel\n   * string and no payload type of its own.\n   */\n  join<E extends { event: string; payload: unknown }, S, P extends readonly string[]>(\n    descriptor: RoomDescriptor<E, S, P>,\n    params: Record<P[number], string>,\n  ): RoomHandle<E, S>;\n  readonly analytics: PalbeAnalytics;\n  readonly calls: PalbeCalls;\n  readonly messaging: PalbeMessaging;\n  /** The PalPerf surface: custom traces (`startTrace`) + the buffered flush of\n   * network/app-start/custom items. `pb.perf.record(...)` is also how the\n   * runtime feeds the cold-start measurement in. */\n  readonly perf: PalbePerf;\n  /** Mark (or unmark) this client's traffic as test — flips the facade's flag\n   * so every subsequent perf flush carries `X-Palbase-Test-Device: 1` (the\n   * SAME header the iOS SDK sends; the server reads it → `is_test_traffic`). */\n  setTestDevice(on: boolean): void;\n}\n\n/**\n * One proxy construction for BOTH client flavors:\n * - global `pb`: resolveRt = getRuntime (late-bound — a __configure swap is\n *   visible to every subsequent call), nsAccessor = the globally-cached path;\n * - bound clients: resolveRt = () => rt (captured once, immune to global\n *   swaps), nsAccessor = a per-client cache (see namespaces.ts).\n */\nfunction createClientProxy(\n  resolveRt: () => PalbeRuntime,\n  nsAccessor: (name: string) => unknown,\n): PB {\n  const base = {\n    call<O = unknown>(name: string, input?: unknown, options?: CallOptions): Promise<O> {\n      return callEndpoint<O>(resolveRt, name, input, options);\n    },\n    upload<O = unknown>(name: string, options: UploadOptions): Promise<O> {\n      return uploadEndpoint<O>(resolveRt, name, options);\n    },\n    get auth(): PalbeAuth {\n      return resolveRt().auth;\n    },\n    get flags(): PalbeFlags {\n      return resolveRt().flags;\n    },\n    get realtime(): PalbeRealtime {\n      return resolveRt().realtime;\n    },\n    /**\n     * Join a room the backend declared with `@Room`.\n     *\n     *     const room = pb.join(AiSessionIdRoom, { sessionId })\n     *     const token = room.on((e) => {\n     *       switch (e.event) {\n     *         case 'token': transcript.push(e.payload.text); break\n     *         case 'done':  finish(e.payload.reason); break\n     *       }\n     *     })\n     *     room.send('say', { text: 'hello' })\n     *     room.off(token)\n     *\n     * The descriptor is GENERATED, so the app writes no channel string and no\n     * payload type of its own. Several handles on the same room share ONE\n     * subscription and the room is left when the last one goes \\u2014 the socket's\n     * own refcount, not a second one.\n     */\n    join<E extends { event: string; payload: unknown }, S, P extends readonly string[]>(\n      descriptor: RoomDescriptor<E, S, P>,\n      params: Record<P[number], string>,\n    ): RoomHandle<E, S> {\n      const realtime = resolveRt().realtime;\n      return joinRoom(descriptor, params, {\n        subscribe(topic, event, handler) {\n          const sub = realtime.subscribe(topic, event, handler);\n          return () => sub.cancel();\n        },\n        send(topic, event, payload) {\n          realtime.send(topic, event, payload);\n        },\n      });\n    },\n    get analytics(): PalbeAnalytics {\n      return resolveRt().analytics;\n    },\n    get calls(): PalbeCalls {\n      return resolveRt().calls;\n    },\n    get messaging(): PalbeMessaging {\n      return resolveRt().messaging;\n    },\n    get perf(): PalbePerf {\n      return resolveRt().perf;\n    },\n    setTestDevice(on: boolean): void {\n      resolveRt().perf.setTestDevice(on);\n    },\n  };\n  return new Proxy(base, {\n    get(target, prop, receiver) {\n      if (prop in target) return Reflect.get(target, prop, receiver);\n      // `then` must NEVER resolve to a namespace: a thenable pb would make\n      // `await pb` (or Promise.resolve(pb)) hang on the proxy. Registration\n      // also rejects it (see namespaces.ts) — this is defense in depth.\n      if (prop === 'then') return undefined;\n      if (typeof prop === 'string') {\n        const ns = nsAccessor(prop);\n        if (ns !== undefined) return ns;\n      }\n      return undefined;\n    },\n    has(target, prop) {\n      if (prop in target) return true;\n      return typeof prop === 'string' && prop !== 'then' && getRegistry()[prop] !== undefined;\n    },\n  }) as PB;\n}\n\nexport const pb: PB = createClientProxy(getRuntime, getNamespace);\n\n/**\n * A `PB` client permanently bound to ONE runtime — typed namespaces, `call`,\n * `upload` and `auth` all resolve `rt`, NEVER the global slot. This is the\n * per-request isolation primitive for server adapters (palbe/next pbServer):\n * two bound clients serving concurrent requests cannot leak each other's\n * sessions, and global `__configure` swaps don't touch them.\n */\nexport function createBoundClient(rt: PalbeRuntime): PB {\n  return createClientProxy(() => rt, boundNamespaceAccessor(rt));\n}\n"],"mappings":"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","names":["crypto","webcrypto","webcrypto","enc","isLE","adjustScalarBytes","isLE","isAligned32","enc","__classPrivateFieldGet","__classPrivateFieldSet","__classPrivateFieldGet","__classPrivateFieldSet","enc","enc","_1n","_2n","HkdfSha256","X25519","DhkemX25519HkdfSha256","HkdfSha256","isBytes","anumber","abytes","aexists","aoutput","abytes","clean","createView","hasHexBuiltin","hexes","bytesToHex","abytes","asciis","asciiToBase16","hexToBytes","abytes","abytes","createHasher","crypto","isLE","_32n","HashMD","isLE","createView","aexists","abytes","aoutput","clean","SHA512_IV","U32_MASK64","_32n","fromBig","split","shrSH","shrSL","rotrSH","rotrSL","rotrBH","rotrBL","add","add3L","add3H","add4L","add4H","add5L","add5H","split","HashMD","SHA512_IV","rotrSH","shrSH","rotrSL","shrSL","rotrBH","rotrBL","add4L","add4H","add5L","add5H","add","add3L","add3H","clean","sha512","createHasher","_0n","_1n","isBytes","hexToNumber","_0n","bytesToHex","bytesToNumberLE","abytes","numberToBytesBE","hexToBytes","numberToBytesLE","hexToBytes","isBytes","equalBytes","copyBytes","isPosBig","_0n","inRange","aInRange","_1n","_1n","_0n","_1n","_2n","_3n","_5n","_7n","mod","pow2","_0n","mod","_1n","Fp","_5n","_2n","_7n","_3n","Fp","_1n","_2n","anumber","isLE","_0n","_1n","mod","numberToBytesLE","numberToBytesBE","bytesToNumberLE","_0n","_1n","window","wbits","isLE","_0n","Fp","Fn","_0n","_1n","_2n","_8n","Fp","Fn","uvRatio","aInRange","copyBytes","bytesToNumberLE","p","bytesToHex","randomBytes","adjustScalarBytes","isBytes","eddsa","_0n","_1n","_2n","_3n","_5n","_8n","ed25519_CURVE_p","ed25519_pow_2_252_3","pow2","adjustScalarBytes","mod","sha512","_1n","bytesToNumberLE","ed25519_CURVE_p","mod","abytes","equalBytes","_0n","mod","encoder","DhkemX25519HkdfSha256","headers","now","seg","decoder","headers","text","record","base64UrlToBytes","record","value","client","validatePathParam","PalbaseError","toBase64","fromBase64","bytesToHex","toBase64","toBase64","fromBase64","text","text","orderLte","text","fromBase64","toBase64","text","add","ptr","module","toBytes","generateClient","bytesToHex","generateClient","bytesToHex","chat","text","utf8","headers","PERF_EXCLUDED_PREFIX","nowMs","FLUSH_AT","FLUSH_INTERVAL_MS","nowMs","headers","record","headers","headers","text","ready","text","after","headers","seg","headers","text"]}