@klum-db/lobby 0.2.0-pre.30 → 0.2.0-pre.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bundle/uint32.ts","../src/bundle/multi-bundle.ts","../src/interchange/extract-cross-vault.ts","../src/interchange/field-authority.ts","../src/interchange/merge-compartment.ts","../src/interchange/stage-records.ts","../src/dock/graduate.ts","../src/interchange/surface.ts","../src/federation/schema-manifest.ts","../src/federation/constants.ts","../src/federation/state-vault.ts","../src/federation/classify-skip.ts","../src/federation/cross-shard-join.ts","../src/federation/cross-vault-live.ts","../src/federation/insight-auto-push.ts","../src/federation/aggregate-across.ts","../src/federation/vault-group.ts","../src/index.ts","../src/dock/docked-unit.ts","../src/federation/group-inspector.ts","../src/federation/meter-group.ts","../src/interchange/migrate-then-merge.ts","../src/dock/unit-driver.ts","../src/dock/index.ts"],"sourcesContent":["/**\n * Big-endian uint32 codec for the NDBM outer container's length fields.\n * The multi-bundle framing is klum's own format; these are local so noy-db\n * need not expose low-level byte utilities.\n * @module\n */\n\n/** Read a big-endian uint32 from `bytes` at `offset`. */\nexport function readUint32BE(bytes: Uint8Array, offset: number): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>> 0\n )\n}\n\n/** Write `value` as a big-endian uint32 into `bytes` at `offset`. */\nexport function writeUint32BE(bytes: Uint8Array, offset: number, value: number): void {\n bytes[offset] = (value >>> 24) & 0xff\n bytes[offset + 1] = (value >>> 16) & 0xff\n bytes[offset + 2] = (value >>> 8) & 0xff\n bytes[offset + 3] = value & 0xff\n}\n","/**\n * Multi-compartment `.noydb` bundle (`NDBM`). A thin outer container\n * that embeds N standard single-vault `.noydb` bundles plus an\n * unencrypted, owner-curated **manifest**. The v1 single-vault format\n * is untouched; each compartment is a complete v1 bundle, produced by\n * `writeNoydbBundle` and read by `readNoydbBundle`.\n *\n * Layout: magic 'NDBM'(4) · version(1) · reserved(1) · manifestLen(4 BE)\n * · manifest JSON · concat(inner v1 bundles, in manifest order).\n *\n * @packageDocumentation\n */\nimport { sha256Hex, generateULID, type Vault } from '@noy-db/hub/kernel'\nimport {\n writeNoydbBundle,\n readNoydbBundleHeader,\n type WriteNoydbBundleOptions,\n} from '@noy-db/hub/bundle'\nimport {\n readNoydbBundlePublicEnvelope,\n hasNoydbBundleMagic,\n type PublicEnvelope,\n} from '@noy-db/hub'\nimport { readUint32BE, writeUint32BE } from './uint32.js'\n\n/** Magic bytes 'NDBM' — NOYDB Multi-compartment bundle. */\nexport const NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([0x4e, 0x44, 0x42, 0x4d])\n/** Fixed prefix: magic(4) + version(1) + reserved(1) + manifestLen(4). */\nexport const NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10\n/** Current multi-bundle layout version. */\nexport const NOYDB_MULTI_BUNDLE_VERSION = 1\n\n/** One compartment's entry in the pre-decrypt manifest. */\nexport interface CompartmentManifest {\n /** The inner v1 bundle's stable ULID handle. */\n readonly handle: string\n /** Owner-curated classification (e.g. 'shard', 'pool'). Opt-in. */\n readonly roleTag?: string\n /** ISO export timestamp. Always set by the writer; absent for a v1 bundle read as a 1-entry manifest. */\n readonly exportedAt?: string\n /** Compartment (vault) name. Opt-in disclosure. */\n readonly name?: string\n /** Collection names + record counts. Opt-in disclosure. */\n readonly collections?: readonly { readonly name: string; readonly count: number }[]\n /** Inner bundle's owner-curated public envelope, surfaced. Opt-in. */\n readonly publicEnvelope?: PublicEnvelope\n /** Byte length of the inner v1 bundle (drives framing). */\n readonly innerBytes: number\n /** SHA-256 (lowercase hex) of the inner v1 bundle bytes — pre-decrypt integrity. */\n readonly innerSha256: string\n /** Source vault's schema fence version at extract time (FR-8). Opt-in; absent on older bundles. */\n readonly schemaVersion?: number\n}\n\n/** The unencrypted manifest of a multi-compartment bundle. */\nexport interface MultiBundleManifest {\n readonly multiFormatVersion: number\n /** Opaque ULID for the outer container. */\n readonly handle: string\n readonly compartments: readonly CompartmentManifest[]\n}\n\n/** Assemble the `NDBM` container from a manifest + inner bundle bytes (in manifest order). */\nexport function encodeMultiBundle(\n manifest: MultiBundleManifest,\n inner: readonly Uint8Array[],\n): Uint8Array {\n validateManifest(manifest)\n if (manifest.compartments.length !== inner.length) {\n throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`)\n }\n for (let i = 0; i < inner.length; i++) {\n if (manifest.compartments[i]!.innerBytes !== inner[i]!.length) {\n throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i]!.innerBytes} but ${inner[i]!.length} bytes were provided.`)\n }\n }\n const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest))\n const bodyLen = inner.reduce((n, b) => n + b.length, 0)\n const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen)\n out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0)\n out[4] = NOYDB_MULTI_BUNDLE_VERSION\n out[5] = 0\n writeUint32BE(out, 6, manifestBytes.length)\n out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES)\n let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length\n for (const b of inner) { out.set(b, off); off += b.length }\n return out\n}\n\nfunction hasMultiMagic(bytes: Uint8Array): boolean {\n if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false\n for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false\n return true\n}\n\nfunction validateManifest(parsed: unknown): asserts parsed is MultiBundleManifest {\n if (parsed === null || typeof parsed !== 'object') throw new Error('multi-bundle manifest must be a JSON object.')\n const m = parsed as Record<string, unknown>\n if (m['multiFormatVersion'] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m['multiFormatVersion'])}.`)\n if (typeof m['handle'] !== 'string' || m['handle'].length === 0) throw new Error('multi-bundle manifest.handle must be a non-empty string.')\n if (!Array.isArray(m['compartments'])) throw new Error('multi-bundle manifest.compartments must be an array.')\n const seenHandles = new Set<string>()\n for (const c of m['compartments'] as unknown[]) {\n if (c === null || typeof c !== 'object') throw new Error('multi-bundle compartment must be an object.')\n const e = c as Record<string, unknown>\n if (typeof e['handle'] !== 'string' || e['handle'].length === 0) throw new Error('multi-bundle compartment.handle must be a non-empty string.')\n if (seenHandles.has(e['handle'])) {\n throw new Error(`multi-bundle manifest has a duplicate compartment handle \"${e['handle']}\".`)\n }\n seenHandles.add(e['handle'])\n if (typeof e['innerBytes'] !== 'number' || !Number.isInteger(e['innerBytes']) || e['innerBytes'] < 0) throw new Error('multi-bundle compartment.innerBytes must be a non-negative integer.')\n if (typeof e['innerSha256'] !== 'string' || !/^[0-9a-f]{64}$/.test(e['innerSha256'])) throw new Error('multi-bundle compartment.innerSha256 must be 64-char lowercase hex.')\n }\n}\n\n/** Parse the `NDBM` container into its manifest + raw inner bundle byte slices. */\nexport function decodeMultiBundle(bytes: Uint8Array): { manifest: MultiBundleManifest; inner: Uint8Array[] } {\n if (!hasMultiMagic(bytes)) throw new Error('not a NOYDB multi-bundle: missing NDBM magic.')\n if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error('multi-bundle truncated: shorter than the fixed prefix.')\n if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`)\n const manifestLen = readUint32BE(bytes, 6)\n const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen\n if (manifestEnd > bytes.length) throw new Error('multi-bundle truncated: manifest length overruns the buffer.')\n const manifestJson = new TextDecoder('utf-8', { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd))\n let parsed: unknown\n try { parsed = JSON.parse(manifestJson) } catch (err) { throw new Error(`multi-bundle manifest is not valid JSON: ${(err as Error).message}`) }\n validateManifest(parsed)\n const inner: Uint8Array[] = []\n let off = manifestEnd\n for (const c of parsed.compartments) {\n const end = off + c.innerBytes\n if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment \"${c.handle}\" innerBytes overruns the buffer.`)\n inner.push(bytes.subarray(off, end))\n off = end\n }\n if (off !== bytes.length) {\n throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment — buffer may be corrupt.`)\n }\n return { manifest: parsed, inner }\n}\n\n/** Per-compartment input to {@link writeMultiVaultBundle}. */\nexport interface MultiVaultCompartmentInput {\n readonly vault: Vault\n /** Owner-curated classification surfaced in the manifest (e.g. 'shard', 'pool'). */\n readonly roleTag?: string\n /** ISO timestamp for the manifest; defaults to now. */\n readonly exportedAt?: string\n /** Opt-in pre-decrypt disclosure for this compartment. */\n readonly disclose?: {\n /** `true` → use `vault.name`; a string → that explicit name. */\n readonly name?: boolean | string\n /** `true` → include collection names + record counts. */\n readonly collections?: boolean\n /** `true` → surface the inner bundle's public envelope into the manifest. */\n readonly publicEnvelope?: boolean\n }\n /** Options forwarded to `writeNoydbBundle` for this compartment's inner bundle. */\n readonly bundleOptions?: WriteNoydbBundleOptions\n}\n\n/** Write N vaults into one `NDBM` multi-compartment bundle. */\nexport async function writeMultiVaultBundle(\n compartments: readonly MultiVaultCompartmentInput[],\n opts: { readonly handle?: string } = {},\n): Promise<Uint8Array> {\n if (compartments.length === 0) throw new Error('writeMultiVaultBundle: at least one compartment is required.')\n const inner: Uint8Array[] = []\n const entries: CompartmentManifest[] = []\n for (const c of compartments) {\n const innerBytes = await writeNoydbBundle(c.vault, c.bundleOptions ?? {})\n const header = readNoydbBundleHeader(innerBytes)\n const entry: {\n -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K]\n } = {\n handle: header.handle,\n exportedAt: c.exportedAt ?? new Date().toISOString(),\n innerBytes: innerBytes.length,\n innerSha256: await sha256Hex(innerBytes),\n }\n if (c.roleTag !== undefined) entry.roleTag = c.roleTag\n if (c.disclose?.name !== undefined && c.disclose.name !== false) {\n entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name\n }\n if (c.disclose?.collections === true) {\n const names = await c.vault.collections()\n entry.collections = await Promise.all(\n names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() })),\n )\n }\n if (c.disclose?.publicEnvelope === true) {\n const env = readNoydbBundlePublicEnvelope(innerBytes)\n if (env !== undefined) entry.publicEnvelope = env\n }\n // FR-8: stamp schema fence version so the bundle self-describes its version.\n const fence = await c.vault.schemaFenceState()\n entry.schemaVersion = fence.currentSchemaVersion\n inner.push(innerBytes)\n entries.push(entry)\n }\n const manifest: MultiBundleManifest = {\n multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,\n handle: opts.handle ?? generateULID(),\n compartments: entries,\n }\n return encodeMultiBundle(manifest, inner)\n}\n\n/**\n * Read the pre-decrypt manifest of a bundle WITHOUT decrypting any\n * compartment. Accepts a multi-compartment `NDBM` bundle (returns its\n * N entries) OR a single v1 `NDB1` bundle (returns a 1-entry manifest,\n * for uniform handling). Throws on anything else.\n */\nexport async function readNoydbBundleManifest(bytes: Uint8Array): Promise<CompartmentManifest[]> {\n if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments]\n if (hasNoydbBundleMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n const env = readNoydbBundlePublicEnvelope(bytes)\n const entry: { -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K] } = {\n handle: header.handle,\n innerBytes: bytes.length,\n innerSha256: await sha256Hex(bytes),\n }\n if (env !== undefined) entry.publicEnvelope = env\n return [entry]\n }\n throw new Error('readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).')\n}\n\n/**\n * Extract one compartment's inner v1 `.noydb` bundle bytes, ready to\n * pass to `readNoydbBundle`. `selector` is a compartment `handle` or a\n * zero-based index. For a single v1 bundle, the bundle itself is the\n * only compartment.\n *\n * Does NOT verify the manifest `innerSha256` — it returns the raw\n * slice. Integrity is enforced downstream: `readNoydbBundle` verifies\n * the inner bundle's own `bodySha256`. Callers wanting an early,\n * pre-decrypt check can hash the returned bytes against the\n * compartment's `innerSha256`.\n */\nexport function readMultiVaultBundleCompartment(bytes: Uint8Array, selector: string | number): Uint8Array {\n if (typeof selector === 'number' && !Number.isInteger(selector)) {\n throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`)\n }\n if (hasNoydbBundleMagic(bytes) && !hasMultiMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n if (selector === 0 || selector === header.handle) return bytes\n throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment \"${header.handle}\".`)\n }\n const { manifest, inner } = decodeMultiBundle(bytes)\n const idx = typeof selector === 'number'\n ? selector\n : manifest.compartments.findIndex((c) => c.handle === selector)\n if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === 'number' ? `at index ${selector}` : `\"${selector}\"`}.`)\n return inner[idx]!\n}\n","/**\n * @klum-db/lobby interchange — cross-vault FK-closure extraction.\n * Composes hub's intra-vault primitives + FR-1's encodeMultiBundle.\n * @packageDocumentation\n */\nimport type { Vault } from '@noy-db/hub'\nimport {\n walkClosure,\n extractPartition,\n readNoydbBundleHeader,\n describeExtraction,\n type ExtractionPreview,\n} from '@noy-db/hub/bundle'\nimport { sha256Hex, generateULID } from '@noy-db/hub/kernel'\nimport {\n encodeMultiBundle,\n NOYDB_MULTI_BUNDLE_VERSION,\n type MultiBundleManifest,\n type CompartmentManifest,\n} from '../bundle/multi-bundle.js'\n\n/** A denormalized cross-vault FK edge (hub refuses these as native refs). */\nexport interface CrossVaultRef {\n readonly from: { readonly collection: string; readonly field: string }\n readonly to: {\n readonly vault: string\n readonly collection: string\n /**\n * Target field the FK points to. **Currently must be `'id'` (or omitted).**\n * Non-`id` business-key target fields are not yet supported (will be added\n * when adopt/merge lands).\n */\n readonly field?: string\n }\n}\n\n/** Seed for the primary vault (predicate per collection, like hub walkClosure). */\nexport interface CrossVaultSeed {\n readonly vault: string\n readonly seeds: Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>\n}\n\nexport interface CrossVaultClosurePlan {\n /** vault → seed predicates to feed extractPartition (primary: caller's; targets: id-membership). */\n readonly perVaultSeeds: Map<string, Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>>\n /** vault → intra closure (collection → ids). */\n readonly perVaultClosure: Map<string, Map<string, Set<string>>>\n /** referenced rows not found in their target closure. */\n readonly dangling: { vault: string; collection: string; id: string }[]\n}\n\nfunction asIdArray(v: unknown): string[] {\n if (v === null || v === undefined) return []\n if (Array.isArray(v)) return v.filter((x) => typeof x === 'string' || typeof x === 'number').map(String)\n if (typeof v === 'string' || typeof v === 'number') return [String(v)]\n return []\n}\n\n/**\n * Walk an FK closure that spans vault boundaries via app-supplied cross-vault refs.\n *\n * @param openVault - resolver for a vault by name (idempotent in the hub —\n * repeated calls return the same cached instance, so the per-round calls are free).\n * @param opts.maxDepth - bounds BOTH the number of inter-vault rounds (this planner's\n * outer fixpoint loop) AND hub's intra-vault `walkClosure` FK depth. Default 16.\n */\nexport async function walkCrossVaultClosure(\n openVault: (name: string) => Promise<Vault>,\n opts: { seed: CrossVaultSeed; crossVaultRefs?: readonly CrossVaultRef[]; maxDepth?: number },\n): Promise<CrossVaultClosurePlan> {\n const refs = opts.crossVaultRefs ?? []\n const maxDepth = opts.maxDepth ?? 16\n\n // Guard: non-id target fields are silently broken (dangling false-positives + fixpoint burn).\n // Fail loud until business-key target support is added with adopt/merge.\n for (const ref of refs) {\n if (ref.to.field !== undefined && ref.to.field !== 'id') {\n throw new Error(\n `cross-vault extraction: to.field \"${ref.to.field}\" (on ${ref.to.vault}/${ref.to.collection}) is not supported yet — `\n + `the cross-vault target field must be \"id\" (or omitted). Business-key target fields are a future enhancement.`,\n )\n }\n }\n\n const perVaultClosure = new Map<string, Map<string, Set<string>>>()\n const perVaultSeeds: CrossVaultClosurePlan['perVaultSeeds'] = new Map()\n // accumulated referenced ids per target vault+collection\n const targetIds = new Map<string, Map<string, Set<string>>>()\n\n const addTarget = (v: string, c: string, id: string) => {\n let m = targetIds.get(v)\n if (!m) { m = new Map(); targetIds.set(v, m) }\n let s = m.get(c)\n if (!s) { s = new Set(); m.set(c, s) }\n s.add(id)\n }\n\n const mergeClosure = (v: string, cl: Map<string, Set<string>>) => {\n let dest = perVaultClosure.get(v)\n if (!dest) { dest = new Map(); perVaultClosure.set(v, dest) }\n for (const [c, ids] of cl) {\n let s = dest.get(c)\n if (!s) { s = new Set(); dest.set(c, s) }\n for (const id of ids) s.add(id)\n }\n }\n\n // round 0: primary vault\n perVaultSeeds.set(opts.seed.vault, opts.seed.seeds)\n const queue: string[] = [opts.seed.vault]\n const walkedSignature = new Set<string>()\n\n let round = 0\n while (queue.length > 0) {\n if (round++ > maxDepth) break\n const batch = queue.splice(0, queue.length)\n for (const vaultName of batch) {\n const seeds = perVaultSeeds.get(vaultName)!\n const v = await openVault(vaultName)\n const { closure } = await walkClosure(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n mergeClosure(vaultName, closure)\n // harvest cross-vault FKs from this vault's closure\n for (const ref of refs) {\n const ids = closure.get(ref.from.collection)\n if (!ids) continue\n const coll = v.collection<Record<string, unknown>>(ref.from.collection)\n for (const id of ids) {\n const rec = await coll.get(id)\n for (const fk of asIdArray(rec?.[ref.from.field])) {\n addTarget(ref.to.vault, ref.to.collection, fk)\n }\n }\n }\n }\n // enqueue targets whose id-set introduces records not yet in their closure\n for (const [tVault, colls] of targetIds) {\n for (const [tColl, ids] of colls) {\n const field = refs.find((r) => r.to.vault === tVault && r.to.collection === tColl)?.to.field ?? 'id'\n const have = perVaultClosure.get(tVault)?.get(tColl) ?? new Set<string>()\n const sig = `${tVault}\\0${tColl}\\0${[...ids].sort().join(',')}`\n if ([...ids].every((id) => have.has(id)) || walkedSignature.has(sig)) continue\n // Stamp before enqueue; safe because harvest is sequential — no other FK\n // accumulation can extend targetIds between this stamp and the next round.\n walkedSignature.add(sig)\n const wanted = new Set(ids)\n const seed = { [tColl]: (rec: Record<string, unknown>) => wanted.has(String(rec[field])) }\n const existing = perVaultSeeds.get(tVault)\n // `wanted` is always the full cumulative targetIds set for this collection,\n // so overwriting an existing predicate for tColl is safe and idempotent.\n perVaultSeeds.set(tVault, existing ? { ...existing, ...seed } : seed)\n queue.push(tVault)\n }\n }\n }\n\n // dangling check: every harvested target id must appear in the final closure\n const dangling: CrossVaultClosurePlan['dangling'] = []\n for (const [tVault, colls] of targetIds) {\n for (const [tColl, ids] of colls) {\n const have = perVaultClosure.get(tVault)?.get(tColl) ?? new Set<string>()\n for (const id of ids) {\n if (!have.has(id)) dangling.push({ vault: tVault, collection: tColl, id })\n }\n }\n }\n\n return { perVaultSeeds, perVaultClosure, dangling }\n}\n\n// ─── Task 2: extractCrossVaultPartition ────────────────────────────────────────\n\nexport class CrossVaultDanglingRefError extends Error {\n constructor(readonly dangling: { vault: string; collection: string; id: string }[]) {\n super(\n `cross-vault extraction: ${dangling.length} referenced row(s) missing from their target closure: `\n + dangling.slice(0, 5).map((d) => `${d.vault}/${d.collection}/${d.id}`).join(', '),\n )\n this.name = 'CrossVaultDanglingRefError'\n }\n}\n\nexport interface CompartmentMeta {\n readonly roleTag?: string\n readonly disclose?: {\n readonly name?: boolean | string\n readonly collections?: boolean\n }\n}\n\nexport interface ExtractCrossVaultOptions {\n readonly seed: CrossVaultSeed\n readonly crossVaultRefs?: readonly CrossVaultRef[]\n readonly maxDepth?: number\n readonly carrySchemas?: boolean\n readonly carryLedger?: boolean\n readonly compression?: 'auto' | 'brotli' | 'gzip' | 'none'\n readonly compartmentMeta?: Record<string, CompartmentMeta>\n}\n\nexport interface ExtractCrossVaultResult {\n readonly bundle: Uint8Array\n /**\n * Per-compartment raw 32-byte transfer keys, keyed by vault name. Each\n * unseals that compartment's DEKs on adoption.\n * @remarks SECRET — deliver these out-of-band, SEPARATELY from `bundle`.\n * Anyone with both the bundle and a compartment's key can decrypt that\n * compartment. Never store them alongside the bundle.\n */\n readonly transferKeys: Record<string, Uint8Array>\n readonly sealIds: Record<string, string>\n}\n\nexport async function extractCrossVaultPartition(\n openVault: (name: string) => Promise<Vault>,\n opts: ExtractCrossVaultOptions,\n): Promise<ExtractCrossVaultResult> {\n const plan = await walkCrossVaultClosure(openVault, opts)\n if (plan.dangling.length > 0) throw new CrossVaultDanglingRefError(plan.dangling)\n\n const inner: Uint8Array[] = []\n const compartments: CompartmentManifest[] = []\n const transferKeys: Record<string, Uint8Array> = {}\n const sealIds: Record<string, string> = {}\n\n for (const [vaultName, seeds] of plan.perVaultSeeds) {\n const v = await openVault(vaultName)\n const { bundleBytes, transferKey, sealId } = await extractPartition(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n carrySchemas: opts.carrySchemas ?? true,\n carryLedger: opts.carryLedger ?? false,\n ...(opts.compression !== undefined ? { compression: opts.compression } : {}),\n })\n\n const header = readNoydbBundleHeader(bundleBytes)\n const meta = opts.compartmentMeta?.[vaultName]\n\n const entry: { -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K] } = {\n handle: header.handle,\n exportedAt: new Date().toISOString(),\n innerBytes: bundleBytes.length,\n innerSha256: await sha256Hex(bundleBytes),\n }\n\n if (meta?.roleTag !== undefined) entry.roleTag = meta.roleTag\n if (meta?.disclose?.name !== undefined && meta.disclose.name !== false) {\n entry.name = meta.disclose.name === true ? v.name : meta.disclose.name\n }\n if (meta?.disclose?.collections === true) {\n const cl = plan.perVaultClosure.get(vaultName)\n // `ids.size` reflects the EXTRACTED CLOSURE SLICE for this vault (the subset\n // selected by the cross-vault FK walk), NOT the full vault record count.\n // This differs from FR-1's writeMultiVaultBundle which counts the full vault.\n if (cl) entry.collections = [...cl].map(([name, ids]) => ({ name, count: ids.size }))\n }\n\n // FR-8: stamp the source vault's schema fence version so the bundle self-describes its version.\n const fence = await v.schemaFenceState()\n entry.schemaVersion = fence.currentSchemaVersion\n\n inner.push(bundleBytes)\n compartments.push(entry)\n transferKeys[vaultName] = transferKey\n sealIds[vaultName] = sealId\n }\n\n const manifest: MultiBundleManifest = {\n multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,\n handle: generateULID(),\n compartments,\n }\n return { bundle: encodeMultiBundle(manifest, inner), transferKeys, sealIds }\n}\n\n// ─── Task 3: describeCrossVaultExtraction ────────────────────────────────────\n\nexport interface CrossVaultPreview {\n readonly compartments: ReadonlyArray<{ readonly vault: string; readonly preview: ExtractionPreview }>\n readonly dangling: ReadonlyArray<{ readonly vault: string; readonly collection: string; readonly id: string }>\n}\n\n/**\n * Dry-run that walks the cross-vault FK closure and aggregates hub's per-vault\n * `describeExtraction` into a per-compartment preview.\n *\n * Writes nothing. Returns the per-vault `ExtractionPreview` (record counts,\n * byte totals) and the dangling list from the closure walk.\n */\nexport async function describeCrossVaultExtraction(\n openVault: (name: string) => Promise<Vault>,\n opts: { seed: CrossVaultSeed; crossVaultRefs?: readonly CrossVaultRef[]; maxDepth?: number },\n): Promise<CrossVaultPreview> {\n const plan = await walkCrossVaultClosure(openVault, opts)\n const compartments: Array<{ vault: string; preview: ExtractionPreview }> = []\n for (const [vaultName, seeds] of plan.perVaultSeeds) {\n const v = await openVault(vaultName)\n const preview = await describeExtraction(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n compartments.push({ vault: vaultName, preview })\n }\n return { compartments, dangling: plan.dangling }\n}\n","/**\n * @klum-db/lobby interchange — field-authority conflict resolution (FR-4).\n *\n * Pure functions: given an app-supplied per-field policy and both sides'\n * RECORD-level provenance (FR-5 `_source`/`_sourceTs`), decide field-by-field\n * whether the incoming value wins. No vault I/O — unit-testable in isolation.\n * @module\n */\n\n/** How a single field's authority is decided on merge. */\nexport type FieldAuthorityRule =\n | { readonly authority: 'source-newest' }\n | { readonly authority: 'owner'; readonly ownerSource: string }\n | { readonly authority: 'fixed-source'; readonly source: string }\n\n/** Per-collection field → rule map. Fields not listed default to keep-local. */\nexport type FieldAuthorityPolicy = Record<string, FieldAuthorityRule>\n\n/** Record-level provenance for both sides (shared across all fields — Q3 defer). */\nexport interface FieldAuthorityInputs {\n readonly incomingSource?: string\n readonly incomingSourceTs?: string\n readonly localSource?: string\n readonly localSourceTs?: string\n}\n\n/** Thrown when a collection resolves to `field-authority` but no policy is supplied for it. */\nexport class FieldAuthorityPolicyMissingError extends Error {\n constructor(collection: string) {\n super(\n `mergeCompartment: the 'field-authority' strategy for \"${collection}\" requires a ` +\n `fieldAuthority policy entry for that collection, but none was supplied.`,\n )\n this.name = 'FieldAuthorityPolicyMissingError'\n }\n}\n\n/** Decide whether the INCOMING value of one field wins. Pure. Defaults never clobber on ambiguity. */\nexport function resolveFieldAuthority(\n rule: FieldAuthorityRule,\n io: FieldAuthorityInputs,\n): 'incoming' | 'local' {\n switch (rule.authority) {\n case 'source-newest': {\n const inc = io.incomingSourceTs\n const loc = io.localSourceTs\n if (inc === undefined) return 'local' // no incoming provenance → don't clobber\n if (loc === undefined) return 'incoming' // local has none, incoming does\n return inc > loc ? 'incoming' : 'local' // ISO-8601 lexicographic; tie → local\n }\n case 'owner':\n return io.incomingSource === rule.ownerSource ? 'incoming' : 'local'\n case 'fixed-source':\n return io.incomingSource === rule.source ? 'incoming' : 'local'\n }\n}\n\n/**\n * Build the merged record per policy, starting from the local (`before`) copy\n * and overlaying only the changed fields whose rule resolves to `incoming`.\n * Returns the merged record plus a per-field decision map (for the audit report).\n * Pure — no I/O.\n */\nexport function resolveRecordByFieldAuthority(\n policy: FieldAuthorityPolicy,\n before: Record<string, unknown>,\n incoming: Record<string, unknown>,\n changedFields: readonly string[],\n io: FieldAuthorityInputs,\n): { merged: Record<string, unknown>; decisions: Record<string, 'incoming' | 'local'> } {\n const merged: Record<string, unknown> = { ...before }\n const decisions: Record<string, 'incoming' | 'local'> = {}\n for (const f of changedFields) {\n const rule = policy[f]\n if (rule === undefined) { decisions[f] = 'local'; continue } // unlisted → keep local\n const who = resolveFieldAuthority(rule, io)\n decisions[f] = who\n if (who === 'incoming') merged[f] = incoming[f]\n }\n return { merged, decisions }\n}\n","/**\n * @klum-db/lobby interchange — reconcile an incoming extracted-partition\n * compartment into an existing receiver vault (FR-3).\n *\n * `mergeCompartment(receiver, compartmentBytes, opts)` → `MergeReport`:\n * 1. Decrypt the incoming bytes via hub's `decryptExtractedPartition`.\n * 2. `diffVault(receiver, incoming)` classifies records as added / modified\n * / deleted (deleted = receiver-only slice, ignored per FR-3 semantics).\n * 3. Resolve each `modified` entry per the per-collection strategy.\n * 4. Apply writes via `collection.put(id, rec, { reason })` (unless dryRun).\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport { diffVault } from '@noy-db/hub'\nimport { decryptExtractedPartition, type DecryptedRecord } from '@noy-db/hub/bundle'\nimport {\n resolveRecordByFieldAuthority,\n FieldAuthorityPolicyMissingError,\n type FieldAuthorityPolicy,\n} from './field-authority.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/** Per-collection conflict strategy. `field-level` is a deprecated alias for `field-authority`. */\nexport type MergeStrategy =\n | 'take-incoming'\n | 'keep-local'\n | 'lww-by-ts'\n | 'manual-queue'\n | 'field-authority'\n /** @deprecated Use `field-authority` instead. */\n | 'field-level'\n\n/** Options for the decrypted-records merge path (no bundle, no transfer key). */\nexport interface DecryptedMergeOptions {\n readonly strategy:\n | MergeStrategy\n | (Record<string, MergeStrategy> & { default?: MergeStrategy })\n readonly dryRun?: boolean\n /** Audit reason stamped on every write. Defaults to `'merge:compartment'`. */\n readonly reason?: string\n /** Per-collection field→authority policy. Required for any collection using `field-authority`. */\n readonly fieldAuthority?: Record<string, FieldAuthorityPolicy>\n}\n\n/** Options for the bundle merge path — adds the transfer key for decryption. */\nexport interface MergeCompartmentOptions extends DecryptedMergeOptions {\n readonly transferKey: Uint8Array\n}\n\nexport interface MergeConflict {\n readonly collection: string\n readonly id: string\n readonly strategy: MergeStrategy\n readonly resolution: 'incoming' | 'local' | 'queued' | 'field-merged'\n}\n\nexport interface MergeReport {\n readonly vault: string\n readonly dryRun: boolean\n readonly summary: {\n readonly inserted: number\n readonly updated: number\n readonly skipped: number\n readonly queued: number\n readonly total: number\n }\n readonly byCollection: Record<\n string,\n { readonly inserted: number; readonly updated: number; readonly skipped: number; readonly queued: number }\n >\n /**\n * One entry per `modified` (id-collision) record, regardless of outcome —\n * including `take-incoming` overwrites (`resolution: 'incoming'`). This is a\n * full audit trail of every conflict the merge encountered and how it was\n * resolved, not just the ones that were skipped or queued.\n */\n readonly conflicts: readonly MergeConflict[]\n}\n\n/** Mutable per-collection tally used while building a {@link MergeReport}. */\ninterface CollectionTally {\n inserted: number\n updated: number\n skipped: number\n queued: number\n}\n\n// ─── Error ────────────────────────────────────────────────────────────────────\n\n/**\n * @deprecated No longer thrown — `field-level` is now a deprecated alias for\n * `field-authority` and resolves via the field-authority resolver (FR-4).\n * Kept for backwards compatibility of existing imports.\n */\nexport class FieldLevelDeferredError extends Error {\n constructor(collection: string) {\n super(\n `mergeCompartment: the 'field-level' strategy for \"${collection}\" is not implemented yet` +\n ` — it lands with FR-4 (field-authority).` +\n ` Use take-incoming / keep-local / lww-by-ts / manual-queue for now.`,\n )\n this.name = 'FieldLevelDeferredError'\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction strategyFor(\n opts: DecryptedMergeOptions['strategy'],\n collection: string,\n): MergeStrategy {\n if (typeof opts === 'string') return opts\n return opts[collection] ?? opts.default ?? 'manual-queue'\n}\n\n// ─── Core ─────────────────────────────────────────────────────────────────────\n\n/**\n * Merge an already-decrypted record set into the receiver. The shared core of\n * `mergeCompartment` (decrypt → this) and `migrateThenMerge` (decrypt → migrate → this).\n * `decrypted` is keyed by collection; each record carries id/record/ts/source/sourceTs.\n *\n * Semantics:\n * - **added**: in incoming, not in receiver → always insert (every strategy).\n * - **modified**: in both, body differs → resolve per collection strategy.\n * - **deleted**: in receiver, not in incoming → IGNORE (incoming is a slice;\n * never delete receiver rows).\n * - **unchanged**: no-op.\n *\n * Returns a {@link MergeReport} describing what was (or would be) written.\n * When `dryRun: true` the report is fully computed but no `put()` is called.\n *\n * Writes are applied sequentially and **non-transactionally**: a `put()`\n * failure mid-loop (e.g. schema mismatch or a storage error) rejects the\n * returned promise but leaves the receiver partially merged. Use `dryRun`\n * first to validate the plan when partial application is unacceptable.\n */\nexport async function mergeDecryptedRecords(\n receiver: Vault,\n decrypted: Record<string, readonly DecryptedRecord[]>,\n opts: DecryptedMergeOptions,\n): Promise<MergeReport> {\n const reason = opts.reason ?? 'merge:compartment'\n\n // Build the candidate for diffVault: Record<collection, T[]> where each T has an `id` field.\n // Also keep incoming _ts for lww-by-ts comparison and _source/_sourceTs for provenance\n // threading (FR-5) and field-authority resolution (FR-4).\n const incomingTs = new Map<string, Map<string, string>>()\n const incomingSource = new Map<string, Map<string, string>>()\n const incomingSourceTs = new Map<string, Map<string, string>>()\n const candidate: Record<string, Record<string, unknown>[]> = {}\n for (const [coll, recs] of Object.entries(decrypted)) {\n const tsMap = new Map<string, string>()\n const srcMap = new Map<string, string>()\n const stsMap = new Map<string, string>()\n for (const r of recs) {\n tsMap.set(r.id, r.ts)\n if (r.source !== undefined) srcMap.set(r.id, r.source)\n if (r.sourceTs !== undefined) stsMap.set(r.id, r.sourceTs)\n }\n candidate[coll] = recs.map((r) => r.record)\n incomingTs.set(coll, tsMap)\n incomingSource.set(coll, srcMap)\n incomingSourceTs.set(coll, stsMap)\n }\n\n // 2. Diff the receiver against the incoming candidate.\n const diff = await diffVault(receiver, candidate)\n\n // 3. Resolve conflicts.\n const byCollection: Record<string, CollectionTally> = {}\n const conflicts: MergeConflict[] = []\n const writes: { collection: string; id: string; record: Record<string, unknown>; source?: string; sourceTs?: string }[] = []\n\n function bump(\n coll: string,\n key: keyof CollectionTally,\n ): void {\n const e = byCollection[coll] ?? { inserted: 0, updated: 0, skipped: 0, queued: 0 }\n e[key]++\n byCollection[coll] = e\n }\n\n // 3a. added → insert (all strategies)\n for (const a of diff.added) {\n const src = incomingSource.get(a.collection)?.get(a.id)\n const sts = incomingSourceTs.get(a.collection)?.get(a.id)\n writes.push({\n collection: a.collection, id: a.id, record: a.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(a.collection, 'inserted')\n }\n\n // 3b. modified → resolve per strategy\n // For lww-by-ts we need the receiver envelope's _ts.\n const { adapter, name: receiverName } = receiver._introspectState()\n\n for (const m of diff.modified) {\n const strat = strategyFor(opts.strategy, m.collection)\n\n if (strat === 'field-authority' || strat === 'field-level') {\n const policy = opts.fieldAuthority?.[m.collection]\n if (policy === undefined) throw new FieldAuthorityPolicyMissingError(m.collection)\n const recvEnv = await adapter.get(receiverName, m.collection, m.id)\n const incSrc = incomingSource.get(m.collection)?.get(m.id)\n const incSts = incomingSourceTs.get(m.collection)?.get(m.id)\n const locSrc = recvEnv?._source\n const locSts = recvEnv?._sourceTs\n const io = {\n ...(incSrc !== undefined ? { incomingSource: incSrc } : {}),\n ...(incSts !== undefined ? { incomingSourceTs: incSts } : {}),\n ...(locSrc !== undefined ? { localSource: locSrc } : {}),\n ...(locSts !== undefined ? { localSourceTs: locSts } : {}),\n }\n const { merged } = resolveRecordByFieldAuthority(\n policy,\n m.before,\n m.record,\n m.fieldsChanged,\n io,\n )\n // Per-field MERGED synthesis carries a record-level 'merged' source (Q3 defer).\n // NO sourceTs override — merged records keep merge-time by design.\n writes.push({ collection: m.collection, id: m.id, record: merged, source: 'merged' })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'field-merged' })\n continue\n }\n\n if (strat === 'take-incoming') {\n const src = incomingSource.get(m.collection)?.get(m.id)\n const sts = incomingSourceTs.get(m.collection)?.get(m.id)\n writes.push({\n collection: m.collection, id: m.id, record: m.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'incoming' })\n } else if (strat === 'keep-local') {\n bump(m.collection, 'skipped')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'local' })\n } else if (strat === 'manual-queue') {\n bump(m.collection, 'queued')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'queued' })\n } else {\n // lww-by-ts: compare ISO _ts strings lexicographically (correct for ISO-8601).\n const incTs = incomingTs.get(m.collection)?.get(m.id) ?? ''\n const recvEnv = await adapter.get(receiverName, m.collection, m.id)\n const localTs = recvEnv?._ts ?? ''\n if (incTs > localTs) {\n const src = incomingSource.get(m.collection)?.get(m.id)\n const sts = incomingSourceTs.get(m.collection)?.get(m.id)\n writes.push({\n collection: m.collection, id: m.id, record: m.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'incoming' })\n } else {\n bump(m.collection, 'skipped')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'local' })\n }\n }\n }\n\n // diff.deleted (receiver-only) is intentionally ignored — incoming is a slice,\n // its absence of a row never means \"delete that row from the receiver\".\n\n // 4. Apply writes (unless dry-run).\n if (!opts.dryRun) {\n for (const w of writes) {\n await receiver.collection(w.collection).put(w.id, w.record, {\n reason,\n ...(w.source !== undefined ? { source: w.source } : {}),\n ...(w.sourceTs !== undefined ? { sourceTs: w.sourceTs } : {}),\n })\n }\n }\n\n // 5. Aggregate summary.\n const summary = { inserted: 0, updated: 0, skipped: 0, queued: 0, total: 0 }\n for (const e of Object.values(byCollection)) {\n summary.inserted += e.inserted\n summary.updated += e.updated\n summary.skipped += e.skipped\n summary.queued += e.queued\n }\n summary.total = summary.inserted + summary.updated + summary.skipped + summary.queued\n\n return {\n vault: receiverName,\n dryRun: opts.dryRun ?? false,\n summary,\n byCollection,\n conflicts,\n }\n}\n\n/**\n * Reconcile an incoming extracted-partition compartment into a receiver vault.\n * Decrypts the compartment bytes then delegates to {@link mergeDecryptedRecords}.\n *\n * See {@link mergeDecryptedRecords} for full semantics, dryRun behaviour, and\n * the non-transactional write caveat.\n */\nexport async function mergeCompartment(\n receiver: Vault,\n compartmentBytes: Uint8Array,\n opts: MergeCompartmentOptions,\n): Promise<MergeReport> {\n const incoming = await decryptExtractedPartition(compartmentBytes, opts.transferKey)\n return mergeDecryptedRecords(receiver, incoming, opts)\n}\n","/**\n * @klum-db/lobby interchange — shared staging helper.\n *\n * Transforms each incoming record, re-injects the canonical `id`, and\n * pre-validates every record against the receiver schema BEFORE any write.\n * A throwing transform or a failing validation bubbles out here, leaving the\n * receiver untouched (staging-safety). Used by both `migrateThenMerge` (FR-8,\n * version-windowed steps) and `graduate()` (foreign→target mapping).\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport type { DecryptedRecord } from '@noy-db/hub/bundle'\n\n/** A pure record-body transform: old body → new body. */\nexport type RecordTransform = (body: Record<string, unknown>) => Record<string, unknown>\n\n/**\n * Thrown BEFORE any write when a collection's records do not validate against\n * the receiver schema and no transform was supplied to fix the shape.\n */\nexport class MigrationTransformRequiredError extends Error {\n constructor(\n public readonly collection: string,\n public readonly cause?: unknown,\n ) {\n super(\n `collection \"${collection}\" did not validate against the receiver schema after ` +\n `transformation and no transform was supplied to reach the target shape. Provide a ` +\n `transform for \"${collection}\". Underlying: ${cause instanceof Error ? cause.message : String(cause)}`,\n )\n this.name = 'MigrationTransformRequiredError'\n }\n}\n\n/**\n * Stage incoming records: apply per-collection transforms (in array order),\n * re-inject the canonical `id`, and validate every staged record against the\n * receiver schema. Returns the staged records; never writes.\n */\nexport async function stageAndValidate(\n receiver: Vault,\n incoming: Record<string, readonly DecryptedRecord[]>,\n transformsByCollection: Record<string, readonly RecordTransform[]>,\n): Promise<Record<string, DecryptedRecord[]>> {\n const staged: Record<string, DecryptedRecord[]> = {}\n for (const [coll, recs] of Object.entries(incoming)) {\n const transforms = transformsByCollection[coll] ?? []\n const out: DecryptedRecord[] = []\n for (const r of recs) {\n let body = r.record\n for (const t of transforms) body = t(body)\n // Re-inject the canonical id: a transform that drops/renames `id` must not\n // silently detach the row from its identity.\n out.push({ ...r, record: { ...body, id: r.id } })\n }\n staged[coll] = out\n\n const rc = receiver.collection(coll)\n for (const r of out) {\n try {\n await rc.validateInput(r.record)\n } catch (cause) {\n throw new MigrationTransformRequiredError(coll, cause)\n }\n }\n }\n return staged\n}\n","/**\n * @klum-db/lobby dock — graduate() (#11). Import a docked foreign unit into a\n * fresh sovereign noy-db vault, unlocking the full tier (keyring, CEK,\n * provenance, custody). Reuses the decrypted-merge core (no crypto round-trip):\n * foreign rows are plaintext to begin with, so they are staged + validated and\n * written via `mergeDecryptedRecords` (a degenerate all-insert merge).\n *\n * @module\n */\nimport { createDeedOwner } from '@noy-db/hub'\nimport type { Noydb, SealingKeyProvider } from '@noy-db/hub'\nimport type { DecryptedRecord } from '@noy-db/hub/bundle'\nimport { mergeDecryptedRecords } from '../interchange/merge-compartment.js'\nimport { stageAndValidate, type RecordTransform } from '../interchange/stage-records.js'\nimport type { VaultTemplate } from '../federation/types.js'\nimport type { StateManagementVault } from '../federation/state-vault.js'\nimport type { DockedUnit } from './docked-unit.js'\n\nexport interface GraduateOptions {\n /** Name of the fresh sovereign vault to create. */\n readonly vaultName: string\n /** Target schema applied to the new vault. */\n readonly template: VaultTemplate\n /** Per-(target)-collection transform mapping foreign rows → the target shape. */\n readonly mapping?: Record<string, RecordTransform>\n /** Map a foreign collection name → its target collection name (when they differ). */\n readonly collectionMap?: Record<string, string>\n /** Optionally seal an inalienable client Deed (FR-6) on the new vault. */\n readonly deed?: { readonly ownerId: string; readonly sealingProvider: SealingKeyProvider }\n /** Optional StateManagement vault to record the audited graduation event into. */\n readonly stateVault?: StateManagementVault\n}\n\nexport interface GraduationReport {\n readonly vaultName: string\n readonly collections: Record<string, { graduated: number }>\n readonly deedSealed: boolean\n readonly event: { type: 'unit-graduated'; unitId: string; vault: string }\n}\n\n/** Thrown when graduation cannot proceed (target vault already populated, etc.). */\nexport class UnitGraduationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'UnitGraduationError'\n }\n}\n\nconst ISO_EPOCH = '1970-01-01T00:00:00.000Z'\n\nexport async function graduate(\n noydb: Noydb,\n docked: DockedUnit,\n opts: GraduateOptions,\n): Promise<GraduationReport> {\n // 1. Mint the fresh vault and apply the target schema.\n const vault = await noydb.openVault(opts.vaultName)\n opts.template.configure(vault)\n\n // 2. Read the foreign unit → DecryptedRecord[] keyed by TARGET collection.\n // Refuse to graduate into a vault that already holds data (create-only;\n // merge-into-existing is mergeCompartment's job, not this).\n const incoming: Record<string, DecryptedRecord[]> = {}\n const transforms: Record<string, RecordTransform[]> = {}\n for (const foreignColl of await docked.listCollections()) {\n const target = opts.collectionMap?.[foreignColl] ?? foreignColl\n const existing = await vault.collection(target).list()\n if (existing.length > 0) {\n throw new UnitGraduationError(\n `graduate: target vault \"${opts.vaultName}\" collection \"${target}\" is not empty`,\n )\n }\n const recs: DecryptedRecord[] = []\n for await (const row of docked.readRecords(foreignColl)) {\n if (row.id == null) {\n throw new UnitGraduationError(\n `graduate: foreign collection \"${foreignColl}\" has a row without an id — every docked row must carry a non-null id`,\n )\n }\n if (typeof row.id !== 'string' && typeof row.id !== 'number') {\n throw new UnitGraduationError(\n `graduate: foreign collection \"${foreignColl}\" has a row whose id is not a string or number — every docked row id must be a primitive`,\n )\n }\n const id = String(row.id)\n recs.push({ id, record: row, ts: ISO_EPOCH, version: opts.template.version })\n }\n incoming[target] = recs\n if (opts.mapping?.[target]) transforms[target] = [opts.mapping[target]]\n }\n\n // 3. Stage + validate (staging-safety), then merge as a degenerate all-insert.\n const staged = await stageAndValidate(vault, incoming, transforms)\n await mergeDecryptedRecords(vault, staged, { strategy: 'take-incoming', reason: 'dock:graduate' })\n\n // 3b. Optional custody Deed — the client's inalienable, sealed owner (FR-6).\n let deedSealed = false\n if (opts.deed) {\n await createDeedOwner(noydb._store, opts.vaultName, opts.deed.ownerId, opts.deed.sealingProvider)\n deedSealed = true\n }\n\n // 3c. Optional audited event.\n if (opts.stateVault) {\n await opts.stateVault.appendEvent({\n type: 'unit-graduated',\n group: opts.vaultName,\n vaultId: opts.vaultName,\n detail: `graduated foreign unit ${docked.unitId}`,\n })\n }\n\n // 4. Report.\n const collections: Record<string, { graduated: number }> = {}\n for (const [coll, recs] of Object.entries(staged)) collections[coll] = { graduated: recs.length }\n\n return {\n vaultName: opts.vaultName,\n collections,\n deedSealed,\n event: { type: 'unit-graduated', unitId: docked.unitId, vault: opts.vaultName },\n }\n}\n","/**\n * @klum-db/lobby interchange — Surface bilateral handshake + export/apply (FR-7).\n * Pure helpers: `now` is always passed in; no Date.now() calls inside.\n * @packageDocumentation\n */\nimport { generateULID } from '@noy-db/hub/kernel'\nimport type { Vault } from '@noy-db/hub'\nimport { extractPartition } from '@noy-db/hub/bundle'\nimport { mergeCompartment, type MergeReport } from './merge-compartment.js'\nimport type { StateManagementVault } from '../federation/state-vault.js'\nimport type {\n SurfaceRow,\n SurfaceDirection,\n SurfaceConflictPolicy,\n} from '../federation/types.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/**\n * User-facing subset of SurfaceRow: the fields a caller provides when\n * proposing a new surface. `id` is optional (auto-generated via ULID when\n * omitted). `status`, `proposedBy`, `createdAt`, etc. are set by `proposeSurface`.\n */\nexport interface SurfaceDefinition {\n readonly id?: string\n readonly collections: readonly string[]\n readonly fields?: Record<string, readonly string[]>\n readonly direction: SurfaceDirection\n readonly conflictPolicy: SurfaceConflictPolicy\n readonly cadenceMs?: number\n}\n\n// ─── Error classes ────────────────────────────────────────────────────────────\n\n/** Thrown when a surface id cannot be found in the StateManagementVault. */\nexport class SurfaceNotFoundError extends Error {\n override name = 'SurfaceNotFoundError'\n constructor(surfaceId: string) {\n super(`Surface not found: ${surfaceId}`)\n }\n}\n\n/**\n * Thrown when an operation is invalid for the surface's current status\n * (e.g. agreeing on an already-agreed or suspended surface).\n */\nexport class SurfaceStateError extends Error {\n override name = 'SurfaceStateError'\n constructor(surfaceId: string, currentStatus: string, requiredStatus: string) {\n super(\n `Surface ${surfaceId} has status '${currentStatus}', expected '${requiredStatus}'`,\n )\n }\n}\n\n// ─── Handshake helpers ────────────────────────────────────────────────────────\n\n/**\n * Party A: persist a new `status:'proposed'` SurfaceRow in the\n * StateManagementVault. The `id` in `def` is used when provided;\n * otherwise a fresh ULID is generated. `now` is the creation timestamp\n * (caller supplies, no Date.now() inside).\n */\nexport async function proposeSurface(\n smv: StateManagementVault,\n def: SurfaceDefinition,\n proposedBy: string,\n now: number,\n): Promise<SurfaceRow> {\n const row: SurfaceRow = {\n ...def,\n id: def.id ?? generateULID(),\n status: 'proposed',\n proposedBy,\n createdAt: now,\n }\n await smv.createSurface(row)\n return row\n}\n\n/**\n * Party B: read the surface, assert it is in `'proposed'` status, then\n * flip it to `'agreed'` (setting `agreedBy`). Returns the updated row.\n *\n * Throws:\n * - `SurfaceNotFoundError` when `surfaceId` is absent.\n * - `SurfaceStateError` when the surface status is not `'proposed'`.\n *\n * `_now` is accepted for API symmetry with `proposeSurface` (Task 5 will\n * use it for `lastSyncAt` stamping); it is not written in this task.\n */\nexport async function agreeSurface(\n smv: StateManagementVault,\n surfaceId: string,\n agreedBy: string,\n _now: number,\n): Promise<SurfaceRow> {\n const existing = await smv.getSurface(surfaceId)\n if (!existing) throw new SurfaceNotFoundError(surfaceId)\n if (existing.status !== 'proposed') {\n throw new SurfaceStateError(surfaceId, existing.status, 'proposed')\n }\n return smv.updateSurface(surfaceId, { status: 'agreed', agreedBy })\n}\n\n// ─── Export / Apply ───────────────────────────────────────────────────────────\n\n/**\n * Export a scoped partition from `source` bounded to the surface's collections\n * and field projection. Only surface.collections are included in the bundle:\n * `seeds` keys are exactly `surface.collections` and `maxDepth: 0` bounds the\n * walk so no non-surface collection can enter the closure. NOTE: if a surface\n * collection holds a `ref()` to an OUT-OF-SURFACE collection, the export\n * hard-fails with `PartitionExtractionError` (the safe outcome — it never\n * silently pulls in or leaks the referenced collection); surfaces over\n * collections that cross-reference outside the surface are not supported.\n * Excluded fields are structurally redacted before re-encryption and never\n * travel in the bundle.\n *\n * `exportSurface`/`applySurface` are direction-AGNOSTIC mechanics: export\n * produces a slice from a source vault, apply merges a slice into a receiver\n * vault. Both are needed for EVERY direction (push: proposer exports → agreer\n * applies; pull: agreer exports → proposer applies; bidi: both). `direction` is\n * orchestration metadata honoured by the sync flow (which party exports vs\n * applies), not a gate on the primitives — gating it here would make pull\n * surfaces unusable.\n *\n * Throws:\n * - `SurfaceStateError` when `surface.status !== 'agreed'`.\n */\nexport async function exportSurface(\n source: Vault,\n surface: SurfaceRow,\n): Promise<{ bundleBytes: Uint8Array; transferKey: Uint8Array }> {\n if (surface.status !== 'agreed') {\n throw new SurfaceStateError(surface.id, surface.status, 'agreed')\n }\n\n // Seeds: include ALL records in each surface collection (no predicate filtering).\n // maxDepth:0 ensures ref-following stops at the seed collections so no\n // non-surface collection can slip into the closure.\n const seeds = Object.fromEntries(surface.collections.map(c => [c, () => true]))\n\n const { bundleBytes, transferKey } = await extractPartition(source, {\n seeds,\n maxDepth: 0,\n ...(surface.fields ? { fieldProjection: surface.fields } : {}),\n carrySchemas: false,\n carryLedger: false,\n })\n\n return { bundleBytes, transferKey }\n}\n\n/**\n * Apply an exported surface bundle into `receiver`. Decrypts + merges using\n * the surface's conflict policy.\n *\n * Direction-agnostic mechanic (see `exportSurface`): the receiver merges the\n * slice regardless of direction; the sync flow decides which party applies.\n *\n * NOTE: a field-projected slice applied with a `take-incoming` conflict policy\n * is DESTRUCTIVE to non-surface fields on a record the receiver already holds\n * (the narrowed `{id, ...surface.fields}` overwrites the full row, dropping its\n * other fields). Use `keep-local` or `field-authority` when the receiver's\n * out-of-surface fields must be preserved across a projected push.\n *\n * Throws:\n * - `SurfaceStateError` when `surface.status !== 'agreed'`.\n */\nexport async function applySurface(\n receiver: Vault,\n surface: SurfaceRow,\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n): Promise<MergeReport> {\n if (surface.status !== 'agreed') {\n throw new SurfaceStateError(surface.id, surface.status, 'agreed')\n }\n\n return mergeCompartment(receiver, bundleBytes, {\n transferKey,\n strategy: surface.conflictPolicy.strategy,\n ...(surface.conflictPolicy.fieldAuthority\n ? { fieldAuthority: surface.conflictPolicy.fieldAuthority }\n : {}),\n reason: `sync:surface:${surface.id}`,\n })\n}\n\n// ─── Cadence helpers ──────────────────────────────────────────────────────────\n\n/**\n * Pure due-check — deterministic, no Date.now() inside.\n *\n * A surface is due iff:\n * - it has a `cadenceMs` (manually-only surfaces are never due via this check)\n * - its `status` is `'agreed'` (proposed/suspended do not fire)\n * - it has never been synced (`lastSyncAt === undefined`), OR\n * `now` has reached or passed `nextSyncDueAt`\n *\n * The caller always passes `now` explicitly so the function is testable without\n * any timer mocking.\n */\nexport function isSurfaceDue(surface: SurfaceRow, now: number): boolean {\n if (surface.cadenceMs === undefined) return false\n if (surface.status !== 'agreed') return false\n if (surface.lastSyncAt === undefined) return true\n return now >= (surface.nextSyncDueAt ?? 0)\n}\n\n/**\n * Filter a list of surfaces to those that are currently due.\n * Delegates to `isSurfaceDue` for each entry.\n */\nexport function listDueSurfaces(surfaces: readonly SurfaceRow[], now: number): SurfaceRow[] {\n return surfaces.filter(s => isSurfaceDue(s, now))\n}\n\n/**\n * Stamp `lastSyncAt = now` and `nextSyncDueAt = now + surface.cadenceMs` in\n * the StateManagementVault after a successful sync run. The surface must exist\n * (reads it to get `cadenceMs`). If `cadenceMs` is undefined the stamps are\n * written with `nextSyncDueAt = now` (no-op for future due-checks).\n *\n * Does NOT call Date.now() internally — the caller supplies `now`.\n */\nexport async function markSynced(\n smv: StateManagementVault,\n id: string,\n now: number,\n): Promise<SurfaceRow> {\n const existing = await smv.getSurface(id)\n if (!existing) throw new Error(`markSynced: surface not found: ${id}`)\n const cadenceMs = existing.cadenceMs ?? 0\n return smv.updateSurface(id, {\n lastSyncAt: now,\n nextSyncDueAt: now + cadenceMs,\n })\n}\n\n/**\n * Thin interval driver for surface cadence.\n *\n * Wraps a `Map<surfaceId, timer>` so each surface can be independently\n * started / stopped. `start` calls `setInterval(fn, intervalMs)` and\n * replaces any existing timer for the same id. `stopAll` clears all.\n *\n * Accepts an injectable `nowFn` (default `Date.now`) for use-sites that\n * need to capture the current time inside the callback — the pure due-check\n * (`isSurfaceDue`) takes `now` explicitly and should not call this.\n */\nexport class SurfaceCadenceScheduler {\n readonly #timers = new Map<string, ReturnType<typeof setInterval>>()\n readonly #nowFn: () => number\n\n constructor(nowFn: () => number = Date.now) {\n this.#nowFn = nowFn\n }\n\n /** Expose nowFn for callback use-sites. */\n get now(): number {\n return this.#nowFn()\n }\n\n /**\n * Schedule `fn` to fire every `intervalMs` milliseconds for the given\n * `surfaceId`. If the id is already running, the previous interval is\n * cancelled first (replace semantics).\n */\n start(surfaceId: string, intervalMs: number, fn: () => void): void {\n this.stop(surfaceId)\n const timer = setInterval(fn, intervalMs)\n this.#timers.set(surfaceId, timer)\n }\n\n /** Cancel the interval for `surfaceId` (no-op if not running). */\n stop(surfaceId: string): void {\n const timer = this.#timers.get(surfaceId)\n if (timer !== undefined) {\n clearInterval(timer)\n this.#timers.delete(surfaceId)\n }\n }\n\n /** Cancel all running intervals. */\n stopAll(): void {\n for (const [id] of this.#timers) {\n this.stop(id)\n }\n }\n}\n","/**\n * @category capability\n * StateManagement Vault — schema blueprint capture + deterministic\n * fingerprint. See\n * docs/superpowers/specs/2026-06-08-statemanagement-vault-design.md.\n */\nimport type { Vault } from '@noy-db/hub/kernel'\nimport type { IndexDef } from '@noy-db/hub/kernel'\nimport { sha256Hex } from '@noy-db/hub/kernel'\nimport type { CapturedBlueprint } from './types.js'\n\ninterface RecordedCollection {\n name: string\n indexes: IndexDef[]\n persistJsonSchema: boolean\n}\n\n/**\n * Run `configure` against a recording proxy that intercepts\n * `collection(name, opts)` calls and captures the declared blueprint.\n * The proxy delegates every other access to a no-op stub so unrelated\n * `configure` calls (guards, blob setup) do not throw — only the\n * declared collections/indexes feed the fingerprint.\n */\nexport function captureBlueprint(configure: (vault: Vault) => void): CapturedBlueprint {\n const recorded: RecordedCollection[] = []\n // Minimal chainable stub returned by intercepted collection() — supports\n // the fluent calls a template might make without affecting the blueprint.\n const collectionStub = new Proxy(\n {},\n {\n get: () => () => collectionStub,\n },\n )\n const proxy = new Proxy(\n {},\n {\n get: (_t, prop) => {\n if (prop === 'collection') {\n return (name: string, opts?: { indexes?: IndexDef[]; persistJsonSchema?: boolean }) => {\n recorded.push({\n name,\n indexes: opts?.indexes ?? [],\n persistJsonSchema: !!opts?.persistJsonSchema,\n })\n return collectionStub\n }\n }\n // Any other vault method/property: a no-op callable that returns the proxy.\n return () => proxy\n },\n },\n ) as unknown as Vault\n\n configure(proxy)\n\n const sorted = [...recorded].sort((a, b) => a.name.localeCompare(b.name))\n const indexes: Record<string, IndexDef[]> = {}\n const persistJsonSchema: string[] = []\n for (const c of sorted) {\n indexes[c.name] = c.indexes\n if (c.persistJsonSchema) persistJsonSchema.push(c.name)\n }\n return {\n // `persistJsonSchema` is already name-sorted: it is populated while\n // iterating `sorted` (collections in name order).\n collections: sorted.map((c) => c.name),\n indexes,\n persistJsonSchema,\n }\n}\n\n/** Canonical JSON: object keys sorted recursively so the bytes are stable. */\nfunction canonical(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(obj[k])}`).join(',')}}`\n}\n\n/** sha256 (hex) over the canonicalized serializable blueprint. Uses the shared hub helper. */\nexport async function fingerprintBlueprint(bp: CapturedBlueprint): Promise<string> {\n return sha256Hex(new TextEncoder().encode(canonical(bp)))\n}\n","export { STATE_VAULT_NAME } from '@noy-db/hub'\n","/**\n * @category capability\n * StateManagement Vault — federation control plane (registry +\n * schema-manifest + append-only deployment-events). See\n * docs/superpowers/specs/2026-06-08-statemanagement-vault-design.md.\n */\nimport type { Noydb } from '@noy-db/hub/kernel'\nimport type { Collection } from '@noy-db/hub/kernel'\nimport type { Query } from '@noy-db/hub/kernel'\nimport type { VaultRegistryRow, SchemaManifestRow, DeploymentEvent, MigrationStatusRow, SurfaceRow, VaultTemplate } from './types.js'\nimport { captureBlueprint, fingerprintBlueprint } from './schema-manifest.js'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { generateULID } from '@noy-db/hub/kernel'\n\n// Re-export so federation/index.ts can surface STATE_VAULT_NAME without reaching past state-vault.\nexport { STATE_VAULT_NAME } from './constants.js'\n\n// Physical collection names — single-token (camelCase) to stay clear of any\n// collection-name charset restrictions; the existing suite uses single-word names.\nconst REGISTRY = 'vaultRegistry'\nconst MANIFEST = 'schemaManifest'\nconst EVENTS = 'deploymentEvents'\nconst MIGRATION_STATUS = 'migrationStatus'\nconst SURFACES = 'surfaces'\n\nexport class StateManagementVault {\n /**\n * The append-only deployment-events log is kept truly private so the raw\n * mutable Collection is never surfaced — events may only be written via\n * `appendEvent` and read via `queryEvents`. (`registry` and\n * `schemaManifest` are deliberately public: consumers read and write them.)\n */\n readonly #events: Collection<DeploymentEvent>\n /** Per-shard fleet-migration progress (#271). Surfaced via typed methods only. */\n readonly #migrationStatus: Collection<MigrationStatusRow>\n /** Persisted Surface agreements (FR-7). Surfaced via typed methods only. */\n readonly #surfaces: Collection<SurfaceRow>\n\n private constructor(\n readonly registry: Collection<VaultRegistryRow>,\n readonly schemaManifest: Collection<SchemaManifestRow>,\n events: Collection<DeploymentEvent>,\n migrationStatus: Collection<MigrationStatusRow>,\n surfaces: Collection<SurfaceRow>,\n ) {\n this.#events = events\n this.#migrationStatus = migrationStatus\n this.#surfaces = surfaces\n }\n\n /** Idempotently open the reserved state vault and bind the control-plane collections. */\n static async open(db: Noydb): Promise<StateManagementVault> {\n const vault = await db.openVault(STATE_VAULT_NAME)\n return new StateManagementVault(\n vault.collection<VaultRegistryRow>(REGISTRY),\n vault.collection<SchemaManifestRow>(MANIFEST),\n vault.collection<DeploymentEvent>(EVENTS),\n vault.collection<MigrationStatusRow>(MIGRATION_STATUS),\n vault.collection<SurfaceRow>(SURFACES),\n )\n }\n\n /** Read one shard's migration status (or null). */\n async getMigrationStatus(vaultId: string): Promise<MigrationStatusRow | null> {\n return this.#migrationStatus.get(vaultId)\n }\n\n /** All migration-status rows (hydrates first). */\n async listMigrationStatus(): Promise<MigrationStatusRow[]> {\n await this.#migrationStatus.list()\n return this.#migrationStatus.query().toArray()\n }\n\n /** Upsert one shard's migration status (keyed by vaultId). */\n async upsertMigrationStatus(row: MigrationStatusRow): Promise<void> {\n await this.#migrationStatus.put(row.vaultId, row)\n }\n\n // ─── FR-7 Surface CRUD ────────────────────────────────────────────────────\n\n /** Persist a new Surface row (keyed by `row.id`). */\n async createSurface(row: SurfaceRow): Promise<void> {\n await this.#surfaces.put(row.id, row)\n }\n\n /** Read one Surface row by id, or null if absent. */\n async getSurface(id: string): Promise<SurfaceRow | null> {\n return this.#surfaces.get(id)\n }\n\n /** All persisted Surface rows (hydrates first). */\n async listSurfaces(): Promise<SurfaceRow[]> {\n await this.#surfaces.list()\n return this.#surfaces.query().toArray()\n }\n\n /**\n * Merge `patch` into the existing Surface row keyed by `id`, persist the\n * result, and return it. Mirrors the migrationStatus upsert pattern but\n * returns the merged row for convenience.\n */\n async updateSurface(id: string, patch: Partial<SurfaceRow>): Promise<SurfaceRow> {\n const existing = await this.#surfaces.get(id)\n if (!existing) throw new Error(`Surface not found: ${id}`)\n const updated: SurfaceRow = { ...existing, ...patch }\n await this.#surfaces.put(id, updated)\n return updated\n }\n\n /** Read-only query over the append-only deployment-events log. */\n queryEvents(): Query<DeploymentEvent> {\n return this.#events.query()\n }\n\n /**\n * Append a deployment event with a fresh unique (ULID) id. This is the\n * only write path to the events log; no update/delete is exposed.\n * Callers should treat failures as non-fatal — this method does not\n * swallow errors, so wrap the call site in try/catch where appropriate.\n */\n async appendEvent(event: Omit<DeploymentEvent, 'id' | 'ts'> & { ts?: number }): Promise<void> {\n const ts = event.ts ?? Date.now()\n const id = generateULID()\n await this.#events.put(id, { ...event, id, ts })\n }\n\n /**\n * Ensure a manifest row exists for `(templateName, template.version)`.\n * Safe to call repeatedly: the `fingerprint` is a deterministic hash of\n * the template's declared shape (stable across calls), though each call\n * refreshes `recordedAt`.\n */\n async recordManifest(templateName: string, template: VaultTemplate): Promise<string> {\n const bp = captureBlueprint(template.configure)\n const fingerprint = await fingerprintBlueprint(bp)\n await this.schemaManifest.put(`${templateName}:${template.version}`, {\n templateName,\n version: template.version,\n collections: bp.collections,\n indexes: bp.indexes,\n persistJsonSchema: bp.persistJsonSchema,\n fingerprint,\n recordedAt: Date.now(),\n })\n return fingerprint\n }\n\n /**\n * True when `template`'s current declared shape does not match the recorded\n * manifest for `(templateName, template.version)`. Because shards carry no\n * schema state independent of their template, this catches \"a template's\n * shape changed without bumping `version`\" — not independent per-shard drift.\n * A missing manifest is treated as drift (nothing to verify against).\n */\n async detectDrift(templateName: string, template: VaultTemplate): Promise<boolean> {\n const row = await this.schemaManifest.get(`${templateName}:${template.version}`)\n if (!row) return true\n const current = await fingerprintBlueprint(captureBlueprint(template.configure))\n return current !== row.fingerprint\n }\n}\n","import { NoAccessError } from '@noy-db/hub/kernel'\nimport type { SkippedVault } from './types.js'\n\n/**\n * Classify a per-shard fan-out failure. `NoAccessError` (no keyring envelope for\n * the calling identity) is the unambiguous not-granted signal → `'no-grant'`\n * (expected under scoped access, not a fault). Everything else → `'error'` —\n * `InvalidKeyError`/`DecryptionError`/`KeyringCorruptError` can mean \"wrong KEK\n * OR whole-file corruption\" per loadKeyring, so they must not hide as no-grant.\n */\nexport function classifyShardSkip(err: Error): Exclude<SkippedVault['reason'], 'schema-drift'> {\n return err instanceof NoAccessError ? 'no-grant' : 'error'\n}\n","/**\n * @category capability\n * crossShardJoin — co-partitioned + broadcast dimension join for\n * ShardedQuery. Spec:\n * docs/superpowers/specs/2026-06-09-cross-shard-join-design.md.\n *\n * This module owns the BROADCAST half (central, post-merge map-attach)\n * and the leg type definitions. The CO-PARTITIONED half is threaded\n * into the existing intra-vault `.join()` from vault-group.ts — see\n * ShardedQuery.fanoutRecords. join.ts is deliberately untouched.\n */\nimport { readPath } from '@noy-db/hub/kernel'\nimport type { JoinStrategy } from '@noy-db/hub/kernel'\n\n/** Public options for `ShardedQuery.crossShardJoin`. */\nexport interface CrossShardJoinOptions {\n /** Alias key under which the joined same-shard record attaches. */\n readonly as: string\n /** Per-shard row ceiling override (default DEFAULT_JOIN_MAX_ROWS). */\n readonly maxRows?: number\n /** Planner strategy override, passed through to intra-vault `.join()`. */\n readonly strategy?: JoinStrategy\n}\n\n/**\n * Minimal structural shape of a broadcast dimension source. A\n * `Collection` satisfies this natively: `list()` hydrates and returns\n * the decoded records. Kept as a one-method interface so plain test\n * sources are trivial to construct.\n */\nexport interface BroadcastSource {\n list(): Promise<readonly unknown[]>\n}\n\n/** Public options for `ShardedQuery.broadcastJoin`. */\nexport interface BroadcastJoinOptions {\n /** Alias key under which the dimension record attaches. */\n readonly as: string\n /** The shared dimension collection (an opened handle in another vault). */\n readonly from: BroadcastSource\n /** Right-side key to match `field` against. Default 'id'. */\n readonly on?: string\n /** Miss behavior. 'warn' (default) attaches null + one-shot warning; 'cascade' is silent. */\n readonly mode?: 'warn' | 'cascade'\n}\n\n/** Internal co-partitioned leg carried on ShardedQuery. */\nexport interface CoPartitionedLeg {\n readonly field: string\n readonly as: string\n readonly maxRows: number | undefined\n readonly strategy: JoinStrategy | undefined\n}\n\n/** Internal broadcast leg carried on ShardedQuery. */\nexport interface BroadcastLeg {\n readonly field: string\n readonly as: string\n readonly from: BroadcastSource\n readonly on: string\n readonly mode: 'warn' | 'cascade'\n}\n\n/**\n * Coerce an unknown key value into a lookup string. Mirrors join.ts's\n * private `coerceRefKey` (string → string; number/bigint → String;\n * else null) — re-implemented locally to keep join.ts literally\n * untouched.\n */\nfunction coerceKey(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'bigint') return String(value)\n return null\n}\n\n/** One-shot warn dedup for broadcast misses, keyed by `field→as`. */\nconst warnedBroadcastKeys = new Set<string>()\nfunction warnOnceBroadcastMiss(field: string, as: string, key: string): void {\n const dedup = `${field}→${as}:${key}`\n if (warnedBroadcastKeys.has(dedup)) return\n warnedBroadcastKeys.add(dedup)\n console.warn(\n `[klum-db] broadcastJoin: no \"${as}\" dimension row for ${field}=\"${key}\". ` +\n `Attaching null. Use mode: 'cascade' to silence.`,\n )\n}\n\n/** Test-only reset for the broadcast warn dedup set. */\nexport function resetBroadcastWarnings(): void {\n warnedBroadcastKeys.clear()\n}\n\n/**\n * Apply every broadcast leg to a merged row set, centrally. Each leg's\n * source is snapshotted ONCE, indexed by its `on` key, then every row\n * gets `{ [as]: match ?? null }`. Returns fresh top-level objects.\n */\nexport async function applyBroadcastLegs(\n rows: readonly unknown[],\n legs: readonly BroadcastLeg[],\n): Promise<unknown[]> {\n if (legs.length === 0) return [...rows]\n\n // Build one index per leg (list() once per source).\n const indexes: { leg: BroadcastLeg; map: Map<string, unknown> }[] = []\n for (const leg of legs) {\n const map = new Map<string, unknown>()\n for (const rec of await leg.from.list()) {\n const k = coerceKey(readPath(rec, leg.on))\n if (k !== null && !map.has(k)) map.set(k, rec)\n }\n indexes.push({ leg, map })\n }\n\n return rows.map((row) => {\n const out = { ...(row as Record<string, unknown>) }\n for (const { leg, map } of indexes) {\n const key = coerceKey(readPath(row, leg.field))\n const match = key === null ? null : map.get(key) ?? null\n if (match === null && leg.mode === 'warn') {\n warnOnceBroadcastMiss(leg.field, leg.as, key ?? '<null>')\n }\n out[leg.as] = match\n }\n return out\n })\n}\n","/**\n * @category capability\n * Reactive core for cross-vault live queries/aggregations. Generic over a\n * snapshot S. Single-flight + microtask-coalesced recompute on relevant\n * change. Mirrors the LiveQuery/LiveAggregation contracts via facades.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport type { ChangeEvent } from '@noy-db/hub/kernel'\n\nexport interface CrossVaultLiveOptions<S> {\n readonly subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n readonly isRelevant: (e: ChangeEvent) => boolean\n readonly compute: () => Promise<S>\n readonly initialSnapshot: S\n readonly debounceMs?: number\n}\n\nexport class CrossVaultLive<S> {\n snapshot: S\n error: Error | null = null\n readonly ready: Promise<void>\n\n private readonly subs = new Set<() => void>()\n private readonly unsubChange: () => void\n private readonly opts: CrossVaultLiveOptions<S>\n private stopped = false\n private computing = false\n private dirty = false\n private scheduled = false\n private timer: ReturnType<typeof setTimeout> | null = null\n private resolveReady!: () => void\n private settledOnce = false\n\n constructor(opts: CrossVaultLiveOptions<S>) {\n this.opts = opts\n this.snapshot = opts.initialSnapshot\n this.ready = new Promise<void>((res) => { this.resolveReady = res })\n this.unsubChange = opts.subscribeToChanges((e) => {\n if (this.stopped || !opts.isRelevant(e)) return\n this.schedule()\n })\n this.schedule() // initial compute\n }\n\n subscribe(cb: () => void): () => void {\n if (this.stopped) return () => {}\n this.subs.add(cb)\n return () => this.subs.delete(cb)\n }\n\n stop(): void {\n if (this.stopped) return\n this.stopped = true\n this.unsubChange()\n if (this.timer !== null) clearTimeout(this.timer)\n this.subs.clear()\n if (!this.settledOnce) this.resolveReady() // never leave ready dangling\n }\n\n private schedule(): void {\n if (this.stopped) return\n if (this.computing) { this.dirty = true; return }\n if (this.scheduled) return\n this.scheduled = true\n const run = () => { this.scheduled = false; void this.runCompute() }\n const ms = this.opts.debounceMs ?? 0\n if (ms > 0) this.timer = setTimeout(run, ms)\n // queueMicrotask is non-cancellable; the `if (this.stopped) return` guard at the top of runCompute makes a post-stop fire a no-op.\n else queueMicrotask(run)\n }\n\n private async runCompute(): Promise<void> {\n if (this.stopped) return\n this.computing = true\n this.dirty = false\n try {\n const next = await this.opts.compute()\n if (this.stopped) return\n this.snapshot = next\n this.error = null\n } catch (err) {\n if (this.stopped) return\n this.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n this.computing = false\n if (!this.stopped) {\n if (!this.settledOnce) { this.settledOnce = true; this.resolveReady() }\n for (const cb of this.subs) cb()\n if (this.dirty) this.schedule()\n }\n }\n }\n}\n","/**\n * @klum-db/lobby federation — Insight auto-push controller (#12).\n *\n * Pure scheduling: coalesces shard writes into one microtask flush per burst.\n * Knows nothing about vaults — it calls back into the owner via `recompute`\n * (re-derive + push that shard's summary) and `isSource` (does this collection\n * feed an auto-push derivation?). Best-effort: a failed recompute is reported\n * via `onError` and never breaks the loop or the awaiting caller.\n *\n * @module\n */\nexport class InsightAutoPush {\n /** Partition keys awaiting recompute. */\n private readonly dirty = new Set<string>()\n /** The in-flight flush, or null when idle. */\n private pending: Promise<void> | null = null\n\n constructor(\n private readonly recompute: (partitionKey: string) => Promise<void>,\n private readonly isSource: (collection: string) => boolean,\n private readonly onError: (err: unknown, partitionKey: string) => void = (err, pk) =>\n console.warn(`[klum-db] insight auto-push failed for shard \"${pk}\":`, err),\n ) {}\n\n /** Called from a shard's onAfterWrite hook. Marks the shard dirty + schedules a flush. */\n noteWrite(partitionKey: string, collection: string): void {\n if (!this.isSource(collection)) return\n this.dirty.add(partitionKey)\n this.schedule()\n }\n\n /** Resolve once no flush is pending (drains rescheduled flushes too). */\n async whenSettled(): Promise<void> {\n while (this.pending) await this.pending\n }\n\n private schedule(): void {\n if (this.pending) return\n this.pending = this.runFlush().finally(() => {\n this.pending = null\n // Writes that arrived during the flush re-dirty the set — drain them.\n if (this.dirty.size > 0) this.schedule()\n })\n }\n\n private async runFlush(): Promise<void> {\n // Let same-tick writes coalesce into this flush before snapshotting.\n await Promise.resolve()\n const pks = [...this.dirty]\n this.dirty.clear()\n for (const pk of pks) {\n try {\n await this.recompute(pk)\n } catch (err) {\n this.onError(err, pk)\n }\n }\n }\n}\n","/**\n * @category capability\n * One-shot distributed aggregate wrappers for cross-vault fan-out.\n * Central-reduce: all shard records are concatenated and reduced in one pass\n * so avg/mean values are computed over the full union, not as avg-of-avgs.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport { reduceRecords } from '@noy-db/hub/kernel'\nimport { groupAndReduce } from '@noy-db/hub/kernel'\nimport type { AggregateResult, AggregateSpec } from '@noy-db/hub/kernel'\nimport type {\n FanoutQueryOptions,\n SkippedVault,\n GroupedRow,\n LiveQueryOptions,\n CrossVaultLiveAggregation,\n CrossVaultLiveQuery,\n} from './types.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport type { ChangeEvent } from '@noy-db/hub/kernel'\n\n/** A source that can fan out records across shards. Satisfied by ShardedQuery. */\nexport interface FanoutRecordSource<R> {\n fanoutRecords(options: FanoutQueryOptions): Promise<{ records: R[]; skippedVaults: SkippedVault[] }>\n}\n\n/** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */\nexport interface LiveBinding {\n subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n isRelevant: (e: ChangeEvent) => boolean\n}\n\n/**\n * One-shot cross-vault aggregate. Concatenates all shard records and runs a\n * single central reduce, ensuring correct avg/mean values.\n */\nexport class CrossVaultAggregation<R, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n result: AggregateResult<Spec>\n skippedVaults: SkippedVault[]\n }> {\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return { result: reduceRecords(records, this.spec), skippedVaults }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveAggregation<AggregateResult<Spec>> {\n if (!this.bind) throw new Error('CrossVaultAggregation: live() requires a LiveBinding — use ShardedQuery.aggregate()')\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ value: AggregateResult<Spec> | undefined; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return { value: reduceRecords(records, spec), skipped: skippedVaults }\n },\n initialSnapshot: { value: undefined, skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.value },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n\n/**\n * One-shot cross-vault grouped aggregate. Concatenates all shard records and\n * runs a single central group-and-reduce, emitting one row per bucket.\n */\nexport class CrossVaultGroupedAggregation<R, F extends string, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly field: F,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n results: GroupedRow<F, Spec>[]\n skippedVaults: SkippedVault[]\n }> {\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return {\n results: groupAndReduce<GroupedRow<F, Spec>>(records, this.field, this.spec),\n skippedVaults,\n }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<GroupedRow<F, Spec>> {\n if (!this.bind) throw new Error('CrossVaultGroupedAggregation: live() requires a LiveBinding — use ShardedQuery.groupBy().aggregate()')\n const field = this.field\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ records: GroupedRow<F, Spec>[]; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return {\n records: groupAndReduce<GroupedRow<F, Spec>>(records, field, spec),\n skipped: skippedVaults,\n }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly GroupedRow<F, Spec>[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n","/**\n * @category capability\n * Multi-vault partition federation — VaultGroup transparent shard\n * routing. Spec:\n * docs/superpowers/specs/2026-06-07-mvf-vaultgroup-routing-mvp-design.md.\n */\nimport type { Noydb } from '@noy-db/hub/kernel'\nimport type { Vault } from '@noy-db/hub/kernel'\nimport type { Collection } from '@noy-db/hub/kernel'\nimport { StateManagementVault } from './state-vault.js'\nimport { CrossShardJoinError, DataResidencyError, ReservedVaultNameError, ShardProvisioningError, UnknownShardError, ValidationError } from '@noy-db/hub/kernel'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { classifyShardSkip } from './classify-skip.js'\nimport { applyBroadcastLegs } from './cross-shard-join.js'\nimport type { CoPartitionedLeg, BroadcastLeg, CrossShardJoinOptions, BroadcastJoinOptions } from './cross-shard-join.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport { InsightAutoPush } from './insight-auto-push.js'\nimport { CrossVaultAggregation, CrossVaultGroupedAggregation } from './aggregate-across.js'\nimport type { FanoutRecordSource, LiveBinding } from './aggregate-across.js'\nimport type { AggregateSpec } from '@noy-db/hub/kernel'\nimport type {\n ShardingConfig,\n VaultRegistryRow,\n VaultTemplate,\n FanoutQueryOptions,\n FanoutResult,\n SkippedVault,\n WhereClause,\n LiveQueryOptions,\n CrossVaultLiveQuery,\n CrossVaultDerivationSpec,\n CrossVaultDerivationContext,\n RefreshInsightsResult,\n MigrationStatusRow,\n SchemaRolloutResult,\n} from './types.js'\n\n/** Reserved separator between group name and partition key in a shard vault id. */\nconst SHARD_SEPARATOR = '--'\n/** Store-safe partition-key charset (single hyphens OK; '--' is the reserved separator). */\nconst SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/\n\nfunction assertSafePartitionKey(partitionKey: string): void {\n if (partitionKey.length === 0) {\n throw new ValidationError('partitionKey must be a non-empty string')\n }\n if (partitionKey === STATE_VAULT_NAME) {\n throw new ReservedVaultNameError(partitionKey)\n }\n if (!SAFE_PARTITION_KEY.test(partitionKey)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" contains characters outside [A-Za-z0-9._-]. ` +\n `Map your records to a store-safe key in sharding.keyOf.`,\n )\n }\n if (partitionKey.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" must not contain \"--\" — it is reserved as the ` +\n `shard vault-id separator and would risk shard-id collisions.`,\n )\n }\n}\n\nexport class VaultGroup<T> {\n constructor(\n /** @internal */ readonly db: Noydb,\n /** @internal */ readonly name: string,\n /** @internal */ readonly registry: Collection<VaultRegistryRow>,\n /** @internal */ readonly sharding: ShardingConfig<T>,\n /** @internal */ readonly template: VaultTemplate,\n /** @internal — lazy cutover-on-open (#271). */ readonly cutoverOnOpen: boolean = false,\n ) {\n if (name.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `VaultGroup name \"${name}\" must not contain \"--\" (reserved shard vault-id separator).`,\n )\n }\n }\n\n /** @internal — set when the group is managed (no explicit registry). */\n private stateVault: StateManagementVault | undefined\n\n /** @internal */\n _attachStateVault(sv: StateManagementVault): void {\n this.stateVault = sv\n }\n\n /** Deterministic vault name for a partition key, namespaced by the group. */\n shardVaultId(partitionKey: string): string {\n assertSafePartitionKey(partitionKey)\n return `${this.name}${SHARD_SEPARATOR}${partitionKey}`\n }\n\n /**\n * @internal — group-qualified registry record key (avoids cross-group key\n * collisions). Identical to the shard vault id by design — the registry row\n * for a shard is keyed by that shard's vault id — so it delegates to\n * `shardVaultId`, reusing its partition-key validation.\n */\n registryId(partitionKey: string): string {\n return this.shardVaultId(partitionKey)\n }\n\n /**\n * Registry rows for THIS group (hydrates the registry collection first).\n * The registry may be shared across groups (the auto-wired StateManagement\n * vault holds one `vaultRegistry` for the whole instance), so rows are\n * filtered by `group` — without this, a group's fan-out reads would leak\n * across into other groups' shards. Mirrors the `${group}--` scoping that\n * `liveBinding().isRelevant` already applies to the reactive path.\n */\n async allRows(): Promise<VaultRegistryRow[]> {\n await this.registry.list()\n const rows = this.registry.query().toArray() // toArray() is synchronous\n return rows.filter((r) => r.group === this.name)\n }\n\n /**\n * Open an existing shard and apply the template. When `cutoverOnOpen` is set\n * (#271) and the shard's registry version is behind the template, its cutover\n * runs inline first — so a behind shard never surfaces a stale handle.\n */\n async openShard(partitionKey: string): Promise<Vault> {\n if (this.cutoverOnOpen) {\n const row = await this.registry.get(this.registryId(partitionKey))\n if (row && row.schemaVersion < this.template.version) {\n await this.cutoverShard(partitionKey)\n }\n }\n return this._openShardRaw(partitionKey)\n }\n\n /** @internal — open + configure with no cutover-on-open hook (used by the migration path itself to avoid recursion). */\n private async _openShardRaw(partitionKey: string): Promise<Vault> {\n const vault = await this.db.openVault(this.shardVaultId(partitionKey), { create: false })\n this.template.configure(vault)\n return vault\n }\n\n /**\n * Idempotently provision a shard for `partitionKey`. Returns the\n * configured vault handle.\n *\n * - row + vault present → no-op, return handle\n * - row present, vault gone → ShardProvisioningError\n * - row absent (vault present or not) → open-or-create, configure, write row\n *\n * When `region` is given (the routing `put` passes `sharding.regionOf(record)`),\n * the candidate backend's `capabilities.region` must match or this throws\n * `DataResidencyError` BEFORE provisioning (#271 data-residency guard).\n */\n async createShard(partitionKey: string, region?: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n\n if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n if (row && provisioned) return this.openShard(partitionKey)\n\n // Data-residency placement guard: refuse a shard landing on a backend\n // whose declared region doesn't match the record's required region.\n if (region !== undefined) {\n const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region\n if (backendRegion !== region) throw new DataResidencyError(vaultId, region, backendRegion)\n }\n\n // Row absent → create (or reconcile a provisioned-but-unregistered vault).\n const vault = await this.db.openVault(vaultId)\n this.template.configure(vault)\n await this.registry.put(this.registryId(partitionKey), {\n vaultId,\n partitionKey,\n templateName: this.sharding.vaultTemplate,\n schemaVersion: this.template.version,\n createdAt: Date.now(),\n group: this.name,\n })\n if (this.stateVault) {\n try {\n await this.stateVault.appendEvent({\n type: 'shard-created',\n group: this.name,\n vaultId,\n templateName: this.sharding.vaultTemplate,\n version: this.template.version,\n })\n } catch {\n /* best-effort: event logging never fails the shard write */\n }\n }\n return vault\n }\n\n /**\n * Drill down to a single shard's full Collection API. Throws if the shard is unknown.\n * Also throws ShardProvisioningError if the registry row exists but the vault has been deleted\n * (registry/store divergence).\n */\n async shard(partitionKey: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) throw new UnknownShardError(partitionKey, this.name)\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n return this.openShard(partitionKey)\n }\n\n /** A sharded view over one logical collection across all shards. */\n collection<R = T>(collectionName: string): ShardedCollection<T, R> {\n return new ShardedCollection<T, R>(this, collectionName)\n }\n\n /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */\n async resolveEligible(options: { minVersion?: number } = {}): Promise<{\n eligible: VaultRegistryRow[]\n skipped: SkippedVault[]\n }> {\n const rows = await this.allRows()\n const skipped: SkippedVault[] = []\n const versionOk: VaultRegistryRow[] = []\n for (const row of rows) {\n if (options.minVersion !== undefined && row.schemaVersion < options.minVersion) {\n skipped.push({ vaultId: row.vaultId, reason: 'schema-drift' })\n } else versionOk.push(row)\n }\n const provisioned = await Promise.all(versionOk.map((r) => this.db._shardVaultProvisioned(r.vaultId)))\n const eligible: VaultRegistryRow[] = []\n versionOk.forEach((row, i) => {\n if (provisioned[i]) eligible.push(row)\n else skipped.push({ vaultId: row.vaultId, reason: 'error', error: new ShardProvisioningError(row.vaultId, row.partitionKey) })\n })\n return { eligible, skipped }\n }\n\n /** @internal — registered push-model cross-vault derivations (#271 Insight Vault). */\n private readonly crossVaultDerivations: CrossVaultDerivationSpec[] = []\n\n /** @internal — auto-push controller; created (and the change-subscription armed) when the first autoPush derivation registers. */\n private insightAutoPush?: InsightAutoPush\n\n /**\n * Register a push-model cross-vault derivation — the Insight Vault pattern\n * (#271, Layer 4). Drive it with {@link refreshInsights}.\n *\n * For each shard, `derive(records, ctx)` runs on that shard's `source`\n * records and its return value is written into the analytics\n * (`target.vault` / `target.collection`) vault, keyed by partition key —\n * one summary row per shard. The derivation runs in-process under THIS\n * group's `Noydb` (which already holds both the shard and Insight Vault\n * keyrings); the shard's decrypted records are reduced to a summary that is\n * re-encrypted under the Insight Vault's own DEK, so no shard ciphertext\n * crosses a DEK boundary.\n *\n * **Zero-knowledge note:** the Insight Vault backend sees aggregated\n * structure (totals, counts, timestamps) drawn from many shards — a weaker\n * ZK profile than the per-shard vaults. Opt-in; keep summaries to aggregate\n * scalars (no embeddings / no raw records).\n *\n * v1 is explicit-refresh (no write-path push); call `refreshInsights()`\n * after a batch of writes, or on a schedule.\n *\n * The `target.vault` must NOT be the group itself or one of its shards —\n * a summary writing back into client-shard data would breach the Insight\n * Vault's separate-DEK-boundary contract. Such a target throws a\n * `ValidationError` at registration (#271 Insight-write isolation).\n */\n withCrossVaultDerivation<R = Record<string, unknown>, S = Record<string, unknown>>(\n spec: CrossVaultDerivationSpec<R, S>,\n ): void {\n const target = spec.target.vault\n if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {\n throw new ValidationError(\n `withCrossVaultDerivation: target.vault \"${target}\" is the \"${this.name}\" group itself or one of ` +\n `its shards — an Insight summary must target a SEPARATE analytics vault, never write back into ` +\n `client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`,\n )\n }\n this.crossVaultDerivations.push(spec as unknown as CrossVaultDerivationSpec)\n if (spec.autoPush && !this.insightAutoPush) {\n const controller = new InsightAutoPush(\n (pk) => this._recomputeShardInsights(pk),\n (collection) => this.crossVaultDerivations.some((s) => s.autoPush && s.source === collection),\n )\n this.insightAutoPush = controller\n // Trigger via the Noydb-level change stream (the runtime hook this version\n // ships). One subscription catches EVERY write path into any of this\n // group's shards (ShardedCollection or a direct shard handle). Filter to\n // this group's shard vaults (`<group>--<pk>`); the Insight target can\n // never match that prefix (guarded above), so its writes can't loop back.\n const prefix = `${this.name}${SHARD_SEPARATOR}`\n this.db.on('change', (e) => {\n if (!e.vault.startsWith(prefix)) return\n controller.noteWrite(e.vault.slice(prefix.length), e.collection)\n })\n }\n }\n\n /**\n * Run every registered {@link withCrossVaultDerivation}: read each eligible\n * shard's source records, derive a per-shard summary, and write it into the\n * Insight Vault keyed by partition key. Shards behind `minVersion`,\n * unprovisioned, or whose read errors are reported in `skippedVaults` and\n * are not written (a stale summary is never left behind for a failed shard).\n */\n async refreshInsights(options: { minVersion?: number; concurrency?: number } = {}): Promise<RefreshInsightsResult> {\n if (this.crossVaultDerivations.length === 0) return { written: 0, skippedVaults: [] }\n const { eligible, skipped } = await this.resolveEligible(\n options.minVersion !== undefined ? { minVersion: options.minVersion } : {},\n )\n let written = 0\n for (const spec of this.crossVaultDerivations) {\n const results = await this.db.queryAcross<Record<string, unknown>[]>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.template.configure(vault)\n return vault.collection<Record<string, unknown>>(spec.source).list()\n },\n { create: false, ...(options.concurrency !== undefined ? { concurrency: options.concurrency } : {}) },\n )\n const insight = await this.db.openVault(spec.target.vault)\n const out = insight.collection<Record<string, unknown>>(spec.target.collection)\n for (let i = 0; i < eligible.length; i++) {\n const row = eligible[i]!\n const res = results[i]\n if (!res || res.result === undefined) {\n skipped.push({ vaultId: row.vaultId, reason: 'error', ...(res?.error ? { error: res.error } : {}) })\n continue\n }\n const ctx: CrossVaultDerivationContext = {\n vaultId: row.vaultId,\n partitionKey: row.partitionKey,\n schemaVersion: row.schemaVersion,\n }\n const summary = spec.derive(res.result, ctx)\n await out.put(row.partitionKey, summary)\n written++\n }\n }\n return { written, skippedVaults: skipped }\n }\n\n /** @internal — re-derive + push every autoPush derivation's summary for one shard. */\n private async _recomputeShardInsights(partitionKey: string): Promise<void> {\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) return\n const shard = await this.openShard(partitionKey)\n const ctx: CrossVaultDerivationContext = {\n vaultId: row.vaultId,\n partitionKey,\n schemaVersion: row.schemaVersion,\n }\n for (const spec of this.crossVaultDerivations) {\n if (!spec.autoPush) continue\n const records = await shard.collection<Record<string, unknown>>(spec.source).list()\n const summary = spec.derive(records, ctx)\n const insight = await this.db.openVault(spec.target.vault)\n await insight.collection<Record<string, unknown>>(spec.target.collection).put(partitionKey, summary)\n }\n }\n\n /**\n * Await any pending Insight auto-push flush (#12). Resolves immediately when\n * no autoPush derivation is registered or nothing is pending. Use after a\n * batch of writes to observe the Insight Vault, or in tests.\n */\n async whenInsightsSettled(): Promise<void> {\n if (this.insightAutoPush) await this.insightAutoPush.whenSettled()\n }\n\n /** @internal — the control-plane vault for migration status; lazily opened. */\n private async ensureStateVault(): Promise<StateManagementVault> {\n if (!this.stateVault) this.stateVault = await StateManagementVault.open(this.db)\n return this.stateVault\n }\n\n /**\n * Migrate ONE shard to the template's current version (#271 fleet runner,\n * per-shard step). Opens the shard (applying the template, which arms the\n * M12 cutover), drains schema-write detection, runs `vault.runSchemaCutover()`\n * (the per-vault drain-barrier-transform protocol), then advances the\n * registry row's `schemaVersion` and records `migration-status`. A shard\n * already at the template version is a no-op (`status: 'done'`, migrated 0).\n * Never throws on a cutover failure — it records `status: 'failed'` and\n * returns the row, so a fleet run continues past a bad shard.\n */\n async cutoverShard(partitionKey: string): Promise<MigrationStatusRow> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) throw new UnknownShardError(partitionKey, this.name)\n const target = this.template.version\n const sv = await this.ensureStateVault()\n const base = { vaultId, group: this.name, currentVersion: row.schemaVersion, targetVersion: target }\n\n if (row.schemaVersion >= target) {\n const done: MigrationStatusRow = { ...base, status: 'done', migrated: 0, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(done)\n return done\n }\n\n await sv.upsertMigrationStatus({ ...base, status: 'running', startedAt: Date.now() })\n try { await sv.appendEvent({ type: 'migration-started', group: this.name, vaultId, version: target }) } catch { /* best-effort */ }\n\n try {\n const vault = await this._openShardRaw(partitionKey)\n await vault._drainPendingSchemaWrites()\n const { migrated } = await vault.runSchemaCutover()\n // Advance the authoritative registry version (no built-in update path).\n await this.registry.put(this.registryId(partitionKey), { ...row, schemaVersion: target })\n const done: MigrationStatusRow = { ...base, currentVersion: target, status: 'done', migrated, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(done)\n try { await sv.appendEvent({ type: 'migration-completed', group: this.name, vaultId, version: target }) } catch { /* best-effort */ }\n return done\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err)\n const failed: MigrationStatusRow = { ...base, status: 'failed', error, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(failed)\n try { await sv.appendEvent({ type: 'migration-failed', group: this.name, vaultId, version: target, detail: error }) } catch { /* best-effort */ }\n return failed\n }\n }\n\n /**\n * Active batch runner (#271): migrate every shard behind the template version\n * to it, in controlled batches. **Resumable + crash-safe** — shards already at\n * the target are skipped (the registry version is the source of truth), so a\n * re-run after a crash only picks up the unfinished + previously-failed shards.\n *\n * - `cohort` — restrict to these partition keys (the staged / canary rollout:\n * migrate a small cohort, verify the Insight Vault, then run the rest).\n * - `batchSize` — max shards migrated concurrently per batch (back-pressure).\n * Default 4. Batches run sequentially; shards within a batch run in parallel.\n */\n async rolloutSchema(options: { cohort?: readonly string[]; batchSize?: number } = {}): Promise<SchemaRolloutResult> {\n const target = this.template.version\n const rows = await this.allRows()\n const cohort = options.cohort\n const todo = rows.filter(\n (r) => r.schemaVersion < target && (cohort === undefined || cohort.includes(r.partitionKey)),\n )\n const batchSize = Math.max(1, options.batchSize ?? 4)\n const migrated: string[] = []\n const failed: { vaultId: string; error: string }[] = []\n for (let i = 0; i < todo.length; i += batchSize) {\n const batch = todo.slice(i, i + batchSize)\n const settled = await Promise.all(batch.map((r) => this.cutoverShard(r.partitionKey)))\n for (const res of settled) {\n if (res.status === 'done') migrated.push(res.vaultId)\n else failed.push({ vaultId: res.vaultId, error: res.error ?? 'unknown' })\n }\n }\n return { target, migrated, failed }\n }\n}\n\nexport class ShardedCollection<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n ) {}\n\n /** Route a write to the shard owning `keyOf(record)`. */\n async put(id: string, record: T): Promise<void> {\n const key = this.group.sharding.keyOf(record)\n const row = await this.group.registry.get(this.group.registryId(key))\n let vault: Vault\n if (!row) {\n if (this.group.sharding.autoCreate === false) {\n throw new UnknownShardError(key, this.group.name)\n }\n vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record))\n } else {\n vault = await this.group.openShard(key)\n }\n await vault.collection<T>(this.collectionName).put(id, record)\n }\n\n /** Begin a cross-shard fan-out query. */\n query(): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(this.group, this.collectionName, [])\n }\n}\n\nexport class ShardedQuery<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n private readonly clauses: readonly WhereClause[],\n private readonly coPartitionedLegs: readonly CoPartitionedLeg[] = [],\n private readonly broadcastLegs: readonly BroadcastLeg[] = [],\n ) {}\n\n where(field: string, op: WhereClause['op'], value: unknown): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n [...this.clauses, { field, op, value }],\n this.coPartitionedLegs,\n this.broadcastLegs,\n )\n }\n\n /** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */\n crossShardJoin(field: string, opts: CrossShardJoinOptions): ShardedQuery<T, R> {\n const leg: CoPartitionedLeg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n [...this.coPartitionedLegs, leg],\n this.broadcastLegs,\n )\n }\n\n /** Broadcast dimension join: enrich every merged row from a single shared collection. */\n broadcastJoin(field: string, opts: BroadcastJoinOptions): ShardedQuery<T, R> {\n const leg: BroadcastLeg = {\n field,\n as: opts.as,\n from: opts.from,\n on: opts.on ?? 'id',\n mode: opts.mode ?? 'warn',\n }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n this.coPartitionedLegs,\n [...this.broadcastLegs, leg],\n )\n }\n\n /** @internal — fan out the where-filtered records across eligible shards. */\n async fanoutRecords(options: FanoutQueryOptions = {}): Promise<{ records: R[]; skippedVaults: SkippedVault[] }> {\n const { eligible, skipped } = await this.group.resolveEligible(options)\n // Deterministic pre-check: an undeclared co-partitioned join ref fails\n // identically on every shard, so surface it as ONE CrossShardJoinError\n // rather than N identical skips. Probe the first eligible shard.\n const probeRow = eligible[0]\n if (this.coPartitionedLegs.length > 0 && probeRow) {\n const probe = await this.group.openShard(probeRow.partitionKey)\n this.group.template.configure(probe)\n for (const leg of this.coPartitionedLegs) {\n if (!probe.resolveRef(this.collectionName, leg.field)) {\n throw new CrossShardJoinError(\n `crossShardJoin(\"${leg.field}\"): no ref() declared for \"${leg.field}\" on ` +\n `collection \"${this.collectionName}\" in template \"${this.group.sharding.vaultTemplate}\". ` +\n `Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`,\n )\n }\n }\n }\n const across = await this.group.db.queryAcross<R[]>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.group.template.configure(vault)\n const coll = vault.collection<R>(this.collectionName)\n await coll.list() // hydrate the in-memory cache before the sync query\n // Hydrate each co-partitioned join target — resolveSource reads the\n // in-memory cache, so an unopened right collection would join to an\n // empty snapshot (every row → null).\n for (const leg of this.coPartitionedLegs) {\n const desc = vault.resolveRef(this.collectionName, leg.field)\n if (desc) await vault.collection(desc.target).list()\n }\n let q = coll.query()\n for (const c of this.clauses) q = q.where(c.field, c.op, c.value)\n for (const leg of this.coPartitionedLegs) {\n q = q.join(leg.field, {\n as: leg.as,\n ...(leg.maxRows !== undefined ? { maxRows: leg.maxRows } : {}),\n ...(leg.strategy ? { strategy: leg.strategy } : {}),\n })\n }\n return q.toArray()\n },\n { concurrency: options.concurrency ?? 1, create: false },\n )\n const results: R[] = []\n for (const r of across) {\n if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error })\n else for (const item of r.result) results.push(item)\n }\n return { records: results, skippedVaults: skipped }\n }\n\n /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */\n async toArray(options: FanoutQueryOptions = {}): Promise<FanoutResult<R>> {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n const results = (await applyBroadcastLegs(records, this.broadcastLegs)) as R[]\n return { results, skippedVaults }\n }\n\n /** @internal — build the change-subscription + relevance binding for this query's group+collection. */\n liveBinding(): LiveBinding {\n const group = this.group\n const collectionName = this.collectionName\n return {\n subscribeToChanges: (h) => { group.db.on('change', h); return () => group.db.off('change', h) },\n isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`),\n }\n }\n\n /** @internal — joined queries don't support reactive/aggregate surfaces in v1. */\n private assertNoJoinLegs(surface: string): void {\n if (this.coPartitionedLegs.length || this.broadcastLegs.length) {\n throw new CrossShardJoinError(\n `${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin ` +\n `legs in v1. Use toArray() for joined cross-shard queries.`,\n )\n }\n }\n\n /** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<R> {\n this.assertNoJoinLegs('live')\n const bind = this.liveBinding()\n const core = new CrossVaultLive<{ records: R[]; skipped: SkippedVault[] }>({\n ...bind,\n compute: async () => {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n return { records, skipped: skippedVaults }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly R[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n\n /** One-shot distributed aggregate — central reduce over all shard records. */\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultAggregation<R, Spec> {\n this.assertNoJoinLegs('aggregate')\n return new CrossVaultAggregation<R, Spec>(this, spec, this.liveBinding())\n }\n\n /** Begin a grouped cross-shard aggregate. */\n groupBy<F extends string>(field: F): ShardedGroupedQuery<T, R, F> {\n this.assertNoJoinLegs('groupBy')\n return new ShardedGroupedQuery<T, R, F>(this, field)\n }\n}\n\n/** Grouped cross-shard query — intermediate after `.groupBy(field)`, terminates with `.aggregate(spec)`. */\nexport class ShardedGroupedQuery<T, R, F extends string> {\n constructor(\n private readonly query: ShardedQuery<T, R>,\n private readonly field: F,\n ) {}\n\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultGroupedAggregation<R, F, Spec> {\n return new CrossVaultGroupedAggregation<R, F, Spec>(\n { fanoutRecords: (o) => this.query.fanoutRecords(o) } satisfies FanoutRecordSource<R>,\n this.field,\n spec,\n this.query.liveBinding(),\n )\n }\n}\n","/**\n * @klum-db/lobby — the Lobby orchestrates a group of sovereign noy-db vaults.\n * @packageDocumentation\n */\nimport type { Noydb } from '@noy-db/hub'\nimport { ValidationError, ReservedVaultNameError, VaultTemplateNotFoundError } from '@noy-db/hub/kernel'\nimport { STATE_VAULT_NAME } from '@noy-db/hub'\nimport type { VaultGroup } from './federation/vault-group.js'\nimport type { StateManagementVault } from './federation/state-vault.js'\nimport type { VaultTemplate, VaultGroupOptions } from './federation/types.js'\nimport type { AsXlsxSheetOptions } from '@noy-db/as-xlsx'\nimport type { CrossVaultRef } from './interchange/extract-cross-vault.js'\n\n/**\n * Options for {@link Lobby.exportMultiVaultXlsx} (FR-9).\n *\n * Walks the cross-vault FK closure (FR-2) starting from `primary.vault` using\n * the supplied `primary.seeds` predicates, then delegates to\n * `@noy-db/as-xlsx`'s `toBytesMultiVault` for edge-pure rendering.\n *\n * **Primary-vault row scope:** `walkCrossVaultClosure` populates\n * `perVaultClosure` for the primary vault (the seed predicate rows are\n * collected there). This orchestrator passes that closure to the primary\n * vault entry, so the export contains exactly the seeded rows — not more,\n * not less. Supporting vaults receive their closure slice (FK-referenced ids\n * only, never the full collection).\n */\nexport interface ExportMultiVaultXlsxOptions {\n /** Primary vault: name + seed predicates per collection. */\n readonly primary: {\n readonly vault: string\n readonly seeds: Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>\n }\n /** Cross-vault FK edges that drive the closure walk. */\n readonly crossVaultRefs?: readonly CrossVaultRef[]\n /**\n * Per-vault sheet specs. Keys must be vault names (including `primary.vault`).\n * Sheet options may include `denormalize` for FK-join columns.\n */\n readonly sheets: Readonly<Record<string, readonly AsXlsxSheetOptions[]>>\n /** Optional maxDepth for walkCrossVaultClosure. */\n readonly maxDepth?: number\n /** Optional sheet-name separator forwarded to toBytesMultiVault. */\n readonly sheetSeparator?: string\n}\n\n// ─── FR-7 Surface type imports (used in Lobby method signatures) ──────────────\nimport type { SurfaceRow } from './federation/types.js'\nimport type { MergeReport } from './interchange/merge-compartment.js'\n\n// ─── Dock imports (lower tier read-only units) ────────────────────────────────\nimport { DockedUnit } from './dock/docked-unit.js'\nimport type { UnitDriver } from './dock/unit-driver.js'\nimport type { GraduateOptions, GraduationReport } from './dock/graduate.js'\n\nexport class Lobby {\n readonly noydb: Noydb\n private readonly vaultTemplates = new Map<string, VaultTemplate>()\n\n constructor(noydb: Noydb) {\n this.noydb = noydb\n }\n\n withVaultTemplate(name: string, template: VaultTemplate): void {\n this.vaultTemplates.set(name, template)\n }\n\n async openVaultGroup<T>(name: string, opts: VaultGroupOptions<T>): Promise<VaultGroup<T>> {\n const db = this.noydb\n if (db.isClosed) throw new ValidationError('Instance is closed')\n if (name === STATE_VAULT_NAME) throw new ReservedVaultNameError(name)\n const template = this.vaultTemplates.get(opts.sharding.vaultTemplate)\n if (!template) throw new VaultTemplateNotFoundError(opts.sharding.vaultTemplate)\n const { VaultGroup } = await import('./federation/vault-group.js')\n const { StateManagementVault } = await import('./federation/state-vault.js')\n const stateVault = opts.registry ? undefined : await StateManagementVault.open(db)\n const registry = opts.registry ?? stateVault!.registry\n const group = new VaultGroup<T>(db, name, registry, opts.sharding, template, opts.cutoverOnOpen ?? false)\n if (stateVault) {\n group._attachStateVault(stateVault)\n await stateVault.recordManifest(opts.sharding.vaultTemplate, template)\n try {\n await stateVault.appendEvent({ type: 'manifest-recorded', group: name, templateName: opts.sharding.vaultTemplate, version: template.version })\n await stateVault.appendEvent({ type: 'group-opened', group: name })\n } catch { /* best-effort */ }\n }\n return group\n }\n\n async openStateManagementVault(): Promise<StateManagementVault> {\n const db = this.noydb\n if (db.isClosed) throw new ValidationError('Instance is closed')\n const { StateManagementVault } = await import('./federation/state-vault.js')\n return StateManagementVault.open(db)\n }\n\n // ─── Dock API ─────────────────────────────────────────────────────────────\n\n /**\n * Dock a foreign (non-noy-db) unit at the lower tier — present + read-only\n * carried, without sovereign guarantees. Graduate it with {@link Lobby.graduate}.\n */\n dock(driver: UnitDriver): DockedUnit {\n return new DockedUnit(driver)\n }\n\n /**\n * Graduate a docked foreign unit into a fresh sovereign vault (#11), unlocking\n * the full tier (keyring, CEK, provenance, custody).\n */\n async graduate(docked: DockedUnit, opts: GraduateOptions): Promise<GraduationReport> {\n const { graduate: graduateFn } = await import('./dock/graduate.js')\n return graduateFn(this.noydb, docked, opts)\n }\n\n // ─── FR-7 Surface API ─────────────────────────────────────────────────────\n\n /**\n * Export a scoped partition from `vaultName` bounded to the given surface.\n * Delegates to `exportSurface` in `interchange/surface.ts`.\n * The vault is opened via `this.noydb.openVault(vaultName)`.\n */\n async exportSurface(\n vaultName: string,\n surface: SurfaceRow,\n ): Promise<{ bundleBytes: Uint8Array; transferKey: Uint8Array }> {\n const { exportSurface: exportSurfaceFn } = await import('./interchange/surface.js')\n const vault = await this.noydb.openVault(vaultName)\n return exportSurfaceFn(vault, surface)\n }\n\n /**\n * Apply an exported surface bundle into `vaultName`.\n * Delegates to `applySurface` in `interchange/surface.ts`.\n * The vault is opened via `this.noydb.openVault(vaultName)`.\n */\n async applySurface(\n vaultName: string,\n surface: SurfaceRow,\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n ): Promise<MergeReport> {\n const { applySurface: applySurfaceFn } = await import('./interchange/surface.js')\n const vault = await this.noydb.openVault(vaultName)\n return applySurfaceFn(vault, surface, bundleBytes, transferKey)\n }\n\n /**\n * One-call multi-vault Excel export (FR-9).\n *\n * 1. Calls `walkCrossVaultClosure` (FR-2) to build the FK closure across all\n * referenced vaults, starting from `opts.primary.vault` using the supplied\n * seed predicates.\n * 2. For each vault in `opts.sheets`, opens the vault and attaches the\n * per-vault closure slice from the plan:\n * - **Primary vault**: gets its `perVaultClosure` slice (the seeded rows).\n * - **Supporting vaults**: get their closure slice (FK-referenced ids only).\n * 3. Delegates to `@noy-db/as-xlsx`'s `toBytesMultiVault` for edge-pure\n * rendering (no cross-vault walk in the adapter).\n *\n * Every vault in `opts.sheets` must independently hold\n * `assertCanExport('plaintext','xlsx')`.\n */\n async exportMultiVaultXlsx(opts: ExportMultiVaultXlsxOptions): Promise<Uint8Array> {\n const { walkCrossVaultClosure } = await import('./interchange/extract-cross-vault.js')\n const { toBytesMultiVault } = await import('@noy-db/as-xlsx')\n\n const openVault = (name: string) => this.noydb.openVault(name)\n\n const plan = await walkCrossVaultClosure(openVault, {\n seed: { vault: opts.primary.vault, seeds: opts.primary.seeds },\n ...(opts.crossVaultRefs !== undefined ? { crossVaultRefs: opts.crossVaultRefs } : {}),\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n\n const entries = await Promise.all(\n Object.entries(opts.sheets).map(async ([vaultName, sheets]) => {\n const vault = await openVault(vaultName)\n const closure = plan.perVaultClosure.get(vaultName)\n // Both primary and supporting vaults get their perVaultClosure slice:\n // - primary: the seeded rows (walkCrossVaultClosure includes the seed vault)\n // - supporting: the FK-referenced ids only\n // This ensures the export is bounded to exactly what the closure walk found.\n return {\n vault,\n sheets: sheets as AsXlsxSheetOptions[],\n label: vaultName,\n ...(closure ? { closure } : {}),\n }\n }),\n )\n\n return toBytesMultiVault(entries, {\n ...(opts.sheetSeparator !== undefined ? { sheetSeparator: opts.sheetSeparator } : {}),\n })\n }\n}\n\nexport function createLobby(noydb: Noydb): Lobby {\n return new Lobby(noydb)\n}\n\nexport type {\n VaultGroup, ShardedCollection, ShardedQuery, ShardedGroupedQuery,\n CrossVaultAggregation, CrossVaultGroupedAggregation, StateManagementVault,\n VaultTemplate, VaultRegistryRow, ShardingConfig, VaultGroupOptions,\n FanoutQueryOptions, FanoutResult, SkippedVault,\n CrossVaultLiveQuery, CrossVaultLiveAggregation, LiveQueryOptions,\n SchemaManifestRow, DeploymentEvent, CapturedBlueprint,\n CrossVaultDerivationSpec, CrossVaultDerivationContext, RefreshInsightsResult,\n MigrationStatusRow, SchemaRolloutResult,\n} from './federation/index.js'\nexport type { GroupedRow as CrossVaultGroupedRow } from './federation/index.js'\n\n// Federation tooling (WS-3): drive the @noy-db dev-tools / meter over a vault group.\nexport { groupInspector } from './federation/group-inspector.js'\nexport { meterGroup } from './federation/meter-group.js'\nexport type { GroupMeterReport, GroupShardMetrics } from './federation/meter-group.js'\n\n// Federation error classes as runtime values — so consumers catch them from\n// @klum-db/lobby directly, not via @noy-db/hub's internal /kernel surface.\nexport {\n CrossShardJoinError,\n UnknownShardError,\n ShardProvisioningError,\n VaultTemplateNotFoundError,\n ReservedVaultNameError,\n DataResidencyError,\n} from '@noy-db/hub/kernel'\n\n// ─── Multivault bundle (NDBM) — relocated from @noy-db/hub ────────────────────\nexport {\n encodeMultiBundle,\n decodeMultiBundle,\n writeMultiVaultBundle,\n readNoydbBundleManifest,\n readMultiVaultBundleCompartment,\n NOYDB_MULTI_BUNDLE_MAGIC,\n NOYDB_MULTI_BUNDLE_PREFIX_BYTES,\n NOYDB_MULTI_BUNDLE_VERSION,\n} from './bundle/multi-bundle.js'\nexport type {\n CompartmentManifest,\n MultiBundleManifest,\n MultiVaultCompartmentInput,\n} from './bundle/multi-bundle.js'\n\n// ─── FR-2: Cross-vault FK-closure extraction ──────────────────────────────────\nexport {\n walkCrossVaultClosure,\n extractCrossVaultPartition,\n describeCrossVaultExtraction,\n CrossVaultDanglingRefError,\n} from './interchange/extract-cross-vault.js'\nexport type {\n CrossVaultRef,\n CrossVaultSeed,\n CrossVaultClosurePlan,\n CompartmentMeta,\n ExtractCrossVaultOptions,\n ExtractCrossVaultResult,\n CrossVaultPreview,\n} from './interchange/extract-cross-vault.js'\n\n// ─── FR-3: Merge-import / reconcile-into-existing vault ───────────────────────\nexport { mergeCompartment, mergeDecryptedRecords, FieldLevelDeferredError } from './interchange/merge-compartment.js'\nexport type {\n MergeStrategy,\n DecryptedMergeOptions,\n MergeCompartmentOptions,\n MergeConflict,\n MergeReport,\n} from './interchange/merge-compartment.js'\n\n// ─── FR-8: Migrate-then-merge — upgrade incoming bundle before reconcile ──────\nexport {\n migrateThenMerge,\n MinVersionError,\n MigrationTransformRequiredError,\n} from './interchange/migrate-then-merge.js'\nexport type {\n MigrationStep,\n MigrateThenMergeOptions,\n MigrateThenMergeReport,\n} from './interchange/migrate-then-merge.js'\n\n// ─── FR-4: Field-authority conflict resolver ──────────────────────────────────\nexport {\n resolveFieldAuthority,\n resolveRecordByFieldAuthority,\n FieldAuthorityPolicyMissingError,\n} from './interchange/field-authority.js'\nexport type {\n FieldAuthorityRule,\n FieldAuthorityPolicy,\n FieldAuthorityInputs,\n} from './interchange/field-authority.js'\n\n// ─── FR-6: Sovereign custody (Deed / Custodian / Liberate) ────────────────────\n// Pure re-exports — custody is a vault-level concern in @noy-db/hub; the Lobby\n// surfaces the types/functions so fleet-level orchestration can reach them\n// without importing hub internals directly (no lobby logic in this slice).\nexport { CustodyApi, liberateVault, createDeedOwner, loadDeedMarker, isDeedVault } from '@noy-db/hub'\nexport type { DeedMarker, LiberateOptions, LiberateResult, GrantCustodianOptions } from '@noy-db/hub'\n\n// ─── FR-9: Multi-vault FK-driven Excel export ─────────────────────────────────\n// ExportMultiVaultXlsxOptions is declared (and exported) above alongside Lobby.\n// Re-export the as-xlsx multi-vault types so consumers don't need to import\n// @noy-db/as-xlsx directly.\nexport type {\n MultiVaultXlsxEntry,\n MultiVaultXlsxOptions,\n MultiVaultDenormColumn,\n} from '@noy-db/as-xlsx'\n\n// ─── #11: Dock tier + graduate() ──────────────────────────────────────────────\nexport type { UnitDriver, GraduateOptions, GraduationReport } from './dock/index.js'\nexport { InMemoryUnitDriver, DockedUnit, UnitGraduationError } from './dock/index.js'\n\n// ─── FR-7: Surface / Scoped Sync ─────────────────────────────────────────────\nexport {\n proposeSurface,\n agreeSurface,\n exportSurface,\n applySurface,\n isSurfaceDue,\n listDueSurfaces,\n markSynced,\n SurfaceNotFoundError,\n SurfaceStateError,\n SurfaceCadenceScheduler,\n} from './interchange/surface.js'\nexport type {\n SurfaceDefinition,\n} from './interchange/surface.js'\nexport type {\n SurfaceRow,\n SurfaceDirection,\n SurfaceStatus,\n SurfaceConflictPolicy,\n} from './federation/types.js'\n","/**\n * @klum-db/lobby dock — the lower tier. A `DockedUnit` is present in the Lobby\n * and read-only carried, WITHOUT the sovereign guarantees (custody, field\n * authority, provenance, forget). Those become reachable only after\n * `graduate()` mints a real noy-db vault. The boundary is structural: this\n * class deliberately has no sovereign methods.\n *\n * @module\n */\nimport type { UnitDriver } from './unit-driver.js'\n\nexport class DockedUnit {\n constructor(readonly driver: UnitDriver) {}\n\n get unitId(): string {\n return this.driver.unitId\n }\n\n listCollections(): Promise<readonly string[]> {\n return this.driver.listCollections()\n }\n\n readRecords(collection: string): AsyncIterable<Record<string, unknown>> {\n return this.driver.readRecords(collection)\n }\n}\n","import type { InspectableContainer } from '@noy-db/in-devtools'\nimport type { AccessibleVault, Vault, WriteHook, WriteConflict, WriteQueue, Unsubscribe } from '@noy-db/hub'\nimport type { VaultGroup } from './vault-group.js'\n\n/**\n * Adapt a federation {@link VaultGroup} to the dev-tools `InspectableContainer`\n * contract from `@noy-db/in-devtools`, so the inspector / TUI can browse a\n * whole fleet exactly like a single instance.\n *\n * Built entirely on the group's public surface (`allRows`, `db`, `template`) —\n * no `VaultGroup` changes, and (critically) no `@klum-db` import lands in any\n * `@noy-db` package: the dependency runs one way, klum → noy.\n *\n * Write-event scoping: `group.db` may host vaults outside this group, so write\n * and conflict events are filtered to the group's shard ids. The id set is\n * primed/refreshed on every `listAccessibleVaults()` call — drive `listVaults()`\n * (the inspector's normal first step) before relying on event scoping.\n */\nexport function groupInspector<T>(group: VaultGroup<T>): InspectableContainer {\n let shardIds = new Set<string>()\n const refresh = async () => {\n const rows = await group.allRows()\n shardIds = new Set(rows.map((r) => r.vaultId))\n return rows\n }\n return {\n async listAccessibleVaults(): Promise<readonly AccessibleVault[]> {\n const rows = await refresh()\n return rows.map((r): AccessibleVault => ({ id: r.vaultId, role: 'owner' }))\n },\n async openVault(name: string): Promise<Vault> {\n const vault = await group.db.openVault(name)\n group.template.configure(vault)\n return vault\n },\n onAfterWrite(handler: WriteHook): Unsubscribe {\n return group.db.onAfterWrite((event) => {\n if (shardIds.has(event.vault)) return handler(event)\n })\n },\n onWriteConflict(handler: (c: WriteConflict) => void): Unsubscribe {\n return group.db.onWriteConflict((c) => {\n if (shardIds.has(c.vault)) handler(c)\n })\n },\n get writeQueue(): WriteQueue {\n return group.db.writeQueue\n },\n }\n}\n","import type { VaultGroup } from './vault-group.js'\nimport type { SkippedVault } from './types.js'\n\nexport interface GroupShardMetrics {\n readonly vaultId: string\n readonly partitionKey: string\n readonly schemaVersion: number\n readonly collections: number\n readonly records: number\n}\n\nexport interface GroupMeterReport {\n /** Number of eligible shards measured. */\n readonly vaults: number\n /** Distinct collection names across the group. */\n readonly collections: number\n /** Total record count summed across shards. */\n readonly records: number\n readonly perShard: ReadonlyArray<GroupShardMetrics>\n /** Drifted / provisioning-failed shards — surfaced, never counted or hidden. */\n readonly skipped: ReadonlyArray<SkippedVault>\n}\n\n/**\n * Fan shape-metrics (collection count + record count) across the group's\n * ELIGIBLE shards. Skipped shards (schema-drift / provisioning failures) are\n * reported in `skipped`, never silently dropped. Reuses the per-vault pattern\n * from `multi-bundle.ts` (`vault.collections()` → `collection(n).count()`).\n *\n * Operational store metrics (calls, CAS conflicts) are a separate concern and\n * are already group-wide via `@noy-db/to-meter` on the underlying store.\n */\nexport async function meterGroup<T>(\n group: VaultGroup<T>,\n opts: { minVersion?: number } = {},\n): Promise<GroupMeterReport> {\n const { eligible, skipped } = await group.resolveEligible(\n opts.minVersion !== undefined ? { minVersion: opts.minVersion } : {},\n )\n const perShard: GroupShardMetrics[] = []\n const names = new Set<string>()\n let records = 0\n for (const row of eligible) {\n const vault = await group.shard(row.partitionKey)\n const collNames = await vault.collections()\n let shardRecords = 0\n for (const n of collNames) {\n names.add(n)\n shardRecords += await vault.collection(n).count()\n }\n records += shardRecords\n perShard.push({\n vaultId: row.vaultId,\n partitionKey: row.partitionKey,\n schemaVersion: row.schemaVersion,\n collections: collNames.length,\n records: shardRecords,\n })\n }\n return { vaults: eligible.length, collections: names.size, records, perShard, skipped }\n}\n","/**\n * @klum-db/lobby interchange — migrate-then-merge (FR-8). Upgrade an incoming\n * compartment to the receiver's schema version IN STAGING, then merge.\n *\n * Pipeline:\n * 1. Resolve fromVersion / toVersion.\n * 2. Refuse if incoming bundle is newer than receiver (MinVersionError).\n * 3. Decrypt the compartment bytes.\n * 4. STAGING: apply per-collection migration transforms in-memory; then\n * pre-validate EVERY staged record via `receiver.collection(coll).validateInput()`\n * BEFORE any write. A throwing transform or validation failure leaves the\n * receiver completely untouched (staging-safety guarantee).\n * 5. Delegate to `mergeDecryptedRecords` with the now schema-homogeneous\n * staged records — the merge engine never branches on schema version.\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport { decryptExtractedPartition } from '@noy-db/hub/bundle'\nimport {\n mergeDecryptedRecords,\n type MergeCompartmentOptions,\n type MergeReport,\n} from './merge-compartment.js'\nimport { stageAndValidate, type RecordTransform } from './stage-records.js'\nexport { MigrationTransformRequiredError } from './stage-records.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/** One upgrade step: transform a record body up to `toVersion`. */\nexport interface MigrationStep {\n /** The target version this step brings records up to. */\n readonly toVersion: number\n /**\n * Pure transform: takes the old record body, returns the new record body.\n * The transform need not preserve `id` — the canonical `id` from the decrypted\n * record is re-injected after every step, so a transform that drops or renames\n * `id` cannot silently detach a row from its identity (which would otherwise\n * make the merge skip it, since the diff keys off `record.id`).\n */\n readonly transform: (record: Record<string, unknown>) => Record<string, unknown>\n}\n\nexport interface MigrateThenMergeOptions extends MergeCompartmentOptions {\n /**\n * Incoming bundle's schema version.\n * Read from `CompartmentManifest.schemaVersion` (stamped by FR-2 extract, Task 2).\n * When omitted, `assumeFromVersion` is used as a fallback.\n */\n readonly fromVersion?: number\n /**\n * Fallback version for bundles whose manifest carries no `schemaVersion` (older bundles).\n * Ignored when `fromVersion` is present.\n */\n readonly assumeFromVersion?: number\n /**\n * Target schema version to migrate to.\n * Defaults to `receiver.schemaFenceState().currentSchemaVersion`.\n */\n readonly toVersion?: number\n /**\n * Per-collection ordered upgrade steps, keyed by collection name.\n * Steps are applied in ascending `toVersion` order, filtered to the\n * `(fromVersion, toVersion]` window.\n */\n readonly migrations?: Record<string, readonly MigrationStep[]>\n}\n\nexport interface MigrateThenMergeReport extends MergeReport {\n readonly migration: {\n readonly fromVersion: number\n readonly toVersion: number\n /** Per-collection account of how records reached the target version. */\n readonly byCollection: Record<string, 'transformed' | 'additive-no-transform' | 'same-version'>\n }\n}\n\n// ─── Errors ───────────────────────────────────────────────────────────────────\n\n/**\n * Thrown when the incoming bundle's schema version is greater than the\n * receiver's `currentSchemaVersion`. The receiver must be upgraded first —\n * a newer bundle cannot be down-migrated.\n */\nexport class MinVersionError extends Error {\n constructor(\n public readonly fromVersion: number,\n public readonly toVersion: number,\n ) {\n super(\n `migrateThenMerge: incoming bundle is at schema version ${fromVersion} but the receiver ` +\n `is at ${toVersion}. Upgrade the receiver to at least v${fromVersion} before merging ` +\n `(a newer bundle cannot be down-migrated).`,\n )\n this.name = 'MinVersionError'\n }\n}\n\n\n// ─── Coordinator ─────────────────────────────────────────────────────────────\n\n/**\n * Two-stage upgrade-then-merge pipeline (FR-8).\n *\n * Migrates an incoming compartment from `fromVersion` to `toVersion` in\n * staging, validates every staged record against the receiver schema (using\n * `Collection.validateInput`), then delegates to `mergeDecryptedRecords`.\n *\n * **Staging-safety guarantee:** all transforms and validations run in-memory\n * before `mergeDecryptedRecords` writes anything. A throwing transform OR a\n * failing validation leaves the receiver completely untouched.\n *\n * **Additive fast-path:** collections with no supplied transform still pass\n * when the old shape validates against the receiver schema (additive-only\n * evolution). When no schema is declared on the receiver collection,\n * `validateInput` is a no-op — any shape passes.\n */\nexport async function migrateThenMerge(\n receiver: Vault,\n compartmentBytes: Uint8Array,\n opts: MigrateThenMergeOptions,\n): Promise<MigrateThenMergeReport> {\n // 1. Resolve target version.\n const toVersion = opts.toVersion ?? (await receiver.schemaFenceState()).currentSchemaVersion\n\n // 2. Resolve source version.\n const fromVersion = opts.fromVersion ?? opts.assumeFromVersion\n if (fromVersion === undefined) {\n throw new Error(\n 'migrateThenMerge: cannot determine the incoming schema version. ' +\n 'Pass `fromVersion` (read from the bundle manifest CompartmentManifest.schemaVersion) ' +\n 'or `assumeFromVersion` as a fallback for older bundles.',\n )\n }\n\n // 3. Refuse bundles that are NEWER than the receiver.\n if (fromVersion > toVersion) throw new MinVersionError(fromVersion, toVersion)\n\n // 4. Decrypt the compartment (records only).\n const incoming = await decryptExtractedPartition(compartmentBytes, opts.transferKey)\n\n // 5. STAGING: transform + pre-validate every record before any write.\n // A throwing transform or a validation failure bubbles out here —\n // `mergeDecryptedRecords` is never reached → receiver is untouched.\n const transformsByCollection: Record<string, RecordTransform[]> = {}\n const migrationByCollection: Record<string, 'transformed' | 'additive-no-transform' | 'same-version'> = {}\n for (const [coll, recs] of Object.entries(incoming)) {\n const steps = (opts.migrations?.[coll] ?? [])\n .filter((s) => s.toVersion > fromVersion && s.toVersion <= toVersion)\n .slice()\n .sort((a, b) => a.toVersion - b.toVersion)\n transformsByCollection[coll] = steps.map((s) => s.transform)\n migrationByCollection[coll] =\n fromVersion === toVersion ? 'same-version' : steps.length > 0 ? 'transformed' : 'additive-no-transform'\n void recs\n }\n const staged = await stageAndValidate(receiver, incoming, transformsByCollection)\n\n // 6. Merge the now schema-homogeneous staged records — no version branching here.\n const report = await mergeDecryptedRecords(receiver, staged, opts)\n\n return {\n ...report,\n migration: {\n fromVersion,\n toVersion,\n byCollection: migrationByCollection,\n },\n }\n}\n","/**\n * @klum-db/lobby dock — the foreign-format contract (unit-driver family).\n *\n * A `UnitDriver` reads a foreign / legacy unit (a raw sqlite file, an external\n * schema, …) as plain records. The noy-db vault is the flagship \"vessel\"; this\n * is the passthrough driver for everything else. klum-db ships the interface\n * plus an in-memory reference driver; concrete adapters (sqlite, …) live in\n * separate packages.\n *\n * @module\n */\n\n/** Reads a foreign unit as plain, plaintext records. */\nexport interface UnitDriver {\n /** Stable identifier for the foreign unit (used in audit events). */\n readonly unitId: string\n /** List the foreign collections/tables available to dock. */\n listCollections(): Promise<readonly string[]>\n /** Stream the records of one foreign collection. */\n readRecords(collection: string): AsyncIterable<Record<string, unknown>>\n}\n\n/** In-memory reference driver — the test/flagship-less vessel. */\nexport class InMemoryUnitDriver implements UnitDriver {\n constructor(\n readonly unitId: string,\n private readonly data: Record<string, readonly Record<string, unknown>[]>,\n ) {}\n\n async listCollections(): Promise<readonly string[]> {\n return Object.keys(this.data)\n }\n\n async *readRecords(collection: string): AsyncIterable<Record<string, unknown>> {\n for (const row of this.data[collection] ?? []) yield row\n }\n}\n","/** @klum-db/lobby dock — foreign-unit docking + graduation (#11). */\nexport type { UnitDriver } from './unit-driver.js'\nexport { InMemoryUnitDriver } from './unit-driver.js'\nexport { DockedUnit } from './docked-unit.js'\nexport { graduate, UnitGraduationError } from './graduate.js'\nexport type { GraduateOptions, GraduationReport } from './graduate.js'\n"],"mappings":"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","names":["readNoydbBundleHeader","sha256Hex","generateULID","generateULID","extractPartition","sha256Hex","generateULID","ValidationError","ReservedVaultNameError","STATE_VAULT_NAME","CrossShardJoinError","UnknownShardError","ShardProvisioningError","VaultTemplateNotFoundError","ReservedVaultNameError","DataResidencyError","decryptExtractedPartition","createDeedOwner","ValidationError","STATE_VAULT_NAME","ReservedVaultNameError","VaultGroup","StateManagementVault","walkCrossVaultClosure"]}
1
+ {"version":3,"sources":["../src/bundle/uint32.ts","../src/bundle/multi-bundle.ts","../src/interchange/extract-cross-vault.ts","../src/interchange/field-authority.ts","../src/interchange/merge-compartment.ts","../src/interchange/stage-records.ts","../src/dock/graduate.ts","../src/interchange/surface.ts","../src/federation/schema-manifest.ts","../src/federation/constants.ts","../src/federation/state-vault.ts","../src/federation/classify-skip.ts","../src/federation/cross-shard-join.ts","../src/federation/cross-vault-live.ts","../src/federation/insight-auto-push.ts","../src/federation/partial-reduce.ts","../src/federation/aggregate-across.ts","../src/federation/vault-group.ts","../src/index.ts","../src/dock/docked-unit.ts","../src/federation/group-inspector.ts","../src/federation/meter-group.ts","../src/interchange/migrate-then-merge.ts","../src/dock/unit-driver.ts","../src/dock/index.ts"],"sourcesContent":["/**\n * Big-endian uint32 codec for the NDBM outer container's length fields.\n * The multi-bundle framing is klum's own format; these are local so noy-db\n * need not expose low-level byte utilities.\n * @module\n */\n\n/** Read a big-endian uint32 from `bytes` at `offset`. */\nexport function readUint32BE(bytes: Uint8Array, offset: number): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>> 0\n )\n}\n\n/** Write `value` as a big-endian uint32 into `bytes` at `offset`. */\nexport function writeUint32BE(bytes: Uint8Array, offset: number, value: number): void {\n bytes[offset] = (value >>> 24) & 0xff\n bytes[offset + 1] = (value >>> 16) & 0xff\n bytes[offset + 2] = (value >>> 8) & 0xff\n bytes[offset + 3] = value & 0xff\n}\n","/**\n * Multi-compartment `.noydb` bundle (`NDBM`). A thin outer container\n * that embeds N standard single-vault `.noydb` bundles plus an\n * unencrypted, owner-curated **manifest**. The v1 single-vault format\n * is untouched; each compartment is a complete v1 bundle, produced by\n * `writeNoydbBundle` and read by `readNoydbBundle`.\n *\n * Layout: magic 'NDBM'(4) · version(1) · reserved(1) · manifestLen(4 BE)\n * · manifest JSON · concat(inner v1 bundles, in manifest order).\n *\n * @packageDocumentation\n */\nimport { sha256Hex, generateULID, type Vault } from '@noy-db/hub/kernel'\nimport {\n writeNoydbBundle,\n readNoydbBundleHeader,\n type WriteNoydbBundleOptions,\n} from '@noy-db/hub/bundle'\nimport {\n readNoydbBundlePublicEnvelope,\n hasNoydbBundleMagic,\n type PublicEnvelope,\n} from '@noy-db/hub'\nimport { readUint32BE, writeUint32BE } from './uint32.js'\n\n/** Magic bytes 'NDBM' — NOYDB Multi-compartment bundle. */\nexport const NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([0x4e, 0x44, 0x42, 0x4d])\n/** Fixed prefix: magic(4) + version(1) + reserved(1) + manifestLen(4). */\nexport const NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10\n/** Current multi-bundle layout version. */\nexport const NOYDB_MULTI_BUNDLE_VERSION = 1\n\n/** One compartment's entry in the pre-decrypt manifest. */\nexport interface CompartmentManifest {\n /** The inner v1 bundle's stable ULID handle. */\n readonly handle: string\n /** Owner-curated classification (e.g. 'shard', 'pool'). Opt-in. */\n readonly roleTag?: string\n /** ISO export timestamp. Always set by the writer; absent for a v1 bundle read as a 1-entry manifest. */\n readonly exportedAt?: string\n /** Compartment (vault) name. Opt-in disclosure. */\n readonly name?: string\n /** Collection names + record counts. Opt-in disclosure. */\n readonly collections?: readonly { readonly name: string; readonly count: number }[]\n /** Inner bundle's owner-curated public envelope, surfaced. Opt-in. */\n readonly publicEnvelope?: PublicEnvelope\n /** Byte length of the inner v1 bundle (drives framing). */\n readonly innerBytes: number\n /** SHA-256 (lowercase hex) of the inner v1 bundle bytes — pre-decrypt integrity. */\n readonly innerSha256: string\n /** Source vault's schema fence version at extract time (FR-8). Opt-in; absent on older bundles. */\n readonly schemaVersion?: number\n}\n\n/** The unencrypted manifest of a multi-compartment bundle. */\nexport interface MultiBundleManifest {\n readonly multiFormatVersion: number\n /** Opaque ULID for the outer container. */\n readonly handle: string\n readonly compartments: readonly CompartmentManifest[]\n}\n\n/** Assemble the `NDBM` container from a manifest + inner bundle bytes (in manifest order). */\nexport function encodeMultiBundle(\n manifest: MultiBundleManifest,\n inner: readonly Uint8Array[],\n): Uint8Array {\n validateManifest(manifest)\n if (manifest.compartments.length !== inner.length) {\n throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`)\n }\n for (let i = 0; i < inner.length; i++) {\n if (manifest.compartments[i]!.innerBytes !== inner[i]!.length) {\n throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i]!.innerBytes} but ${inner[i]!.length} bytes were provided.`)\n }\n }\n const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest))\n const bodyLen = inner.reduce((n, b) => n + b.length, 0)\n const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen)\n out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0)\n out[4] = NOYDB_MULTI_BUNDLE_VERSION\n out[5] = 0\n writeUint32BE(out, 6, manifestBytes.length)\n out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES)\n let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length\n for (const b of inner) { out.set(b, off); off += b.length }\n return out\n}\n\nfunction hasMultiMagic(bytes: Uint8Array): boolean {\n if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false\n for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false\n return true\n}\n\nfunction validateManifest(parsed: unknown): asserts parsed is MultiBundleManifest {\n if (parsed === null || typeof parsed !== 'object') throw new Error('multi-bundle manifest must be a JSON object.')\n const m = parsed as Record<string, unknown>\n if (m['multiFormatVersion'] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m['multiFormatVersion'])}.`)\n if (typeof m['handle'] !== 'string' || m['handle'].length === 0) throw new Error('multi-bundle manifest.handle must be a non-empty string.')\n if (!Array.isArray(m['compartments'])) throw new Error('multi-bundle manifest.compartments must be an array.')\n const seenHandles = new Set<string>()\n for (const c of m['compartments'] as unknown[]) {\n if (c === null || typeof c !== 'object') throw new Error('multi-bundle compartment must be an object.')\n const e = c as Record<string, unknown>\n if (typeof e['handle'] !== 'string' || e['handle'].length === 0) throw new Error('multi-bundle compartment.handle must be a non-empty string.')\n if (seenHandles.has(e['handle'])) {\n throw new Error(`multi-bundle manifest has a duplicate compartment handle \"${e['handle']}\".`)\n }\n seenHandles.add(e['handle'])\n if (typeof e['innerBytes'] !== 'number' || !Number.isInteger(e['innerBytes']) || e['innerBytes'] < 0) throw new Error('multi-bundle compartment.innerBytes must be a non-negative integer.')\n if (typeof e['innerSha256'] !== 'string' || !/^[0-9a-f]{64}$/.test(e['innerSha256'])) throw new Error('multi-bundle compartment.innerSha256 must be 64-char lowercase hex.')\n }\n}\n\n/** Parse the `NDBM` container into its manifest + raw inner bundle byte slices. */\nexport function decodeMultiBundle(bytes: Uint8Array): { manifest: MultiBundleManifest; inner: Uint8Array[] } {\n if (!hasMultiMagic(bytes)) throw new Error('not a NOYDB multi-bundle: missing NDBM magic.')\n if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error('multi-bundle truncated: shorter than the fixed prefix.')\n if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`)\n const manifestLen = readUint32BE(bytes, 6)\n const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen\n if (manifestEnd > bytes.length) throw new Error('multi-bundle truncated: manifest length overruns the buffer.')\n const manifestJson = new TextDecoder('utf-8', { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd))\n let parsed: unknown\n try { parsed = JSON.parse(manifestJson) } catch (err) { throw new Error(`multi-bundle manifest is not valid JSON: ${(err as Error).message}`) }\n validateManifest(parsed)\n const inner: Uint8Array[] = []\n let off = manifestEnd\n for (const c of parsed.compartments) {\n const end = off + c.innerBytes\n if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment \"${c.handle}\" innerBytes overruns the buffer.`)\n inner.push(bytes.subarray(off, end))\n off = end\n }\n if (off !== bytes.length) {\n throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment — buffer may be corrupt.`)\n }\n return { manifest: parsed, inner }\n}\n\n/** Per-compartment input to {@link writeMultiVaultBundle}. */\nexport interface MultiVaultCompartmentInput {\n readonly vault: Vault\n /** Owner-curated classification surfaced in the manifest (e.g. 'shard', 'pool'). */\n readonly roleTag?: string\n /** ISO timestamp for the manifest; defaults to now. */\n readonly exportedAt?: string\n /** Opt-in pre-decrypt disclosure for this compartment. */\n readonly disclose?: {\n /** `true` → use `vault.name`; a string → that explicit name. */\n readonly name?: boolean | string\n /** `true` → include collection names + record counts. */\n readonly collections?: boolean\n /** `true` → surface the inner bundle's public envelope into the manifest. */\n readonly publicEnvelope?: boolean\n }\n /** Options forwarded to `writeNoydbBundle` for this compartment's inner bundle. */\n readonly bundleOptions?: WriteNoydbBundleOptions\n}\n\n/** Write N vaults into one `NDBM` multi-compartment bundle. */\nexport async function writeMultiVaultBundle(\n compartments: readonly MultiVaultCompartmentInput[],\n opts: { readonly handle?: string } = {},\n): Promise<Uint8Array> {\n if (compartments.length === 0) throw new Error('writeMultiVaultBundle: at least one compartment is required.')\n const inner: Uint8Array[] = []\n const entries: CompartmentManifest[] = []\n for (const c of compartments) {\n const innerBytes = await writeNoydbBundle(c.vault, c.bundleOptions ?? {})\n const header = readNoydbBundleHeader(innerBytes)\n const entry: {\n -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K]\n } = {\n handle: header.handle,\n exportedAt: c.exportedAt ?? new Date().toISOString(),\n innerBytes: innerBytes.length,\n innerSha256: await sha256Hex(innerBytes),\n }\n if (c.roleTag !== undefined) entry.roleTag = c.roleTag\n if (c.disclose?.name !== undefined && c.disclose.name !== false) {\n entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name\n }\n if (c.disclose?.collections === true) {\n const names = await c.vault.collections()\n entry.collections = await Promise.all(\n names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() })),\n )\n }\n if (c.disclose?.publicEnvelope === true) {\n const env = readNoydbBundlePublicEnvelope(innerBytes)\n if (env !== undefined) entry.publicEnvelope = env\n }\n // FR-8: stamp schema fence version so the bundle self-describes its version.\n const fence = await c.vault.schemaFenceState()\n entry.schemaVersion = fence.currentSchemaVersion\n inner.push(innerBytes)\n entries.push(entry)\n }\n const manifest: MultiBundleManifest = {\n multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,\n handle: opts.handle ?? generateULID(),\n compartments: entries,\n }\n return encodeMultiBundle(manifest, inner)\n}\n\n/**\n * Read the pre-decrypt manifest of a bundle WITHOUT decrypting any\n * compartment. Accepts a multi-compartment `NDBM` bundle (returns its\n * N entries) OR a single v1 `NDB1` bundle (returns a 1-entry manifest,\n * for uniform handling). Throws on anything else.\n */\nexport async function readNoydbBundleManifest(bytes: Uint8Array): Promise<CompartmentManifest[]> {\n if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments]\n if (hasNoydbBundleMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n const env = readNoydbBundlePublicEnvelope(bytes)\n const entry: { -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K] } = {\n handle: header.handle,\n innerBytes: bytes.length,\n innerSha256: await sha256Hex(bytes),\n }\n if (env !== undefined) entry.publicEnvelope = env\n return [entry]\n }\n throw new Error('readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).')\n}\n\n/**\n * Extract one compartment's inner v1 `.noydb` bundle bytes, ready to\n * pass to `readNoydbBundle`. `selector` is a compartment `handle` or a\n * zero-based index. For a single v1 bundle, the bundle itself is the\n * only compartment.\n *\n * Does NOT verify the manifest `innerSha256` — it returns the raw\n * slice. Integrity is enforced downstream: `readNoydbBundle` verifies\n * the inner bundle's own `bodySha256`. Callers wanting an early,\n * pre-decrypt check can hash the returned bytes against the\n * compartment's `innerSha256`.\n */\nexport function readMultiVaultBundleCompartment(bytes: Uint8Array, selector: string | number): Uint8Array {\n if (typeof selector === 'number' && !Number.isInteger(selector)) {\n throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`)\n }\n if (hasNoydbBundleMagic(bytes) && !hasMultiMagic(bytes)) {\n const header = readNoydbBundleHeader(bytes)\n if (selector === 0 || selector === header.handle) return bytes\n throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment \"${header.handle}\".`)\n }\n const { manifest, inner } = decodeMultiBundle(bytes)\n const idx = typeof selector === 'number'\n ? selector\n : manifest.compartments.findIndex((c) => c.handle === selector)\n if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === 'number' ? `at index ${selector}` : `\"${selector}\"`}.`)\n return inner[idx]!\n}\n","/**\n * @klum-db/lobby interchange — cross-vault FK-closure extraction.\n * Composes hub's intra-vault primitives + FR-1's encodeMultiBundle.\n * @packageDocumentation\n */\nimport type { Vault } from '@noy-db/hub'\nimport {\n walkClosure,\n extractPartition,\n readNoydbBundleHeader,\n describeExtraction,\n type ExtractionPreview,\n} from '@noy-db/hub/bundle'\nimport { sha256Hex, generateULID } from '@noy-db/hub/kernel'\nimport {\n encodeMultiBundle,\n NOYDB_MULTI_BUNDLE_VERSION,\n type MultiBundleManifest,\n type CompartmentManifest,\n} from '../bundle/multi-bundle.js'\n\n/** A denormalized cross-vault FK edge (hub refuses these as native refs). */\nexport interface CrossVaultRef {\n readonly from: { readonly collection: string; readonly field: string }\n readonly to: {\n readonly vault: string\n readonly collection: string\n /**\n * Target field the FK points to. **Currently must be `'id'` (or omitted).**\n * Non-`id` business-key target fields are not yet supported (will be added\n * when adopt/merge lands).\n */\n readonly field?: string\n }\n}\n\n/** Seed for the primary vault (predicate per collection, like hub walkClosure). */\nexport interface CrossVaultSeed {\n readonly vault: string\n readonly seeds: Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>\n}\n\nexport interface CrossVaultClosurePlan {\n /** vault → seed predicates to feed extractPartition (primary: caller's; targets: id-membership). */\n readonly perVaultSeeds: Map<string, Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>>\n /** vault → intra closure (collection → ids). */\n readonly perVaultClosure: Map<string, Map<string, Set<string>>>\n /** referenced rows not found in their target closure. */\n readonly dangling: { vault: string; collection: string; id: string }[]\n}\n\nfunction asIdArray(v: unknown): string[] {\n if (v === null || v === undefined) return []\n if (Array.isArray(v)) return v.filter((x) => typeof x === 'string' || typeof x === 'number').map(String)\n if (typeof v === 'string' || typeof v === 'number') return [String(v)]\n return []\n}\n\n/**\n * Walk an FK closure that spans vault boundaries via app-supplied cross-vault refs.\n *\n * @param openVault - resolver for a vault by name (idempotent in the hub —\n * repeated calls return the same cached instance, so the per-round calls are free).\n * @param opts.maxDepth - bounds BOTH the number of inter-vault rounds (this planner's\n * outer fixpoint loop) AND hub's intra-vault `walkClosure` FK depth. Default 16.\n */\nexport async function walkCrossVaultClosure(\n openVault: (name: string) => Promise<Vault>,\n opts: { seed: CrossVaultSeed; crossVaultRefs?: readonly CrossVaultRef[]; maxDepth?: number },\n): Promise<CrossVaultClosurePlan> {\n const refs = opts.crossVaultRefs ?? []\n const maxDepth = opts.maxDepth ?? 16\n\n // Guard: non-id target fields are silently broken (dangling false-positives + fixpoint burn).\n // Fail loud until business-key target support is added with adopt/merge.\n for (const ref of refs) {\n if (ref.to.field !== undefined && ref.to.field !== 'id') {\n throw new Error(\n `cross-vault extraction: to.field \"${ref.to.field}\" (on ${ref.to.vault}/${ref.to.collection}) is not supported yet — `\n + `the cross-vault target field must be \"id\" (or omitted). Business-key target fields are a future enhancement.`,\n )\n }\n }\n\n const perVaultClosure = new Map<string, Map<string, Set<string>>>()\n const perVaultSeeds: CrossVaultClosurePlan['perVaultSeeds'] = new Map()\n // accumulated referenced ids per target vault+collection\n const targetIds = new Map<string, Map<string, Set<string>>>()\n\n const addTarget = (v: string, c: string, id: string) => {\n let m = targetIds.get(v)\n if (!m) { m = new Map(); targetIds.set(v, m) }\n let s = m.get(c)\n if (!s) { s = new Set(); m.set(c, s) }\n s.add(id)\n }\n\n const mergeClosure = (v: string, cl: Map<string, Set<string>>) => {\n let dest = perVaultClosure.get(v)\n if (!dest) { dest = new Map(); perVaultClosure.set(v, dest) }\n for (const [c, ids] of cl) {\n let s = dest.get(c)\n if (!s) { s = new Set(); dest.set(c, s) }\n for (const id of ids) s.add(id)\n }\n }\n\n // round 0: primary vault\n perVaultSeeds.set(opts.seed.vault, opts.seed.seeds)\n const queue: string[] = [opts.seed.vault]\n const walkedSignature = new Set<string>()\n\n let round = 0\n while (queue.length > 0) {\n if (round++ > maxDepth) break\n const batch = queue.splice(0, queue.length)\n for (const vaultName of batch) {\n const seeds = perVaultSeeds.get(vaultName)!\n const v = await openVault(vaultName)\n const { closure } = await walkClosure(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n mergeClosure(vaultName, closure)\n // harvest cross-vault FKs from this vault's closure\n for (const ref of refs) {\n const ids = closure.get(ref.from.collection)\n if (!ids) continue\n const coll = v.collection<Record<string, unknown>>(ref.from.collection)\n for (const id of ids) {\n const rec = await coll.get(id)\n for (const fk of asIdArray(rec?.[ref.from.field])) {\n addTarget(ref.to.vault, ref.to.collection, fk)\n }\n }\n }\n }\n // enqueue targets whose id-set introduces records not yet in their closure\n for (const [tVault, colls] of targetIds) {\n for (const [tColl, ids] of colls) {\n const field = refs.find((r) => r.to.vault === tVault && r.to.collection === tColl)?.to.field ?? 'id'\n const have = perVaultClosure.get(tVault)?.get(tColl) ?? new Set<string>()\n const sig = `${tVault}\\0${tColl}\\0${[...ids].sort().join(',')}`\n if ([...ids].every((id) => have.has(id)) || walkedSignature.has(sig)) continue\n // Stamp before enqueue; safe because harvest is sequential — no other FK\n // accumulation can extend targetIds between this stamp and the next round.\n walkedSignature.add(sig)\n const wanted = new Set(ids)\n const seed = { [tColl]: (rec: Record<string, unknown>) => wanted.has(String(rec[field])) }\n const existing = perVaultSeeds.get(tVault)\n // `wanted` is always the full cumulative targetIds set for this collection,\n // so overwriting an existing predicate for tColl is safe and idempotent.\n perVaultSeeds.set(tVault, existing ? { ...existing, ...seed } : seed)\n queue.push(tVault)\n }\n }\n }\n\n // dangling check: every harvested target id must appear in the final closure\n const dangling: CrossVaultClosurePlan['dangling'] = []\n for (const [tVault, colls] of targetIds) {\n for (const [tColl, ids] of colls) {\n const have = perVaultClosure.get(tVault)?.get(tColl) ?? new Set<string>()\n for (const id of ids) {\n if (!have.has(id)) dangling.push({ vault: tVault, collection: tColl, id })\n }\n }\n }\n\n return { perVaultSeeds, perVaultClosure, dangling }\n}\n\n// ─── Task 2: extractCrossVaultPartition ────────────────────────────────────────\n\nexport class CrossVaultDanglingRefError extends Error {\n constructor(readonly dangling: { vault: string; collection: string; id: string }[]) {\n super(\n `cross-vault extraction: ${dangling.length} referenced row(s) missing from their target closure: `\n + dangling.slice(0, 5).map((d) => `${d.vault}/${d.collection}/${d.id}`).join(', '),\n )\n this.name = 'CrossVaultDanglingRefError'\n }\n}\n\nexport interface CompartmentMeta {\n readonly roleTag?: string\n readonly disclose?: {\n readonly name?: boolean | string\n readonly collections?: boolean\n }\n}\n\nexport interface ExtractCrossVaultOptions {\n readonly seed: CrossVaultSeed\n readonly crossVaultRefs?: readonly CrossVaultRef[]\n readonly maxDepth?: number\n readonly carrySchemas?: boolean\n readonly carryLedger?: boolean\n readonly compression?: 'auto' | 'brotli' | 'gzip' | 'none'\n readonly compartmentMeta?: Record<string, CompartmentMeta>\n}\n\nexport interface ExtractCrossVaultResult {\n readonly bundle: Uint8Array\n /**\n * Per-compartment raw 32-byte transfer keys, keyed by vault name. Each\n * unseals that compartment's DEKs on adoption.\n * @remarks SECRET — deliver these out-of-band, SEPARATELY from `bundle`.\n * Anyone with both the bundle and a compartment's key can decrypt that\n * compartment. Never store them alongside the bundle.\n */\n readonly transferKeys: Record<string, Uint8Array>\n readonly sealIds: Record<string, string>\n}\n\nexport async function extractCrossVaultPartition(\n openVault: (name: string) => Promise<Vault>,\n opts: ExtractCrossVaultOptions,\n): Promise<ExtractCrossVaultResult> {\n const plan = await walkCrossVaultClosure(openVault, opts)\n if (plan.dangling.length > 0) throw new CrossVaultDanglingRefError(plan.dangling)\n\n const inner: Uint8Array[] = []\n const compartments: CompartmentManifest[] = []\n const transferKeys: Record<string, Uint8Array> = {}\n const sealIds: Record<string, string> = {}\n\n for (const [vaultName, seeds] of plan.perVaultSeeds) {\n const v = await openVault(vaultName)\n const { bundleBytes, transferKey, sealId } = await extractPartition(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n carrySchemas: opts.carrySchemas ?? true,\n carryLedger: opts.carryLedger ?? false,\n ...(opts.compression !== undefined ? { compression: opts.compression } : {}),\n })\n\n const header = readNoydbBundleHeader(bundleBytes)\n const meta = opts.compartmentMeta?.[vaultName]\n\n const entry: { -readonly [K in keyof CompartmentManifest]: CompartmentManifest[K] } = {\n handle: header.handle,\n exportedAt: new Date().toISOString(),\n innerBytes: bundleBytes.length,\n innerSha256: await sha256Hex(bundleBytes),\n }\n\n if (meta?.roleTag !== undefined) entry.roleTag = meta.roleTag\n if (meta?.disclose?.name !== undefined && meta.disclose.name !== false) {\n entry.name = meta.disclose.name === true ? v.name : meta.disclose.name\n }\n if (meta?.disclose?.collections === true) {\n const cl = plan.perVaultClosure.get(vaultName)\n // `ids.size` reflects the EXTRACTED CLOSURE SLICE for this vault (the subset\n // selected by the cross-vault FK walk), NOT the full vault record count.\n // This differs from FR-1's writeMultiVaultBundle which counts the full vault.\n if (cl) entry.collections = [...cl].map(([name, ids]) => ({ name, count: ids.size }))\n }\n\n // FR-8: stamp the source vault's schema fence version so the bundle self-describes its version.\n const fence = await v.schemaFenceState()\n entry.schemaVersion = fence.currentSchemaVersion\n\n inner.push(bundleBytes)\n compartments.push(entry)\n transferKeys[vaultName] = transferKey\n sealIds[vaultName] = sealId\n }\n\n const manifest: MultiBundleManifest = {\n multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,\n handle: generateULID(),\n compartments,\n }\n return { bundle: encodeMultiBundle(manifest, inner), transferKeys, sealIds }\n}\n\n// ─── Task 3: describeCrossVaultExtraction ────────────────────────────────────\n\nexport interface CrossVaultPreview {\n readonly compartments: ReadonlyArray<{ readonly vault: string; readonly preview: ExtractionPreview }>\n readonly dangling: ReadonlyArray<{ readonly vault: string; readonly collection: string; readonly id: string }>\n}\n\n/**\n * Dry-run that walks the cross-vault FK closure and aggregates hub's per-vault\n * `describeExtraction` into a per-compartment preview.\n *\n * Writes nothing. Returns the per-vault `ExtractionPreview` (record counts,\n * byte totals) and the dangling list from the closure walk.\n */\nexport async function describeCrossVaultExtraction(\n openVault: (name: string) => Promise<Vault>,\n opts: { seed: CrossVaultSeed; crossVaultRefs?: readonly CrossVaultRef[]; maxDepth?: number },\n): Promise<CrossVaultPreview> {\n const plan = await walkCrossVaultClosure(openVault, opts)\n const compartments: Array<{ vault: string; preview: ExtractionPreview }> = []\n for (const [vaultName, seeds] of plan.perVaultSeeds) {\n const v = await openVault(vaultName)\n const preview = await describeExtraction(v, {\n seeds,\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n compartments.push({ vault: vaultName, preview })\n }\n return { compartments, dangling: plan.dangling }\n}\n","/**\n * @klum-db/lobby interchange — field-authority conflict resolution (FR-4).\n *\n * Pure functions: given an app-supplied per-field policy and both sides'\n * RECORD-level provenance (FR-5 `_source`/`_sourceTs`), decide field-by-field\n * whether the incoming value wins. No vault I/O — unit-testable in isolation.\n * @module\n */\n\n/** How a single field's authority is decided on merge. */\nexport type FieldAuthorityRule =\n | { readonly authority: 'source-newest' }\n | { readonly authority: 'owner'; readonly ownerSource: string }\n | { readonly authority: 'fixed-source'; readonly source: string }\n\n/** Per-collection field → rule map. Fields not listed default to keep-local. */\nexport type FieldAuthorityPolicy = Record<string, FieldAuthorityRule>\n\n/** Record-level provenance for both sides (shared across all fields — Q3 defer). */\nexport interface FieldAuthorityInputs {\n readonly incomingSource?: string\n readonly incomingSourceTs?: string\n readonly localSource?: string\n readonly localSourceTs?: string\n}\n\n/** Thrown when a collection resolves to `field-authority` but no policy is supplied for it. */\nexport class FieldAuthorityPolicyMissingError extends Error {\n constructor(collection: string) {\n super(\n `mergeCompartment: the 'field-authority' strategy for \"${collection}\" requires a ` +\n `fieldAuthority policy entry for that collection, but none was supplied.`,\n )\n this.name = 'FieldAuthorityPolicyMissingError'\n }\n}\n\n/** Decide whether the INCOMING value of one field wins. Pure. Defaults never clobber on ambiguity. */\nexport function resolveFieldAuthority(\n rule: FieldAuthorityRule,\n io: FieldAuthorityInputs,\n): 'incoming' | 'local' {\n switch (rule.authority) {\n case 'source-newest': {\n const inc = io.incomingSourceTs\n const loc = io.localSourceTs\n if (inc === undefined) return 'local' // no incoming provenance → don't clobber\n if (loc === undefined) return 'incoming' // local has none, incoming does\n return inc > loc ? 'incoming' : 'local' // ISO-8601 lexicographic; tie → local\n }\n case 'owner':\n return io.incomingSource === rule.ownerSource ? 'incoming' : 'local'\n case 'fixed-source':\n return io.incomingSource === rule.source ? 'incoming' : 'local'\n }\n}\n\n/**\n * Build the merged record per policy, starting from the local (`before`) copy\n * and overlaying only the changed fields whose rule resolves to `incoming`.\n * Returns the merged record plus a per-field decision map (for the audit report).\n * Pure — no I/O.\n */\nexport function resolveRecordByFieldAuthority(\n policy: FieldAuthorityPolicy,\n before: Record<string, unknown>,\n incoming: Record<string, unknown>,\n changedFields: readonly string[],\n io: FieldAuthorityInputs,\n): { merged: Record<string, unknown>; decisions: Record<string, 'incoming' | 'local'> } {\n const merged: Record<string, unknown> = { ...before }\n const decisions: Record<string, 'incoming' | 'local'> = {}\n for (const f of changedFields) {\n const rule = policy[f]\n if (rule === undefined) { decisions[f] = 'local'; continue } // unlisted → keep local\n const who = resolveFieldAuthority(rule, io)\n decisions[f] = who\n if (who === 'incoming') merged[f] = incoming[f]\n }\n return { merged, decisions }\n}\n","/**\n * @klum-db/lobby interchange — reconcile an incoming extracted-partition\n * compartment into an existing receiver vault (FR-3).\n *\n * `mergeCompartment(receiver, compartmentBytes, opts)` → `MergeReport`:\n * 1. Decrypt the incoming bytes via hub's `decryptExtractedPartition`.\n * 2. `diffVault(receiver, incoming)` classifies records as added / modified\n * / deleted (deleted = receiver-only slice, ignored per FR-3 semantics).\n * 3. Resolve each `modified` entry per the per-collection strategy.\n * 4. Apply writes via `collection.put(id, rec, { reason })` (unless dryRun).\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport { diffVault } from '@noy-db/hub'\nimport { decryptExtractedPartition, type DecryptedRecord } from '@noy-db/hub/bundle'\nimport {\n resolveRecordByFieldAuthority,\n FieldAuthorityPolicyMissingError,\n type FieldAuthorityPolicy,\n} from './field-authority.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/** Per-collection conflict strategy. `field-level` is a deprecated alias for `field-authority`. */\nexport type MergeStrategy =\n | 'take-incoming'\n | 'keep-local'\n | 'lww-by-ts'\n | 'manual-queue'\n | 'field-authority'\n /** @deprecated Use `field-authority` instead. */\n | 'field-level'\n\n/** Options for the decrypted-records merge path (no bundle, no transfer key). */\nexport interface DecryptedMergeOptions {\n readonly strategy:\n | MergeStrategy\n | (Record<string, MergeStrategy> & { default?: MergeStrategy })\n readonly dryRun?: boolean\n /** Audit reason stamped on every write. Defaults to `'merge:compartment'`. */\n readonly reason?: string\n /** Per-collection field→authority policy. Required for any collection using `field-authority`. */\n readonly fieldAuthority?: Record<string, FieldAuthorityPolicy>\n}\n\n/** Options for the bundle merge path — adds the transfer key for decryption. */\nexport interface MergeCompartmentOptions extends DecryptedMergeOptions {\n readonly transferKey: Uint8Array\n}\n\nexport interface MergeConflict {\n readonly collection: string\n readonly id: string\n readonly strategy: MergeStrategy\n readonly resolution: 'incoming' | 'local' | 'queued' | 'field-merged'\n}\n\nexport interface MergeReport {\n readonly vault: string\n readonly dryRun: boolean\n readonly summary: {\n readonly inserted: number\n readonly updated: number\n readonly skipped: number\n readonly queued: number\n readonly total: number\n }\n readonly byCollection: Record<\n string,\n { readonly inserted: number; readonly updated: number; readonly skipped: number; readonly queued: number }\n >\n /**\n * One entry per `modified` (id-collision) record, regardless of outcome —\n * including `take-incoming` overwrites (`resolution: 'incoming'`). This is a\n * full audit trail of every conflict the merge encountered and how it was\n * resolved, not just the ones that were skipped or queued.\n */\n readonly conflicts: readonly MergeConflict[]\n}\n\n/** Mutable per-collection tally used while building a {@link MergeReport}. */\ninterface CollectionTally {\n inserted: number\n updated: number\n skipped: number\n queued: number\n}\n\n// ─── Error ────────────────────────────────────────────────────────────────────\n\n/**\n * @deprecated No longer thrown — `field-level` is now a deprecated alias for\n * `field-authority` and resolves via the field-authority resolver (FR-4).\n * Kept for backwards compatibility of existing imports.\n */\nexport class FieldLevelDeferredError extends Error {\n constructor(collection: string) {\n super(\n `mergeCompartment: the 'field-level' strategy for \"${collection}\" is not implemented yet` +\n ` — it lands with FR-4 (field-authority).` +\n ` Use take-incoming / keep-local / lww-by-ts / manual-queue for now.`,\n )\n this.name = 'FieldLevelDeferredError'\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction strategyFor(\n opts: DecryptedMergeOptions['strategy'],\n collection: string,\n): MergeStrategy {\n if (typeof opts === 'string') return opts\n return opts[collection] ?? opts.default ?? 'manual-queue'\n}\n\n// ─── Core ─────────────────────────────────────────────────────────────────────\n\n/**\n * Merge an already-decrypted record set into the receiver. The shared core of\n * `mergeCompartment` (decrypt → this) and `migrateThenMerge` (decrypt → migrate → this).\n * `decrypted` is keyed by collection; each record carries id/record/ts/source/sourceTs.\n *\n * Semantics:\n * - **added**: in incoming, not in receiver → always insert (every strategy).\n * - **modified**: in both, body differs → resolve per collection strategy.\n * - **deleted**: in receiver, not in incoming → IGNORE (incoming is a slice;\n * never delete receiver rows).\n * - **unchanged**: no-op.\n *\n * Returns a {@link MergeReport} describing what was (or would be) written.\n * When `dryRun: true` the report is fully computed but no `put()` is called.\n *\n * Writes are applied sequentially and **non-transactionally**: a `put()`\n * failure mid-loop (e.g. schema mismatch or a storage error) rejects the\n * returned promise but leaves the receiver partially merged. Use `dryRun`\n * first to validate the plan when partial application is unacceptable.\n */\nexport async function mergeDecryptedRecords(\n receiver: Vault,\n decrypted: Record<string, readonly DecryptedRecord[]>,\n opts: DecryptedMergeOptions,\n): Promise<MergeReport> {\n const reason = opts.reason ?? 'merge:compartment'\n\n // Build the candidate for diffVault: Record<collection, T[]> where each T has an `id` field.\n // Also keep incoming _ts for lww-by-ts comparison and _source/_sourceTs for provenance\n // threading (FR-5) and field-authority resolution (FR-4).\n const incomingTs = new Map<string, Map<string, string>>()\n const incomingSource = new Map<string, Map<string, string>>()\n const incomingSourceTs = new Map<string, Map<string, string>>()\n const candidate: Record<string, Record<string, unknown>[]> = {}\n for (const [coll, recs] of Object.entries(decrypted)) {\n const tsMap = new Map<string, string>()\n const srcMap = new Map<string, string>()\n const stsMap = new Map<string, string>()\n for (const r of recs) {\n tsMap.set(r.id, r.ts)\n if (r.source !== undefined) srcMap.set(r.id, r.source)\n if (r.sourceTs !== undefined) stsMap.set(r.id, r.sourceTs)\n }\n candidate[coll] = recs.map((r) => r.record)\n incomingTs.set(coll, tsMap)\n incomingSource.set(coll, srcMap)\n incomingSourceTs.set(coll, stsMap)\n }\n\n // 2. Diff the receiver against the incoming candidate.\n const diff = await diffVault(receiver, candidate)\n\n // 3. Resolve conflicts.\n const byCollection: Record<string, CollectionTally> = {}\n const conflicts: MergeConflict[] = []\n const writes: { collection: string; id: string; record: Record<string, unknown>; source?: string; sourceTs?: string }[] = []\n\n function bump(\n coll: string,\n key: keyof CollectionTally,\n ): void {\n const e = byCollection[coll] ?? { inserted: 0, updated: 0, skipped: 0, queued: 0 }\n e[key]++\n byCollection[coll] = e\n }\n\n // 3a. added → insert (all strategies)\n for (const a of diff.added) {\n const src = incomingSource.get(a.collection)?.get(a.id)\n const sts = incomingSourceTs.get(a.collection)?.get(a.id)\n writes.push({\n collection: a.collection, id: a.id, record: a.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(a.collection, 'inserted')\n }\n\n // 3b. modified → resolve per strategy\n // For lww-by-ts we need the receiver envelope's _ts.\n const { adapter, name: receiverName } = receiver._introspectState()\n\n for (const m of diff.modified) {\n const strat = strategyFor(opts.strategy, m.collection)\n\n if (strat === 'field-authority' || strat === 'field-level') {\n const policy = opts.fieldAuthority?.[m.collection]\n if (policy === undefined) throw new FieldAuthorityPolicyMissingError(m.collection)\n const recvEnv = await adapter.get(receiverName, m.collection, m.id)\n const incSrc = incomingSource.get(m.collection)?.get(m.id)\n const incSts = incomingSourceTs.get(m.collection)?.get(m.id)\n const locSrc = recvEnv?._source\n const locSts = recvEnv?._sourceTs\n const io = {\n ...(incSrc !== undefined ? { incomingSource: incSrc } : {}),\n ...(incSts !== undefined ? { incomingSourceTs: incSts } : {}),\n ...(locSrc !== undefined ? { localSource: locSrc } : {}),\n ...(locSts !== undefined ? { localSourceTs: locSts } : {}),\n }\n const { merged } = resolveRecordByFieldAuthority(\n policy,\n m.before,\n m.record,\n m.fieldsChanged,\n io,\n )\n // Per-field MERGED synthesis carries a record-level 'merged' source (Q3 defer).\n // NO sourceTs override — merged records keep merge-time by design.\n writes.push({ collection: m.collection, id: m.id, record: merged, source: 'merged' })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'field-merged' })\n continue\n }\n\n if (strat === 'take-incoming') {\n const src = incomingSource.get(m.collection)?.get(m.id)\n const sts = incomingSourceTs.get(m.collection)?.get(m.id)\n writes.push({\n collection: m.collection, id: m.id, record: m.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'incoming' })\n } else if (strat === 'keep-local') {\n bump(m.collection, 'skipped')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'local' })\n } else if (strat === 'manual-queue') {\n bump(m.collection, 'queued')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'queued' })\n } else {\n // lww-by-ts: compare ISO _ts strings lexicographically (correct for ISO-8601).\n const incTs = incomingTs.get(m.collection)?.get(m.id) ?? ''\n const recvEnv = await adapter.get(receiverName, m.collection, m.id)\n const localTs = recvEnv?._ts ?? ''\n if (incTs > localTs) {\n const src = incomingSource.get(m.collection)?.get(m.id)\n const sts = incomingSourceTs.get(m.collection)?.get(m.id)\n writes.push({\n collection: m.collection, id: m.id, record: m.record,\n ...(src !== undefined ? { source: src } : {}),\n ...(sts !== undefined ? { sourceTs: sts } : {}),\n })\n bump(m.collection, 'updated')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'incoming' })\n } else {\n bump(m.collection, 'skipped')\n conflicts.push({ collection: m.collection, id: m.id, strategy: strat, resolution: 'local' })\n }\n }\n }\n\n // diff.deleted (receiver-only) is intentionally ignored — incoming is a slice,\n // its absence of a row never means \"delete that row from the receiver\".\n\n // 4. Apply writes (unless dry-run).\n if (!opts.dryRun) {\n for (const w of writes) {\n await receiver.collection(w.collection).put(w.id, w.record, {\n reason,\n ...(w.source !== undefined ? { source: w.source } : {}),\n ...(w.sourceTs !== undefined ? { sourceTs: w.sourceTs } : {}),\n })\n }\n }\n\n // 5. Aggregate summary.\n const summary = { inserted: 0, updated: 0, skipped: 0, queued: 0, total: 0 }\n for (const e of Object.values(byCollection)) {\n summary.inserted += e.inserted\n summary.updated += e.updated\n summary.skipped += e.skipped\n summary.queued += e.queued\n }\n summary.total = summary.inserted + summary.updated + summary.skipped + summary.queued\n\n return {\n vault: receiverName,\n dryRun: opts.dryRun ?? false,\n summary,\n byCollection,\n conflicts,\n }\n}\n\n/**\n * Reconcile an incoming extracted-partition compartment into a receiver vault.\n * Decrypts the compartment bytes then delegates to {@link mergeDecryptedRecords}.\n *\n * See {@link mergeDecryptedRecords} for full semantics, dryRun behaviour, and\n * the non-transactional write caveat.\n */\nexport async function mergeCompartment(\n receiver: Vault,\n compartmentBytes: Uint8Array,\n opts: MergeCompartmentOptions,\n): Promise<MergeReport> {\n const incoming = await decryptExtractedPartition(compartmentBytes, opts.transferKey)\n return mergeDecryptedRecords(receiver, incoming, opts)\n}\n","/**\n * @klum-db/lobby interchange — shared staging helper.\n *\n * Transforms each incoming record, re-injects the canonical `id`, and\n * pre-validates every record against the receiver schema BEFORE any write.\n * A throwing transform or a failing validation bubbles out here, leaving the\n * receiver untouched (staging-safety). Used by both `migrateThenMerge` (FR-8,\n * version-windowed steps) and `graduate()` (foreign→target mapping).\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport type { DecryptedRecord } from '@noy-db/hub/bundle'\n\n/** A pure record-body transform: old body → new body. */\nexport type RecordTransform = (body: Record<string, unknown>) => Record<string, unknown>\n\n/**\n * Thrown BEFORE any write when a collection's records do not validate against\n * the receiver schema and no transform was supplied to fix the shape.\n */\nexport class MigrationTransformRequiredError extends Error {\n constructor(\n public readonly collection: string,\n public readonly cause?: unknown,\n ) {\n super(\n `collection \"${collection}\" did not validate against the receiver schema after ` +\n `transformation and no transform was supplied to reach the target shape. Provide a ` +\n `transform for \"${collection}\". Underlying: ${cause instanceof Error ? cause.message : String(cause)}`,\n )\n this.name = 'MigrationTransformRequiredError'\n }\n}\n\n/**\n * Stage incoming records: apply per-collection transforms (in array order),\n * re-inject the canonical `id`, and validate every staged record against the\n * receiver schema. Returns the staged records; never writes.\n */\nexport async function stageAndValidate(\n receiver: Vault,\n incoming: Record<string, readonly DecryptedRecord[]>,\n transformsByCollection: Record<string, readonly RecordTransform[]>,\n): Promise<Record<string, DecryptedRecord[]>> {\n const staged: Record<string, DecryptedRecord[]> = {}\n for (const [coll, recs] of Object.entries(incoming)) {\n const transforms = transformsByCollection[coll] ?? []\n const out: DecryptedRecord[] = []\n for (const r of recs) {\n let body = r.record\n for (const t of transforms) body = t(body)\n // Re-inject the canonical id: a transform that drops/renames `id` must not\n // silently detach the row from its identity.\n out.push({ ...r, record: { ...body, id: r.id } })\n }\n staged[coll] = out\n\n const rc = receiver.collection(coll)\n for (const r of out) {\n try {\n await rc.validateInput(r.record)\n } catch (cause) {\n throw new MigrationTransformRequiredError(coll, cause)\n }\n }\n }\n return staged\n}\n","/**\n * @klum-db/lobby dock — graduate() (#11). Import a docked foreign unit into a\n * fresh sovereign noy-db vault, unlocking the full tier (keyring, CEK,\n * provenance, custody). Reuses the decrypted-merge core (no crypto round-trip):\n * foreign rows are plaintext to begin with, so they are staged + validated and\n * written via `mergeDecryptedRecords` (a degenerate all-insert merge).\n *\n * @module\n */\nimport { createDeedOwner } from '@noy-db/hub'\nimport type { Noydb, SealingKeyProvider } from '@noy-db/hub'\nimport type { DecryptedRecord } from '@noy-db/hub/bundle'\nimport { mergeDecryptedRecords } from '../interchange/merge-compartment.js'\nimport { stageAndValidate, type RecordTransform } from '../interchange/stage-records.js'\nimport type { VaultTemplate } from '../federation/types.js'\nimport type { StateManagementVault } from '../federation/state-vault.js'\nimport type { DockedUnit } from './docked-unit.js'\n\nexport interface GraduateOptions {\n /** Name of the fresh sovereign vault to create. */\n readonly vaultName: string\n /** Target schema applied to the new vault. */\n readonly template: VaultTemplate\n /** Per-(target)-collection transform mapping foreign rows → the target shape. */\n readonly mapping?: Record<string, RecordTransform>\n /** Map a foreign collection name → its target collection name (when they differ). */\n readonly collectionMap?: Record<string, string>\n /** Optionally seal an inalienable client Deed (FR-6) on the new vault. */\n readonly deed?: { readonly ownerId: string; readonly sealingProvider: SealingKeyProvider }\n /** Optional StateManagement vault to record the audited graduation event into. */\n readonly stateVault?: StateManagementVault\n}\n\nexport interface GraduationReport {\n readonly vaultName: string\n readonly collections: Record<string, { graduated: number }>\n readonly deedSealed: boolean\n readonly event: { type: 'unit-graduated'; unitId: string; vault: string }\n}\n\n/** Thrown when graduation cannot proceed (target vault already populated, etc.). */\nexport class UnitGraduationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'UnitGraduationError'\n }\n}\n\nconst ISO_EPOCH = '1970-01-01T00:00:00.000Z'\n\nexport async function graduate(\n noydb: Noydb,\n docked: DockedUnit,\n opts: GraduateOptions,\n): Promise<GraduationReport> {\n // 1. Mint the fresh vault and apply the target schema.\n const vault = await noydb.openVault(opts.vaultName)\n opts.template.configure(vault)\n\n // 2. Read the foreign unit → DecryptedRecord[] keyed by TARGET collection.\n // Refuse to graduate into a vault that already holds data (create-only;\n // merge-into-existing is mergeCompartment's job, not this).\n const incoming: Record<string, DecryptedRecord[]> = {}\n const transforms: Record<string, RecordTransform[]> = {}\n for (const foreignColl of await docked.listCollections()) {\n const target = opts.collectionMap?.[foreignColl] ?? foreignColl\n const existing = await vault.collection(target).list()\n if (existing.length > 0) {\n throw new UnitGraduationError(\n `graduate: target vault \"${opts.vaultName}\" collection \"${target}\" is not empty`,\n )\n }\n const recs: DecryptedRecord[] = []\n for await (const row of docked.readRecords(foreignColl)) {\n if (row.id == null) {\n throw new UnitGraduationError(\n `graduate: foreign collection \"${foreignColl}\" has a row without an id — every docked row must carry a non-null id`,\n )\n }\n if (typeof row.id !== 'string' && typeof row.id !== 'number') {\n throw new UnitGraduationError(\n `graduate: foreign collection \"${foreignColl}\" has a row whose id is not a string or number — every docked row id must be a primitive`,\n )\n }\n const id = String(row.id)\n recs.push({ id, record: row, ts: ISO_EPOCH, version: opts.template.version })\n }\n incoming[target] = recs\n if (opts.mapping?.[target]) transforms[target] = [opts.mapping[target]]\n }\n\n // 3. Stage + validate (staging-safety), then merge as a degenerate all-insert.\n const staged = await stageAndValidate(vault, incoming, transforms)\n await mergeDecryptedRecords(vault, staged, { strategy: 'take-incoming', reason: 'dock:graduate' })\n\n // 3b. Optional custody Deed — the client's inalienable, sealed owner (FR-6).\n let deedSealed = false\n if (opts.deed) {\n await createDeedOwner(noydb._store, opts.vaultName, opts.deed.ownerId, opts.deed.sealingProvider)\n deedSealed = true\n }\n\n // 3c. Optional audited event.\n if (opts.stateVault) {\n await opts.stateVault.appendEvent({\n type: 'unit-graduated',\n group: opts.vaultName,\n vaultId: opts.vaultName,\n detail: `graduated foreign unit ${docked.unitId}`,\n })\n }\n\n // 4. Report.\n const collections: Record<string, { graduated: number }> = {}\n for (const [coll, recs] of Object.entries(staged)) collections[coll] = { graduated: recs.length }\n\n return {\n vaultName: opts.vaultName,\n collections,\n deedSealed,\n event: { type: 'unit-graduated', unitId: docked.unitId, vault: opts.vaultName },\n }\n}\n","/**\n * @klum-db/lobby interchange — Surface bilateral handshake + export/apply (FR-7).\n * Pure helpers: `now` is always passed in; no Date.now() calls inside.\n * @packageDocumentation\n */\nimport { generateULID } from '@noy-db/hub/kernel'\nimport type { Vault } from '@noy-db/hub'\nimport { extractPartition } from '@noy-db/hub/bundle'\nimport { mergeCompartment, type MergeReport } from './merge-compartment.js'\nimport type { StateManagementVault } from '../federation/state-vault.js'\nimport type {\n SurfaceRow,\n SurfaceDirection,\n SurfaceConflictPolicy,\n} from '../federation/types.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/**\n * User-facing subset of SurfaceRow: the fields a caller provides when\n * proposing a new surface. `id` is optional (auto-generated via ULID when\n * omitted). `status`, `proposedBy`, `createdAt`, etc. are set by `proposeSurface`.\n */\nexport interface SurfaceDefinition {\n readonly id?: string\n readonly collections: readonly string[]\n readonly fields?: Record<string, readonly string[]>\n readonly direction: SurfaceDirection\n readonly conflictPolicy: SurfaceConflictPolicy\n readonly cadenceMs?: number\n}\n\n// ─── Error classes ────────────────────────────────────────────────────────────\n\n/** Thrown when a surface id cannot be found in the StateManagementVault. */\nexport class SurfaceNotFoundError extends Error {\n override name = 'SurfaceNotFoundError'\n constructor(surfaceId: string) {\n super(`Surface not found: ${surfaceId}`)\n }\n}\n\n/**\n * Thrown when an operation is invalid for the surface's current status\n * (e.g. agreeing on an already-agreed or suspended surface).\n */\nexport class SurfaceStateError extends Error {\n override name = 'SurfaceStateError'\n constructor(surfaceId: string, currentStatus: string, requiredStatus: string) {\n super(\n `Surface ${surfaceId} has status '${currentStatus}', expected '${requiredStatus}'`,\n )\n }\n}\n\n// ─── Handshake helpers ────────────────────────────────────────────────────────\n\n/**\n * Party A: persist a new `status:'proposed'` SurfaceRow in the\n * StateManagementVault. The `id` in `def` is used when provided;\n * otherwise a fresh ULID is generated. `now` is the creation timestamp\n * (caller supplies, no Date.now() inside).\n */\nexport async function proposeSurface(\n smv: StateManagementVault,\n def: SurfaceDefinition,\n proposedBy: string,\n now: number,\n): Promise<SurfaceRow> {\n const row: SurfaceRow = {\n ...def,\n id: def.id ?? generateULID(),\n status: 'proposed',\n proposedBy,\n createdAt: now,\n }\n await smv.createSurface(row)\n return row\n}\n\n/**\n * Party B: read the surface, assert it is in `'proposed'` status, then\n * flip it to `'agreed'` (setting `agreedBy`). Returns the updated row.\n *\n * Throws:\n * - `SurfaceNotFoundError` when `surfaceId` is absent.\n * - `SurfaceStateError` when the surface status is not `'proposed'`.\n *\n * `_now` is accepted for API symmetry with `proposeSurface` (Task 5 will\n * use it for `lastSyncAt` stamping); it is not written in this task.\n */\nexport async function agreeSurface(\n smv: StateManagementVault,\n surfaceId: string,\n agreedBy: string,\n _now: number,\n): Promise<SurfaceRow> {\n const existing = await smv.getSurface(surfaceId)\n if (!existing) throw new SurfaceNotFoundError(surfaceId)\n if (existing.status !== 'proposed') {\n throw new SurfaceStateError(surfaceId, existing.status, 'proposed')\n }\n return smv.updateSurface(surfaceId, { status: 'agreed', agreedBy })\n}\n\n// ─── Export / Apply ───────────────────────────────────────────────────────────\n\n/**\n * Export a scoped partition from `source` bounded to the surface's collections\n * and field projection. Only surface.collections are included in the bundle:\n * `seeds` keys are exactly `surface.collections` and `maxDepth: 0` bounds the\n * walk so no non-surface collection can enter the closure. NOTE: if a surface\n * collection holds a `ref()` to an OUT-OF-SURFACE collection, the export\n * hard-fails with `PartitionExtractionError` (the safe outcome — it never\n * silently pulls in or leaks the referenced collection); surfaces over\n * collections that cross-reference outside the surface are not supported.\n * Excluded fields are structurally redacted before re-encryption and never\n * travel in the bundle.\n *\n * `exportSurface`/`applySurface` are direction-AGNOSTIC mechanics: export\n * produces a slice from a source vault, apply merges a slice into a receiver\n * vault. Both are needed for EVERY direction (push: proposer exports → agreer\n * applies; pull: agreer exports → proposer applies; bidi: both). `direction` is\n * orchestration metadata honoured by the sync flow (which party exports vs\n * applies), not a gate on the primitives — gating it here would make pull\n * surfaces unusable.\n *\n * Throws:\n * - `SurfaceStateError` when `surface.status !== 'agreed'`.\n */\nexport async function exportSurface(\n source: Vault,\n surface: SurfaceRow,\n): Promise<{ bundleBytes: Uint8Array; transferKey: Uint8Array }> {\n if (surface.status !== 'agreed') {\n throw new SurfaceStateError(surface.id, surface.status, 'agreed')\n }\n\n // Seeds: include ALL records in each surface collection (no predicate filtering).\n // maxDepth:0 ensures ref-following stops at the seed collections so no\n // non-surface collection can slip into the closure.\n const seeds = Object.fromEntries(surface.collections.map(c => [c, () => true]))\n\n const { bundleBytes, transferKey } = await extractPartition(source, {\n seeds,\n maxDepth: 0,\n ...(surface.fields ? { fieldProjection: surface.fields } : {}),\n carrySchemas: false,\n carryLedger: false,\n })\n\n return { bundleBytes, transferKey }\n}\n\n/**\n * Apply an exported surface bundle into `receiver`. Decrypts + merges using\n * the surface's conflict policy.\n *\n * Direction-agnostic mechanic (see `exportSurface`): the receiver merges the\n * slice regardless of direction; the sync flow decides which party applies.\n *\n * NOTE: a field-projected slice applied with a `take-incoming` conflict policy\n * is DESTRUCTIVE to non-surface fields on a record the receiver already holds\n * (the narrowed `{id, ...surface.fields}` overwrites the full row, dropping its\n * other fields). Use `keep-local` or `field-authority` when the receiver's\n * out-of-surface fields must be preserved across a projected push.\n *\n * Throws:\n * - `SurfaceStateError` when `surface.status !== 'agreed'`.\n */\nexport async function applySurface(\n receiver: Vault,\n surface: SurfaceRow,\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n): Promise<MergeReport> {\n if (surface.status !== 'agreed') {\n throw new SurfaceStateError(surface.id, surface.status, 'agreed')\n }\n\n return mergeCompartment(receiver, bundleBytes, {\n transferKey,\n strategy: surface.conflictPolicy.strategy,\n ...(surface.conflictPolicy.fieldAuthority\n ? { fieldAuthority: surface.conflictPolicy.fieldAuthority }\n : {}),\n reason: `sync:surface:${surface.id}`,\n })\n}\n\n// ─── Cadence helpers ──────────────────────────────────────────────────────────\n\n/**\n * Pure due-check — deterministic, no Date.now() inside.\n *\n * A surface is due iff:\n * - it has a `cadenceMs` (manually-only surfaces are never due via this check)\n * - its `status` is `'agreed'` (proposed/suspended do not fire)\n * - it has never been synced (`lastSyncAt === undefined`), OR\n * `now` has reached or passed `nextSyncDueAt`\n *\n * The caller always passes `now` explicitly so the function is testable without\n * any timer mocking.\n */\nexport function isSurfaceDue(surface: SurfaceRow, now: number): boolean {\n if (surface.cadenceMs === undefined) return false\n if (surface.status !== 'agreed') return false\n if (surface.lastSyncAt === undefined) return true\n return now >= (surface.nextSyncDueAt ?? 0)\n}\n\n/**\n * Filter a list of surfaces to those that are currently due.\n * Delegates to `isSurfaceDue` for each entry.\n */\nexport function listDueSurfaces(surfaces: readonly SurfaceRow[], now: number): SurfaceRow[] {\n return surfaces.filter(s => isSurfaceDue(s, now))\n}\n\n/**\n * Stamp `lastSyncAt = now` and `nextSyncDueAt = now + surface.cadenceMs` in\n * the StateManagementVault after a successful sync run. The surface must exist\n * (reads it to get `cadenceMs`). If `cadenceMs` is undefined the stamps are\n * written with `nextSyncDueAt = now` (no-op for future due-checks).\n *\n * Does NOT call Date.now() internally — the caller supplies `now`.\n */\nexport async function markSynced(\n smv: StateManagementVault,\n id: string,\n now: number,\n): Promise<SurfaceRow> {\n const existing = await smv.getSurface(id)\n if (!existing) throw new Error(`markSynced: surface not found: ${id}`)\n const cadenceMs = existing.cadenceMs ?? 0\n return smv.updateSurface(id, {\n lastSyncAt: now,\n nextSyncDueAt: now + cadenceMs,\n })\n}\n\n/**\n * Thin interval driver for surface cadence.\n *\n * Wraps a `Map<surfaceId, timer>` so each surface can be independently\n * started / stopped. `start` calls `setInterval(fn, intervalMs)` and\n * replaces any existing timer for the same id. `stopAll` clears all.\n *\n * Accepts an injectable `nowFn` (default `Date.now`) for use-sites that\n * need to capture the current time inside the callback — the pure due-check\n * (`isSurfaceDue`) takes `now` explicitly and should not call this.\n */\nexport class SurfaceCadenceScheduler {\n readonly #timers = new Map<string, ReturnType<typeof setInterval>>()\n readonly #nowFn: () => number\n\n constructor(nowFn: () => number = Date.now) {\n this.#nowFn = nowFn\n }\n\n /** Expose nowFn for callback use-sites. */\n get now(): number {\n return this.#nowFn()\n }\n\n /**\n * Schedule `fn` to fire every `intervalMs` milliseconds for the given\n * `surfaceId`. If the id is already running, the previous interval is\n * cancelled first (replace semantics).\n */\n start(surfaceId: string, intervalMs: number, fn: () => void): void {\n this.stop(surfaceId)\n const timer = setInterval(fn, intervalMs)\n this.#timers.set(surfaceId, timer)\n }\n\n /** Cancel the interval for `surfaceId` (no-op if not running). */\n stop(surfaceId: string): void {\n const timer = this.#timers.get(surfaceId)\n if (timer !== undefined) {\n clearInterval(timer)\n this.#timers.delete(surfaceId)\n }\n }\n\n /** Cancel all running intervals. */\n stopAll(): void {\n for (const [id] of this.#timers) {\n this.stop(id)\n }\n }\n}\n","/**\n * @category capability\n * StateManagement Vault — schema blueprint capture + deterministic\n * fingerprint. See\n * docs/superpowers/specs/2026-06-08-statemanagement-vault-design.md.\n */\nimport type { Vault } from '@noy-db/hub/kernel'\nimport type { IndexDef } from '@noy-db/hub/kernel'\nimport { sha256Hex } from '@noy-db/hub/kernel'\nimport type { CapturedBlueprint } from './types.js'\n\ninterface RecordedCollection {\n name: string\n indexes: IndexDef[]\n persistJsonSchema: boolean\n}\n\n/**\n * Run `configure` against a recording proxy that intercepts\n * `collection(name, opts)` calls and captures the declared blueprint.\n * The proxy delegates every other access to a no-op stub so unrelated\n * `configure` calls (guards, blob setup) do not throw — only the\n * declared collections/indexes feed the fingerprint.\n */\nexport function captureBlueprint(configure: (vault: Vault) => void): CapturedBlueprint {\n const recorded: RecordedCollection[] = []\n // Minimal chainable stub returned by intercepted collection() — supports\n // the fluent calls a template might make without affecting the blueprint.\n const collectionStub = new Proxy(\n {},\n {\n get: () => () => collectionStub,\n },\n )\n const proxy = new Proxy(\n {},\n {\n get: (_t, prop) => {\n if (prop === 'collection') {\n return (name: string, opts?: { indexes?: IndexDef[]; persistJsonSchema?: boolean }) => {\n recorded.push({\n name,\n indexes: opts?.indexes ?? [],\n persistJsonSchema: !!opts?.persistJsonSchema,\n })\n return collectionStub\n }\n }\n // Any other vault method/property: a no-op callable that returns the proxy.\n return () => proxy\n },\n },\n ) as unknown as Vault\n\n configure(proxy)\n\n const sorted = [...recorded].sort((a, b) => a.name.localeCompare(b.name))\n const indexes: Record<string, IndexDef[]> = {}\n const persistJsonSchema: string[] = []\n for (const c of sorted) {\n indexes[c.name] = c.indexes\n if (c.persistJsonSchema) persistJsonSchema.push(c.name)\n }\n return {\n // `persistJsonSchema` is already name-sorted: it is populated while\n // iterating `sorted` (collections in name order).\n collections: sorted.map((c) => c.name),\n indexes,\n persistJsonSchema,\n }\n}\n\n/** Canonical JSON: object keys sorted recursively so the bytes are stable. */\nfunction canonical(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(obj[k])}`).join(',')}}`\n}\n\n/** sha256 (hex) over the canonicalized serializable blueprint. Uses the shared hub helper. */\nexport async function fingerprintBlueprint(bp: CapturedBlueprint): Promise<string> {\n return sha256Hex(new TextEncoder().encode(canonical(bp)))\n}\n","export { STATE_VAULT_NAME } from '@noy-db/hub'\n","/**\n * @category capability\n * StateManagement Vault — federation control plane (registry +\n * schema-manifest + append-only deployment-events). See\n * docs/superpowers/specs/2026-06-08-statemanagement-vault-design.md.\n */\nimport type { Noydb } from '@noy-db/hub/kernel'\nimport type { Collection } from '@noy-db/hub/kernel'\nimport type { Query } from '@noy-db/hub/kernel'\nimport type { VaultRegistryRow, SchemaManifestRow, DeploymentEvent, MigrationStatusRow, SurfaceRow, VaultTemplate } from './types.js'\nimport { captureBlueprint, fingerprintBlueprint } from './schema-manifest.js'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { generateULID } from '@noy-db/hub/kernel'\n\n// Re-export so federation/index.ts can surface STATE_VAULT_NAME without reaching past state-vault.\nexport { STATE_VAULT_NAME } from './constants.js'\n\n// Physical collection names — single-token (camelCase) to stay clear of any\n// collection-name charset restrictions; the existing suite uses single-word names.\nconst REGISTRY = 'vaultRegistry'\nconst MANIFEST = 'schemaManifest'\nconst EVENTS = 'deploymentEvents'\nconst MIGRATION_STATUS = 'migrationStatus'\nconst SURFACES = 'surfaces'\n\nexport class StateManagementVault {\n /**\n * The append-only deployment-events log is kept truly private so the raw\n * mutable Collection is never surfaced — events may only be written via\n * `appendEvent` and read via `queryEvents`. (`registry` and\n * `schemaManifest` are deliberately public: consumers read and write them.)\n */\n readonly #events: Collection<DeploymentEvent>\n /** Per-shard fleet-migration progress (#271). Surfaced via typed methods only. */\n readonly #migrationStatus: Collection<MigrationStatusRow>\n /** Persisted Surface agreements (FR-7). Surfaced via typed methods only. */\n readonly #surfaces: Collection<SurfaceRow>\n\n private constructor(\n readonly registry: Collection<VaultRegistryRow>,\n readonly schemaManifest: Collection<SchemaManifestRow>,\n events: Collection<DeploymentEvent>,\n migrationStatus: Collection<MigrationStatusRow>,\n surfaces: Collection<SurfaceRow>,\n ) {\n this.#events = events\n this.#migrationStatus = migrationStatus\n this.#surfaces = surfaces\n }\n\n /** Idempotently open the reserved state vault and bind the control-plane collections. */\n static async open(db: Noydb): Promise<StateManagementVault> {\n const vault = await db.openVault(STATE_VAULT_NAME)\n return new StateManagementVault(\n vault.collection<VaultRegistryRow>(REGISTRY),\n vault.collection<SchemaManifestRow>(MANIFEST),\n vault.collection<DeploymentEvent>(EVENTS),\n vault.collection<MigrationStatusRow>(MIGRATION_STATUS),\n vault.collection<SurfaceRow>(SURFACES),\n )\n }\n\n /** Read one shard's migration status (or null). */\n async getMigrationStatus(vaultId: string): Promise<MigrationStatusRow | null> {\n return this.#migrationStatus.get(vaultId)\n }\n\n /** All migration-status rows (hydrates first). */\n async listMigrationStatus(): Promise<MigrationStatusRow[]> {\n await this.#migrationStatus.list()\n return this.#migrationStatus.query().toArray()\n }\n\n /** Upsert one shard's migration status (keyed by vaultId). */\n async upsertMigrationStatus(row: MigrationStatusRow): Promise<void> {\n await this.#migrationStatus.put(row.vaultId, row)\n }\n\n // ─── FR-7 Surface CRUD ────────────────────────────────────────────────────\n\n /** Persist a new Surface row (keyed by `row.id`). */\n async createSurface(row: SurfaceRow): Promise<void> {\n await this.#surfaces.put(row.id, row)\n }\n\n /** Read one Surface row by id, or null if absent. */\n async getSurface(id: string): Promise<SurfaceRow | null> {\n return this.#surfaces.get(id)\n }\n\n /** All persisted Surface rows (hydrates first). */\n async listSurfaces(): Promise<SurfaceRow[]> {\n await this.#surfaces.list()\n return this.#surfaces.query().toArray()\n }\n\n /**\n * Merge `patch` into the existing Surface row keyed by `id`, persist the\n * result, and return it. Mirrors the migrationStatus upsert pattern but\n * returns the merged row for convenience.\n */\n async updateSurface(id: string, patch: Partial<SurfaceRow>): Promise<SurfaceRow> {\n const existing = await this.#surfaces.get(id)\n if (!existing) throw new Error(`Surface not found: ${id}`)\n const updated: SurfaceRow = { ...existing, ...patch }\n await this.#surfaces.put(id, updated)\n return updated\n }\n\n /** Read-only query over the append-only deployment-events log. */\n queryEvents(): Query<DeploymentEvent> {\n return this.#events.query()\n }\n\n /**\n * Append a deployment event with a fresh unique (ULID) id. This is the\n * only write path to the events log; no update/delete is exposed.\n * Callers should treat failures as non-fatal — this method does not\n * swallow errors, so wrap the call site in try/catch where appropriate.\n */\n async appendEvent(event: Omit<DeploymentEvent, 'id' | 'ts'> & { ts?: number }): Promise<void> {\n const ts = event.ts ?? Date.now()\n const id = generateULID()\n await this.#events.put(id, { ...event, id, ts })\n }\n\n /**\n * Ensure a manifest row exists for `(templateName, template.version)`.\n * Safe to call repeatedly: the `fingerprint` is a deterministic hash of\n * the template's declared shape (stable across calls), though each call\n * refreshes `recordedAt`.\n */\n async recordManifest(templateName: string, template: VaultTemplate): Promise<string> {\n const bp = captureBlueprint(template.configure)\n const fingerprint = await fingerprintBlueprint(bp)\n await this.schemaManifest.put(`${templateName}:${template.version}`, {\n templateName,\n version: template.version,\n collections: bp.collections,\n indexes: bp.indexes,\n persistJsonSchema: bp.persistJsonSchema,\n fingerprint,\n recordedAt: Date.now(),\n })\n return fingerprint\n }\n\n /**\n * True when `template`'s current declared shape does not match the recorded\n * manifest for `(templateName, template.version)`. Because shards carry no\n * schema state independent of their template, this catches \"a template's\n * shape changed without bumping `version`\" — not independent per-shard drift.\n * A missing manifest is treated as drift (nothing to verify against).\n */\n async detectDrift(templateName: string, template: VaultTemplate): Promise<boolean> {\n const row = await this.schemaManifest.get(`${templateName}:${template.version}`)\n if (!row) return true\n const current = await fingerprintBlueprint(captureBlueprint(template.configure))\n return current !== row.fingerprint\n }\n}\n","import { NoAccessError } from '@noy-db/hub/kernel'\nimport type { SkippedVault } from './types.js'\n\n/**\n * Classify a per-shard fan-out failure. `NoAccessError` (no keyring envelope for\n * the calling identity) is the unambiguous not-granted signal → `'no-grant'`\n * (expected under scoped access, not a fault). Everything else → `'error'` —\n * `InvalidKeyError`/`DecryptionError`/`KeyringCorruptError` can mean \"wrong KEK\n * OR whole-file corruption\" per loadKeyring, so they must not hide as no-grant.\n */\nexport function classifyShardSkip(err: Error): Exclude<SkippedVault['reason'], 'schema-drift'> {\n return err instanceof NoAccessError ? 'no-grant' : 'error'\n}\n","/**\n * @category capability\n * crossShardJoin — co-partitioned + broadcast dimension join for\n * ShardedQuery. Spec:\n * docs/superpowers/specs/2026-06-09-cross-shard-join-design.md.\n *\n * This module owns the BROADCAST half (central, post-merge map-attach)\n * and the leg type definitions. The CO-PARTITIONED half is threaded\n * into the existing intra-vault `.join()` from vault-group.ts — see\n * ShardedQuery.fanoutRecords. join.ts is deliberately untouched.\n */\nimport { readPath } from '@noy-db/hub/kernel'\nimport type { JoinStrategy } from '@noy-db/hub/kernel'\n\n/** Public options for `ShardedQuery.crossShardJoin`. */\nexport interface CrossShardJoinOptions {\n /** Alias key under which the joined same-shard record attaches. */\n readonly as: string\n /** Per-shard row ceiling override (default DEFAULT_JOIN_MAX_ROWS). */\n readonly maxRows?: number\n /** Planner strategy override, passed through to intra-vault `.join()`. */\n readonly strategy?: JoinStrategy\n}\n\n/**\n * Minimal structural shape of a broadcast dimension source. A\n * `Collection` satisfies this natively: `list()` hydrates and returns\n * the decoded records. Kept as a one-method interface so plain test\n * sources are trivial to construct.\n */\nexport interface BroadcastSource {\n list(): Promise<readonly unknown[]>\n}\n\n/** Public options for `ShardedQuery.broadcastJoin`. */\nexport interface BroadcastJoinOptions {\n /** Alias key under which the dimension record attaches. */\n readonly as: string\n /** The shared dimension collection (an opened handle in another vault). */\n readonly from: BroadcastSource\n /** Right-side key to match `field` against. Default 'id'. */\n readonly on?: string\n /** Miss behavior. 'warn' (default) attaches null + one-shot warning; 'cascade' is silent. */\n readonly mode?: 'warn' | 'cascade'\n}\n\n/** Internal co-partitioned leg carried on ShardedQuery. */\nexport interface CoPartitionedLeg {\n readonly field: string\n readonly as: string\n readonly maxRows: number | undefined\n readonly strategy: JoinStrategy | undefined\n}\n\n/** Internal broadcast leg carried on ShardedQuery. */\nexport interface BroadcastLeg {\n readonly field: string\n readonly as: string\n readonly from: BroadcastSource\n readonly on: string\n readonly mode: 'warn' | 'cascade'\n}\n\n/**\n * Coerce an unknown key value into a lookup string. Mirrors join.ts's\n * private `coerceRefKey` (string → string; number/bigint → String;\n * else null) — re-implemented locally to keep join.ts literally\n * untouched.\n */\nfunction coerceKey(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'bigint') return String(value)\n return null\n}\n\n/** One-shot warn dedup for broadcast misses, keyed by `field→as`. */\nconst warnedBroadcastKeys = new Set<string>()\nfunction warnOnceBroadcastMiss(field: string, as: string, key: string): void {\n const dedup = `${field}→${as}:${key}`\n if (warnedBroadcastKeys.has(dedup)) return\n warnedBroadcastKeys.add(dedup)\n console.warn(\n `[klum-db] broadcastJoin: no \"${as}\" dimension row for ${field}=\"${key}\". ` +\n `Attaching null. Use mode: 'cascade' to silence.`,\n )\n}\n\n/** Test-only reset for the broadcast warn dedup set. */\nexport function resetBroadcastWarnings(): void {\n warnedBroadcastKeys.clear()\n}\n\n/**\n * Apply every broadcast leg to a merged row set, centrally. Each leg's\n * source is snapshotted ONCE, indexed by its `on` key, then every row\n * gets `{ [as]: match ?? null }`. Returns fresh top-level objects.\n */\nexport async function applyBroadcastLegs(\n rows: readonly unknown[],\n legs: readonly BroadcastLeg[],\n): Promise<unknown[]> {\n if (legs.length === 0) return [...rows]\n\n // Build one index per leg (list() once per source).\n const indexes: { leg: BroadcastLeg; map: Map<string, unknown> }[] = []\n for (const leg of legs) {\n const map = new Map<string, unknown>()\n for (const rec of await leg.from.list()) {\n const k = coerceKey(readPath(rec, leg.on))\n if (k !== null && !map.has(k)) map.set(k, rec)\n }\n indexes.push({ leg, map })\n }\n\n return rows.map((row) => {\n const out = { ...(row as Record<string, unknown>) }\n for (const { leg, map } of indexes) {\n const key = coerceKey(readPath(row, leg.field))\n const match = key === null ? null : map.get(key) ?? null\n if (match === null && leg.mode === 'warn') {\n warnOnceBroadcastMiss(leg.field, leg.as, key ?? '<null>')\n }\n out[leg.as] = match\n }\n return out\n })\n}\n","/**\n * @category capability\n * Reactive core for cross-vault live queries/aggregations. Generic over a\n * snapshot S. Single-flight + microtask-coalesced recompute on relevant\n * change. Mirrors the LiveQuery/LiveAggregation contracts via facades.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport type { ChangeEvent } from '@noy-db/hub/kernel'\n\nexport interface CrossVaultLiveOptions<S> {\n readonly subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n readonly isRelevant: (e: ChangeEvent) => boolean\n readonly compute: () => Promise<S>\n readonly initialSnapshot: S\n readonly debounceMs?: number\n}\n\nexport class CrossVaultLive<S> {\n snapshot: S\n error: Error | null = null\n readonly ready: Promise<void>\n\n private readonly subs = new Set<() => void>()\n private readonly unsubChange: () => void\n private readonly opts: CrossVaultLiveOptions<S>\n private stopped = false\n private computing = false\n private dirty = false\n private scheduled = false\n private timer: ReturnType<typeof setTimeout> | null = null\n private resolveReady!: () => void\n private settledOnce = false\n\n constructor(opts: CrossVaultLiveOptions<S>) {\n this.opts = opts\n this.snapshot = opts.initialSnapshot\n this.ready = new Promise<void>((res) => { this.resolveReady = res })\n this.unsubChange = opts.subscribeToChanges((e) => {\n if (this.stopped || !opts.isRelevant(e)) return\n this.schedule()\n })\n this.schedule() // initial compute\n }\n\n subscribe(cb: () => void): () => void {\n if (this.stopped) return () => {}\n this.subs.add(cb)\n return () => this.subs.delete(cb)\n }\n\n stop(): void {\n if (this.stopped) return\n this.stopped = true\n this.unsubChange()\n if (this.timer !== null) clearTimeout(this.timer)\n this.subs.clear()\n if (!this.settledOnce) this.resolveReady() // never leave ready dangling\n }\n\n private schedule(): void {\n if (this.stopped) return\n if (this.computing) { this.dirty = true; return }\n if (this.scheduled) return\n this.scheduled = true\n const run = () => { this.scheduled = false; void this.runCompute() }\n const ms = this.opts.debounceMs ?? 0\n if (ms > 0) this.timer = setTimeout(run, ms)\n // queueMicrotask is non-cancellable; the `if (this.stopped) return` guard at the top of runCompute makes a post-stop fire a no-op.\n else queueMicrotask(run)\n }\n\n private async runCompute(): Promise<void> {\n if (this.stopped) return\n this.computing = true\n this.dirty = false\n try {\n const next = await this.opts.compute()\n if (this.stopped) return\n this.snapshot = next\n this.error = null\n } catch (err) {\n if (this.stopped) return\n this.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n this.computing = false\n if (!this.stopped) {\n if (!this.settledOnce) { this.settledOnce = true; this.resolveReady() }\n for (const cb of this.subs) cb()\n if (this.dirty) this.schedule()\n }\n }\n }\n}\n","/**\n * @klum-db/lobby federation — Insight auto-push controller (#12).\n *\n * Pure scheduling: coalesces shard writes into one microtask flush per burst.\n * Knows nothing about vaults — it calls back into the owner via `recompute`\n * (re-derive + push that shard's summary) and `isSource` (does this collection\n * feed an auto-push derivation?). Best-effort: a failed recompute is reported\n * via `onError` and never breaks the loop or the awaiting caller.\n *\n * @module\n */\nexport class InsightAutoPush {\n /** Partition keys awaiting recompute. */\n private readonly dirty = new Set<string>()\n /** The in-flight flush, or null when idle. */\n private pending: Promise<void> | null = null\n\n constructor(\n private readonly recompute: (partitionKey: string) => Promise<void>,\n private readonly isSource: (collection: string) => boolean,\n private readonly onError: (err: unknown, partitionKey: string) => void = (err, pk) =>\n console.warn(`[klum-db] insight auto-push failed for shard \"${pk}\":`, err),\n ) {}\n\n /** Called from a shard's onAfterWrite hook. Marks the shard dirty + schedules a flush. */\n noteWrite(partitionKey: string, collection: string): void {\n if (!this.isSource(collection)) return\n this.dirty.add(partitionKey)\n this.schedule()\n }\n\n /** Resolve once no flush is pending (drains rescheduled flushes too). */\n async whenSettled(): Promise<void> {\n while (this.pending) await this.pending\n }\n\n private schedule(): void {\n if (this.pending) return\n this.pending = this.runFlush().finally(() => {\n this.pending = null\n // Writes that arrived during the flush re-dirty the set — drain them.\n if (this.dirty.size > 0) this.schedule()\n })\n }\n\n private async runFlush(): Promise<void> {\n // Let same-tick writes coalesce into this flush before snapshotting.\n await Promise.resolve()\n const pks = [...this.dirty]\n this.dirty.clear()\n for (const pk of pks) {\n try {\n await this.recompute(pk)\n } catch (err) {\n this.onError(err, pk)\n }\n }\n }\n}\n","/**\n * @category capability\n * Distributed partial-reduce over the kernel Reducer protocol (#8). Each shard\n * folds its own records to a partial STATE; states are merged centrally and\n * finalized once — identical to central `reduceRecords` over the union, but\n * without materializing the union. Used by the scalar `.aggregate().run()` path\n * when every reducer exposes `merge` (else the caller falls back to central).\n */\nimport type { AggregateResult, AggregateSpec } from '@noy-db/hub/kernel'\n\n/**\n * Structural view of the kernel `Reducer` protocol. `Reducer` itself is not\n * exported on the `@noy-db/hub/kernel` boundary, so we model the shape locally\n * (an `AggregateSpec` value carries exactly these methods).\n */\ninterface ReducerLike {\n init(): unknown\n step(state: unknown, record: unknown): unknown\n finalize(state: unknown): unknown\n /** Optional — associative + commutative with init() as identity (kernel contract). */\n merge?(a: unknown, b: unknown): unknown\n}\n\n/** One opaque reducer state per spec key. */\nexport type PartialState = Record<string, unknown>\n\n/** True iff every reducer in the spec exposes a callable `merge` (safe to partial-reduce). */\nexport function canPartialReduce(spec: AggregateSpec): boolean {\n return Object.values(spec).every((r) => typeof (r as ReducerLike).merge === 'function')\n}\n\n/** Fold one shard's records to a partial state per spec key (no finalize). */\nexport function reduceToPartial(records: readonly unknown[], spec: AggregateSpec): PartialState {\n const out: PartialState = {}\n for (const [key, reducer] of Object.entries(spec)) {\n const r = reducer as ReducerLike\n let state = r.init()\n for (const rec of records) state = r.step(state, rec)\n out[key] = state\n }\n return out\n}\n\n/**\n * Merge partial states across shards per spec key, seeded with each reducer's\n * `init()` (the merge identity) so an empty `partials` array yields the\n * empty-aggregate state.\n */\nexport function mergePartials(spec: AggregateSpec, partials: readonly PartialState[]): PartialState {\n const out: PartialState = {}\n for (const [key, reducer] of Object.entries(spec)) {\n const r = reducer as ReducerLike\n let acc = r.init()\n for (const p of partials) acc = r.merge!(acc, p[key])\n out[key] = acc\n }\n return out\n}\n\n/** Finalize a merged state into the user-visible aggregate result. */\nexport function finalizePartial<Spec extends AggregateSpec>(spec: Spec, merged: PartialState): AggregateResult<Spec> {\n const out: Record<string, unknown> = {}\n for (const [key, reducer] of Object.entries(spec)) {\n out[key] = (reducer as ReducerLike).finalize(merged[key])\n }\n return out as AggregateResult<Spec>\n}\n","/**\n * @category capability\n * One-shot distributed aggregate wrappers for cross-vault fan-out.\n * Central-reduce: all shard records are concatenated and reduced in one pass\n * so avg/mean values are computed over the full union, not as avg-of-avgs.\n * Spec: docs/superpowers/specs/2026-06-07-cross-vault-live-and-aggregate-design.md.\n */\nimport { reduceRecords } from '@noy-db/hub/kernel'\nimport { groupAndReduce } from '@noy-db/hub/kernel'\nimport type { AggregateResult, AggregateSpec } from '@noy-db/hub/kernel'\nimport type {\n FanoutQueryOptions,\n SkippedVault,\n GroupedRow,\n LiveQueryOptions,\n CrossVaultLiveAggregation,\n CrossVaultLiveQuery,\n} from './types.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport type { ChangeEvent } from '@noy-db/hub/kernel'\nimport { canPartialReduce, mergePartials, finalizePartial } from './partial-reduce.js'\nimport type { PartialState } from './partial-reduce.js'\n\n/** A source that can fan out records across shards. Satisfied by ShardedQuery. */\nexport interface FanoutRecordSource<R> {\n fanoutRecords(options: FanoutQueryOptions): Promise<{ records: R[]; skippedVaults: SkippedVault[] }>\n /** Optional distributed partial-reduce (#8): fold each shard to a state in-callback. */\n fanoutReduce?(\n spec: AggregateSpec,\n options: FanoutQueryOptions,\n ): Promise<{ partials: PartialState[]; skippedVaults: SkippedVault[] }>\n}\n\n/** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */\nexport interface LiveBinding {\n subscribeToChanges: (handler: (e: ChangeEvent) => void) => () => void\n isRelevant: (e: ChangeEvent) => boolean\n}\n\n/**\n * One-shot cross-vault aggregate. When every reducer in the spec exposes the\n * `merge` seam, `run()` uses **distributed partial-reduce** — each shard folds\n * its own records to a partial state, merged centrally and finalized once (no\n * union materialized). A spec with any merge-less reducer falls back to\n * central-reduce. The result is identical either way. `.live()` and grouped\n * aggregates remain central-reduce.\n */\nexport class CrossVaultAggregation<R, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n result: AggregateResult<Spec>\n skippedVaults: SkippedVault[]\n }> {\n // Distributed partial-reduce when every reducer has `merge` and the source\n // supports it; otherwise central-reduce over the union (identical result).\n if (this.src.fanoutReduce && canPartialReduce(this.spec)) {\n const { partials, skippedVaults } = await this.src.fanoutReduce(this.spec, options)\n return { result: finalizePartial(this.spec, mergePartials(this.spec, partials)), skippedVaults }\n }\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return { result: reduceRecords(records, this.spec), skippedVaults }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveAggregation<AggregateResult<Spec>> {\n if (!this.bind) throw new Error('CrossVaultAggregation: live() requires a LiveBinding — use ShardedQuery.aggregate()')\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ value: AggregateResult<Spec> | undefined; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return { value: reduceRecords(records, spec), skipped: skippedVaults }\n },\n initialSnapshot: { value: undefined, skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.value },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n\n/**\n * One-shot cross-vault grouped aggregate. Concatenates all shard records and\n * runs a single central group-and-reduce, emitting one row per bucket.\n */\nexport class CrossVaultGroupedAggregation<R, F extends string, Spec extends AggregateSpec> {\n constructor(\n private readonly src: FanoutRecordSource<R>,\n private readonly field: F,\n private readonly spec: Spec,\n private readonly bind?: LiveBinding,\n ) {}\n\n async run(options: FanoutQueryOptions = {}): Promise<{\n results: GroupedRow<F, Spec>[]\n skippedVaults: SkippedVault[]\n }> {\n const { records, skippedVaults } = await this.src.fanoutRecords(options)\n return {\n results: groupAndReduce<GroupedRow<F, Spec>>(records, this.field, this.spec),\n skippedVaults,\n }\n }\n\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<GroupedRow<F, Spec>> {\n if (!this.bind) throw new Error('CrossVaultGroupedAggregation: live() requires a LiveBinding — use ShardedQuery.groupBy().aggregate()')\n const field = this.field\n const spec = this.spec\n const src = this.src\n const core = new CrossVaultLive<{ records: GroupedRow<F, Spec>[]; skipped: SkippedVault[] }>({\n subscribeToChanges: this.bind.subscribeToChanges,\n isRelevant: this.bind.isRelevant,\n compute: async () => {\n const { records, skippedVaults } = await src.fanoutRecords(options)\n return {\n records: groupAndReduce<GroupedRow<F, Spec>>(records, field, spec),\n skipped: skippedVaults,\n }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly GroupedRow<F, Spec>[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n}\n","/**\n * @category capability\n * Multi-vault partition federation — VaultGroup transparent shard\n * routing. Spec:\n * docs/superpowers/specs/2026-06-07-mvf-vaultgroup-routing-mvp-design.md.\n */\nimport type { Noydb } from '@noy-db/hub/kernel'\nimport type { Vault } from '@noy-db/hub/kernel'\nimport type { Collection } from '@noy-db/hub/kernel'\nimport { StateManagementVault } from './state-vault.js'\nimport { CrossShardJoinError, DataResidencyError, ReservedVaultNameError, ShardProvisioningError, UnknownShardError, ValidationError } from '@noy-db/hub/kernel'\nimport { STATE_VAULT_NAME } from './constants.js'\nimport { classifyShardSkip } from './classify-skip.js'\nimport { applyBroadcastLegs } from './cross-shard-join.js'\nimport type { CoPartitionedLeg, BroadcastLeg, CrossShardJoinOptions, BroadcastJoinOptions } from './cross-shard-join.js'\nimport { CrossVaultLive } from './cross-vault-live.js'\nimport { InsightAutoPush } from './insight-auto-push.js'\nimport { CrossVaultAggregation, CrossVaultGroupedAggregation } from './aggregate-across.js'\nimport type { FanoutRecordSource, LiveBinding } from './aggregate-across.js'\nimport type { AggregateSpec } from '@noy-db/hub/kernel'\nimport { reduceToPartial } from './partial-reduce.js'\nimport type { PartialState } from './partial-reduce.js'\nimport type {\n ShardingConfig,\n VaultRegistryRow,\n VaultTemplate,\n FanoutQueryOptions,\n FanoutResult,\n SkippedVault,\n WhereClause,\n LiveQueryOptions,\n CrossVaultLiveQuery,\n CrossVaultDerivationSpec,\n CrossVaultDerivationContext,\n RefreshInsightsResult,\n MigrationStatusRow,\n SchemaRolloutResult,\n} from './types.js'\n\n/** Reserved separator between group name and partition key in a shard vault id. */\nconst SHARD_SEPARATOR = '--'\n/** Store-safe partition-key charset (single hyphens OK; '--' is the reserved separator). */\nconst SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/\n\nfunction assertSafePartitionKey(partitionKey: string): void {\n if (partitionKey.length === 0) {\n throw new ValidationError('partitionKey must be a non-empty string')\n }\n if (partitionKey === STATE_VAULT_NAME) {\n throw new ReservedVaultNameError(partitionKey)\n }\n if (!SAFE_PARTITION_KEY.test(partitionKey)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" contains characters outside [A-Za-z0-9._-]. ` +\n `Map your records to a store-safe key in sharding.keyOf.`,\n )\n }\n if (partitionKey.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `partitionKey \"${partitionKey}\" must not contain \"--\" — it is reserved as the ` +\n `shard vault-id separator and would risk shard-id collisions.`,\n )\n }\n}\n\nexport class VaultGroup<T> {\n constructor(\n /** @internal */ readonly db: Noydb,\n /** @internal */ readonly name: string,\n /** @internal */ readonly registry: Collection<VaultRegistryRow>,\n /** @internal */ readonly sharding: ShardingConfig<T>,\n /** @internal */ readonly template: VaultTemplate,\n /** @internal — lazy cutover-on-open (#271). */ readonly cutoverOnOpen: boolean = false,\n ) {\n if (name.includes(SHARD_SEPARATOR)) {\n throw new ValidationError(\n `VaultGroup name \"${name}\" must not contain \"--\" (reserved shard vault-id separator).`,\n )\n }\n }\n\n /** @internal — set when the group is managed (no explicit registry). */\n private stateVault: StateManagementVault | undefined\n\n /** @internal */\n _attachStateVault(sv: StateManagementVault): void {\n this.stateVault = sv\n }\n\n /** Deterministic vault name for a partition key, namespaced by the group. */\n shardVaultId(partitionKey: string): string {\n assertSafePartitionKey(partitionKey)\n return `${this.name}${SHARD_SEPARATOR}${partitionKey}`\n }\n\n /**\n * @internal — group-qualified registry record key (avoids cross-group key\n * collisions). Identical to the shard vault id by design — the registry row\n * for a shard is keyed by that shard's vault id — so it delegates to\n * `shardVaultId`, reusing its partition-key validation.\n */\n registryId(partitionKey: string): string {\n return this.shardVaultId(partitionKey)\n }\n\n /**\n * Registry rows for THIS group (hydrates the registry collection first).\n * The registry may be shared across groups (the auto-wired StateManagement\n * vault holds one `vaultRegistry` for the whole instance), so rows are\n * filtered by `group` — without this, a group's fan-out reads would leak\n * across into other groups' shards. Mirrors the `${group}--` scoping that\n * `liveBinding().isRelevant` already applies to the reactive path.\n */\n async allRows(): Promise<VaultRegistryRow[]> {\n await this.registry.list()\n const rows = this.registry.query().toArray() // toArray() is synchronous\n return rows.filter((r) => r.group === this.name)\n }\n\n /**\n * Open an existing shard and apply the template. When `cutoverOnOpen` is set\n * (#271) and the shard's registry version is behind the template, its cutover\n * runs inline first — so a behind shard never surfaces a stale handle.\n */\n async openShard(partitionKey: string): Promise<Vault> {\n if (this.cutoverOnOpen) {\n const row = await this.registry.get(this.registryId(partitionKey))\n if (row && row.schemaVersion < this.template.version) {\n await this.cutoverShard(partitionKey)\n }\n }\n return this._openShardRaw(partitionKey)\n }\n\n /** @internal — open + configure with no cutover-on-open hook (used by the migration path itself to avoid recursion). */\n private async _openShardRaw(partitionKey: string): Promise<Vault> {\n const vault = await this.db.openVault(this.shardVaultId(partitionKey), { create: false })\n this.template.configure(vault)\n return vault\n }\n\n /**\n * Idempotently provision a shard for `partitionKey`. Returns the\n * configured vault handle.\n *\n * - row + vault present → no-op, return handle\n * - row present, vault gone → ShardProvisioningError\n * - row absent (vault present or not) → open-or-create, configure, write row\n *\n * When `region` is given (the routing `put` passes `sharding.regionOf(record)`),\n * the candidate backend's `capabilities.region` must match or this throws\n * `DataResidencyError` BEFORE provisioning (#271 data-residency guard).\n */\n async createShard(partitionKey: string, region?: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n\n if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n if (row && provisioned) return this.openShard(partitionKey)\n\n // Data-residency placement guard: refuse a shard landing on a backend\n // whose declared region doesn't match the record's required region.\n if (region !== undefined) {\n const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region\n if (backendRegion !== region) throw new DataResidencyError(vaultId, region, backendRegion)\n }\n\n // Row absent → create (or reconcile a provisioned-but-unregistered vault).\n const vault = await this.db.openVault(vaultId)\n this.template.configure(vault)\n await this.registry.put(this.registryId(partitionKey), {\n vaultId,\n partitionKey,\n templateName: this.sharding.vaultTemplate,\n schemaVersion: this.template.version,\n createdAt: Date.now(),\n group: this.name,\n })\n if (this.stateVault) {\n try {\n await this.stateVault.appendEvent({\n type: 'shard-created',\n group: this.name,\n vaultId,\n templateName: this.sharding.vaultTemplate,\n version: this.template.version,\n })\n } catch {\n /* best-effort: event logging never fails the shard write */\n }\n }\n return vault\n }\n\n /**\n * Drill down to a single shard's full Collection API. Throws if the shard is unknown.\n * Also throws ShardProvisioningError if the registry row exists but the vault has been deleted\n * (registry/store divergence).\n */\n async shard(partitionKey: string): Promise<Vault> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) throw new UnknownShardError(partitionKey, this.name)\n const provisioned = await this.db._shardVaultProvisioned(vaultId)\n if (!provisioned) throw new ShardProvisioningError(vaultId, partitionKey)\n return this.openShard(partitionKey)\n }\n\n /** A sharded view over one logical collection across all shards. */\n collection<R = T>(collectionName: string): ShardedCollection<T, R> {\n return new ShardedCollection<T, R>(this, collectionName)\n }\n\n /** @internal — eligible (openable-candidate) rows + drift/divergence/unreachable skips. */\n async resolveEligible(options: { minVersion?: number; only?: readonly string[]; failFast?: boolean } = {}): Promise<{\n eligible: VaultRegistryRow[]\n skipped: SkippedVault[]\n }> {\n const rows = await this.allRows()\n const candidates = options.only ? rows.filter((r) => options.only!.includes(r.partitionKey)) : rows\n const skipped: SkippedVault[] = []\n const versionOk: VaultRegistryRow[] = []\n for (const row of candidates) {\n if (options.minVersion !== undefined && row.schemaVersion < options.minVersion) {\n skipped.push({ vaultId: row.vaultId, reason: 'schema-drift' })\n } else versionOk.push(row)\n }\n // Probe provisioning per shard. An unreachable backend throws here; catch it\n // (record a skip) so one down shard does not sink the fleet — unless failFast.\n const probes = await Promise.all(\n versionOk.map(async (row) => {\n try {\n return { row, provisioned: await this.db._shardVaultProvisioned(row.vaultId) }\n } catch (err) {\n if (options.failFast) throw err\n return { row, error: err as Error }\n }\n }),\n )\n const eligible: VaultRegistryRow[] = []\n for (const p of probes) {\n if ('error' in p) skipped.push({ vaultId: p.row.vaultId, reason: 'error', error: p.error })\n else if (p.provisioned) eligible.push(p.row)\n else skipped.push({ vaultId: p.row.vaultId, reason: 'error', error: new ShardProvisioningError(p.row.vaultId, p.row.partitionKey) })\n }\n return { eligible, skipped }\n }\n\n /** @internal — registered push-model cross-vault derivations (#271 Insight Vault). */\n private readonly crossVaultDerivations: CrossVaultDerivationSpec[] = []\n\n /** @internal — auto-push controller; created (and the change-subscription armed) when the first autoPush derivation registers. */\n private insightAutoPush?: InsightAutoPush\n\n /**\n * Register a push-model cross-vault derivation — the Insight Vault pattern\n * (#271, Layer 4). Drive it with {@link refreshInsights}.\n *\n * For each shard, `derive(records, ctx)` runs on that shard's `source`\n * records and its return value is written into the analytics\n * (`target.vault` / `target.collection`) vault, keyed by partition key —\n * one summary row per shard. The derivation runs in-process under THIS\n * group's `Noydb` (which already holds both the shard and Insight Vault\n * keyrings); the shard's decrypted records are reduced to a summary that is\n * re-encrypted under the Insight Vault's own DEK, so no shard ciphertext\n * crosses a DEK boundary.\n *\n * **Zero-knowledge note:** the Insight Vault backend sees aggregated\n * structure (totals, counts, timestamps) drawn from many shards — a weaker\n * ZK profile than the per-shard vaults. Opt-in; keep summaries to aggregate\n * scalars (no embeddings / no raw records).\n *\n * v1 is explicit-refresh (no write-path push); call `refreshInsights()`\n * after a batch of writes, or on a schedule.\n *\n * The `target.vault` must NOT be the group itself or one of its shards —\n * a summary writing back into client-shard data would breach the Insight\n * Vault's separate-DEK-boundary contract. Such a target throws a\n * `ValidationError` at registration (#271 Insight-write isolation).\n */\n withCrossVaultDerivation<R = Record<string, unknown>, S = Record<string, unknown>>(\n spec: CrossVaultDerivationSpec<R, S>,\n ): void {\n const target = spec.target.vault\n if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {\n throw new ValidationError(\n `withCrossVaultDerivation: target.vault \"${target}\" is the \"${this.name}\" group itself or one of ` +\n `its shards — an Insight summary must target a SEPARATE analytics vault, never write back into ` +\n `client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`,\n )\n }\n this.crossVaultDerivations.push(spec as unknown as CrossVaultDerivationSpec)\n if (spec.autoPush && !this.insightAutoPush) {\n const controller = new InsightAutoPush(\n (pk) => this._recomputeShardInsights(pk),\n (collection) => this.crossVaultDerivations.some((s) => s.autoPush && s.source === collection),\n )\n this.insightAutoPush = controller\n // Trigger via the Noydb-level change stream (the runtime hook this version\n // ships). One subscription catches EVERY write path into any of this\n // group's shards (ShardedCollection or a direct shard handle). Filter to\n // this group's shard vaults (`<group>--<pk>`); the Insight target can\n // never match that prefix (guarded above), so its writes can't loop back.\n const prefix = `${this.name}${SHARD_SEPARATOR}`\n this.db.on('change', (e) => {\n if (!e.vault.startsWith(prefix)) return\n controller.noteWrite(e.vault.slice(prefix.length), e.collection)\n })\n }\n }\n\n /**\n * Run every registered {@link withCrossVaultDerivation}: read each eligible\n * shard's source records, derive a per-shard summary, and write it into the\n * Insight Vault keyed by partition key. Shards behind `minVersion`,\n * unprovisioned, or whose read errors are reported in `skippedVaults` and\n * are not written (a stale summary is never left behind for a failed shard).\n * A shard whose backend is unreachable (provisioning probe or read throws) is\n * **skipped** (`reason: 'error'`) and the pass continues for the others — its\n * prior summary is left intact. Pass `failFast: true` for the legacy\n * all-or-nothing throw. Reconcile a lagging shard later with\n * `refreshInsights({ only: [pk] })` or `refreshDerivation(pk)`.\n */\n async refreshInsights(options: { minVersion?: number; concurrency?: number; only?: readonly string[]; failFast?: boolean } = {}): Promise<RefreshInsightsResult> {\n if (this.crossVaultDerivations.length === 0) return { written: 0, skippedVaults: [] }\n const { eligible, skipped } = await this.resolveEligible({\n ...(options.minVersion !== undefined ? { minVersion: options.minVersion } : {}),\n ...(options.only !== undefined ? { only: options.only } : {}),\n ...(options.failFast !== undefined ? { failFast: options.failFast } : {}),\n })\n let written = 0\n for (const spec of this.crossVaultDerivations) {\n const results = await this.db.queryAcross<Record<string, unknown>[]>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.template.configure(vault)\n return vault.collection<Record<string, unknown>>(spec.source).list()\n },\n { create: false, ...(options.concurrency !== undefined ? { concurrency: options.concurrency } : {}) },\n )\n const insight = await this.db.openVault(spec.target.vault)\n const out = insight.collection<Record<string, unknown>>(spec.target.collection)\n for (let i = 0; i < eligible.length; i++) {\n const row = eligible[i]!\n const res = results[i]\n if (!res || res.result === undefined) {\n if (options.failFast && res?.error) throw res.error\n skipped.push({ vaultId: row.vaultId, reason: 'error', ...(res?.error ? { error: res.error } : {}) })\n continue\n }\n const ctx: CrossVaultDerivationContext = {\n vaultId: row.vaultId,\n partitionKey: row.partitionKey,\n schemaVersion: row.schemaVersion,\n }\n const summary = spec.derive(res.result, ctx)\n await out.put(row.partitionKey, summary)\n written++\n }\n }\n return { written, skippedVaults: skipped }\n }\n\n /**\n * Reconcile one shard's Insight summaries after its backend was unreachable.\n * Equivalent to `refreshInsights({ only: [partitionKey] })` — runs every\n * registered derivation (autoPush or not) for just this shard.\n */\n async refreshDerivation(partitionKey: string): Promise<RefreshInsightsResult> {\n return this.refreshInsights({ only: [partitionKey] })\n }\n\n /** @internal — re-derive + push every autoPush derivation's summary for one shard. */\n private async _recomputeShardInsights(partitionKey: string): Promise<void> {\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) return\n const shard = await this.openShard(partitionKey)\n const ctx: CrossVaultDerivationContext = {\n vaultId: row.vaultId,\n partitionKey,\n schemaVersion: row.schemaVersion,\n }\n for (const spec of this.crossVaultDerivations) {\n if (!spec.autoPush) continue\n const records = await shard.collection<Record<string, unknown>>(spec.source).list()\n const summary = spec.derive(records, ctx)\n const insight = await this.db.openVault(spec.target.vault)\n await insight.collection<Record<string, unknown>>(spec.target.collection).put(partitionKey, summary)\n }\n }\n\n /**\n * Await any pending Insight auto-push flush (#12). Resolves immediately when\n * no autoPush derivation is registered or nothing is pending. Use after a\n * batch of writes to observe the Insight Vault, or in tests.\n */\n async whenInsightsSettled(): Promise<void> {\n if (this.insightAutoPush) await this.insightAutoPush.whenSettled()\n }\n\n /** @internal — the control-plane vault for migration status; lazily opened. */\n private async ensureStateVault(): Promise<StateManagementVault> {\n if (!this.stateVault) this.stateVault = await StateManagementVault.open(this.db)\n return this.stateVault\n }\n\n /**\n * Migrate ONE shard to the template's current version (#271 fleet runner,\n * per-shard step). Opens the shard (applying the template, which arms the\n * M12 cutover), drains schema-write detection, runs `vault.runSchemaCutover()`\n * (the per-vault drain-barrier-transform protocol), then advances the\n * registry row's `schemaVersion` and records `migration-status`. A shard\n * already at the template version is a no-op (`status: 'done'`, migrated 0).\n * Never throws on a cutover failure — it records `status: 'failed'` and\n * returns the row, so a fleet run continues past a bad shard.\n */\n async cutoverShard(partitionKey: string): Promise<MigrationStatusRow> {\n const vaultId = this.shardVaultId(partitionKey)\n const row = await this.registry.get(this.registryId(partitionKey))\n if (!row) throw new UnknownShardError(partitionKey, this.name)\n const target = this.template.version\n const sv = await this.ensureStateVault()\n const base = { vaultId, group: this.name, currentVersion: row.schemaVersion, targetVersion: target }\n\n if (row.schemaVersion >= target) {\n const done: MigrationStatusRow = { ...base, status: 'done', migrated: 0, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(done)\n return done\n }\n\n await sv.upsertMigrationStatus({ ...base, status: 'running', startedAt: Date.now() })\n try { await sv.appendEvent({ type: 'migration-started', group: this.name, vaultId, version: target }) } catch { /* best-effort */ }\n\n try {\n const vault = await this._openShardRaw(partitionKey)\n await vault._drainPendingSchemaWrites()\n const { migrated } = await vault.runSchemaCutover()\n // Advance the authoritative registry version (no built-in update path).\n await this.registry.put(this.registryId(partitionKey), { ...row, schemaVersion: target })\n const done: MigrationStatusRow = { ...base, currentVersion: target, status: 'done', migrated, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(done)\n try { await sv.appendEvent({ type: 'migration-completed', group: this.name, vaultId, version: target }) } catch { /* best-effort */ }\n return done\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err)\n const failed: MigrationStatusRow = { ...base, status: 'failed', error, finishedAt: Date.now() }\n await sv.upsertMigrationStatus(failed)\n try { await sv.appendEvent({ type: 'migration-failed', group: this.name, vaultId, version: target, detail: error }) } catch { /* best-effort */ }\n return failed\n }\n }\n\n /**\n * Active batch runner (#271): migrate every shard behind the template version\n * to it, in controlled batches. **Resumable + crash-safe** — shards already at\n * the target are skipped (the registry version is the source of truth), so a\n * re-run after a crash only picks up the unfinished + previously-failed shards.\n *\n * - `cohort` — restrict to these partition keys (the staged / canary rollout:\n * migrate a small cohort, verify the Insight Vault, then run the rest).\n * - `batchSize` — max shards migrated concurrently per batch (back-pressure).\n * Default 4. Batches run sequentially; shards within a batch run in parallel.\n */\n async rolloutSchema(options: { cohort?: readonly string[]; batchSize?: number } = {}): Promise<SchemaRolloutResult> {\n const target = this.template.version\n const rows = await this.allRows()\n const cohort = options.cohort\n const todo = rows.filter(\n (r) => r.schemaVersion < target && (cohort === undefined || cohort.includes(r.partitionKey)),\n )\n const batchSize = Math.max(1, options.batchSize ?? 4)\n const migrated: string[] = []\n const failed: { vaultId: string; error: string }[] = []\n for (let i = 0; i < todo.length; i += batchSize) {\n const batch = todo.slice(i, i + batchSize)\n const settled = await Promise.all(batch.map((r) => this.cutoverShard(r.partitionKey)))\n for (const res of settled) {\n if (res.status === 'done') migrated.push(res.vaultId)\n else failed.push({ vaultId: res.vaultId, error: res.error ?? 'unknown' })\n }\n }\n return { target, migrated, failed }\n }\n}\n\nexport class ShardedCollection<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n ) {}\n\n /** Route a write to the shard owning `keyOf(record)`. */\n async put(id: string, record: T): Promise<void> {\n const key = this.group.sharding.keyOf(record)\n const row = await this.group.registry.get(this.group.registryId(key))\n let vault: Vault\n if (!row) {\n if (this.group.sharding.autoCreate === false) {\n throw new UnknownShardError(key, this.group.name)\n }\n vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record))\n } else {\n vault = await this.group.openShard(key)\n }\n await vault.collection<T>(this.collectionName).put(id, record)\n }\n\n /** Begin a cross-shard fan-out query. */\n query(): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(this.group, this.collectionName, [])\n }\n}\n\nexport class ShardedQuery<T, R = T> {\n constructor(\n private readonly group: VaultGroup<T>,\n private readonly collectionName: string,\n private readonly clauses: readonly WhereClause[],\n private readonly coPartitionedLegs: readonly CoPartitionedLeg[] = [],\n private readonly broadcastLegs: readonly BroadcastLeg[] = [],\n ) {}\n\n where(field: string, op: WhereClause['op'], value: unknown): ShardedQuery<T, R> {\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n [...this.clauses, { field, op, value }],\n this.coPartitionedLegs,\n this.broadcastLegs,\n )\n }\n\n /** Co-partitioned join: each shard joins its own same-vault right collection (resolved via ref()), then union. */\n crossShardJoin(field: string, opts: CrossShardJoinOptions): ShardedQuery<T, R> {\n const leg: CoPartitionedLeg = { field, as: opts.as, maxRows: opts.maxRows, strategy: opts.strategy }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n [...this.coPartitionedLegs, leg],\n this.broadcastLegs,\n )\n }\n\n /** Broadcast dimension join: enrich every merged row from a single shared collection. */\n broadcastJoin(field: string, opts: BroadcastJoinOptions): ShardedQuery<T, R> {\n const leg: BroadcastLeg = {\n field,\n as: opts.as,\n from: opts.from,\n on: opts.on ?? 'id',\n mode: opts.mode ?? 'warn',\n }\n return new ShardedQuery<T, R>(\n this.group,\n this.collectionName,\n this.clauses,\n this.coPartitionedLegs,\n [...this.broadcastLegs, leg],\n )\n }\n\n /** @internal — fan out the where-filtered records across eligible shards. */\n async fanoutRecords(options: FanoutQueryOptions = {}): Promise<{ records: R[]; skippedVaults: SkippedVault[] }> {\n const { eligible, skipped } = await this.group.resolveEligible(options)\n // Deterministic pre-check: an undeclared co-partitioned join ref fails\n // identically on every shard, so surface it as ONE CrossShardJoinError\n // rather than N identical skips. Probe the first eligible shard.\n const probeRow = eligible[0]\n if (this.coPartitionedLegs.length > 0 && probeRow) {\n const probe = await this.group.openShard(probeRow.partitionKey)\n this.group.template.configure(probe)\n for (const leg of this.coPartitionedLegs) {\n if (!probe.resolveRef(this.collectionName, leg.field)) {\n throw new CrossShardJoinError(\n `crossShardJoin(\"${leg.field}\"): no ref() declared for \"${leg.field}\" on ` +\n `collection \"${this.collectionName}\" in template \"${this.group.sharding.vaultTemplate}\". ` +\n `Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`,\n )\n }\n }\n }\n const across = await this.group.db.queryAcross<R[]>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.group.template.configure(vault)\n const coll = vault.collection<R>(this.collectionName)\n await coll.list() // hydrate the in-memory cache before the sync query\n // Hydrate each co-partitioned join target — resolveSource reads the\n // in-memory cache, so an unopened right collection would join to an\n // empty snapshot (every row → null).\n for (const leg of this.coPartitionedLegs) {\n const desc = vault.resolveRef(this.collectionName, leg.field)\n if (desc) await vault.collection(desc.target).list()\n }\n let q = coll.query()\n for (const c of this.clauses) q = q.where(c.field, c.op, c.value)\n for (const leg of this.coPartitionedLegs) {\n q = q.join(leg.field, {\n as: leg.as,\n ...(leg.maxRows !== undefined ? { maxRows: leg.maxRows } : {}),\n ...(leg.strategy ? { strategy: leg.strategy } : {}),\n })\n }\n return q.toArray()\n },\n { concurrency: options.concurrency ?? 1, create: false },\n )\n const results: R[] = []\n for (const r of across) {\n if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error })\n else for (const item of r.result) results.push(item)\n }\n return { records: results, skippedVaults: skipped }\n }\n\n /**\n * @internal — distributed partial-reduce (#8). Fan out across eligible shards,\n * but fold each shard's where-filtered records to a partial reducer STATE\n * inside the per-shard callback (never returning the rows). Only the scalar\n * `.aggregate()` path calls this, and that path rejects join legs upstream.\n */\n async fanoutReduce(\n spec: AggregateSpec,\n options: FanoutQueryOptions = {},\n ): Promise<{ partials: PartialState[]; skippedVaults: SkippedVault[] }> {\n const { eligible, skipped } = await this.group.resolveEligible(options)\n const across = await this.group.db.queryAcross<PartialState>(\n eligible.map((r) => r.vaultId),\n async (vault) => {\n this.group.template.configure(vault)\n const coll = vault.collection<R>(this.collectionName)\n await coll.list() // hydrate the in-memory cache before the sync query\n let q = coll.query()\n for (const c of this.clauses) q = q.where(c.field, c.op, c.value)\n const rows = q.toArray()\n return reduceToPartial(rows, spec)\n },\n { concurrency: options.concurrency ?? 1, create: false },\n )\n const partials: PartialState[] = []\n for (const r of across) {\n if (r.error) skipped.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error })\n else partials.push(r.result)\n }\n return { partials, skippedVaults: skipped }\n }\n\n /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */\n async toArray(options: FanoutQueryOptions = {}): Promise<FanoutResult<R>> {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n const results = (await applyBroadcastLegs(records, this.broadcastLegs)) as R[]\n return { results, skippedVaults }\n }\n\n /** @internal — build the change-subscription + relevance binding for this query's group+collection. */\n liveBinding(): LiveBinding {\n const group = this.group\n const collectionName = this.collectionName\n return {\n subscribeToChanges: (h) => { group.db.on('change', h); return () => group.db.off('change', h) },\n isRelevant: (e) => e.collection === collectionName && e.vault.startsWith(`${group.name}--`),\n }\n }\n\n /** @internal — joined queries don't support reactive/aggregate surfaces in v1. */\n private assertNoJoinLegs(surface: string): void {\n if (this.coPartitionedLegs.length || this.broadcastLegs.length) {\n throw new CrossShardJoinError(\n `${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin ` +\n `legs in v1. Use toArray() for joined cross-shard queries.`,\n )\n }\n }\n\n /** Returns a reactive cross-shard live query — a facade over CrossVaultLive. */\n live(options: LiveQueryOptions = {}): CrossVaultLiveQuery<R> {\n this.assertNoJoinLegs('live')\n const bind = this.liveBinding()\n const core = new CrossVaultLive<{ records: R[]; skipped: SkippedVault[] }>({\n ...bind,\n compute: async () => {\n const { records, skippedVaults } = await this.fanoutRecords(options)\n return { records, skipped: skippedVaults }\n },\n initialSnapshot: { records: [], skipped: [] },\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n })\n return {\n get value() { return core.snapshot.records as readonly R[] },\n get skippedVaults() { return core.snapshot.skipped as readonly SkippedVault[] },\n get error() { return core.error },\n ready: core.ready,\n subscribe: (cb) => core.subscribe(cb),\n stop: () => core.stop(),\n }\n }\n\n /** One-shot distributed aggregate — central reduce over all shard records. */\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultAggregation<R, Spec> {\n this.assertNoJoinLegs('aggregate')\n return new CrossVaultAggregation<R, Spec>(this, spec, this.liveBinding())\n }\n\n /** Begin a grouped cross-shard aggregate. */\n groupBy<F extends string>(field: F): ShardedGroupedQuery<T, R, F> {\n this.assertNoJoinLegs('groupBy')\n return new ShardedGroupedQuery<T, R, F>(this, field)\n }\n}\n\n/** Grouped cross-shard query — intermediate after `.groupBy(field)`, terminates with `.aggregate(spec)`. */\nexport class ShardedGroupedQuery<T, R, F extends string> {\n constructor(\n private readonly query: ShardedQuery<T, R>,\n private readonly field: F,\n ) {}\n\n aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultGroupedAggregation<R, F, Spec> {\n return new CrossVaultGroupedAggregation<R, F, Spec>(\n { fanoutRecords: (o) => this.query.fanoutRecords(o) } satisfies FanoutRecordSource<R>,\n this.field,\n spec,\n this.query.liveBinding(),\n )\n }\n}\n","/**\n * @klum-db/lobby — the Lobby orchestrates a group of sovereign noy-db vaults.\n * @packageDocumentation\n */\nimport type { Noydb } from '@noy-db/hub'\nimport { ValidationError, ReservedVaultNameError, VaultTemplateNotFoundError } from '@noy-db/hub/kernel'\nimport { STATE_VAULT_NAME } from '@noy-db/hub'\nimport type { VaultGroup } from './federation/vault-group.js'\nimport type { StateManagementVault } from './federation/state-vault.js'\nimport type { VaultTemplate, VaultGroupOptions } from './federation/types.js'\nimport type { AsXlsxSheetOptions } from '@noy-db/as-xlsx'\nimport type { CrossVaultRef } from './interchange/extract-cross-vault.js'\n\n/**\n * Options for {@link Lobby.exportMultiVaultXlsx} (FR-9).\n *\n * Walks the cross-vault FK closure (FR-2) starting from `primary.vault` using\n * the supplied `primary.seeds` predicates, then delegates to\n * `@noy-db/as-xlsx`'s `toBytesMultiVault` for edge-pure rendering.\n *\n * **Primary-vault row scope:** `walkCrossVaultClosure` populates\n * `perVaultClosure` for the primary vault (the seed predicate rows are\n * collected there). This orchestrator passes that closure to the primary\n * vault entry, so the export contains exactly the seeded rows — not more,\n * not less. Supporting vaults receive their closure slice (FK-referenced ids\n * only, never the full collection).\n */\nexport interface ExportMultiVaultXlsxOptions {\n /** Primary vault: name + seed predicates per collection. */\n readonly primary: {\n readonly vault: string\n readonly seeds: Record<string, (rec: Record<string, unknown>) => boolean | Promise<boolean>>\n }\n /** Cross-vault FK edges that drive the closure walk. */\n readonly crossVaultRefs?: readonly CrossVaultRef[]\n /**\n * Per-vault sheet specs. Keys must be vault names (including `primary.vault`).\n * Sheet options may include `denormalize` for FK-join columns.\n */\n readonly sheets: Readonly<Record<string, readonly AsXlsxSheetOptions[]>>\n /** Optional maxDepth for walkCrossVaultClosure. */\n readonly maxDepth?: number\n /** Optional sheet-name separator forwarded to toBytesMultiVault. */\n readonly sheetSeparator?: string\n}\n\n// ─── FR-7 Surface type imports (used in Lobby method signatures) ──────────────\nimport type { SurfaceRow } from './federation/types.js'\nimport type { MergeReport } from './interchange/merge-compartment.js'\n\n// ─── Dock imports (lower tier read-only units) ────────────────────────────────\nimport { DockedUnit } from './dock/docked-unit.js'\nimport type { UnitDriver } from './dock/unit-driver.js'\nimport type { GraduateOptions, GraduationReport } from './dock/graduate.js'\n\nexport class Lobby {\n readonly noydb: Noydb\n private readonly vaultTemplates = new Map<string, VaultTemplate>()\n\n constructor(noydb: Noydb) {\n this.noydb = noydb\n }\n\n withVaultTemplate(name: string, template: VaultTemplate): void {\n this.vaultTemplates.set(name, template)\n }\n\n async openVaultGroup<T>(name: string, opts: VaultGroupOptions<T>): Promise<VaultGroup<T>> {\n const db = this.noydb\n if (db.isClosed) throw new ValidationError('Instance is closed')\n if (name === STATE_VAULT_NAME) throw new ReservedVaultNameError(name)\n const template = this.vaultTemplates.get(opts.sharding.vaultTemplate)\n if (!template) throw new VaultTemplateNotFoundError(opts.sharding.vaultTemplate)\n const { VaultGroup } = await import('./federation/vault-group.js')\n const { StateManagementVault } = await import('./federation/state-vault.js')\n const stateVault = opts.registry ? undefined : await StateManagementVault.open(db)\n const registry = opts.registry ?? stateVault!.registry\n const group = new VaultGroup<T>(db, name, registry, opts.sharding, template, opts.cutoverOnOpen ?? false)\n if (stateVault) {\n group._attachStateVault(stateVault)\n await stateVault.recordManifest(opts.sharding.vaultTemplate, template)\n try {\n await stateVault.appendEvent({ type: 'manifest-recorded', group: name, templateName: opts.sharding.vaultTemplate, version: template.version })\n await stateVault.appendEvent({ type: 'group-opened', group: name })\n } catch { /* best-effort */ }\n }\n return group\n }\n\n async openStateManagementVault(): Promise<StateManagementVault> {\n const db = this.noydb\n if (db.isClosed) throw new ValidationError('Instance is closed')\n const { StateManagementVault } = await import('./federation/state-vault.js')\n return StateManagementVault.open(db)\n }\n\n // ─── Dock API ─────────────────────────────────────────────────────────────\n\n /**\n * Dock a foreign (non-noy-db) unit at the lower tier — present + read-only\n * carried, without sovereign guarantees. Graduate it with {@link Lobby.graduate}.\n */\n dock(driver: UnitDriver): DockedUnit {\n return new DockedUnit(driver)\n }\n\n /**\n * Graduate a docked foreign unit into a fresh sovereign vault (#11), unlocking\n * the full tier (keyring, CEK, provenance, custody).\n */\n async graduate(docked: DockedUnit, opts: GraduateOptions): Promise<GraduationReport> {\n const { graduate: graduateFn } = await import('./dock/graduate.js')\n return graduateFn(this.noydb, docked, opts)\n }\n\n // ─── FR-7 Surface API ─────────────────────────────────────────────────────\n\n /**\n * Export a scoped partition from `vaultName` bounded to the given surface.\n * Delegates to `exportSurface` in `interchange/surface.ts`.\n * The vault is opened via `this.noydb.openVault(vaultName)`.\n */\n async exportSurface(\n vaultName: string,\n surface: SurfaceRow,\n ): Promise<{ bundleBytes: Uint8Array; transferKey: Uint8Array }> {\n const { exportSurface: exportSurfaceFn } = await import('./interchange/surface.js')\n const vault = await this.noydb.openVault(vaultName)\n return exportSurfaceFn(vault, surface)\n }\n\n /**\n * Apply an exported surface bundle into `vaultName`.\n * Delegates to `applySurface` in `interchange/surface.ts`.\n * The vault is opened via `this.noydb.openVault(vaultName)`.\n */\n async applySurface(\n vaultName: string,\n surface: SurfaceRow,\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n ): Promise<MergeReport> {\n const { applySurface: applySurfaceFn } = await import('./interchange/surface.js')\n const vault = await this.noydb.openVault(vaultName)\n return applySurfaceFn(vault, surface, bundleBytes, transferKey)\n }\n\n /**\n * One-call multi-vault Excel export (FR-9).\n *\n * 1. Calls `walkCrossVaultClosure` (FR-2) to build the FK closure across all\n * referenced vaults, starting from `opts.primary.vault` using the supplied\n * seed predicates.\n * 2. For each vault in `opts.sheets`, opens the vault and attaches the\n * per-vault closure slice from the plan:\n * - **Primary vault**: gets its `perVaultClosure` slice (the seeded rows).\n * - **Supporting vaults**: get their closure slice (FK-referenced ids only).\n * 3. Delegates to `@noy-db/as-xlsx`'s `toBytesMultiVault` for edge-pure\n * rendering (no cross-vault walk in the adapter).\n *\n * Every vault in `opts.sheets` must independently hold\n * `assertCanExport('plaintext','xlsx')`.\n */\n async exportMultiVaultXlsx(opts: ExportMultiVaultXlsxOptions): Promise<Uint8Array> {\n const { walkCrossVaultClosure } = await import('./interchange/extract-cross-vault.js')\n const { toBytesMultiVault } = await import('@noy-db/as-xlsx')\n\n const openVault = (name: string) => this.noydb.openVault(name)\n\n const plan = await walkCrossVaultClosure(openVault, {\n seed: { vault: opts.primary.vault, seeds: opts.primary.seeds },\n ...(opts.crossVaultRefs !== undefined ? { crossVaultRefs: opts.crossVaultRefs } : {}),\n ...(opts.maxDepth !== undefined ? { maxDepth: opts.maxDepth } : {}),\n })\n\n const entries = await Promise.all(\n Object.entries(opts.sheets).map(async ([vaultName, sheets]) => {\n const vault = await openVault(vaultName)\n const closure = plan.perVaultClosure.get(vaultName)\n // Both primary and supporting vaults get their perVaultClosure slice:\n // - primary: the seeded rows (walkCrossVaultClosure includes the seed vault)\n // - supporting: the FK-referenced ids only\n // This ensures the export is bounded to exactly what the closure walk found.\n return {\n vault,\n sheets: sheets as AsXlsxSheetOptions[],\n label: vaultName,\n ...(closure ? { closure } : {}),\n }\n }),\n )\n\n return toBytesMultiVault(entries, {\n ...(opts.sheetSeparator !== undefined ? { sheetSeparator: opts.sheetSeparator } : {}),\n })\n }\n}\n\nexport function createLobby(noydb: Noydb): Lobby {\n return new Lobby(noydb)\n}\n\nexport type {\n VaultGroup, ShardedCollection, ShardedQuery, ShardedGroupedQuery,\n CrossVaultAggregation, CrossVaultGroupedAggregation, StateManagementVault,\n VaultTemplate, VaultRegistryRow, ShardingConfig, VaultGroupOptions,\n FanoutQueryOptions, FanoutResult, SkippedVault,\n CrossVaultLiveQuery, CrossVaultLiveAggregation, LiveQueryOptions,\n SchemaManifestRow, DeploymentEvent, CapturedBlueprint,\n CrossVaultDerivationSpec, CrossVaultDerivationContext, RefreshInsightsResult,\n MigrationStatusRow, SchemaRolloutResult,\n} from './federation/index.js'\nexport type { GroupedRow as CrossVaultGroupedRow } from './federation/index.js'\n\n// Federation tooling (WS-3): drive the @noy-db dev-tools / meter over a vault group.\nexport { groupInspector } from './federation/group-inspector.js'\nexport { meterGroup } from './federation/meter-group.js'\nexport type { GroupMeterReport, GroupShardMetrics } from './federation/meter-group.js'\n\n// Federation error classes as runtime values — so consumers catch them from\n// @klum-db/lobby directly, not via @noy-db/hub's internal /kernel surface.\nexport {\n CrossShardJoinError,\n UnknownShardError,\n ShardProvisioningError,\n VaultTemplateNotFoundError,\n ReservedVaultNameError,\n DataResidencyError,\n} from '@noy-db/hub/kernel'\n\n// ─── Multivault bundle (NDBM) — relocated from @noy-db/hub ────────────────────\nexport {\n encodeMultiBundle,\n decodeMultiBundle,\n writeMultiVaultBundle,\n readNoydbBundleManifest,\n readMultiVaultBundleCompartment,\n NOYDB_MULTI_BUNDLE_MAGIC,\n NOYDB_MULTI_BUNDLE_PREFIX_BYTES,\n NOYDB_MULTI_BUNDLE_VERSION,\n} from './bundle/multi-bundle.js'\nexport type {\n CompartmentManifest,\n MultiBundleManifest,\n MultiVaultCompartmentInput,\n} from './bundle/multi-bundle.js'\n\n// ─── FR-2: Cross-vault FK-closure extraction ──────────────────────────────────\nexport {\n walkCrossVaultClosure,\n extractCrossVaultPartition,\n describeCrossVaultExtraction,\n CrossVaultDanglingRefError,\n} from './interchange/extract-cross-vault.js'\nexport type {\n CrossVaultRef,\n CrossVaultSeed,\n CrossVaultClosurePlan,\n CompartmentMeta,\n ExtractCrossVaultOptions,\n ExtractCrossVaultResult,\n CrossVaultPreview,\n} from './interchange/extract-cross-vault.js'\n\n// ─── FR-3: Merge-import / reconcile-into-existing vault ───────────────────────\nexport { mergeCompartment, mergeDecryptedRecords, FieldLevelDeferredError } from './interchange/merge-compartment.js'\nexport type {\n MergeStrategy,\n DecryptedMergeOptions,\n MergeCompartmentOptions,\n MergeConflict,\n MergeReport,\n} from './interchange/merge-compartment.js'\n\n// ─── FR-8: Migrate-then-merge — upgrade incoming bundle before reconcile ──────\nexport {\n migrateThenMerge,\n MinVersionError,\n MigrationTransformRequiredError,\n} from './interchange/migrate-then-merge.js'\nexport type {\n MigrationStep,\n MigrateThenMergeOptions,\n MigrateThenMergeReport,\n} from './interchange/migrate-then-merge.js'\n\n// ─── FR-4: Field-authority conflict resolver ──────────────────────────────────\nexport {\n resolveFieldAuthority,\n resolveRecordByFieldAuthority,\n FieldAuthorityPolicyMissingError,\n} from './interchange/field-authority.js'\nexport type {\n FieldAuthorityRule,\n FieldAuthorityPolicy,\n FieldAuthorityInputs,\n} from './interchange/field-authority.js'\n\n// ─── FR-6: Sovereign custody (Deed / Custodian / Liberate) ────────────────────\n// Pure re-exports — custody is a vault-level concern in @noy-db/hub; the Lobby\n// surfaces the types/functions so fleet-level orchestration can reach them\n// without importing hub internals directly (no lobby logic in this slice).\nexport { CustodyApi, liberateVault, createDeedOwner, loadDeedMarker, isDeedVault } from '@noy-db/hub'\nexport type { DeedMarker, LiberateOptions, LiberateResult, GrantCustodianOptions } from '@noy-db/hub'\n\n// ─── FR-9: Multi-vault FK-driven Excel export ─────────────────────────────────\n// ExportMultiVaultXlsxOptions is declared (and exported) above alongside Lobby.\n// Re-export the as-xlsx multi-vault types so consumers don't need to import\n// @noy-db/as-xlsx directly.\nexport type {\n MultiVaultXlsxEntry,\n MultiVaultXlsxOptions,\n MultiVaultDenormColumn,\n} from '@noy-db/as-xlsx'\n\n// ─── #11: Dock tier + graduate() ──────────────────────────────────────────────\nexport type { UnitDriver, GraduateOptions, GraduationReport } from './dock/index.js'\nexport { InMemoryUnitDriver, DockedUnit, UnitGraduationError } from './dock/index.js'\n\n// ─── FR-7: Surface / Scoped Sync ─────────────────────────────────────────────\nexport {\n proposeSurface,\n agreeSurface,\n exportSurface,\n applySurface,\n isSurfaceDue,\n listDueSurfaces,\n markSynced,\n SurfaceNotFoundError,\n SurfaceStateError,\n SurfaceCadenceScheduler,\n} from './interchange/surface.js'\nexport type {\n SurfaceDefinition,\n} from './interchange/surface.js'\nexport type {\n SurfaceRow,\n SurfaceDirection,\n SurfaceStatus,\n SurfaceConflictPolicy,\n} from './federation/types.js'\n","/**\n * @klum-db/lobby dock — the lower tier. A `DockedUnit` is present in the Lobby\n * and read-only carried, WITHOUT the sovereign guarantees (custody, field\n * authority, provenance, forget). Those become reachable only after\n * `graduate()` mints a real noy-db vault. The boundary is structural: this\n * class deliberately has no sovereign methods.\n *\n * @module\n */\nimport type { UnitDriver } from './unit-driver.js'\n\nexport class DockedUnit {\n constructor(readonly driver: UnitDriver) {}\n\n get unitId(): string {\n return this.driver.unitId\n }\n\n listCollections(): Promise<readonly string[]> {\n return this.driver.listCollections()\n }\n\n readRecords(collection: string): AsyncIterable<Record<string, unknown>> {\n return this.driver.readRecords(collection)\n }\n}\n","import type { InspectableContainer } from '@noy-db/in-devtools'\nimport type { AccessibleVault, Vault, WriteHook, WriteConflict, WriteQueue, Unsubscribe } from '@noy-db/hub'\nimport type { VaultGroup } from './vault-group.js'\n\n/**\n * Adapt a federation {@link VaultGroup} to the dev-tools `InspectableContainer`\n * contract from `@noy-db/in-devtools`, so the inspector / TUI can browse a\n * whole fleet exactly like a single instance.\n *\n * Built entirely on the group's public surface (`allRows`, `db`, `template`) —\n * no `VaultGroup` changes, and (critically) no `@klum-db` import lands in any\n * `@noy-db` package: the dependency runs one way, klum → noy.\n *\n * Write-event scoping: `group.db` may host vaults outside this group, so write\n * and conflict events are filtered to the group's shard ids. The id set is\n * primed/refreshed on every `listAccessibleVaults()` call — drive `listVaults()`\n * (the inspector's normal first step) before relying on event scoping.\n */\nexport function groupInspector<T>(group: VaultGroup<T>): InspectableContainer {\n let shardIds = new Set<string>()\n const refresh = async () => {\n const rows = await group.allRows()\n shardIds = new Set(rows.map((r) => r.vaultId))\n return rows\n }\n return {\n async listAccessibleVaults(): Promise<readonly AccessibleVault[]> {\n const rows = await refresh()\n return rows.map((r): AccessibleVault => ({ id: r.vaultId, role: 'owner' }))\n },\n async openVault(name: string): Promise<Vault> {\n const vault = await group.db.openVault(name)\n group.template.configure(vault)\n return vault\n },\n onAfterWrite(handler: WriteHook): Unsubscribe {\n return group.db.onAfterWrite((event) => {\n if (shardIds.has(event.vault)) return handler(event)\n })\n },\n onWriteConflict(handler: (c: WriteConflict) => void): Unsubscribe {\n return group.db.onWriteConflict((c) => {\n if (shardIds.has(c.vault)) handler(c)\n })\n },\n get writeQueue(): WriteQueue {\n return group.db.writeQueue\n },\n }\n}\n","import type { VaultGroup } from './vault-group.js'\nimport type { SkippedVault } from './types.js'\n\nexport interface GroupShardMetrics {\n readonly vaultId: string\n readonly partitionKey: string\n readonly schemaVersion: number\n readonly collections: number\n readonly records: number\n}\n\nexport interface GroupMeterReport {\n /** Number of eligible shards measured. */\n readonly vaults: number\n /** Distinct collection names across the group. */\n readonly collections: number\n /** Total record count summed across shards. */\n readonly records: number\n readonly perShard: ReadonlyArray<GroupShardMetrics>\n /** Drifted / provisioning-failed shards — surfaced, never counted or hidden. */\n readonly skipped: ReadonlyArray<SkippedVault>\n}\n\n/**\n * Fan shape-metrics (collection count + record count) across the group's\n * ELIGIBLE shards. Skipped shards (schema-drift / provisioning failures) are\n * reported in `skipped`, never silently dropped. Reuses the per-vault pattern\n * from `multi-bundle.ts` (`vault.collections()` → `collection(n).count()`).\n *\n * Operational store metrics (calls, CAS conflicts) are a separate concern and\n * are already group-wide via `@noy-db/to-meter` on the underlying store.\n */\nexport async function meterGroup<T>(\n group: VaultGroup<T>,\n opts: { minVersion?: number } = {},\n): Promise<GroupMeterReport> {\n const { eligible, skipped } = await group.resolveEligible(\n opts.minVersion !== undefined ? { minVersion: opts.minVersion } : {},\n )\n const perShard: GroupShardMetrics[] = []\n const names = new Set<string>()\n let records = 0\n for (const row of eligible) {\n const vault = await group.shard(row.partitionKey)\n const collNames = await vault.collections()\n let shardRecords = 0\n for (const n of collNames) {\n names.add(n)\n shardRecords += await vault.collection(n).count()\n }\n records += shardRecords\n perShard.push({\n vaultId: row.vaultId,\n partitionKey: row.partitionKey,\n schemaVersion: row.schemaVersion,\n collections: collNames.length,\n records: shardRecords,\n })\n }\n return { vaults: eligible.length, collections: names.size, records, perShard, skipped }\n}\n","/**\n * @klum-db/lobby interchange — migrate-then-merge (FR-8). Upgrade an incoming\n * compartment to the receiver's schema version IN STAGING, then merge.\n *\n * Pipeline:\n * 1. Resolve fromVersion / toVersion.\n * 2. Refuse if incoming bundle is newer than receiver (MinVersionError).\n * 3. Decrypt the compartment bytes.\n * 4. STAGING: apply per-collection migration transforms in-memory; then\n * pre-validate EVERY staged record via `receiver.collection(coll).validateInput()`\n * BEFORE any write. A throwing transform or validation failure leaves the\n * receiver completely untouched (staging-safety guarantee).\n * 5. Delegate to `mergeDecryptedRecords` with the now schema-homogeneous\n * staged records — the merge engine never branches on schema version.\n *\n * @module\n */\nimport type { Vault } from '@noy-db/hub'\nimport { decryptExtractedPartition } from '@noy-db/hub/bundle'\nimport {\n mergeDecryptedRecords,\n type MergeCompartmentOptions,\n type MergeReport,\n} from './merge-compartment.js'\nimport { stageAndValidate, type RecordTransform } from './stage-records.js'\nexport { MigrationTransformRequiredError } from './stage-records.js'\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\n/** One upgrade step: transform a record body up to `toVersion`. */\nexport interface MigrationStep {\n /** The target version this step brings records up to. */\n readonly toVersion: number\n /**\n * Pure transform: takes the old record body, returns the new record body.\n * The transform need not preserve `id` — the canonical `id` from the decrypted\n * record is re-injected after every step, so a transform that drops or renames\n * `id` cannot silently detach a row from its identity (which would otherwise\n * make the merge skip it, since the diff keys off `record.id`).\n */\n readonly transform: (record: Record<string, unknown>) => Record<string, unknown>\n}\n\nexport interface MigrateThenMergeOptions extends MergeCompartmentOptions {\n /**\n * Incoming bundle's schema version.\n * Read from `CompartmentManifest.schemaVersion` (stamped by FR-2 extract, Task 2).\n * When omitted, `assumeFromVersion` is used as a fallback.\n */\n readonly fromVersion?: number\n /**\n * Fallback version for bundles whose manifest carries no `schemaVersion` (older bundles).\n * Ignored when `fromVersion` is present.\n */\n readonly assumeFromVersion?: number\n /**\n * Target schema version to migrate to.\n * Defaults to `receiver.schemaFenceState().currentSchemaVersion`.\n */\n readonly toVersion?: number\n /**\n * Per-collection ordered upgrade steps, keyed by collection name.\n * Steps are applied in ascending `toVersion` order, filtered to the\n * `(fromVersion, toVersion]` window.\n */\n readonly migrations?: Record<string, readonly MigrationStep[]>\n}\n\nexport interface MigrateThenMergeReport extends MergeReport {\n readonly migration: {\n readonly fromVersion: number\n readonly toVersion: number\n /** Per-collection account of how records reached the target version. */\n readonly byCollection: Record<string, 'transformed' | 'additive-no-transform' | 'same-version'>\n }\n}\n\n// ─── Errors ───────────────────────────────────────────────────────────────────\n\n/**\n * Thrown when the incoming bundle's schema version is greater than the\n * receiver's `currentSchemaVersion`. The receiver must be upgraded first —\n * a newer bundle cannot be down-migrated.\n */\nexport class MinVersionError extends Error {\n constructor(\n public readonly fromVersion: number,\n public readonly toVersion: number,\n ) {\n super(\n `migrateThenMerge: incoming bundle is at schema version ${fromVersion} but the receiver ` +\n `is at ${toVersion}. Upgrade the receiver to at least v${fromVersion} before merging ` +\n `(a newer bundle cannot be down-migrated).`,\n )\n this.name = 'MinVersionError'\n }\n}\n\n\n// ─── Coordinator ─────────────────────────────────────────────────────────────\n\n/**\n * Two-stage upgrade-then-merge pipeline (FR-8).\n *\n * Migrates an incoming compartment from `fromVersion` to `toVersion` in\n * staging, validates every staged record against the receiver schema (using\n * `Collection.validateInput`), then delegates to `mergeDecryptedRecords`.\n *\n * **Staging-safety guarantee:** all transforms and validations run in-memory\n * before `mergeDecryptedRecords` writes anything. A throwing transform OR a\n * failing validation leaves the receiver completely untouched.\n *\n * **Additive fast-path:** collections with no supplied transform still pass\n * when the old shape validates against the receiver schema (additive-only\n * evolution). When no schema is declared on the receiver collection,\n * `validateInput` is a no-op — any shape passes.\n */\nexport async function migrateThenMerge(\n receiver: Vault,\n compartmentBytes: Uint8Array,\n opts: MigrateThenMergeOptions,\n): Promise<MigrateThenMergeReport> {\n // 1. Resolve target version.\n const toVersion = opts.toVersion ?? (await receiver.schemaFenceState()).currentSchemaVersion\n\n // 2. Resolve source version.\n const fromVersion = opts.fromVersion ?? opts.assumeFromVersion\n if (fromVersion === undefined) {\n throw new Error(\n 'migrateThenMerge: cannot determine the incoming schema version. ' +\n 'Pass `fromVersion` (read from the bundle manifest CompartmentManifest.schemaVersion) ' +\n 'or `assumeFromVersion` as a fallback for older bundles.',\n )\n }\n\n // 3. Refuse bundles that are NEWER than the receiver.\n if (fromVersion > toVersion) throw new MinVersionError(fromVersion, toVersion)\n\n // 4. Decrypt the compartment (records only).\n const incoming = await decryptExtractedPartition(compartmentBytes, opts.transferKey)\n\n // 5. STAGING: transform + pre-validate every record before any write.\n // A throwing transform or a validation failure bubbles out here —\n // `mergeDecryptedRecords` is never reached → receiver is untouched.\n const transformsByCollection: Record<string, RecordTransform[]> = {}\n const migrationByCollection: Record<string, 'transformed' | 'additive-no-transform' | 'same-version'> = {}\n for (const [coll, recs] of Object.entries(incoming)) {\n const steps = (opts.migrations?.[coll] ?? [])\n .filter((s) => s.toVersion > fromVersion && s.toVersion <= toVersion)\n .slice()\n .sort((a, b) => a.toVersion - b.toVersion)\n transformsByCollection[coll] = steps.map((s) => s.transform)\n migrationByCollection[coll] =\n fromVersion === toVersion ? 'same-version' : steps.length > 0 ? 'transformed' : 'additive-no-transform'\n void recs\n }\n const staged = await stageAndValidate(receiver, incoming, transformsByCollection)\n\n // 6. Merge the now schema-homogeneous staged records — no version branching here.\n const report = await mergeDecryptedRecords(receiver, staged, opts)\n\n return {\n ...report,\n migration: {\n fromVersion,\n toVersion,\n byCollection: migrationByCollection,\n },\n }\n}\n","/**\n * @klum-db/lobby dock — the foreign-format contract (unit-driver family).\n *\n * A `UnitDriver` reads a foreign / legacy unit (a raw sqlite file, an external\n * schema, …) as plain records. The noy-db vault is the flagship \"vessel\"; this\n * is the passthrough driver for everything else. klum-db ships the interface\n * plus an in-memory reference driver; concrete adapters (sqlite, …) live in\n * separate packages.\n *\n * @module\n */\n\n/** Reads a foreign unit as plain, plaintext records. */\nexport interface UnitDriver {\n /** Stable identifier for the foreign unit (used in audit events). */\n readonly unitId: string\n /** List the foreign collections/tables available to dock. */\n listCollections(): Promise<readonly string[]>\n /** Stream the records of one foreign collection. */\n readRecords(collection: string): AsyncIterable<Record<string, unknown>>\n}\n\n/** In-memory reference driver — the test/flagship-less vessel. */\nexport class InMemoryUnitDriver implements UnitDriver {\n constructor(\n readonly unitId: string,\n private readonly data: Record<string, readonly Record<string, unknown>[]>,\n ) {}\n\n async listCollections(): Promise<readonly string[]> {\n return Object.keys(this.data)\n }\n\n async *readRecords(collection: string): AsyncIterable<Record<string, unknown>> {\n for (const row of this.data[collection] ?? []) yield row\n }\n}\n","/** @klum-db/lobby dock — foreign-unit docking + graduation (#11). */\nexport type { UnitDriver } from './unit-driver.js'\nexport { InMemoryUnitDriver } from './unit-driver.js'\nexport { DockedUnit } from './docked-unit.js'\nexport { graduate, UnitGraduationError } from './graduate.js'\nexport type { GraduateOptions, GraduationReport } from './graduate.js'\n"],"mappings":";;;;;;;;;;;AAQO,SAAS,aAAa,OAAmB,QAAwB;AACtE,UACI,MAAM,MAAM,KAAM,KACjB,MAAM,SAAS,CAAC,KAAM,KACtB,MAAM,SAAS,CAAC,KAAM,IACvB,MAAM,SAAS,CAAC,OAAQ;AAE9B;AAGO,SAAS,cAAc,OAAmB,QAAgB,OAAqB;AACpF,QAAM,MAAM,IAAK,UAAU,KAAM;AACjC,QAAM,SAAS,CAAC,IAAK,UAAU,KAAM;AACrC,QAAM,SAAS,CAAC,IAAK,UAAU,IAAK;AACpC,QAAM,SAAS,CAAC,IAAI,QAAQ;AAC9B;AAvBA;AAAA;AAAA;AAAA;AAAA;;;ACYA,SAAS,WAAW,oBAAgC;AACpD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAyCA,SAAS,kBACd,UACA,OACY;AACZ,mBAAiB,QAAQ;AACzB,MAAI,SAAS,aAAa,WAAW,MAAM,QAAQ;AACjD,UAAM,IAAI,MAAM,8BAA8B,SAAS,aAAa,MAAM,qBAAqB,MAAM,MAAM,+BAA+B;AAAA,EAC5I;AACA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI,SAAS,aAAa,CAAC,EAAG,eAAe,MAAM,CAAC,EAAG,QAAQ;AAC7D,YAAM,IAAI,MAAM,6BAA6B,CAAC,wBAAwB,SAAS,aAAa,CAAC,EAAG,UAAU,QAAQ,MAAM,CAAC,EAAG,MAAM,uBAAuB;AAAA,IAC3J;AAAA,EACF;AACA,QAAM,gBAAgB,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,QAAQ,CAAC;AACvE,QAAM,UAAU,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC;AACtD,QAAM,MAAM,IAAI,WAAW,kCAAkC,cAAc,SAAS,OAAO;AAC3F,MAAI,IAAI,0BAA0B,CAAC;AACnC,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,gBAAc,KAAK,GAAG,cAAc,MAAM;AAC1C,MAAI,IAAI,eAAe,+BAA+B;AACtD,MAAI,MAAM,kCAAkC,cAAc;AAC1D,aAAW,KAAK,OAAO;AAAE,QAAI,IAAI,GAAG,GAAG;AAAG,WAAO,EAAE;AAAA,EAAO;AAC1D,SAAO;AACT;AAEA,SAAS,cAAc,OAA4B;AACjD,MAAI,MAAM,SAAS,yBAAyB,OAAQ,QAAO;AAC3D,WAAS,IAAI,GAAG,IAAI,yBAAyB,QAAQ,IAAK,KAAI,MAAM,CAAC,MAAM,yBAAyB,CAAC,EAAG,QAAO;AAC/G,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAwD;AAChF,MAAI,WAAW,QAAQ,OAAO,WAAW,SAAU,OAAM,IAAI,MAAM,8CAA8C;AACjH,QAAM,IAAI;AACV,MAAI,EAAE,oBAAoB,MAAM,2BAA4B,OAAM,IAAI,MAAM,oDAAoD,0BAA0B,SAAS,OAAO,EAAE,oBAAoB,CAAC,CAAC,GAAG;AACrM,MAAI,OAAO,EAAE,QAAQ,MAAM,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAG,OAAM,IAAI,MAAM,0DAA0D;AAC3I,MAAI,CAAC,MAAM,QAAQ,EAAE,cAAc,CAAC,EAAG,OAAM,IAAI,MAAM,sDAAsD;AAC7G,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,KAAK,EAAE,cAAc,GAAgB;AAC9C,QAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,6CAA6C;AACtG,UAAM,IAAI;AACV,QAAI,OAAO,EAAE,QAAQ,MAAM,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAG,OAAM,IAAI,MAAM,6DAA6D;AAC9I,QAAI,YAAY,IAAI,EAAE,QAAQ,CAAC,GAAG;AAChC,YAAM,IAAI,MAAM,6DAA6D,EAAE,QAAQ,CAAC,IAAI;AAAA,IAC9F;AACA,gBAAY,IAAI,EAAE,QAAQ,CAAC;AAC3B,QAAI,OAAO,EAAE,YAAY,MAAM,YAAY,CAAC,OAAO,UAAU,EAAE,YAAY,CAAC,KAAK,EAAE,YAAY,IAAI,EAAG,OAAM,IAAI,MAAM,qEAAqE;AAC3L,QAAI,OAAO,EAAE,aAAa,MAAM,YAAY,CAAC,iBAAiB,KAAK,EAAE,aAAa,CAAC,EAAG,OAAM,IAAI,MAAM,qEAAqE;AAAA,EAC7K;AACF;AAGO,SAAS,kBAAkB,OAA2E;AAC3G,MAAI,CAAC,cAAc,KAAK,EAAG,OAAM,IAAI,MAAM,+CAA+C;AAC1F,MAAI,MAAM,SAAS,gCAAiC,OAAM,IAAI,MAAM,wDAAwD;AAC5H,MAAI,MAAM,CAAC,MAAM,2BAA4B,OAAM,IAAI,MAAM,oCAAoC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG;AACpH,QAAM,cAAc,aAAa,OAAO,CAAC;AACzC,QAAM,cAAc,kCAAkC;AACtD,MAAI,cAAc,MAAM,OAAQ,OAAM,IAAI,MAAM,8DAA8D;AAC9G,QAAM,eAAe,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,MAAM,SAAS,iCAAiC,WAAW,CAAC;AAClI,MAAI;AACJ,MAAI;AAAE,aAAS,KAAK,MAAM,YAAY;AAAA,EAAE,SAAS,KAAK;AAAE,UAAM,IAAI,MAAM,4CAA6C,IAAc,OAAO,EAAE;AAAA,EAAE;AAC9I,mBAAiB,MAAM;AACvB,QAAM,QAAsB,CAAC;AAC7B,MAAI,MAAM;AACV,aAAW,KAAK,OAAO,cAAc;AACnC,UAAM,MAAM,MAAM,EAAE;AACpB,QAAI,MAAM,MAAM,OAAQ,OAAM,IAAI,MAAM,wCAAwC,EAAE,MAAM,mCAAmC;AAC3H,UAAM,KAAK,MAAM,SAAS,KAAK,GAAG,CAAC;AACnC,UAAM;AAAA,EACR;AACA,MAAI,QAAQ,MAAM,QAAQ;AACxB,UAAM,IAAI,MAAM,iBAAiB,MAAM,SAAS,GAAG,4EAAuE;AAAA,EAC5H;AACA,SAAO,EAAE,UAAU,QAAQ,MAAM;AACnC;AAuBA,eAAsB,sBACpB,cACA,OAAqC,CAAC,GACjB;AACrB,MAAI,aAAa,WAAW,EAAG,OAAM,IAAI,MAAM,8DAA8D;AAC7G,QAAM,QAAsB,CAAC;AAC7B,QAAM,UAAiC,CAAC;AACxC,aAAW,KAAK,cAAc;AAC5B,UAAM,aAAa,MAAM,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;AACxE,UAAM,SAAS,sBAAsB,UAAU;AAC/C,UAAM,QAEF;AAAA,MACF,QAAQ,OAAO;AAAA,MACf,YAAY,EAAE,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnD,YAAY,WAAW;AAAA,MACvB,aAAa,MAAM,UAAU,UAAU;AAAA,IACzC;AACA,QAAI,EAAE,YAAY,OAAW,OAAM,UAAU,EAAE;AAC/C,QAAI,EAAE,UAAU,SAAS,UAAa,EAAE,SAAS,SAAS,OAAO;AAC/D,YAAM,OAAO,EAAE,SAAS,SAAS,OAAO,EAAE,MAAM,OAAO,EAAE,SAAS;AAAA,IACpE;AACA,QAAI,EAAE,UAAU,gBAAgB,MAAM;AACpC,YAAM,QAAQ,MAAM,EAAE,MAAM,YAAY;AACxC,YAAM,cAAc,MAAM,QAAQ;AAAA,QAChC,MAAM,IAAI,OAAO,OAAO,EAAE,MAAM,GAAG,OAAO,MAAM,EAAE,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE;AAAA,MAClF;AAAA,IACF;AACA,QAAI,EAAE,UAAU,mBAAmB,MAAM;AACvC,YAAM,MAAM,8BAA8B,UAAU;AACpD,UAAI,QAAQ,OAAW,OAAM,iBAAiB;AAAA,IAChD;AAEA,UAAM,QAAQ,MAAM,EAAE,MAAM,iBAAiB;AAC7C,UAAM,gBAAgB,MAAM;AAC5B,UAAM,KAAK,UAAU;AACrB,YAAQ,KAAK,KAAK;AAAA,EACpB;AACA,QAAM,WAAgC;AAAA,IACpC,oBAAoB;AAAA,IACpB,QAAQ,KAAK,UAAU,aAAa;AAAA,IACpC,cAAc;AAAA,EAChB;AACA,SAAO,kBAAkB,UAAU,KAAK;AAC1C;AAQA,eAAsB,wBAAwB,OAAmD;AAC/F,MAAI,cAAc,KAAK,EAAG,QAAO,CAAC,GAAG,kBAAkB,KAAK,EAAE,SAAS,YAAY;AACnF,MAAI,oBAAoB,KAAK,GAAG;AAC9B,UAAM,SAAS,sBAAsB,KAAK;AAC1C,UAAM,MAAM,8BAA8B,KAAK;AAC/C,UAAM,QAAgF;AAAA,MACpF,QAAQ,OAAO;AAAA,MACf,YAAY,MAAM;AAAA,MAClB,aAAa,MAAM,UAAU,KAAK;AAAA,IACpC;AACA,QAAI,QAAQ,OAAW,OAAM,iBAAiB;AAC9C,WAAO,CAAC,KAAK;AAAA,EACf;AACA,QAAM,IAAI,MAAM,sEAAsE;AACxF;AAcO,SAAS,gCAAgC,OAAmB,UAAuC;AACxG,MAAI,OAAO,aAAa,YAAY,CAAC,OAAO,UAAU,QAAQ,GAAG;AAC/D,UAAM,IAAI,MAAM,6EAA6E,QAAQ,GAAG;AAAA,EAC1G;AACA,MAAI,oBAAoB,KAAK,KAAK,CAAC,cAAc,KAAK,GAAG;AACvD,UAAM,SAAS,sBAAsB,KAAK;AAC1C,QAAI,aAAa,KAAK,aAAa,OAAO,OAAQ,QAAO;AACzD,UAAM,IAAI,MAAM,2EAA2E,OAAO,MAAM,IAAI;AAAA,EAC9G;AACA,QAAM,EAAE,UAAU,MAAM,IAAI,kBAAkB,KAAK;AACnD,QAAM,MAAM,OAAO,aAAa,WAC5B,WACA,SAAS,aAAa,UAAU,CAAC,MAAM,EAAE,WAAW,QAAQ;AAChE,MAAI,MAAM,KAAK,OAAO,MAAM,OAAQ,OAAM,IAAI,MAAM,mDAAmD,OAAO,aAAa,WAAW,YAAY,QAAQ,KAAK,IAAI,QAAQ,GAAG,GAAG;AACjL,SAAO,MAAM,GAAG;AAClB;AAjQA,IA0Ba,0BAEA,iCAEA;AA9Bb;AAAA;AAAA;AAuBA;AAGO,IAAM,2BAA2B,IAAI,WAAW,CAAC,IAAM,IAAM,IAAM,EAAI,CAAC;AAExE,IAAM,kCAAkC;AAExC,IAAM,6BAA6B;AAAA;AAAA;;;AC9B1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EACE;AAAA,EACA;AAAA,EACA,yBAAAA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,aAAAC,YAAW,gBAAAC,qBAAoB;AAsCxC,SAAS,UAAU,GAAsB;AACvC,MAAI,MAAM,QAAQ,MAAM,OAAW,QAAO,CAAC;AAC3C,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,OAAO,CAAC,MAAM,OAAO,MAAM,YAAY,OAAO,MAAM,QAAQ,EAAE,IAAI,MAAM;AACvG,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO,CAAC,OAAO,CAAC,CAAC;AACrE,SAAO,CAAC;AACV;AAUA,eAAsB,sBACpB,WACA,MACgC;AAChC,QAAM,OAAO,KAAK,kBAAkB,CAAC;AACrC,QAAM,WAAW,KAAK,YAAY;AAIlC,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,GAAG,UAAU,UAAa,IAAI,GAAG,UAAU,MAAM;AACvD,YAAM,IAAI;AAAA,QACR,qCAAqC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,UAAU;AAAA,MAE7F;AAAA,IACF;AAAA,EACF;AAEA,QAAM,kBAAkB,oBAAI,IAAsC;AAClE,QAAM,gBAAwD,oBAAI,IAAI;AAEtE,QAAM,YAAY,oBAAI,IAAsC;AAE5D,QAAM,YAAY,CAAC,GAAW,GAAW,OAAe;AACtD,QAAI,IAAI,UAAU,IAAI,CAAC;AACvB,QAAI,CAAC,GAAG;AAAE,UAAI,oBAAI,IAAI;AAAG,gBAAU,IAAI,GAAG,CAAC;AAAA,IAAE;AAC7C,QAAI,IAAI,EAAE,IAAI,CAAC;AACf,QAAI,CAAC,GAAG;AAAE,UAAI,oBAAI,IAAI;AAAG,QAAE,IAAI,GAAG,CAAC;AAAA,IAAE;AACrC,MAAE,IAAI,EAAE;AAAA,EACV;AAEA,QAAM,eAAe,CAAC,GAAW,OAAiC;AAChE,QAAI,OAAO,gBAAgB,IAAI,CAAC;AAChC,QAAI,CAAC,MAAM;AAAE,aAAO,oBAAI,IAAI;AAAG,sBAAgB,IAAI,GAAG,IAAI;AAAA,IAAE;AAC5D,eAAW,CAAC,GAAG,GAAG,KAAK,IAAI;AACzB,UAAI,IAAI,KAAK,IAAI,CAAC;AAClB,UAAI,CAAC,GAAG;AAAE,YAAI,oBAAI,IAAI;AAAG,aAAK,IAAI,GAAG,CAAC;AAAA,MAAE;AACxC,iBAAW,MAAM,IAAK,GAAE,IAAI,EAAE;AAAA,IAChC;AAAA,EACF;AAGA,gBAAc,IAAI,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK;AAClD,QAAM,QAAkB,CAAC,KAAK,KAAK,KAAK;AACxC,QAAM,kBAAkB,oBAAI,IAAY;AAExC,MAAI,QAAQ;AACZ,SAAO,MAAM,SAAS,GAAG;AACvB,QAAI,UAAU,SAAU;AACxB,UAAM,QAAQ,MAAM,OAAO,GAAG,MAAM,MAAM;AAC1C,eAAW,aAAa,OAAO;AAC7B,YAAM,QAAQ,cAAc,IAAI,SAAS;AACzC,YAAM,IAAI,MAAM,UAAU,SAAS;AACnC,YAAM,EAAE,QAAQ,IAAI,MAAM,YAAY,GAAG;AAAA,QACvC;AAAA,QACA,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MACnE,CAAC;AACD,mBAAa,WAAW,OAAO;AAE/B,iBAAW,OAAO,MAAM;AACtB,cAAM,MAAM,QAAQ,IAAI,IAAI,KAAK,UAAU;AAC3C,YAAI,CAAC,IAAK;AACV,cAAM,OAAO,EAAE,WAAoC,IAAI,KAAK,UAAU;AACtE,mBAAW,MAAM,KAAK;AACpB,gBAAM,MAAM,MAAM,KAAK,IAAI,EAAE;AAC7B,qBAAW,MAAM,UAAU,MAAM,IAAI,KAAK,KAAK,CAAC,GAAG;AACjD,sBAAU,IAAI,GAAG,OAAO,IAAI,GAAG,YAAY,EAAE;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,eAAW,CAAC,QAAQ,KAAK,KAAK,WAAW;AACvC,iBAAW,CAAC,OAAO,GAAG,KAAK,OAAO;AAChC,cAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,EAAE,GAAG,UAAU,UAAU,EAAE,GAAG,eAAe,KAAK,GAAG,GAAG,SAAS;AAChG,cAAM,OAAO,gBAAgB,IAAI,MAAM,GAAG,IAAI,KAAK,KAAK,oBAAI,IAAY;AACxE,cAAM,MAAM,GAAG,MAAM,KAAK,KAAK,KAAK,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAC7D,YAAI,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,KAAK,gBAAgB,IAAI,GAAG,EAAG;AAGtE,wBAAgB,IAAI,GAAG;AACvB,cAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,cAAM,OAAO,EAAE,CAAC,KAAK,GAAG,CAAC,QAAiC,OAAO,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE;AACzF,cAAM,WAAW,cAAc,IAAI,MAAM;AAGzC,sBAAc,IAAI,QAAQ,WAAW,EAAE,GAAG,UAAU,GAAG,KAAK,IAAI,IAAI;AACpE,cAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAA8C,CAAC;AACrD,aAAW,CAAC,QAAQ,KAAK,KAAK,WAAW;AACvC,eAAW,CAAC,OAAO,GAAG,KAAK,OAAO;AAChC,YAAM,OAAO,gBAAgB,IAAI,MAAM,GAAG,IAAI,KAAK,KAAK,oBAAI,IAAY;AACxE,iBAAW,MAAM,KAAK;AACpB,YAAI,CAAC,KAAK,IAAI,EAAE,EAAG,UAAS,KAAK,EAAE,OAAO,QAAQ,YAAY,OAAO,GAAG,CAAC;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,eAAe,iBAAiB,SAAS;AACpD;AA6CA,eAAsB,2BACpB,WACA,MACkC;AAClC,QAAM,OAAO,MAAM,sBAAsB,WAAW,IAAI;AACxD,MAAI,KAAK,SAAS,SAAS,EAAG,OAAM,IAAI,2BAA2B,KAAK,QAAQ;AAEhF,QAAM,QAAsB,CAAC;AAC7B,QAAM,eAAsC,CAAC;AAC7C,QAAM,eAA2C,CAAC;AAClD,QAAM,UAAkC,CAAC;AAEzC,aAAW,CAAC,WAAW,KAAK,KAAK,KAAK,eAAe;AACnD,UAAM,IAAI,MAAM,UAAU,SAAS;AACnC,UAAM,EAAE,aAAa,aAAa,OAAO,IAAI,MAAM,iBAAiB,GAAG;AAAA,MACrE;AAAA,MACA,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MACjE,cAAc,KAAK,gBAAgB;AAAA,MACnC,aAAa,KAAK,eAAe;AAAA,MACjC,GAAI,KAAK,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,IAC5E,CAAC;AAED,UAAM,SAASF,uBAAsB,WAAW;AAChD,UAAM,OAAO,KAAK,kBAAkB,SAAS;AAE7C,UAAM,QAAgF;AAAA,MACpF,QAAQ,OAAO;AAAA,MACf,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC,YAAY,YAAY;AAAA,MACxB,aAAa,MAAMC,WAAU,WAAW;AAAA,IAC1C;AAEA,QAAI,MAAM,YAAY,OAAW,OAAM,UAAU,KAAK;AACtD,QAAI,MAAM,UAAU,SAAS,UAAa,KAAK,SAAS,SAAS,OAAO;AACtE,YAAM,OAAO,KAAK,SAAS,SAAS,OAAO,EAAE,OAAO,KAAK,SAAS;AAAA,IACpE;AACA,QAAI,MAAM,UAAU,gBAAgB,MAAM;AACxC,YAAM,KAAK,KAAK,gBAAgB,IAAI,SAAS;AAI7C,UAAI,GAAI,OAAM,cAAc,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,OAAO,IAAI,KAAK,EAAE;AAAA,IACtF;AAGA,UAAM,QAAQ,MAAM,EAAE,iBAAiB;AACvC,UAAM,gBAAgB,MAAM;AAE5B,UAAM,KAAK,WAAW;AACtB,iBAAa,KAAK,KAAK;AACvB,iBAAa,SAAS,IAAI;AAC1B,YAAQ,SAAS,IAAI;AAAA,EACvB;AAEA,QAAM,WAAgC;AAAA,IACpC,oBAAoB;AAAA,IACpB,QAAQC,cAAa;AAAA,IACrB;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,kBAAkB,UAAU,KAAK,GAAG,cAAc,QAAQ;AAC7E;AAgBA,eAAsB,6BACpB,WACA,MAC4B;AAC5B,QAAM,OAAO,MAAM,sBAAsB,WAAW,IAAI;AACxD,QAAM,eAAqE,CAAC;AAC5E,aAAW,CAAC,WAAW,KAAK,KAAK,KAAK,eAAe;AACnD,UAAM,IAAI,MAAM,UAAU,SAAS;AACnC,UAAM,UAAU,MAAM,mBAAmB,GAAG;AAAA,MAC1C;AAAA,MACA,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,IACnE,CAAC;AACD,iBAAa,KAAK,EAAE,OAAO,WAAW,QAAQ,CAAC;AAAA,EACjD;AACA,SAAO,EAAE,cAAc,UAAU,KAAK,SAAS;AACjD;AAlTA,IA8Ka;AA9Kb;AAAA;AAAA;AAcA;AAgKO,IAAM,6BAAN,cAAyC,MAAM;AAAA,MACpD,YAAqB,UAA+D;AAClF;AAAA,UACE,2BAA2B,SAAS,MAAM,2DACxC,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,UAAU,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,IAAI;AAAA,QACnF;AAJmB;AAKnB,aAAK,OAAO;AAAA,MACd;AAAA,MANqB;AAAA,IAOvB;AAAA;AAAA;;;AChJO,SAAS,sBACd,MACA,IACsB;AACtB,UAAQ,KAAK,WAAW;AAAA,IACtB,KAAK,iBAAiB;AACpB,YAAM,MAAM,GAAG;AACf,YAAM,MAAM,GAAG;AACf,UAAI,QAAQ,OAAW,QAAO;AAC9B,UAAI,QAAQ,OAAW,QAAO;AAC9B,aAAO,MAAM,MAAM,aAAa;AAAA,IAClC;AAAA,IACA,KAAK;AACH,aAAO,GAAG,mBAAmB,KAAK,cAAc,aAAa;AAAA,IAC/D,KAAK;AACH,aAAO,GAAG,mBAAmB,KAAK,SAAS,aAAa;AAAA,EAC5D;AACF;AAQO,SAAS,8BACd,QACA,QACA,UACA,eACA,IACsF;AACtF,QAAM,SAAkC,EAAE,GAAG,OAAO;AACpD,QAAM,YAAkD,CAAC;AACzD,aAAW,KAAK,eAAe;AAC7B,UAAM,OAAO,OAAO,CAAC;AACrB,QAAI,SAAS,QAAW;AAAE,gBAAU,CAAC,IAAI;AAAS;AAAA,IAAS;AAC3D,UAAM,MAAM,sBAAsB,MAAM,EAAE;AAC1C,cAAU,CAAC,IAAI;AACf,QAAI,QAAQ,WAAY,QAAO,CAAC,IAAI,SAAS,CAAC;AAAA,EAChD;AACA,SAAO,EAAE,QAAQ,UAAU;AAC7B;AAhFA,IA2Ba;AA3Bb;AAAA;AAAA;AA2BO,IAAM,mCAAN,cAA+C,MAAM;AAAA,MAC1D,YAAY,YAAoB;AAC9B;AAAA,UACE,yDAAyD,UAAU;AAAA,QAErE;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACrBA,SAAS,iBAAiB;AAC1B,SAAS,iCAAuD;AA8FhE,SAAS,YACP,MACA,YACe;AACf,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,SAAO,KAAK,UAAU,KAAK,KAAK,WAAW;AAC7C;AAwBA,eAAsB,sBACpB,UACA,WACA,MACsB;AACtB,QAAM,SAAS,KAAK,UAAU;AAK9B,QAAM,aAAa,oBAAI,IAAiC;AACxD,QAAM,iBAAiB,oBAAI,IAAiC;AAC5D,QAAM,mBAAmB,oBAAI,IAAiC;AAC9D,QAAM,YAAuD,CAAC;AAC9D,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,UAAM,QAAQ,oBAAI,IAAoB;AACtC,UAAM,SAAS,oBAAI,IAAoB;AACvC,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,KAAK,MAAM;AACpB,YAAM,IAAI,EAAE,IAAI,EAAE,EAAE;AACpB,UAAI,EAAE,WAAW,OAAW,QAAO,IAAI,EAAE,IAAI,EAAE,MAAM;AACrD,UAAI,EAAE,aAAa,OAAW,QAAO,IAAI,EAAE,IAAI,EAAE,QAAQ;AAAA,IAC3D;AACA,cAAU,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAC1C,eAAW,IAAI,MAAM,KAAK;AAC1B,mBAAe,IAAI,MAAM,MAAM;AAC/B,qBAAiB,IAAI,MAAM,MAAM;AAAA,EACnC;AAGA,QAAM,OAAO,MAAM,UAAU,UAAU,SAAS;AAGhD,QAAM,eAAgD,CAAC;AACvD,QAAM,YAA6B,CAAC;AACpC,QAAM,SAAoH,CAAC;AAE3H,WAAS,KACP,MACA,KACM;AACN,UAAM,IAAI,aAAa,IAAI,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,EAAE;AACjF,MAAE,GAAG;AACL,iBAAa,IAAI,IAAI;AAAA,EACvB;AAGA,aAAW,KAAK,KAAK,OAAO;AAC1B,UAAM,MAAM,eAAe,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACtD,UAAM,MAAM,iBAAiB,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACxD,WAAO,KAAK;AAAA,MACV,YAAY,EAAE;AAAA,MAAY,IAAI,EAAE;AAAA,MAAI,QAAQ,EAAE;AAAA,MAC9C,GAAI,QAAQ,SAAY,EAAE,QAAQ,IAAI,IAAI,CAAC;AAAA,MAC3C,GAAI,QAAQ,SAAY,EAAE,UAAU,IAAI,IAAI,CAAC;AAAA,IAC/C,CAAC;AACD,SAAK,EAAE,YAAY,UAAU;AAAA,EAC/B;AAIA,QAAM,EAAE,SAAS,MAAM,aAAa,IAAI,SAAS,iBAAiB;AAElE,aAAW,KAAK,KAAK,UAAU;AAC7B,UAAM,QAAQ,YAAY,KAAK,UAAU,EAAE,UAAU;AAErD,QAAI,UAAU,qBAAqB,UAAU,eAAe;AAC1D,YAAM,SAAS,KAAK,iBAAiB,EAAE,UAAU;AACjD,UAAI,WAAW,OAAW,OAAM,IAAI,iCAAiC,EAAE,UAAU;AACjF,YAAM,UAAU,MAAM,QAAQ,IAAI,cAAc,EAAE,YAAY,EAAE,EAAE;AAClE,YAAM,SAAS,eAAe,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACzD,YAAM,SAAS,iBAAiB,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AAC3D,YAAM,SAAS,SAAS;AACxB,YAAM,SAAS,SAAS;AACxB,YAAM,KAAK;AAAA,QACT,GAAI,WAAW,SAAY,EAAE,gBAAgB,OAAO,IAAI,CAAC;AAAA,QACzD,GAAI,WAAW,SAAY,EAAE,kBAAkB,OAAO,IAAI,CAAC;AAAA,QAC3D,GAAI,WAAW,SAAY,EAAE,aAAa,OAAO,IAAI,CAAC;AAAA,QACtD,GAAI,WAAW,SAAY,EAAE,eAAe,OAAO,IAAI,CAAC;AAAA,MAC1D;AACA,YAAM,EAAE,OAAO,IAAI;AAAA,QACjB;AAAA,QACA,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,MACF;AAGA,aAAO,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,QAAQ,QAAQ,QAAQ,SAAS,CAAC;AACpF,WAAK,EAAE,YAAY,SAAS;AAC5B,gBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,eAAe,CAAC;AAClG;AAAA,IACF;AAEA,QAAI,UAAU,iBAAiB;AAC7B,YAAM,MAAM,eAAe,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACtD,YAAM,MAAM,iBAAiB,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACxD,aAAO,KAAK;AAAA,QACV,YAAY,EAAE;AAAA,QAAY,IAAI,EAAE;AAAA,QAAI,QAAQ,EAAE;AAAA,QAC9C,GAAI,QAAQ,SAAY,EAAE,QAAQ,IAAI,IAAI,CAAC;AAAA,QAC3C,GAAI,QAAQ,SAAY,EAAE,UAAU,IAAI,IAAI,CAAC;AAAA,MAC/C,CAAC;AACD,WAAK,EAAE,YAAY,SAAS;AAC5B,gBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,WAAW,CAAC;AAAA,IAChG,WAAW,UAAU,cAAc;AACjC,WAAK,EAAE,YAAY,SAAS;AAC5B,gBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,QAAQ,CAAC;AAAA,IAC7F,WAAW,UAAU,gBAAgB;AACnC,WAAK,EAAE,YAAY,QAAQ;AAC3B,gBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,SAAS,CAAC;AAAA,IAC9F,OAAO;AAEL,YAAM,QAAQ,WAAW,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE,KAAK;AACzD,YAAM,UAAU,MAAM,QAAQ,IAAI,cAAc,EAAE,YAAY,EAAE,EAAE;AAClE,YAAM,UAAU,SAAS,OAAO;AAChC,UAAI,QAAQ,SAAS;AACnB,cAAM,MAAM,eAAe,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACtD,cAAM,MAAM,iBAAiB,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE;AACxD,eAAO,KAAK;AAAA,UACV,YAAY,EAAE;AAAA,UAAY,IAAI,EAAE;AAAA,UAAI,QAAQ,EAAE;AAAA,UAC9C,GAAI,QAAQ,SAAY,EAAE,QAAQ,IAAI,IAAI,CAAC;AAAA,UAC3C,GAAI,QAAQ,SAAY,EAAE,UAAU,IAAI,IAAI,CAAC;AAAA,QAC/C,CAAC;AACD,aAAK,EAAE,YAAY,SAAS;AAC5B,kBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,WAAW,CAAC;AAAA,MAChG,OAAO;AACL,aAAK,EAAE,YAAY,SAAS;AAC5B,kBAAU,KAAK,EAAE,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,UAAU,OAAO,YAAY,QAAQ,CAAC;AAAA,MAC7F;AAAA,IACF;AAAA,EACF;AAMA,MAAI,CAAC,KAAK,QAAQ;AAChB,eAAW,KAAK,QAAQ;AACtB,YAAM,SAAS,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ;AAAA,QAC1D;AAAA,QACA,GAAI,EAAE,WAAW,SAAY,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,QACrD,GAAI,EAAE,aAAa,SAAY,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7D,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,EAAE;AAC3E,aAAW,KAAK,OAAO,OAAO,YAAY,GAAG;AAC3C,YAAQ,YAAY,EAAE;AACtB,YAAQ,WAAW,EAAE;AACrB,YAAQ,WAAW,EAAE;AACrB,YAAQ,UAAU,EAAE;AAAA,EACtB;AACA,UAAQ,QAAQ,QAAQ,WAAW,QAAQ,UAAU,QAAQ,UAAU,QAAQ;AAE/E,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ,KAAK,UAAU;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AASA,eAAsB,iBACpB,UACA,kBACA,MACsB;AACtB,QAAM,WAAW,MAAM,0BAA0B,kBAAkB,KAAK,WAAW;AACnF,SAAO,sBAAsB,UAAU,UAAU,IAAI;AACvD;AA9TA,IAgGa;AAhGb;AAAA;AAAA;AAgBA;AAgFO,IAAM,0BAAN,cAAsC,MAAM;AAAA,MACjD,YAAY,YAAoB;AAC9B;AAAA,UACE,qDAAqD,UAAU;AAAA,QAGjE;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACjEA,eAAsB,iBACpB,UACA,UACA,wBAC4C;AAC5C,QAAM,SAA4C,CAAC;AACnD,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,aAAa,uBAAuB,IAAI,KAAK,CAAC;AACpD,UAAM,MAAyB,CAAC;AAChC,eAAW,KAAK,MAAM;AACpB,UAAI,OAAO,EAAE;AACb,iBAAW,KAAK,WAAY,QAAO,EAAE,IAAI;AAGzC,UAAI,KAAK,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,MAAM,IAAI,EAAE,GAAG,EAAE,CAAC;AAAA,IAClD;AACA,WAAO,IAAI,IAAI;AAEf,UAAM,KAAK,SAAS,WAAW,IAAI;AACnC,eAAW,KAAK,KAAK;AACnB,UAAI;AACF,cAAM,GAAG,cAAc,EAAE,MAAM;AAAA,MACjC,SAAS,OAAO;AACd,cAAM,IAAI,gCAAgC,MAAM,KAAK;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AApEA,IAqBa;AArBb;AAAA;AAAA;AAqBO,IAAM,kCAAN,cAA8C,MAAM;AAAA,MACzD,YACkB,YACA,OAChB;AACA;AAAA,UACE,eAAe,UAAU,yJAEL,UAAU,kBAAkB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACxG;AAPgB;AACA;AAOhB,aAAK,OAAO;AAAA,MACd;AAAA,MATkB;AAAA,MACA;AAAA,IASpB;AAAA;AAAA;;;ACjCA;AAAA;AAAA;AAAA;AAAA;AASA,SAAS,uBAAuB;AAyChC,eAAsB,SACpB,OACA,QACA,MAC2B;AAE3B,QAAM,QAAQ,MAAM,MAAM,UAAU,KAAK,SAAS;AAClD,OAAK,SAAS,UAAU,KAAK;AAK7B,QAAM,WAA8C,CAAC;AACrD,QAAM,aAAgD,CAAC;AACvD,aAAW,eAAe,MAAM,OAAO,gBAAgB,GAAG;AACxD,UAAM,SAAS,KAAK,gBAAgB,WAAW,KAAK;AACpD,UAAM,WAAW,MAAM,MAAM,WAAW,MAAM,EAAE,KAAK;AACrD,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,IAAI;AAAA,QACR,2BAA2B,KAAK,SAAS,iBAAiB,MAAM;AAAA,MAClE;AAAA,IACF;AACA,UAAM,OAA0B,CAAC;AACjC,qBAAiB,OAAO,OAAO,YAAY,WAAW,GAAG;AACvD,UAAI,IAAI,MAAM,MAAM;AAClB,cAAM,IAAI;AAAA,UACR,iCAAiC,WAAW;AAAA,QAC9C;AAAA,MACF;AACA,UAAI,OAAO,IAAI,OAAO,YAAY,OAAO,IAAI,OAAO,UAAU;AAC5D,cAAM,IAAI;AAAA,UACR,iCAAiC,WAAW;AAAA,QAC9C;AAAA,MACF;AACA,YAAM,KAAK,OAAO,IAAI,EAAE;AACxB,WAAK,KAAK,EAAE,IAAI,QAAQ,KAAK,IAAI,WAAW,SAAS,KAAK,SAAS,QAAQ,CAAC;AAAA,IAC9E;AACA,aAAS,MAAM,IAAI;AACnB,QAAI,KAAK,UAAU,MAAM,EAAG,YAAW,MAAM,IAAI,CAAC,KAAK,QAAQ,MAAM,CAAC;AAAA,EACxE;AAGA,QAAM,SAAS,MAAM,iBAAiB,OAAO,UAAU,UAAU;AACjE,QAAM,sBAAsB,OAAO,QAAQ,EAAE,UAAU,iBAAiB,QAAQ,gBAAgB,CAAC;AAGjG,MAAI,aAAa;AACjB,MAAI,KAAK,MAAM;AACb,UAAM,gBAAgB,MAAM,QAAQ,KAAK,WAAW,KAAK,KAAK,SAAS,KAAK,KAAK,eAAe;AAChG,iBAAa;AAAA,EACf;AAGA,MAAI,KAAK,YAAY;AACnB,UAAM,KAAK,WAAW,YAAY;AAAA,MAChC,MAAM;AAAA,MACN,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,QAAQ,0BAA0B,OAAO,MAAM;AAAA,IACjD,CAAC;AAAA,EACH;AAGA,QAAM,cAAqD,CAAC;AAC5D,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,MAAM,EAAG,aAAY,IAAI,IAAI,EAAE,WAAW,KAAK,OAAO;AAEhG,SAAO;AAAA,IACL,WAAW,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA,OAAO,EAAE,MAAM,kBAAkB,QAAQ,OAAO,QAAQ,OAAO,KAAK,UAAU;AAAA,EAChF;AACF;AA1HA,IAyCa,qBAOP;AAhDN;AAAA;AAAA;AAYA;AACA;AA4BO,IAAM,sBAAN,cAAkC,MAAM;AAAA,MAC7C,YAAY,SAAiB;AAC3B,cAAM,OAAO;AACb,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEA,IAAM,YAAY;AAAA;AAAA;;;AChDlB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,gBAAAC,qBAAoB;AAE7B,SAAS,oBAAAC,yBAAwB;AAwDjC,eAAsB,eACpB,KACA,KACA,YACA,KACqB;AACrB,QAAM,MAAkB;AAAA,IACtB,GAAG;AAAA,IACH,IAAI,IAAI,MAAMD,cAAa;AAAA,IAC3B,QAAQ;AAAA,IACR;AAAA,IACA,WAAW;AAAA,EACb;AACA,QAAM,IAAI,cAAc,GAAG;AAC3B,SAAO;AACT;AAaA,eAAsB,aACpB,KACA,WACA,UACA,MACqB;AACrB,QAAM,WAAW,MAAM,IAAI,WAAW,SAAS;AAC/C,MAAI,CAAC,SAAU,OAAM,IAAI,qBAAqB,SAAS;AACvD,MAAI,SAAS,WAAW,YAAY;AAClC,UAAM,IAAI,kBAAkB,WAAW,SAAS,QAAQ,UAAU;AAAA,EACpE;AACA,SAAO,IAAI,cAAc,WAAW,EAAE,QAAQ,UAAU,SAAS,CAAC;AACpE;AA2BA,eAAsB,cACpB,QACA,SAC+D;AAC/D,MAAI,QAAQ,WAAW,UAAU;AAC/B,UAAM,IAAI,kBAAkB,QAAQ,IAAI,QAAQ,QAAQ,QAAQ;AAAA,EAClE;AAKA,QAAM,QAAQ,OAAO,YAAY,QAAQ,YAAY,IAAI,OAAK,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;AAE9E,QAAM,EAAE,aAAa,YAAY,IAAI,MAAMC,kBAAiB,QAAQ;AAAA,IAClE;AAAA,IACA,UAAU;AAAA,IACV,GAAI,QAAQ,SAAS,EAAE,iBAAiB,QAAQ,OAAO,IAAI,CAAC;AAAA,IAC5D,cAAc;AAAA,IACd,aAAa;AAAA,EACf,CAAC;AAED,SAAO,EAAE,aAAa,YAAY;AACpC;AAkBA,eAAsB,aACpB,UACA,SACA,aACA,aACsB;AACtB,MAAI,QAAQ,WAAW,UAAU;AAC/B,UAAM,IAAI,kBAAkB,QAAQ,IAAI,QAAQ,QAAQ,QAAQ;AAAA,EAClE;AAEA,SAAO,iBAAiB,UAAU,aAAa;AAAA,IAC7C;AAAA,IACA,UAAU,QAAQ,eAAe;AAAA,IACjC,GAAI,QAAQ,eAAe,iBACvB,EAAE,gBAAgB,QAAQ,eAAe,eAAe,IACxD,CAAC;AAAA,IACL,QAAQ,gBAAgB,QAAQ,EAAE;AAAA,EACpC,CAAC;AACH;AAgBO,SAAS,aAAa,SAAqB,KAAsB;AACtE,MAAI,QAAQ,cAAc,OAAW,QAAO;AAC5C,MAAI,QAAQ,WAAW,SAAU,QAAO;AACxC,MAAI,QAAQ,eAAe,OAAW,QAAO;AAC7C,SAAO,QAAQ,QAAQ,iBAAiB;AAC1C;AAMO,SAAS,gBAAgB,UAAiC,KAA2B;AAC1F,SAAO,SAAS,OAAO,OAAK,aAAa,GAAG,GAAG,CAAC;AAClD;AAUA,eAAsB,WACpB,KACA,IACA,KACqB;AACrB,QAAM,WAAW,MAAM,IAAI,WAAW,EAAE;AACxC,MAAI,CAAC,SAAU,OAAM,IAAI,MAAM,kCAAkC,EAAE,EAAE;AACrE,QAAM,YAAY,SAAS,aAAa;AACxC,SAAO,IAAI,cAAc,IAAI;AAAA,IAC3B,YAAY;AAAA,IACZ,eAAe,MAAM;AAAA,EACvB,CAAC;AACH;AA/OA,IAmCa,sBAWA,mBA8MA;AA5Pb;AAAA;AAAA;AAQA;AA2BO,IAAM,uBAAN,cAAmC,MAAM;AAAA,MACrC,OAAO;AAAA,MAChB,YAAY,WAAmB;AAC7B,cAAM,sBAAsB,SAAS,EAAE;AAAA,MACzC;AAAA,IACF;AAMO,IAAM,oBAAN,cAAgC,MAAM;AAAA,MAClC,OAAO;AAAA,MAChB,YAAY,WAAmB,eAAuB,gBAAwB;AAC5E;AAAA,UACE,WAAW,SAAS,gBAAgB,aAAa,gBAAgB,cAAc;AAAA,QACjF;AAAA,MACF;AAAA,IACF;AAuMO,IAAM,0BAAN,MAA8B;AAAA,MAC1B,UAAU,oBAAI,IAA4C;AAAA,MAC1D;AAAA,MAET,YAAY,QAAsB,KAAK,KAAK;AAC1C,aAAK,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,IAAI,MAAc;AAChB,eAAO,KAAK,OAAO;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,WAAmB,YAAoB,IAAsB;AACjE,aAAK,KAAK,SAAS;AACnB,cAAM,QAAQ,YAAY,IAAI,UAAU;AACxC,aAAK,QAAQ,IAAI,WAAW,KAAK;AAAA,MACnC;AAAA;AAAA,MAGA,KAAK,WAAyB;AAC5B,cAAM,QAAQ,KAAK,QAAQ,IAAI,SAAS;AACxC,YAAI,UAAU,QAAW;AACvB,wBAAc,KAAK;AACnB,eAAK,QAAQ,OAAO,SAAS;AAAA,QAC/B;AAAA,MACF;AAAA;AAAA,MAGA,UAAgB;AACd,mBAAW,CAAC,EAAE,KAAK,KAAK,SAAS;AAC/B,eAAK,KAAK,EAAE;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC3RA,SAAS,aAAAC,kBAAiB;AAgBnB,SAAS,iBAAiB,WAAsD;AACrF,QAAM,WAAiC,CAAC;AAGxC,QAAM,iBAAiB,IAAI;AAAA,IACzB,CAAC;AAAA,IACD;AAAA,MACE,KAAK,MAAM,MAAM;AAAA,IACnB;AAAA,EACF;AACA,QAAM,QAAQ,IAAI;AAAA,IAChB,CAAC;AAAA,IACD;AAAA,MACE,KAAK,CAAC,IAAI,SAAS;AACjB,YAAI,SAAS,cAAc;AACzB,iBAAO,CAAC,MAAc,SAAiE;AACrF,qBAAS,KAAK;AAAA,cACZ;AAAA,cACA,SAAS,MAAM,WAAW,CAAC;AAAA,cAC3B,mBAAmB,CAAC,CAAC,MAAM;AAAA,YAC7B,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,YAAU,KAAK;AAEf,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACxE,QAAM,UAAsC,CAAC;AAC7C,QAAM,oBAA8B,CAAC;AACrC,aAAW,KAAK,QAAQ;AACtB,YAAQ,EAAE,IAAI,IAAI,EAAE;AACpB,QAAI,EAAE,kBAAmB,mBAAkB,KAAK,EAAE,IAAI;AAAA,EACxD;AACA,SAAO;AAAA;AAAA;AAAA,IAGL,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,UAAU,OAAwB;AACzC,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC5E,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,GAAG,CAAC;AACnE,QAAM,MAAM;AACZ,QAAM,OAAO,OAAO,KAAK,GAAG,EAAE,KAAK;AACnC,SAAO,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AACnF;AAGA,eAAsB,qBAAqB,IAAwC;AACjF,SAAOA,WAAU,IAAI,YAAY,EAAE,OAAO,UAAU,EAAE,CAAC,CAAC;AAC1D;AApFA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,wBAAwB;AAAjC;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAYA,SAAS,gBAAAC,qBAAoB;AAZ7B,IAmBM,UACA,UACA,QACA,kBACA,UAEO;AAzBb;AAAA;AAAA;AAUA;AACA;AAIA;AAIA,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,mBAAmB;AACzB,IAAM,WAAW;AAEV,IAAM,uBAAN,MAAM,sBAAqB;AAAA,MAaxB,YACG,UACA,gBACT,QACA,iBACA,UACA;AALS;AACA;AAKT,aAAK,UAAU;AACf,aAAK,mBAAmB;AACxB,aAAK,YAAY;AAAA,MACnB;AAAA,MATW;AAAA,MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MARF;AAAA;AAAA,MAEA;AAAA;AAAA,MAEA;AAAA;AAAA,MAeT,aAAa,KAAK,IAA0C;AAC1D,cAAM,QAAQ,MAAM,GAAG,UAAU,gBAAgB;AACjD,eAAO,IAAI;AAAA,UACT,MAAM,WAA6B,QAAQ;AAAA,UAC3C,MAAM,WAA8B,QAAQ;AAAA,UAC5C,MAAM,WAA4B,MAAM;AAAA,UACxC,MAAM,WAA+B,gBAAgB;AAAA,UACrD,MAAM,WAAuB,QAAQ;AAAA,QACvC;AAAA,MACF;AAAA;AAAA,MAGA,MAAM,mBAAmB,SAAqD;AAC5E,eAAO,KAAK,iBAAiB,IAAI,OAAO;AAAA,MAC1C;AAAA;AAAA,MAGA,MAAM,sBAAqD;AACzD,cAAM,KAAK,iBAAiB,KAAK;AACjC,eAAO,KAAK,iBAAiB,MAAM,EAAE,QAAQ;AAAA,MAC/C;AAAA;AAAA,MAGA,MAAM,sBAAsB,KAAwC;AAClE,cAAM,KAAK,iBAAiB,IAAI,IAAI,SAAS,GAAG;AAAA,MAClD;AAAA;AAAA;AAAA,MAKA,MAAM,cAAc,KAAgC;AAClD,cAAM,KAAK,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,MACtC;AAAA;AAAA,MAGA,MAAM,WAAW,IAAwC;AACvD,eAAO,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9B;AAAA;AAAA,MAGA,MAAM,eAAsC;AAC1C,cAAM,KAAK,UAAU,KAAK;AAC1B,eAAO,KAAK,UAAU,MAAM,EAAE,QAAQ;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,cAAc,IAAY,OAAiD;AAC/E,cAAM,WAAW,MAAM,KAAK,UAAU,IAAI,EAAE;AAC5C,YAAI,CAAC,SAAU,OAAM,IAAI,MAAM,sBAAsB,EAAE,EAAE;AACzD,cAAM,UAAsB,EAAE,GAAG,UAAU,GAAG,MAAM;AACpD,cAAM,KAAK,UAAU,IAAI,IAAI,OAAO;AACpC,eAAO;AAAA,MACT;AAAA;AAAA,MAGA,cAAsC;AACpC,eAAO,KAAK,QAAQ,MAAM;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,YAAY,OAA4E;AAC5F,cAAM,KAAK,MAAM,MAAM,KAAK,IAAI;AAChC,cAAM,KAAKA,cAAa;AACxB,cAAM,KAAK,QAAQ,IAAI,IAAI,EAAE,GAAG,OAAO,IAAI,GAAG,CAAC;AAAA,MACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,eAAe,cAAsB,UAA0C;AACnF,cAAM,KAAK,iBAAiB,SAAS,SAAS;AAC9C,cAAM,cAAc,MAAM,qBAAqB,EAAE;AACjD,cAAM,KAAK,eAAe,IAAI,GAAG,YAAY,IAAI,SAAS,OAAO,IAAI;AAAA,UACnE;AAAA,UACA,SAAS,SAAS;AAAA,UAClB,aAAa,GAAG;AAAA,UAChB,SAAS,GAAG;AAAA,UACZ,mBAAmB,GAAG;AAAA,UACtB;AAAA,UACA,YAAY,KAAK,IAAI;AAAA,QACvB,CAAC;AACD,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,YAAY,cAAsB,UAA2C;AACjF,cAAM,MAAM,MAAM,KAAK,eAAe,IAAI,GAAG,YAAY,IAAI,SAAS,OAAO,EAAE;AAC/E,YAAI,CAAC,IAAK,QAAO;AACjB,cAAM,UAAU,MAAM,qBAAqB,iBAAiB,SAAS,SAAS,CAAC;AAC/E,eAAO,YAAY,IAAI;AAAA,MACzB;AAAA,IACF;AAAA;AAAA;;;AChKA,SAAS,qBAAqB;AAUvB,SAAS,kBAAkB,KAA6D;AAC7F,SAAO,eAAe,gBAAgB,aAAa;AACrD;AAZA;AAAA;AAAA;AAAA;AAAA;;;ACWA,SAAS,gBAAgB;AA0DzB,SAAS,UAAU,OAA+B;AAChD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAC/E,SAAO;AACT;AAIA,SAAS,sBAAsB,OAAe,IAAY,KAAmB;AAC3E,QAAM,QAAQ,GAAG,KAAK,SAAI,EAAE,IAAI,GAAG;AACnC,MAAI,oBAAoB,IAAI,KAAK,EAAG;AACpC,sBAAoB,IAAI,KAAK;AAC7B,UAAQ;AAAA,IACN,gCAAgC,EAAE,uBAAuB,KAAK,KAAK,GAAG;AAAA,EAExE;AACF;AAYA,eAAsB,mBACpB,MACA,MACoB;AACpB,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC,GAAG,IAAI;AAGtC,QAAM,UAA8D,CAAC;AACrE,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,oBAAI,IAAqB;AACrC,eAAW,OAAO,MAAM,IAAI,KAAK,KAAK,GAAG;AACvC,YAAM,IAAI,UAAU,SAAS,KAAK,IAAI,EAAE,CAAC;AACzC,UAAI,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC,EAAG,KAAI,IAAI,GAAG,GAAG;AAAA,IAC/C;AACA,YAAQ,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,EAC3B;AAEA,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,MAAM,EAAE,GAAI,IAAgC;AAClD,eAAW,EAAE,KAAK,IAAI,KAAK,SAAS;AAClC,YAAM,MAAM,UAAU,SAAS,KAAK,IAAI,KAAK,CAAC;AAC9C,YAAM,QAAQ,QAAQ,OAAO,OAAO,IAAI,IAAI,GAAG,KAAK;AACpD,UAAI,UAAU,QAAQ,IAAI,SAAS,QAAQ;AACzC,8BAAsB,IAAI,OAAO,IAAI,IAAI,OAAO,QAAQ;AAAA,MAC1D;AACA,UAAI,IAAI,EAAE,IAAI;AAAA,IAChB;AACA,WAAO;AAAA,EACT,CAAC;AACH;AA/HA,IA6EM;AA7EN;AAAA;AAAA;AA6EA,IAAM,sBAAsB,oBAAI,IAAY;AAAA;AAAA;;;AC7E5C,IAiBa;AAjBb;AAAA;AAAA;AAiBO,IAAM,iBAAN,MAAwB;AAAA,MAC7B;AAAA,MACA,QAAsB;AAAA,MACb;AAAA,MAEQ,OAAO,oBAAI,IAAgB;AAAA,MAC3B;AAAA,MACA;AAAA,MACT,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAA8C;AAAA,MAC9C;AAAA,MACA,cAAc;AAAA,MAEtB,YAAY,MAAgC;AAC1C,aAAK,OAAO;AACZ,aAAK,WAAW,KAAK;AACrB,aAAK,QAAQ,IAAI,QAAc,CAAC,QAAQ;AAAE,eAAK,eAAe;AAAA,QAAI,CAAC;AACnE,aAAK,cAAc,KAAK,mBAAmB,CAAC,MAAM;AAChD,cAAI,KAAK,WAAW,CAAC,KAAK,WAAW,CAAC,EAAG;AACzC,eAAK,SAAS;AAAA,QAChB,CAAC;AACD,aAAK,SAAS;AAAA,MAChB;AAAA,MAEA,UAAU,IAA4B;AACpC,YAAI,KAAK,QAAS,QAAO,MAAM;AAAA,QAAC;AAChC,aAAK,KAAK,IAAI,EAAE;AAChB,eAAO,MAAM,KAAK,KAAK,OAAO,EAAE;AAAA,MAClC;AAAA,MAEA,OAAa;AACX,YAAI,KAAK,QAAS;AAClB,aAAK,UAAU;AACf,aAAK,YAAY;AACjB,YAAI,KAAK,UAAU,KAAM,cAAa,KAAK,KAAK;AAChD,aAAK,KAAK,MAAM;AAChB,YAAI,CAAC,KAAK,YAAa,MAAK,aAAa;AAAA,MAC3C;AAAA,MAEQ,WAAiB;AACvB,YAAI,KAAK,QAAS;AAClB,YAAI,KAAK,WAAW;AAAE,eAAK,QAAQ;AAAM;AAAA,QAAO;AAChD,YAAI,KAAK,UAAW;AACpB,aAAK,YAAY;AACjB,cAAM,MAAM,MAAM;AAAE,eAAK,YAAY;AAAO,eAAK,KAAK,WAAW;AAAA,QAAE;AACnE,cAAM,KAAK,KAAK,KAAK,cAAc;AACnC,YAAI,KAAK,EAAG,MAAK,QAAQ,WAAW,KAAK,EAAE;AAAA,YAEtC,gBAAe,GAAG;AAAA,MACzB;AAAA,MAEA,MAAc,aAA4B;AACxC,YAAI,KAAK,QAAS;AAClB,aAAK,YAAY;AACjB,aAAK,QAAQ;AACb,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,KAAK,QAAQ;AACrC,cAAI,KAAK,QAAS;AAClB,eAAK,WAAW;AAChB,eAAK,QAAQ;AAAA,QACf,SAAS,KAAK;AACZ,cAAI,KAAK,QAAS;AAClB,eAAK,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,QACjE,UAAE;AACA,eAAK,YAAY;AACjB,cAAI,CAAC,KAAK,SAAS;AACjB,gBAAI,CAAC,KAAK,aAAa;AAAE,mBAAK,cAAc;AAAM,mBAAK,aAAa;AAAA,YAAE;AACtE,uBAAW,MAAM,KAAK,KAAM,IAAG;AAC/B,gBAAI,KAAK,MAAO,MAAK,SAAS;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC5FA,IAWa;AAXb;AAAA;AAAA;AAWO,IAAM,kBAAN,MAAsB;AAAA,MAM3B,YACmB,WACA,UACA,UAAwD,CAAC,KAAK,OAC7E,QAAQ,KAAK,iDAAiD,EAAE,MAAM,GAAG,GAC3E;AAJiB;AACA;AACA;AAAA,MAEhB;AAAA,MAJgB;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAPF,QAAQ,oBAAI,IAAY;AAAA;AAAA,MAEjC,UAAgC;AAAA;AAAA,MAUxC,UAAU,cAAsB,YAA0B;AACxD,YAAI,CAAC,KAAK,SAAS,UAAU,EAAG;AAChC,aAAK,MAAM,IAAI,YAAY;AAC3B,aAAK,SAAS;AAAA,MAChB;AAAA;AAAA,MAGA,MAAM,cAA6B;AACjC,eAAO,KAAK,QAAS,OAAM,KAAK;AAAA,MAClC;AAAA,MAEQ,WAAiB;AACvB,YAAI,KAAK,QAAS;AAClB,aAAK,UAAU,KAAK,SAAS,EAAE,QAAQ,MAAM;AAC3C,eAAK,UAAU;AAEf,cAAI,KAAK,MAAM,OAAO,EAAG,MAAK,SAAS;AAAA,QACzC,CAAC;AAAA,MACH;AAAA,MAEA,MAAc,WAA0B;AAEtC,cAAM,QAAQ,QAAQ;AACtB,cAAM,MAAM,CAAC,GAAG,KAAK,KAAK;AAC1B,aAAK,MAAM,MAAM;AACjB,mBAAW,MAAM,KAAK;AACpB,cAAI;AACF,kBAAM,KAAK,UAAU,EAAE;AAAA,UACzB,SAAS,KAAK;AACZ,iBAAK,QAAQ,KAAK,EAAE;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC/BO,SAAS,iBAAiB,MAA8B;AAC7D,SAAO,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,MAAM,OAAQ,EAAkB,UAAU,UAAU;AACxF;AAGO,SAAS,gBAAgB,SAA6B,MAAmC;AAC9F,QAAM,MAAoB,CAAC;AAC3B,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,IAAI,GAAG;AACjD,UAAM,IAAI;AACV,QAAI,QAAQ,EAAE,KAAK;AACnB,eAAW,OAAO,QAAS,SAAQ,EAAE,KAAK,OAAO,GAAG;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAOO,SAAS,cAAc,MAAqB,UAAiD;AAClG,QAAM,MAAoB,CAAC;AAC3B,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,IAAI,GAAG;AACjD,UAAM,IAAI;AACV,QAAI,MAAM,EAAE,KAAK;AACjB,eAAW,KAAK,SAAU,OAAM,EAAE,MAAO,KAAK,EAAE,GAAG,CAAC;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAGO,SAAS,gBAA4C,MAAY,QAA6C;AACnH,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,IAAI,GAAG;AACjD,QAAI,GAAG,IAAK,QAAwB,SAAS,OAAO,GAAG,CAAC;AAAA,EAC1D;AACA,SAAO;AACT;AAlEA;AAAA;AAAA;AAAA;AAAA;;;ACOA,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAR/B,IA+Ca,uBAkDA;AAjGb;AAAA;AAAA;AAkBA;AAEA;AA2BO,IAAM,wBAAN,MAA2D;AAAA,MAChE,YACmB,KACA,MACA,MACjB;AAHiB;AACA;AACA;AAAA,MAChB;AAAA,MAHgB;AAAA,MACA;AAAA,MACA;AAAA,MAGnB,MAAM,IAAI,UAA8B,CAAC,GAGtC;AAGD,YAAI,KAAK,IAAI,gBAAgB,iBAAiB,KAAK,IAAI,GAAG;AACxD,gBAAM,EAAE,UAAU,eAAAC,eAAc,IAAI,MAAM,KAAK,IAAI,aAAa,KAAK,MAAM,OAAO;AAClF,iBAAO,EAAE,QAAQ,gBAAgB,KAAK,MAAM,cAAc,KAAK,MAAM,QAAQ,CAAC,GAAG,eAAAA,eAAc;AAAA,QACjG;AACA,cAAM,EAAE,SAAS,cAAc,IAAI,MAAM,KAAK,IAAI,cAAc,OAAO;AACvE,eAAO,EAAE,QAAQ,cAAc,SAAS,KAAK,IAAI,GAAG,cAAc;AAAA,MACpE;AAAA,MAEA,KAAK,UAA4B,CAAC,GAAqD;AACrF,YAAI,CAAC,KAAK,KAAM,OAAM,IAAI,MAAM,0FAAqF;AACrH,cAAM,OAAO,KAAK;AAClB,cAAM,MAAM,KAAK;AACjB,cAAM,OAAO,IAAI,eAAsF;AAAA,UACrG,oBAAoB,KAAK,KAAK;AAAA,UAC9B,YAAY,KAAK,KAAK;AAAA,UACtB,SAAS,YAAY;AACnB,kBAAM,EAAE,SAAS,cAAc,IAAI,MAAM,IAAI,cAAc,OAAO;AAClE,mBAAO,EAAE,OAAO,cAAc,SAAS,IAAI,GAAG,SAAS,cAAc;AAAA,UACvE;AAAA,UACA,iBAAiB,EAAE,OAAO,QAAW,SAAS,CAAC,EAAE;AAAA,UACjD,GAAI,QAAQ,eAAe,SAAY,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,QAC/E,CAAC;AACD,eAAO;AAAA,UACL,IAAI,QAAQ;AAAE,mBAAO,KAAK,SAAS;AAAA,UAAM;AAAA,UACzC,IAAI,gBAAgB;AAAE,mBAAO,KAAK,SAAS;AAAA,UAAmC;AAAA,UAC9E,IAAI,QAAQ;AAAE,mBAAO,KAAK;AAAA,UAAM;AAAA,UAChC,OAAO,KAAK;AAAA,UACZ,WAAW,CAAC,OAAO,KAAK,UAAU,EAAE;AAAA,UACpC,MAAM,MAAM,KAAK,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAMO,IAAM,+BAAN,MAAoF;AAAA,MACzF,YACmB,KACA,OACA,MACA,MACjB;AAJiB;AACA;AACA;AACA;AAAA,MAChB;AAAA,MAJgB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAGnB,MAAM,IAAI,UAA8B,CAAC,GAGtC;AACD,cAAM,EAAE,SAAS,cAAc,IAAI,MAAM,KAAK,IAAI,cAAc,OAAO;AACvE,eAAO;AAAA,UACL,SAAS,eAAoC,SAAS,KAAK,OAAO,KAAK,IAAI;AAAA,UAC3E;AAAA,QACF;AAAA,MACF;AAAA,MAEA,KAAK,UAA4B,CAAC,GAA6C;AAC7E,YAAI,CAAC,KAAK,KAAM,OAAM,IAAI,MAAM,2GAAsG;AACtI,cAAM,QAAQ,KAAK;AACnB,cAAM,OAAO,KAAK;AAClB,cAAM,MAAM,KAAK;AACjB,cAAM,OAAO,IAAI,eAA4E;AAAA,UAC3F,oBAAoB,KAAK,KAAK;AAAA,UAC9B,YAAY,KAAK,KAAK;AAAA,UACtB,SAAS,YAAY;AACnB,kBAAM,EAAE,SAAS,cAAc,IAAI,MAAM,IAAI,cAAc,OAAO;AAClE,mBAAO;AAAA,cACL,SAAS,eAAoC,SAAS,OAAO,IAAI;AAAA,cACjE,SAAS;AAAA,YACX;AAAA,UACF;AAAA,UACA,iBAAiB,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,UAC5C,GAAI,QAAQ,eAAe,SAAY,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,QAC/E,CAAC;AACD,eAAO;AAAA,UACL,IAAI,QAAQ;AAAE,mBAAO,KAAK,SAAS;AAAA,UAA0C;AAAA,UAC7E,IAAI,gBAAgB;AAAE,mBAAO,KAAK,SAAS;AAAA,UAAmC;AAAA,UAC9E,IAAI,QAAQ;AAAE,mBAAO,KAAK;AAAA,UAAM;AAAA,UAChC,OAAO,KAAK;AAAA,UACZ,WAAW,CAAC,OAAO,KAAK,UAAU,EAAE;AAAA,UACpC,MAAM,MAAM,KAAK,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC/IA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,SAAS,qBAAqB,oBAAoB,wBAAwB,wBAAwB,mBAAmB,uBAAuB;AAkC5I,SAAS,uBAAuB,cAA4B;AAC1D,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,IAAI,gBAAgB,yCAAyC;AAAA,EACrE;AACA,MAAI,iBAAiB,kBAAkB;AACrC,UAAM,IAAI,uBAAuB,YAAY;AAAA,EAC/C;AACA,MAAI,CAAC,mBAAmB,KAAK,YAAY,GAAG;AAC1C,UAAM,IAAI;AAAA,MACR,iBAAiB,YAAY;AAAA,IAE/B;AAAA,EACF;AACA,MAAI,aAAa,SAAS,eAAe,GAAG;AAC1C,UAAM,IAAI;AAAA,MACR,iBAAiB,YAAY;AAAA,IAE/B;AAAA,EACF;AACF;AA/DA,IAwCM,iBAEA,oBAuBO,YAqaA,mBA4BA,cAuMA;AAzsBb;AAAA;AAAA;AASA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAoBA,IAAM,kBAAkB;AAExB,IAAM,qBAAqB;AAuBpB,IAAM,aAAN,MAAoB;AAAA,MACzB,YAC4B,IACA,MACA,UACA,UACA,UAC+B,gBAAyB,OAClF;AAN0B;AACA;AACA;AACA;AACA;AAC+B;AAEzD,YAAI,KAAK,SAAS,eAAe,GAAG;AAClC,gBAAM,IAAI;AAAA,YACR,oBAAoB,IAAI;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,MAZ4B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAC+B;AAAA;AAAA,MAUnD;AAAA;AAAA,MAGR,kBAAkB,IAAgC;AAChD,aAAK,aAAa;AAAA,MACpB;AAAA;AAAA,MAGA,aAAa,cAA8B;AACzC,+BAAuB,YAAY;AACnC,eAAO,GAAG,KAAK,IAAI,GAAG,eAAe,GAAG,YAAY;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,WAAW,cAA8B;AACvC,eAAO,KAAK,aAAa,YAAY;AAAA,MACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,MAAM,UAAuC;AAC3C,cAAM,KAAK,SAAS,KAAK;AACzB,cAAM,OAAO,KAAK,SAAS,MAAM,EAAE,QAAQ;AAC3C,eAAO,KAAK,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI;AAAA,MACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,UAAU,cAAsC;AACpD,YAAI,KAAK,eAAe;AACtB,gBAAM,MAAM,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC;AACjE,cAAI,OAAO,IAAI,gBAAgB,KAAK,SAAS,SAAS;AACpD,kBAAM,KAAK,aAAa,YAAY;AAAA,UACtC;AAAA,QACF;AACA,eAAO,KAAK,cAAc,YAAY;AAAA,MACxC;AAAA;AAAA,MAGA,MAAc,cAAc,cAAsC;AAChE,cAAM,QAAQ,MAAM,KAAK,GAAG,UAAU,KAAK,aAAa,YAAY,GAAG,EAAE,QAAQ,MAAM,CAAC;AACxF,aAAK,SAAS,UAAU,KAAK;AAC7B,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAcA,MAAM,YAAY,cAAsB,QAAiC;AACvE,cAAM,UAAU,KAAK,aAAa,YAAY;AAC9C,cAAM,MAAM,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC;AACjE,cAAM,cAAc,MAAM,KAAK,GAAG,uBAAuB,OAAO;AAEhE,YAAI,OAAO,CAAC,YAAa,OAAM,IAAI,uBAAuB,SAAS,YAAY;AAC/E,YAAI,OAAO,YAAa,QAAO,KAAK,UAAU,YAAY;AAI1D,YAAI,WAAW,QAAW;AACxB,gBAAM,gBAAgB,KAAK,GAAG,gBAAgB,OAAO,EAAE,cAAc;AACrE,cAAI,kBAAkB,OAAQ,OAAM,IAAI,mBAAmB,SAAS,QAAQ,aAAa;AAAA,QAC3F;AAGA,cAAM,QAAQ,MAAM,KAAK,GAAG,UAAU,OAAO;AAC7C,aAAK,SAAS,UAAU,KAAK;AAC7B,cAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,GAAG;AAAA,UACrD;AAAA,UACA;AAAA,UACA,cAAc,KAAK,SAAS;AAAA,UAC5B,eAAe,KAAK,SAAS;AAAA,UAC7B,WAAW,KAAK,IAAI;AAAA,UACpB,OAAO,KAAK;AAAA,QACd,CAAC;AACD,YAAI,KAAK,YAAY;AACnB,cAAI;AACF,kBAAM,KAAK,WAAW,YAAY;AAAA,cAChC,MAAM;AAAA,cACN,OAAO,KAAK;AAAA,cACZ;AAAA,cACA,cAAc,KAAK,SAAS;AAAA,cAC5B,SAAS,KAAK,SAAS;AAAA,YACzB,CAAC;AAAA,UACH,QAAQ;AAAA,UAER;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,MAAM,cAAsC;AAChD,cAAM,UAAU,KAAK,aAAa,YAAY;AAC9C,cAAM,MAAM,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC;AACjE,YAAI,CAAC,IAAK,OAAM,IAAI,kBAAkB,cAAc,KAAK,IAAI;AAC7D,cAAM,cAAc,MAAM,KAAK,GAAG,uBAAuB,OAAO;AAChE,YAAI,CAAC,YAAa,OAAM,IAAI,uBAAuB,SAAS,YAAY;AACxE,eAAO,KAAK,UAAU,YAAY;AAAA,MACpC;AAAA;AAAA,MAGA,WAAkB,gBAAiD;AACjE,eAAO,IAAI,kBAAwB,MAAM,cAAc;AAAA,MACzD;AAAA;AAAA,MAGA,MAAM,gBAAgB,UAAiF,CAAC,GAGrG;AACD,cAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,cAAM,aAAa,QAAQ,OAAO,KAAK,OAAO,CAAC,MAAM,QAAQ,KAAM,SAAS,EAAE,YAAY,CAAC,IAAI;AAC/F,cAAM,UAA0B,CAAC;AACjC,cAAM,YAAgC,CAAC;AACvC,mBAAW,OAAO,YAAY;AAC5B,cAAI,QAAQ,eAAe,UAAa,IAAI,gBAAgB,QAAQ,YAAY;AAC9E,oBAAQ,KAAK,EAAE,SAAS,IAAI,SAAS,QAAQ,eAAe,CAAC;AAAA,UAC/D,MAAO,WAAU,KAAK,GAAG;AAAA,QAC3B;AAGA,cAAM,SAAS,MAAM,QAAQ;AAAA,UAC3B,UAAU,IAAI,OAAO,QAAQ;AAC3B,gBAAI;AACF,qBAAO,EAAE,KAAK,aAAa,MAAM,KAAK,GAAG,uBAAuB,IAAI,OAAO,EAAE;AAAA,YAC/E,SAAS,KAAK;AACZ,kBAAI,QAAQ,SAAU,OAAM;AAC5B,qBAAO,EAAE,KAAK,OAAO,IAAa;AAAA,YACpC;AAAA,UACF,CAAC;AAAA,QACH;AACA,cAAM,WAA+B,CAAC;AACtC,mBAAW,KAAK,QAAQ;AACtB,cAAI,WAAW,EAAG,SAAQ,KAAK,EAAE,SAAS,EAAE,IAAI,SAAS,QAAQ,SAAS,OAAO,EAAE,MAAM,CAAC;AAAA,mBACjF,EAAE,YAAa,UAAS,KAAK,EAAE,GAAG;AAAA,cACtC,SAAQ,KAAK,EAAE,SAAS,EAAE,IAAI,SAAS,QAAQ,SAAS,OAAO,IAAI,uBAAuB,EAAE,IAAI,SAAS,EAAE,IAAI,YAAY,EAAE,CAAC;AAAA,QACrI;AACA,eAAO,EAAE,UAAU,QAAQ;AAAA,MAC7B;AAAA;AAAA,MAGiB,wBAAoD,CAAC;AAAA;AAAA,MAG9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA4BR,yBACE,MACM;AACN,cAAM,SAAS,KAAK,OAAO;AAC3B,YAAI,WAAW,KAAK,QAAQ,OAAO,WAAW,GAAG,KAAK,IAAI,GAAG,eAAe,EAAE,GAAG;AAC/E,gBAAM,IAAI;AAAA,YACR,2CAA2C,MAAM,aAAa,KAAK,IAAI;AAAA,UAGzE;AAAA,QACF;AACA,aAAK,sBAAsB,KAAK,IAA2C;AAC3E,YAAI,KAAK,YAAY,CAAC,KAAK,iBAAiB;AAC1C,gBAAM,aAAa,IAAI;AAAA,YACrB,CAAC,OAAO,KAAK,wBAAwB,EAAE;AAAA,YACvC,CAAC,eAAe,KAAK,sBAAsB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,UAAU;AAAA,UAC9F;AACA,eAAK,kBAAkB;AAMvB,gBAAM,SAAS,GAAG,KAAK,IAAI,GAAG,eAAe;AAC7C,eAAK,GAAG,GAAG,UAAU,CAAC,MAAM;AAC1B,gBAAI,CAAC,EAAE,MAAM,WAAW,MAAM,EAAG;AACjC,uBAAW,UAAU,EAAE,MAAM,MAAM,OAAO,MAAM,GAAG,EAAE,UAAU;AAAA,UACjE,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAcA,MAAM,gBAAgB,UAAuG,CAAC,GAAmC;AAC/J,YAAI,KAAK,sBAAsB,WAAW,EAAG,QAAO,EAAE,SAAS,GAAG,eAAe,CAAC,EAAE;AACpF,cAAM,EAAE,UAAU,QAAQ,IAAI,MAAM,KAAK,gBAAgB;AAAA,UACvD,GAAI,QAAQ,eAAe,SAAY,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,UAC7E,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,UAC3D,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,QACzE,CAAC;AACD,YAAI,UAAU;AACd,mBAAW,QAAQ,KAAK,uBAAuB;AAC7C,gBAAM,UAAU,MAAM,KAAK,GAAG;AAAA,YAC5B,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,YAC7B,OAAO,UAAU;AACf,mBAAK,SAAS,UAAU,KAAK;AAC7B,qBAAO,MAAM,WAAoC,KAAK,MAAM,EAAE,KAAK;AAAA,YACrE;AAAA,YACA,EAAE,QAAQ,OAAO,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC,EAAG;AAAA,UACtG;AACA,gBAAM,UAAU,MAAM,KAAK,GAAG,UAAU,KAAK,OAAO,KAAK;AACzD,gBAAM,MAAM,QAAQ,WAAoC,KAAK,OAAO,UAAU;AAC9E,mBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,kBAAM,MAAM,SAAS,CAAC;AACtB,kBAAM,MAAM,QAAQ,CAAC;AACrB,gBAAI,CAAC,OAAO,IAAI,WAAW,QAAW;AACpC,kBAAI,QAAQ,YAAY,KAAK,MAAO,OAAM,IAAI;AAC9C,sBAAQ,KAAK,EAAE,SAAS,IAAI,SAAS,QAAQ,SAAS,GAAI,KAAK,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC,EAAG,CAAC;AACnG;AAAA,YACF;AACA,kBAAM,MAAmC;AAAA,cACvC,SAAS,IAAI;AAAA,cACb,cAAc,IAAI;AAAA,cAClB,eAAe,IAAI;AAAA,YACrB;AACA,kBAAM,UAAU,KAAK,OAAO,IAAI,QAAQ,GAAG;AAC3C,kBAAM,IAAI,IAAI,IAAI,cAAc,OAAO;AACvC;AAAA,UACF;AAAA,QACF;AACA,eAAO,EAAE,SAAS,eAAe,QAAQ;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,kBAAkB,cAAsD;AAC5E,eAAO,KAAK,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;AAAA,MACtD;AAAA;AAAA,MAGA,MAAc,wBAAwB,cAAqC;AACzE,cAAM,MAAM,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC;AACjE,YAAI,CAAC,IAAK;AACV,cAAM,QAAQ,MAAM,KAAK,UAAU,YAAY;AAC/C,cAAM,MAAmC;AAAA,UACvC,SAAS,IAAI;AAAA,UACb;AAAA,UACA,eAAe,IAAI;AAAA,QACrB;AACA,mBAAW,QAAQ,KAAK,uBAAuB;AAC7C,cAAI,CAAC,KAAK,SAAU;AACpB,gBAAM,UAAU,MAAM,MAAM,WAAoC,KAAK,MAAM,EAAE,KAAK;AAClF,gBAAM,UAAU,KAAK,OAAO,SAAS,GAAG;AACxC,gBAAM,UAAU,MAAM,KAAK,GAAG,UAAU,KAAK,OAAO,KAAK;AACzD,gBAAM,QAAQ,WAAoC,KAAK,OAAO,UAAU,EAAE,IAAI,cAAc,OAAO;AAAA,QACrG;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,sBAAqC;AACzC,YAAI,KAAK,gBAAiB,OAAM,KAAK,gBAAgB,YAAY;AAAA,MACnE;AAAA;AAAA,MAGA,MAAc,mBAAkD;AAC9D,YAAI,CAAC,KAAK,WAAY,MAAK,aAAa,MAAM,qBAAqB,KAAK,KAAK,EAAE;AAC/E,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYA,MAAM,aAAa,cAAmD;AACpE,cAAM,UAAU,KAAK,aAAa,YAAY;AAC9C,cAAM,MAAM,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC;AACjE,YAAI,CAAC,IAAK,OAAM,IAAI,kBAAkB,cAAc,KAAK,IAAI;AAC7D,cAAM,SAAS,KAAK,SAAS;AAC7B,cAAM,KAAK,MAAM,KAAK,iBAAiB;AACvC,cAAM,OAAO,EAAE,SAAS,OAAO,KAAK,MAAM,gBAAgB,IAAI,eAAe,eAAe,OAAO;AAEnG,YAAI,IAAI,iBAAiB,QAAQ;AAC/B,gBAAM,OAA2B,EAAE,GAAG,MAAM,QAAQ,QAAQ,UAAU,GAAG,YAAY,KAAK,IAAI,EAAE;AAChG,gBAAM,GAAG,sBAAsB,IAAI;AACnC,iBAAO;AAAA,QACT;AAEA,cAAM,GAAG,sBAAsB,EAAE,GAAG,MAAM,QAAQ,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AACpF,YAAI;AAAE,gBAAM,GAAG,YAAY,EAAE,MAAM,qBAAqB,OAAO,KAAK,MAAM,SAAS,SAAS,OAAO,CAAC;AAAA,QAAE,QAAQ;AAAA,QAAoB;AAElI,YAAI;AACF,gBAAM,QAAQ,MAAM,KAAK,cAAc,YAAY;AACnD,gBAAM,MAAM,0BAA0B;AACtC,gBAAM,EAAE,SAAS,IAAI,MAAM,MAAM,iBAAiB;AAElD,gBAAM,KAAK,SAAS,IAAI,KAAK,WAAW,YAAY,GAAG,EAAE,GAAG,KAAK,eAAe,OAAO,CAAC;AACxF,gBAAM,OAA2B,EAAE,GAAG,MAAM,gBAAgB,QAAQ,QAAQ,QAAQ,UAAU,YAAY,KAAK,IAAI,EAAE;AACrH,gBAAM,GAAG,sBAAsB,IAAI;AACnC,cAAI;AAAE,kBAAM,GAAG,YAAY,EAAE,MAAM,uBAAuB,OAAO,KAAK,MAAM,SAAS,SAAS,OAAO,CAAC;AAAA,UAAE,QAAQ;AAAA,UAAoB;AACpI,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,gBAAM,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC7D,gBAAM,SAA6B,EAAE,GAAG,MAAM,QAAQ,UAAU,OAAO,YAAY,KAAK,IAAI,EAAE;AAC9F,gBAAM,GAAG,sBAAsB,MAAM;AACrC,cAAI;AAAE,kBAAM,GAAG,YAAY,EAAE,MAAM,oBAAoB,OAAO,KAAK,MAAM,SAAS,SAAS,QAAQ,QAAQ,MAAM,CAAC;AAAA,UAAE,QAAQ;AAAA,UAAoB;AAChJ,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaA,MAAM,cAAc,UAA8D,CAAC,GAAiC;AAClH,cAAM,SAAS,KAAK,SAAS;AAC7B,cAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,cAAM,SAAS,QAAQ;AACvB,cAAM,OAAO,KAAK;AAAA,UAChB,CAAC,MAAM,EAAE,gBAAgB,WAAW,WAAW,UAAa,OAAO,SAAS,EAAE,YAAY;AAAA,QAC5F;AACA,cAAM,YAAY,KAAK,IAAI,GAAG,QAAQ,aAAa,CAAC;AACpD,cAAM,WAAqB,CAAC;AAC5B,cAAM,SAA+C,CAAC;AACtD,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,WAAW;AAC/C,gBAAM,QAAQ,KAAK,MAAM,GAAG,IAAI,SAAS;AACzC,gBAAM,UAAU,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,aAAa,EAAE,YAAY,CAAC,CAAC;AACrF,qBAAW,OAAO,SAAS;AACzB,gBAAI,IAAI,WAAW,OAAQ,UAAS,KAAK,IAAI,OAAO;AAAA,gBAC/C,QAAO,KAAK,EAAE,SAAS,IAAI,SAAS,OAAO,IAAI,SAAS,UAAU,CAAC;AAAA,UAC1E;AAAA,QACF;AACA,eAAO,EAAE,QAAQ,UAAU,OAAO;AAAA,MACpC;AAAA,IACF;AAEO,IAAM,oBAAN,MAAkC;AAAA,MACvC,YACmB,OACA,gBACjB;AAFiB;AACA;AAAA,MAChB;AAAA,MAFgB;AAAA,MACA;AAAA;AAAA,MAInB,MAAM,IAAI,IAAY,QAA0B;AAC9C,cAAM,MAAM,KAAK,MAAM,SAAS,MAAM,MAAM;AAC5C,cAAM,MAAM,MAAM,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,WAAW,GAAG,CAAC;AACpE,YAAI;AACJ,YAAI,CAAC,KAAK;AACR,cAAI,KAAK,MAAM,SAAS,eAAe,OAAO;AAC5C,kBAAM,IAAI,kBAAkB,KAAK,KAAK,MAAM,IAAI;AAAA,UAClD;AACA,kBAAQ,MAAM,KAAK,MAAM,YAAY,KAAK,KAAK,MAAM,SAAS,WAAW,MAAM,CAAC;AAAA,QAClF,OAAO;AACL,kBAAQ,MAAM,KAAK,MAAM,UAAU,GAAG;AAAA,QACxC;AACA,cAAM,MAAM,WAAc,KAAK,cAAc,EAAE,IAAI,IAAI,MAAM;AAAA,MAC/D;AAAA;AAAA,MAGA,QAA4B;AAC1B,eAAO,IAAI,aAAmB,KAAK,OAAO,KAAK,gBAAgB,CAAC,CAAC;AAAA,MACnE;AAAA,IACF;AAEO,IAAM,eAAN,MAAM,cAAuB;AAAA,MAClC,YACmB,OACA,gBACA,SACA,oBAAiD,CAAC,GAClD,gBAAyC,CAAC,GAC3D;AALiB;AACA;AACA;AACA;AACA;AAAA,MAChB;AAAA,MALgB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAGnB,MAAM,OAAe,IAAuB,OAAoC;AAC9E,eAAO,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL,CAAC,GAAG,KAAK,SAAS,EAAE,OAAO,IAAI,MAAM,CAAC;AAAA,UACtC,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,MACF;AAAA;AAAA,MAGA,eAAe,OAAe,MAAiD;AAC7E,cAAM,MAAwB,EAAE,OAAO,IAAI,KAAK,IAAI,SAAS,KAAK,SAAS,UAAU,KAAK,SAAS;AACnG,eAAO,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,CAAC,GAAG,KAAK,mBAAmB,GAAG;AAAA,UAC/B,KAAK;AAAA,QACP;AAAA,MACF;AAAA;AAAA,MAGA,cAAc,OAAe,MAAgD;AAC3E,cAAM,MAAoB;AAAA,UACxB;AAAA,UACA,IAAI,KAAK;AAAA,UACT,MAAM,KAAK;AAAA,UACX,IAAI,KAAK,MAAM;AAAA,UACf,MAAM,KAAK,QAAQ;AAAA,QACrB;AACA,eAAO,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,CAAC,GAAG,KAAK,eAAe,GAAG;AAAA,QAC7B;AAAA,MACF;AAAA;AAAA,MAGA,MAAM,cAAc,UAA8B,CAAC,GAA6D;AAC9G,cAAM,EAAE,UAAU,QAAQ,IAAI,MAAM,KAAK,MAAM,gBAAgB,OAAO;AAItE,cAAM,WAAW,SAAS,CAAC;AAC3B,YAAI,KAAK,kBAAkB,SAAS,KAAK,UAAU;AACjD,gBAAM,QAAQ,MAAM,KAAK,MAAM,UAAU,SAAS,YAAY;AAC9D,eAAK,MAAM,SAAS,UAAU,KAAK;AACnC,qBAAW,OAAO,KAAK,mBAAmB;AACxC,gBAAI,CAAC,MAAM,WAAW,KAAK,gBAAgB,IAAI,KAAK,GAAG;AACrD,oBAAM,IAAI;AAAA,gBACR,mBAAmB,IAAI,KAAK,8BAA8B,IAAI,KAAK,oBAClD,KAAK,cAAc,kBAAkB,KAAK,MAAM,SAAS,aAAa,kBACtE,IAAI,KAAK;AAAA,cAC5B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,SAAS,MAAM,KAAK,MAAM,GAAG;AAAA,UACjC,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,UAC7B,OAAO,UAAU;AACf,iBAAK,MAAM,SAAS,UAAU,KAAK;AACnC,kBAAM,OAAO,MAAM,WAAc,KAAK,cAAc;AACpD,kBAAM,KAAK,KAAK;AAIhB,uBAAW,OAAO,KAAK,mBAAmB;AACxC,oBAAM,OAAO,MAAM,WAAW,KAAK,gBAAgB,IAAI,KAAK;AAC5D,kBAAI,KAAM,OAAM,MAAM,WAAW,KAAK,MAAM,EAAE,KAAK;AAAA,YACrD;AACA,gBAAI,IAAI,KAAK,MAAM;AACnB,uBAAW,KAAK,KAAK,QAAS,KAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK;AAChE,uBAAW,OAAO,KAAK,mBAAmB;AACxC,kBAAI,EAAE,KAAK,IAAI,OAAO;AAAA,gBACpB,IAAI,IAAI;AAAA,gBACR,GAAI,IAAI,YAAY,SAAY,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,gBAC5D,GAAI,IAAI,WAAW,EAAE,UAAU,IAAI,SAAS,IAAI,CAAC;AAAA,cACnD,CAAC;AAAA,YACH;AACA,mBAAO,EAAE,QAAQ;AAAA,UACnB;AAAA,UACA,EAAE,aAAa,QAAQ,eAAe,GAAG,QAAQ,MAAM;AAAA,QACzD;AACA,cAAM,UAAe,CAAC;AACtB,mBAAW,KAAK,QAAQ;AACtB,cAAI,EAAE,MAAO,SAAQ,KAAK,EAAE,SAAS,EAAE,OAAO,QAAQ,kBAAkB,EAAE,KAAK,GAAG,OAAO,EAAE,MAAM,CAAC;AAAA,cAC7F,YAAW,QAAQ,EAAE,OAAQ,SAAQ,KAAK,IAAI;AAAA,QACrD;AACA,eAAO,EAAE,SAAS,SAAS,eAAe,QAAQ;AAAA,MACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,aACJ,MACA,UAA8B,CAAC,GACuC;AACtE,cAAM,EAAE,UAAU,QAAQ,IAAI,MAAM,KAAK,MAAM,gBAAgB,OAAO;AACtE,cAAM,SAAS,MAAM,KAAK,MAAM,GAAG;AAAA,UACjC,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,UAC7B,OAAO,UAAU;AACf,iBAAK,MAAM,SAAS,UAAU,KAAK;AACnC,kBAAM,OAAO,MAAM,WAAc,KAAK,cAAc;AACpD,kBAAM,KAAK,KAAK;AAChB,gBAAI,IAAI,KAAK,MAAM;AACnB,uBAAW,KAAK,KAAK,QAAS,KAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK;AAChE,kBAAM,OAAO,EAAE,QAAQ;AACvB,mBAAO,gBAAgB,MAAM,IAAI;AAAA,UACnC;AAAA,UACA,EAAE,aAAa,QAAQ,eAAe,GAAG,QAAQ,MAAM;AAAA,QACzD;AACA,cAAM,WAA2B,CAAC;AAClC,mBAAW,KAAK,QAAQ;AACtB,cAAI,EAAE,MAAO,SAAQ,KAAK,EAAE,SAAS,EAAE,OAAO,QAAQ,kBAAkB,EAAE,KAAK,GAAG,OAAO,EAAE,MAAM,CAAC;AAAA,cAC7F,UAAS,KAAK,EAAE,MAAM;AAAA,QAC7B;AACA,eAAO,EAAE,UAAU,eAAe,QAAQ;AAAA,MAC5C;AAAA;AAAA,MAGA,MAAM,QAAQ,UAA8B,CAAC,GAA6B;AACxE,cAAM,EAAE,SAAS,cAAc,IAAI,MAAM,KAAK,cAAc,OAAO;AACnE,cAAM,UAAW,MAAM,mBAAmB,SAAS,KAAK,aAAa;AACrE,eAAO,EAAE,SAAS,cAAc;AAAA,MAClC;AAAA;AAAA,MAGA,cAA2B;AACzB,cAAM,QAAQ,KAAK;AACnB,cAAM,iBAAiB,KAAK;AAC5B,eAAO;AAAA,UACL,oBAAoB,CAAC,MAAM;AAAE,kBAAM,GAAG,GAAG,UAAU,CAAC;AAAG,mBAAO,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;AAAA,UAAE;AAAA,UAC9F,YAAY,CAAC,MAAM,EAAE,eAAe,kBAAkB,EAAE,MAAM,WAAW,GAAG,MAAM,IAAI,IAAI;AAAA,QAC5F;AAAA,MACF;AAAA;AAAA,MAGQ,iBAAiB,SAAuB;AAC9C,YAAI,KAAK,kBAAkB,UAAU,KAAK,cAAc,QAAQ;AAC9D,gBAAM,IAAI;AAAA,YACR,GAAG,OAAO;AAAA,UAEZ;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAGA,KAAK,UAA4B,CAAC,GAA2B;AAC3D,aAAK,iBAAiB,MAAM;AAC5B,cAAM,OAAO,KAAK,YAAY;AAC9B,cAAM,OAAO,IAAI,eAA0D;AAAA,UACzE,GAAG;AAAA,UACH,SAAS,YAAY;AACnB,kBAAM,EAAE,SAAS,cAAc,IAAI,MAAM,KAAK,cAAc,OAAO;AACnE,mBAAO,EAAE,SAAS,SAAS,cAAc;AAAA,UAC3C;AAAA,UACA,iBAAiB,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,UAC5C,GAAI,QAAQ,eAAe,SAAY,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,QAC/E,CAAC;AACD,eAAO;AAAA,UACL,IAAI,QAAQ;AAAE,mBAAO,KAAK,SAAS;AAAA,UAAwB;AAAA,UAC3D,IAAI,gBAAgB;AAAE,mBAAO,KAAK,SAAS;AAAA,UAAmC;AAAA,UAC9E,IAAI,QAAQ;AAAE,mBAAO,KAAK;AAAA,UAAM;AAAA,UAChC,OAAO,KAAK;AAAA,UACZ,WAAW,CAAC,OAAO,KAAK,UAAU,EAAE;AAAA,UACpC,MAAM,MAAM,KAAK,KAAK;AAAA,QACxB;AAAA,MACF;AAAA;AAAA,MAGA,UAAsC,MAA4C;AAChF,aAAK,iBAAiB,WAAW;AACjC,eAAO,IAAI,sBAA+B,MAAM,MAAM,KAAK,YAAY,CAAC;AAAA,MAC1E;AAAA;AAAA,MAGA,QAA0B,OAAwC;AAChE,aAAK,iBAAiB,SAAS;AAC/B,eAAO,IAAI,oBAA6B,MAAM,KAAK;AAAA,MACrD;AAAA,IACF;AAGO,IAAM,sBAAN,MAAkD;AAAA,MACvD,YACmB,OACA,OACjB;AAFiB;AACA;AAAA,MAChB;AAAA,MAFgB;AAAA,MACA;AAAA,MAGnB,UAAsC,MAAsD;AAC1F,eAAO,IAAI;AAAA,UACT,EAAE,eAAe,CAAC,MAAM,KAAK,MAAM,cAAc,CAAC,EAAE;AAAA,UACpD,KAAK;AAAA,UACL;AAAA,UACA,KAAK,MAAM,YAAY;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACltBA,SAAS,mBAAAC,kBAAiB,0BAAAC,yBAAwB,kCAAkC;AACpF,SAAS,oBAAAC,yBAAwB;;;ACK1B,IAAM,aAAN,MAAiB;AAAA,EACtB,YAAqB,QAAoB;AAApB;AAAA,EAAqB;AAAA,EAArB;AAAA,EAErB,IAAI,SAAiB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,kBAA8C;AAC5C,WAAO,KAAK,OAAO,gBAAgB;AAAA,EACrC;AAAA,EAEA,YAAY,YAA4D;AACtE,WAAO,KAAK,OAAO,YAAY,UAAU;AAAA,EAC3C;AACF;;;ACPO,SAAS,eAAkB,OAA4C;AAC5E,MAAI,WAAW,oBAAI,IAAY;AAC/B,QAAM,UAAU,YAAY;AAC1B,UAAM,OAAO,MAAM,MAAM,QAAQ;AACjC,eAAW,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAC7C,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM,uBAA4D;AAChE,YAAM,OAAO,MAAM,QAAQ;AAC3B,aAAO,KAAK,IAAI,CAAC,OAAwB,EAAE,IAAI,EAAE,SAAS,MAAM,QAAQ,EAAE;AAAA,IAC5E;AAAA,IACA,MAAM,UAAU,MAA8B;AAC5C,YAAM,QAAQ,MAAM,MAAM,GAAG,UAAU,IAAI;AAC3C,YAAM,SAAS,UAAU,KAAK;AAC9B,aAAO;AAAA,IACT;AAAA,IACA,aAAa,SAAiC;AAC5C,aAAO,MAAM,GAAG,aAAa,CAAC,UAAU;AACtC,YAAI,SAAS,IAAI,MAAM,KAAK,EAAG,QAAO,QAAQ,KAAK;AAAA,MACrD,CAAC;AAAA,IACH;AAAA,IACA,gBAAgB,SAAkD;AAChE,aAAO,MAAM,GAAG,gBAAgB,CAAC,MAAM;AACrC,YAAI,SAAS,IAAI,EAAE,KAAK,EAAG,SAAQ,CAAC;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,IACA,IAAI,aAAyB;AAC3B,aAAO,MAAM,GAAG;AAAA,IAClB;AAAA,EACF;AACF;;;ACjBA,eAAsB,WACpB,OACA,OAAgC,CAAC,GACN;AAC3B,QAAM,EAAE,UAAU,QAAQ,IAAI,MAAM,MAAM;AAAA,IACxC,KAAK,eAAe,SAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,WAAgC,CAAC;AACvC,QAAM,QAAQ,oBAAI,IAAY;AAC9B,MAAI,UAAU;AACd,aAAW,OAAO,UAAU;AAC1B,UAAM,QAAQ,MAAM,MAAM,MAAM,IAAI,YAAY;AAChD,UAAM,YAAY,MAAM,MAAM,YAAY;AAC1C,QAAI,eAAe;AACnB,eAAW,KAAK,WAAW;AACzB,YAAM,IAAI,CAAC;AACX,sBAAgB,MAAM,MAAM,WAAW,CAAC,EAAE,MAAM;AAAA,IAClD;AACA,eAAW;AACX,aAAS,KAAK;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,cAAc,IAAI;AAAA,MAClB,eAAe,IAAI;AAAA,MACnB,aAAa,UAAU;AAAA,MACvB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,SAAO,EAAE,QAAQ,SAAS,QAAQ,aAAa,MAAM,MAAM,SAAS,UAAU,QAAQ;AACxF;;;AH2KA;AAiBA;AAiBA;AA5CA;AAAA,EACE,uBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,8BAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;;;AIjNP;AAKA;AACA;AAPA,SAAS,6BAAAC,kCAAiC;AAkEnC,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACkB,aACA,WAChB;AACA;AAAA,MACE,0DAA0D,WAAW,2BAC1D,SAAS,uCAAuC,WAAW;AAAA,IAExE;AAPgB;AACA;AAOhB,SAAK,OAAO;AAAA,EACd;AAAA,EATkB;AAAA,EACA;AASpB;AAqBA,eAAsB,iBACpB,UACA,kBACA,MACiC;AAEjC,QAAM,YAAY,KAAK,cAAc,MAAM,SAAS,iBAAiB,GAAG;AAGxE,QAAM,cAAc,KAAK,eAAe,KAAK;AAC7C,MAAI,gBAAgB,QAAW;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AAGA,MAAI,cAAc,UAAW,OAAM,IAAI,gBAAgB,aAAa,SAAS;AAG7E,QAAM,WAAW,MAAMA,2BAA0B,kBAAkB,KAAK,WAAW;AAKnF,QAAM,yBAA4D,CAAC;AACnE,QAAM,wBAAkG,CAAC;AACzG,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,SAAS,KAAK,aAAa,IAAI,KAAK,CAAC,GACxC,OAAO,CAAC,MAAM,EAAE,YAAY,eAAe,EAAE,aAAa,SAAS,EACnE,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC3C,2BAAuB,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,SAAS;AAC3D,0BAAsB,IAAI,IACxB,gBAAgB,YAAY,iBAAiB,MAAM,SAAS,IAAI,gBAAgB;AAClF,SAAK;AAAA,EACP;AACA,QAAM,SAAS,MAAM,iBAAiB,UAAU,UAAU,sBAAsB;AAGhF,QAAM,SAAS,MAAM,sBAAsB,UAAU,QAAQ,IAAI;AAEjE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA,cAAc;AAAA,IAChB;AAAA,EACF;AACF;;;AJsHA;AAeA,SAAS,YAAY,eAAe,mBAAAC,kBAAiB,gBAAgB,mBAAmB;;;AKvRjF,IAAM,qBAAN,MAA+C;AAAA,EACpD,YACW,QACQ,MACjB;AAFS;AACQ;AAAA,EAChB;AAAA,EAFQ;AAAA,EACQ;AAAA,EAGnB,MAAM,kBAA8C;AAClD,WAAO,OAAO,KAAK,KAAK,IAAI;AAAA,EAC9B;AAAA,EAEA,OAAO,YAAY,YAA4D;AAC7E,eAAW,OAAO,KAAK,KAAK,UAAU,KAAK,CAAC,EAAG,OAAM;AAAA,EACvD;AACF;;;AChCA;;;AN4TA;AAzQO,IAAM,QAAN,MAAY;AAAA,EACR;AAAA,EACQ,iBAAiB,oBAAI,IAA2B;AAAA,EAEjE,YAAY,OAAc;AACxB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,kBAAkB,MAAc,UAA+B;AAC7D,SAAK,eAAe,IAAI,MAAM,QAAQ;AAAA,EACxC;AAAA,EAEA,MAAM,eAAkB,MAAc,MAAoD;AACxF,UAAM,KAAK,KAAK;AAChB,QAAI,GAAG,SAAU,OAAM,IAAIC,iBAAgB,oBAAoB;AAC/D,QAAI,SAASC,kBAAkB,OAAM,IAAIC,wBAAuB,IAAI;AACpE,UAAM,WAAW,KAAK,eAAe,IAAI,KAAK,SAAS,aAAa;AACpE,QAAI,CAAC,SAAU,OAAM,IAAI,2BAA2B,KAAK,SAAS,aAAa;AAC/E,UAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,UAAM,EAAE,sBAAAC,sBAAqB,IAAI,MAAM;AACvC,UAAM,aAAa,KAAK,WAAW,SAAY,MAAMA,sBAAqB,KAAK,EAAE;AACjF,UAAM,WAAW,KAAK,YAAY,WAAY;AAC9C,UAAM,QAAQ,IAAID,YAAc,IAAI,MAAM,UAAU,KAAK,UAAU,UAAU,KAAK,iBAAiB,KAAK;AACxG,QAAI,YAAY;AACd,YAAM,kBAAkB,UAAU;AAClC,YAAM,WAAW,eAAe,KAAK,SAAS,eAAe,QAAQ;AACrE,UAAI;AACF,cAAM,WAAW,YAAY,EAAE,MAAM,qBAAqB,OAAO,MAAM,cAAc,KAAK,SAAS,eAAe,SAAS,SAAS,QAAQ,CAAC;AAC7I,cAAM,WAAW,YAAY,EAAE,MAAM,gBAAgB,OAAO,KAAK,CAAC;AAAA,MACpE,QAAQ;AAAA,MAAoB;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,2BAA0D;AAC9D,UAAM,KAAK,KAAK;AAChB,QAAI,GAAG,SAAU,OAAM,IAAIH,iBAAgB,oBAAoB;AAC/D,UAAM,EAAE,sBAAAI,sBAAqB,IAAI,MAAM;AACvC,WAAOA,sBAAqB,KAAK,EAAE;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,QAAgC;AACnC,WAAO,IAAI,WAAW,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,QAAoB,MAAkD;AACnF,UAAM,EAAE,UAAU,WAAW,IAAI,MAAM;AACvC,WAAO,WAAW,KAAK,OAAO,QAAQ,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,WACA,SAC+D;AAC/D,UAAM,EAAE,eAAe,gBAAgB,IAAI,MAAM;AACjD,UAAM,QAAQ,MAAM,KAAK,MAAM,UAAU,SAAS;AAClD,WAAO,gBAAgB,OAAO,OAAO;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aACJ,WACA,SACA,aACA,aACsB;AACtB,UAAM,EAAE,cAAc,eAAe,IAAI,MAAM;AAC/C,UAAM,QAAQ,MAAM,KAAK,MAAM,UAAU,SAAS;AAClD,WAAO,eAAe,OAAO,SAAS,aAAa,WAAW;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,qBAAqB,MAAwD;AACjF,UAAM,EAAE,uBAAAC,uBAAsB,IAAI,MAAM;AACxC,UAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,iBAAiB;AAE5D,UAAM,YAAY,CAAC,SAAiB,KAAK,MAAM,UAAU,IAAI;AAE7D,UAAM,OAAO,MAAMA,uBAAsB,WAAW;AAAA,MAClD,MAAM,EAAE,OAAO,KAAK,QAAQ,OAAO,OAAO,KAAK,QAAQ,MAAM;AAAA,MAC7D,GAAI,KAAK,mBAAmB,SAAY,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MACnF,GAAI,KAAK,aAAa,SAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,IACnE,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,OAAO,QAAQ,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,WAAW,MAAM,MAAM;AAC7D,cAAM,QAAQ,MAAM,UAAU,SAAS;AACvC,cAAM,UAAU,KAAK,gBAAgB,IAAI,SAAS;AAKlD,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,kBAAkB,SAAS;AAAA,MAChC,GAAI,KAAK,mBAAmB,SAAY,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,IACrF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,YAAY,OAAqB;AAC/C,SAAO,IAAI,MAAM,KAAK;AACxB;","names":["readNoydbBundleHeader","sha256Hex","generateULID","generateULID","extractPartition","sha256Hex","generateULID","skippedVaults","ValidationError","ReservedVaultNameError","STATE_VAULT_NAME","CrossShardJoinError","UnknownShardError","ShardProvisioningError","VaultTemplateNotFoundError","ReservedVaultNameError","DataResidencyError","decryptExtractedPartition","createDeedOwner","ValidationError","STATE_VAULT_NAME","ReservedVaultNameError","VaultGroup","StateManagementVault","walkCrossVaultClosure"]}