@korajs/store 1.0.0-beta.13 → 1.0.0-beta.14
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/adapters/better-sqlite3.cjs.map +1 -1
- package/dist/adapters/better-sqlite3.js +1 -1
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.js +4 -4
- package/dist/adapters/sqlite-wasm-worker.cjs +67 -15
- package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.js +65 -17
- package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
- package/dist/adapters/sqlite-wasm.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm.js +5 -5
- package/dist/{backup-4NUPDEMB.js → backup-IHKVMUAM.js} +5 -5
- package/dist/{chunk-Y5LRH7KI.js → chunk-5AQSGMJV.js} +151 -21
- package/dist/chunk-5AQSGMJV.js.map +1 -0
- package/dist/{chunk-W5F2LWG6.js → chunk-5JMGMPUE.js} +2 -2
- package/dist/{chunk-HZTDBLDB.js → chunk-BILSA6XZ.js} +4 -3
- package/dist/{chunk-HZTDBLDB.js.map → chunk-BILSA6XZ.js.map} +1 -1
- package/dist/{chunk-QDUSJMFV.js → chunk-BQSIL6TT.js} +5 -5
- package/dist/{chunk-MCQKEHOD.js → chunk-KK3GBONL.js} +2 -2
- package/dist/{chunk-32EDKWMI.js → chunk-KTVNANUH.js} +2 -2
- package/dist/{chunk-SJP2HTYZ.js → chunk-QW4UU7NG.js} +2 -2
- package/dist/{chunk-DUKTWVZW.js → chunk-SRHDJF5B.js} +13 -2
- package/dist/{chunk-DUKTWVZW.js.map → chunk-SRHDJF5B.js.map} +1 -1
- package/dist/{chunk-P4V375FY.js → chunk-UC2LGFPV.js} +4 -4
- package/dist/index.cjs +203 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +96 -6
- package/dist/index.d.ts +96 -6
- package/dist/index.js +55 -39
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +1 -0
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +3 -3
- package/dist/{restore-FR7XIKT2.js → restore-MNDPR557.js} +4 -4
- package/dist/{sql-builder-C4u55jKW.d.cts → sql-builder-D0tC3sv9.d.cts} +8 -1
- package/dist/{sql-builder-CGckdBDL.d.ts → sql-builder-D5UMzHEo.d.ts} +8 -1
- package/dist/sqlite-wasm-channel-QCCNBYCU.js +12 -0
- package/dist/store-HNGX4KTT.js +16 -0
- package/package.json +2 -2
- package/dist/chunk-Y5LRH7KI.js.map +0 -1
- package/dist/sqlite-wasm-channel-MLHLKEED.js +0 -12
- package/dist/store-IMWKZLWB.js +0 -16
- /package/dist/{backup-4NUPDEMB.js.map → backup-IHKVMUAM.js.map} +0 -0
- /package/dist/{chunk-W5F2LWG6.js.map → chunk-5JMGMPUE.js.map} +0 -0
- /package/dist/{chunk-QDUSJMFV.js.map → chunk-BQSIL6TT.js.map} +0 -0
- /package/dist/{chunk-MCQKEHOD.js.map → chunk-KK3GBONL.js.map} +0 -0
- /package/dist/{chunk-32EDKWMI.js.map → chunk-KTVNANUH.js.map} +0 -0
- /package/dist/{chunk-SJP2HTYZ.js.map → chunk-QW4UU7NG.js.map} +0 -0
- /package/dist/{chunk-P4V375FY.js.map → chunk-UC2LGFPV.js.map} +0 -0
- /package/dist/{restore-FR7XIKT2.js.map → restore-MNDPR557.js.map} +0 -0
- /package/dist/{sqlite-wasm-channel-MLHLKEED.js.map → sqlite-wasm-channel-QCCNBYCU.js.map} +0 -0
- /package/dist/{store-IMWKZLWB.js.map → store-HNGX4KTT.js.map} +0 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/compaction/types.ts","../src/compaction/compact-operation-log.ts","../src/lww/row-version.ts","../src/serialization/op-data-encoding.ts","../src/serialization/richtext-serializer.ts","../src/serialization/serializer.ts","../src/query/sql-builder.ts","../src/sync/rehash-operation.ts","../src/store/sequence-allocator.ts","../src/store/sequence-repair.ts","../src/sync/sync-state.ts","../src/sync/sync-durability.ts","../src/sync/local-sync-records.ts","../src/fold/record-folder.ts","../src/log-integrity/log-integrity.ts","../src/backup/backup.ts","../src/mutations/write-context.ts","../src/mutations/run-local-write.ts","../src/lww/field-versions.ts","../src/state-machine/state-validator.ts","../src/mutations/secret-write.ts","../src/mutations/write-ops.ts","../src/mutations/execute-delete.ts","../src/mutations/execute-insert.ts","../src/mutations/execute-update.ts","../src/collection/collection.ts","../src/fold/compact-folded-log.ts","../src/fold/legacy-bodies.ts","../src/fold/rematerialize.ts","../src/migrations/run-migrations.ts","../src/migrations/schema-ceiling.ts","../src/subscription/result-equality.ts","../src/query/pluralize.ts","../src/query/query-key.ts","../src/query/query-builder.ts","../src/relations/relation-lookup.ts","../src/relations/relation-enforcer.ts","../src/replay/replay-to.ts","../src/sequences/sequence-manager.ts","../src/serialization/stored-text-migration.ts","../src/subscription/bloom-filter.ts","../src/subscription/subscription-manager.ts","../src/sync/rebase-unsynced-operations.ts","../src/sync/rotate-node-id.ts","../src/transaction/transaction-context.ts","../src/store/legacy-indexes.ts","../src/store/node-lock.ts","../src/store/relax-constraints.ts","../src/store/tab-node-id.ts","../src/audit/audit-json.ts","../src/audit/audit-trace-store.ts","../src/audit/export-audit.ts","../src/backup/restore.ts","../src/store/store.ts","../src/index.ts","../src/persistence/storage-persistence.ts","../src/reactivity/query-store.ts","../src/reactivity/assert-query-ready.ts","../src/reactivity/query-store-cache.ts","../src/richtext/create-richtext-controller.ts","../src/richtext/as-rich-text-sync-engine.ts","../src/backup/index.ts","../src/audit/index.ts","../src/blob/content-addressed-blob-store.ts","../src/blob/opfs-blob-store.ts","../src/blob/blob-chunking.ts","../src/blob/blob-transfer.ts","../src/blob/blob-manifest-transfer.ts","../src/blob/server-blob-callbacks.ts","../src/blob/blob-gc.ts","../src/blob/blob-chunk-transport.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\n\n/**\n * Thrown when a query is invalid (bad field names, invalid operators, etc.).\n */\nexport class QueryError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'QUERY_ERROR', context)\n\t\tthis.name = 'QueryError'\n\t}\n}\n\n/**\n * Thrown when a record is not found by ID (findById, update, delete on missing record).\n */\nexport class RecordNotFoundError extends KoraError {\n\tconstructor(collection: string, recordId: string) {\n\t\tsuper(`Record \"${recordId}\" not found in collection \"${collection}\"`, 'RECORD_NOT_FOUND', {\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t})\n\t\tthis.name = 'RecordNotFoundError'\n\t}\n}\n\n/**\n * Thrown inside `applyRemoteOperation` when the row's version state changed\n * between the caller's snapshot read and the guarded write (a concurrent local\n * mutation landed in the window). The transaction is rolled back with nothing\n * written; the caller re-reads fresh state, recomputes its merge, and retries.\n * This is the optimistic-concurrency guard that keeps merge-engine results\n * (richtext, add-wins arrays, constraint resolutions) from clobbering newer\n * local edits they never saw.\n */\nexport class OptimisticLockError extends KoraError {\n\tconstructor(collection: string, recordId: string) {\n\t\tsuper(\n\t\t\t`Row version changed while merging record \"${recordId}\" in \"${collection}\"; retry with fresh state`,\n\t\t\t'OPTIMISTIC_LOCK',\n\t\t\t{ collection, recordId },\n\t\t)\n\t\tthis.name = 'OptimisticLockError'\n\t}\n}\n\n/**\n * Thrown when a storage adapter operation fails.\n */\nexport class AdapterError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'ADAPTER_ERROR', context)\n\t\tthis.name = 'AdapterError'\n\t}\n}\n\n/**\n * Thrown when a write reaches a storage adapter that could not obtain durable\n * storage (it opened, or was promoted to leader, on a non-persistent in-memory\n * database). Kora refuses such writes instead of accepting data that would be\n * lost on reload. Reads still work.\n *\n * Fix: close other tabs or apps using the same origin's OPFS storage and reopen,\n * or opt in explicitly with `allowNonDurable: true` if in-memory storage is\n * acceptable for this app.\n */\nexport class StorageDurabilityError extends KoraError {\n\tconstructor(dbName: string, phase: 'open' | 'promotion', reason: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" has no durable storage (${reason} during ${phase}); writes are refused so they are not silently lost on reload. Close other tabs or apps using this origin's storage and reload, or set allowNonDurable: true to accept in-memory storage.`,\n\t\t\t'STORAGE_DURABILITY_LOST',\n\t\t\t{ dbName, phase, reason },\n\t\t)\n\t\tthis.name = 'StorageDurabilityError'\n\t}\n}\n\n/**\n * Thrown when the store opens a database a NEWER build of the app already migrated: its\n * stored schema version is above this code's `schema.version` (RT-109). Running older\n * code against it would write operations of the old schema into the new one, or fail\n * part-way, so the store refuses before changing anything and emits `store:schema-ahead`.\n *\n * Fix: run the newer build (reload while online, or accept the app's update prompt).\n * Never lower `schema.version` in a deployed app.\n */\nexport class SchemaVersionAheadError extends KoraError {\n\tconstructor(\n\t\tpublic readonly dbName: string,\n\t\tpublic readonly storedVersion: number,\n\t\tpublic readonly codeVersion: number,\n\t) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is at schema version ${storedVersion}, newer than this build's schema version ${codeVersion}: a newer build of the app already migrated it. It was not opened and nothing in it changed. Run the newer build (reload while online, or accept the update); never lower schema.version in a deployed app.`,\n\t\t\t'SCHEMA_VERSION_AHEAD',\n\t\t\t{ dbName, storedVersion, codeVersion },\n\t\t)\n\t\tthis.name = 'SchemaVersionAheadError'\n\t}\n}\n\n/**\n * Thrown when an operation is attempted on a store that has not been opened.\n */\nexport class StoreNotOpenError extends KoraError {\n\tconstructor() {\n\t\tsuper('Store is not open. Call store.open() before performing operations.', 'STORE_NOT_OPEN')\n\t\tthis.name = 'StoreNotOpenError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker fails to initialize (WASM load failure, OPFS unavailable, etc.).\n */\nexport class WorkerInitError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Worker initialization failed: ${message}`, 'WORKER_INIT_ERROR', context)\n\t\tthis.name = 'WorkerInitError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker does not respond within the configured timeout.\n */\nexport class WorkerTimeoutError extends KoraError {\n\tconstructor(operation: string, timeoutMs: number) {\n\t\tsuper(\n\t\t\t`Worker did not respond within ${timeoutMs}ms for operation \"${operation}\"`,\n\t\t\t'WORKER_TIMEOUT',\n\t\t\t{ operation, timeoutMs },\n\t\t)\n\t\tthis.name = 'WorkerTimeoutError'\n\t}\n}\n\n/**\n * Thrown when a follower tab cannot reach a live leader tab over the multi-tab\n * broadcast channel (the leader tab was closed, crashed, or is unresponsive).\n * Distinct from {@link WorkerTimeoutError}: this fails fast on a confirmed-absent\n * leader instead of waiting out the full RPC timeout.\n */\nexport class NoLeaderError extends KoraError {\n\tconstructor(\n\t\toperation: string,\n\t\tmessage = `No live leader tab is answering multi-tab storage RPC for operation \"${operation}\"`,\n\t\tcode = 'NO_LEADER',\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message, code, { operation, ...context })\n\t\tthis.name = 'NoLeaderError'\n\t}\n}\n\n/**\n * Thrown to a follower tab's pending storage requests when the leader tab that\n * was answering stopped sending heartbeats (hung, frozen, or suspended). The\n * request may or may not have been applied: retry it with the same `requestId`\n * (in the error context) and the leader de-duplicates it. Retriable.\n */\nexport class LeaderUnresponsiveError extends NoLeaderError {\n\tconstructor(operation: string, silentMs: number, requestId: string) {\n\t\tsuper(\n\t\t\toperation,\n\t\t\t`The leader tab stopped responding (no heartbeat for ${silentMs}ms) during \"${operation}\". The request may or may not have been applied; retry it with the same requestId and the leader de-duplicates it.`,\n\t\t\t'LEADER_UNRESPONSIVE',\n\t\t\t{ silentMs, requestId, retriable: true },\n\t\t)\n\t\tthis.name = 'LeaderUnresponsiveError'\n\t}\n}\n\n/**\n * Thrown to pending storage requests when their bridge was torn down, typically\n * because this tab was just promoted to leader or the leader handed over.\n * Retriable: the next attempt goes to the new leader.\n */\nexport class BridgeTerminatedError extends KoraError {\n\tconstructor(operation: string, reason: string) {\n\t\tsuper(\n\t\t\t`Storage request \"${operation}\" was interrupted (${reason}); retry it against the new storage leader.`,\n\t\t\t'BRIDGE_TERMINATED',\n\t\t\t{ operation, reason, retriable: true },\n\t\t)\n\t\tthis.name = 'BridgeTerminatedError'\n\t}\n}\n\n/** Thrown when a storage request is cancelled through its `AbortSignal`. */\nexport class RequestAbortedError extends KoraError {\n\tconstructor(operation: string, requestId: string) {\n\t\tsuper(\n\t\t\t`Storage request \"${operation}\" was aborted by the caller. A write may already have reached the leader; retry with the same requestId to stay idempotent.`,\n\t\t\t'REQUEST_ABORTED',\n\t\t\t{ operation, requestId },\n\t\t)\n\t\tthis.name = 'RequestAbortedError'\n\t}\n}\n\n/**\n * Thrown by `deleteDatabase()` when the database is open in some tab or worker\n * on this origin. Close it everywhere (or call `app.close()`) and retry.\n */\nexport class StorageInUseError extends KoraError {\n\tconstructor(dbName: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is open in a tab on this origin; close it before deleting it.`,\n\t\t\t'STORAGE_IN_USE',\n\t\t\t{ dbName },\n\t\t)\n\t\tthis.name = 'StorageInUseError'\n\t}\n}\n\n/**\n * Thrown by `deleteDatabase()` when the database still holds operations that\n * never reached the server. Sync first, or pass `{ force: true }` to discard them.\n */\nexport class UnsyncedDataError extends KoraError {\n\tconstructor(dbName: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" has unsynced operations; deleting it would lose them. Sync first, or pass { force: true } to discard them deliberately.`,\n\t\t\t'UNSYNCED_DATA',\n\t\t\t{ dbName },\n\t\t)\n\t\tthis.name = 'UnsyncedDataError'\n\t}\n}\n\n/**\n * Thrown when a database's data lives in a storage backend this runtime cannot\n * read (for example it was written to OPFS, and OPFS is unavailable now). Kora\n * refuses to start an empty, disjoint copy rather than hide the existing data.\n */\nexport class StorageBackendMismatchError extends KoraError {\n\tconstructor(dbName: string, recorded: string, requested: string, reason: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is stored in ${recorded}, but this session can only use ${requested} (${reason}). Kora will not start a separate empty copy; reload in a browser profile where ${recorded} is available.`,\n\t\t\t'STORAGE_BACKEND_MISMATCH',\n\t\t\t{ dbName, recorded, requested, reason },\n\t\t)\n\t\tthis.name = 'StorageBackendMismatchError'\n\t}\n}\n\n/**\n * Thrown when IndexedDB persistence operations fail (serialize/deserialize).\n */\nexport class PersistenceError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Persistence error: ${message}`, 'PERSISTENCE_ERROR', context)\n\t\tthis.name = 'PersistenceError'\n\t}\n}\n","import type { VersionVector } from '@korajs/core'\n\n/**\n * How the local operation log may be compacted.\n * Materialized collection rows are always kept as the convergence baseline.\n */\nexport type CompactionStrategy =\n\t| { mode: 'never' }\n\t| {\n\t\t\tmode: 'after-ack'\n\t\t\t/** Server version vector; defaults to persisted last-acked vector on the store. */\n\t\t\tserverVector?: VersionVector\n\t }\n\t| {\n\t\t\tmode: 'after-days'\n\t\t\t/** Delete only ops older than this many days (still requires ack watermark). */\n\t\t\tdays: number\n\t\t\tserverVector?: VersionVector\n\t }\n\n/**\n * Result of a compaction run.\n */\nexport interface CompactionResult {\n\t/** Number of operation log rows removed. */\n\tdeletedCount: number\n\t/** Per-node sequence ceiling used for deletion (from server ack vector). */\n\twatermark: VersionVector\n}\n\nexport const COMPACTION_BASELINE_META_KEY = 'compaction_baseline_at'\n","import type { SchemaDefinition, VersionVector } from '@korajs/core'\nimport { HybridLogicalClock, createVersionVector, quoteIdent } from '@korajs/core'\nimport type { StorageAdapter, Transaction } from '../types'\nimport type { CompactionResult, CompactionStrategy } from './types'\nimport { COMPACTION_BASELINE_META_KEY } from './types'\n\n/**\n * Compute per-node sequence watermarks safe to compact (server has acknowledged these ops).\n */\nexport function computeAckCompactionWatermark(serverVector: VersionVector): VersionVector {\n\tconst watermark = createVersionVector()\n\tfor (const [nodeId, seq] of serverVector) {\n\t\tif (seq > 0) {\n\t\t\twatermark.set(nodeId, seq)\n\t\t}\n\t}\n\treturn watermark\n}\n\n/**\n * Remove acknowledged, materialized operation log entries from `_kora_ops_*` tables.\n * Does not modify collection rows — they are the compaction baseline snapshot.\n */\nexport async function compactOperationLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tstrategy: CompactionStrategy,\n\tserverVector: VersionVector,\n): Promise<CompactionResult> {\n\tif (strategy.mode === 'never') {\n\t\treturn { deletedCount: 0, watermark: createVersionVector() }\n\t}\n\n\tconst watermark = computeAckCompactionWatermark(serverVector)\n\tif (watermark.size === 0) {\n\t\treturn { deletedCount: 0, watermark }\n\t}\n\n\tconst ageCutoffWall =\n\t\tstrategy.mode === 'after-days' ? Date.now() - strategy.days * 24 * 60 * 60 * 1000 : null\n\tconst ageCutoffSerialized =\n\t\tageCutoffWall !== null\n\t\t\t? HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: ageCutoffWall,\n\t\t\t\t\tlogical: 0,\n\t\t\t\t\tnodeId: '',\n\t\t\t\t}).slice(0, 15)\n\t\t\t: null\n\n\tlet deletedCount = 0\n\tconst collectionNames = Object.keys(schema.collections)\n\n\tawait adapter.transaction(async (tx: Transaction) => {\n\t\tfor (const collectionName of collectionNames) {\n\t\t\t// Already quoted here so the buildCountSql / buildDeleteSql helpers can\n\t\t\t// interpolate it verbatim (they do not route through sql-builder).\n\t\t\tconst table = quoteIdent(`_kora_ops_${collectionName}`)\n\t\t\tfor (const [nodeId, maxSeq] of watermark) {\n\t\t\t\tif (maxSeq <= 0) continue\n\n\t\t\t\tconst countSql = buildCountSql(table, ageCutoffSerialized !== null)\n\t\t\t\tconst countParams =\n\t\t\t\t\tageCutoffSerialized !== null ? [nodeId, maxSeq, ageCutoffSerialized] : [nodeId, maxSeq]\n\t\t\t\tconst countRows = await tx.query<{ count: number }>(countSql, countParams)\n\t\t\t\tdeletedCount += countRows[0]?.count ?? 0\n\n\t\t\t\tconst deleteSql = buildDeleteSql(table, ageCutoffSerialized !== null)\n\t\t\t\tawait tx.execute(deleteSql, countParams)\n\t\t\t}\n\t\t}\n\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\n\treturn { deletedCount, watermark }\n}\n\nfunction buildCountSql(table: string, withAge: boolean): string {\n\tif (withAge) {\n\t\treturn `SELECT COUNT(*) as count FROM ${table} WHERE node_id = ? AND sequence_number <= ? AND SUBSTR(timestamp, 1, 15) < ?`\n\t}\n\treturn `SELECT COUNT(*) as count FROM ${table} WHERE node_id = ? AND sequence_number <= ?`\n}\n\nfunction buildDeleteSql(table: string, withAge: boolean): string {\n\tif (withAge) {\n\t\treturn `DELETE FROM ${table} WHERE node_id = ? AND sequence_number <= ? AND SUBSTR(timestamp, 1, 15) < ?`\n\t}\n\treturn `DELETE FROM ${table} WHERE node_id = ? AND sequence_number <= ?`\n}\n","import { type HLCTimestamp, HybridLogicalClock } from '@korajs/core'\nimport type { RawCollectionRow } from '../types'\n\n/** Empty _version means legacy rows (compare by wallTime only via fallback). */\nexport const EMPTY_ROW_VERSION = ''\n\n/**\n * Serialize an HLC timestamp for storage in the `_version` column.\n * Lexicographic order matches {@link HybridLogicalClock.compare}.\n */\nexport function serializeRowVersion(timestamp: HLCTimestamp): string {\n\treturn HybridLogicalClock.serialize(timestamp)\n}\n\n/**\n * Read the version stamp stored on a materialized row.\n * Legacy rows without `_version` fall back to wallTime with logical 0.\n */\nexport function rowVersionFromRecord(\n\trow: Pick<RawCollectionRow, '_updated_at' | '_version'>,\n): HLCTimestamp {\n\tconst version = row._version\n\tif (typeof version === 'string' && version.length > 0) {\n\t\treturn HybridLogicalClock.deserialize(version)\n\t}\n\treturn { wallTime: row._updated_at, logical: 0, nodeId: '' }\n}\n\n/**\n * Returns true when `incoming` is strictly newer than the version on `row`.\n */\nexport function isIncomingNewerThanRow(\n\tincoming: HLCTimestamp,\n\trow: Pick<RawCollectionRow, '_updated_at' | '_version'>,\n): boolean {\n\treturn HybridLogicalClock.compare(incoming, rowVersionFromRecord(row)) > 0\n}\n\n/**\n * SQL fragment and params for LWW guards: apply only when row is missing or older.\n * Uses serialized `_version` for total order (matches HLC compare).\n */\nexport function lwwVersionWhereClause(remoteVersion: string): { sql: string; params: string[] } {\n\treturn {\n\t\tsql: '(_version = ? OR _version < ?)',\n\t\tparams: [EMPTY_ROW_VERSION, remoteVersion],\n\t}\n}\n","import {\n\ttype KoraBytesValue,\n\tbase64ToBytes,\n\tbytesToBase64,\n\tdecodeBytesFromOpData,\n\tencodeBytesForOpData,\n\tisKoraBytesValue,\n\tisLegacyNumericByteObject,\n} from '@korajs/core'\nimport type { FieldDescriptor } from '@korajs/core'\n\n/**\n * The canonical binary op-data encoding lives in `@korajs/core` because\n * `op.data` is a core concept shared by store (creation, persistence) and merge\n * (CRDT merge). These re-exports keep existing store-internal import paths\n * working while the single source of truth is the core module.\n */\nexport type { KoraBytesValue }\nexport { base64ToBytes, bytesToBase64, isKoraBytesValue, isLegacyNumericByteObject }\n\n/** @deprecated Use {@link encodeRichtextForOpData}; kept for existing imports. */\nexport const encodeRichtextForOpData = encodeBytesForOpData\n/** @deprecated Use {@link decodeRichtextOpDataValue}; kept for existing imports. */\nexport const decodeRichtextOpDataValue = decodeBytesFromOpData\n\n/**\n * Apply {@link encodeBytesForOpData} to every richtext-typed field in an\n * operation's data payload. Called at operation creation, BEFORE the payload\n * is content-hashed, so the hash input, persisted JSON, wire payload, and the\n * value the merge engine sees are the identical canonical value. Non-richtext\n * fields are untouched.\n */\nexport function encodeRichtextFieldsForOpData(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...data }\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (fields[key]?.kind !== 'richtext') {\n\t\t\tcontinue\n\t\t}\n\t\tif (typeof value === 'string' || value instanceof Uint8Array || value instanceof ArrayBuffer) {\n\t\t\tresult[key] = encodeBytesForOpData(value)\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Reverse of {@link encodeRichtextFieldsForOpData}: decode tagged (or legacy\n * numeric-key) richtext values in an op-data payload back to record-shaped\n * values (string or Uint8Array). Null/undefined and plain strings pass\n * through, preserving pre-fix behavior exactly.\n */\nexport function decodeRichtextFieldsFromOpData(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...data }\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (fields[key]?.kind !== 'richtext' || value === null || value === undefined) {\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = decodeBytesFromOpData(value)\n\t}\n\treturn result\n}\n","import * as Y from 'yjs'\nimport {\n\ttype KoraBytesValue,\n\tdecodeRichtextOpDataValue,\n\tisKoraBytesValue,\n\tisLegacyNumericByteObject,\n} from './op-data-encoding'\n\nconst TEXT_KEY = 'content'\n\nexport type RichtextInput = string | Uint8Array | ArrayBuffer | null | undefined\n\n/**\n * Encodes richtext values into Yjs document updates.\n *\n * Also accepts the tagged `{ $koraBytes }` form that binary richtext values\n * take inside `op.data` (and, for old dev databases, the pre-fix numeric-key\n * object shape), so every consumer that writes op-data values to columns\n * inherits the decoding. Plain strings keep their exact historical behavior:\n * encoded as a fresh Yjs document containing the string.\n */\nexport function encodeRichtext(value: RichtextInput | KoraBytesValue): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof value === 'string') {\n\t\tconst doc = new Y.Doc()\n\t\t// Deterministic clientId so the same string encodes to the same bytes on every\n\t\t// device (a plain string is a replacement, not a collaborative actor). A random\n\t\t// clientId would make a string-derived richtext column diverge byte-wise across\n\t\t// replicas even when the text is identical.\n\t\tdoc.clientID = 0\n\t\tdoc.getText(TEXT_KEY).insert(0, value)\n\t\treturn Y.encodeStateAsUpdate(doc)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tif (isKoraBytesValue(value) || isLegacyNumericByteObject(value)) {\n\t\tconst decoded = decodeRichtextOpDataValue(value)\n\t\t// Both accepted shapes decode to bytes; strings were handled above.\n\t\treturn decoded instanceof Uint8Array ? decoded : null\n\t}\n\n\tthrow new Error('Richtext value must be a string, Uint8Array, ArrayBuffer, null, or undefined.')\n}\n\n/**\n * Decodes driver-provided richtext values into Uint8Array.\n */\nexport function decodeRichtext(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tthrow new Error(\n\t\t'Richtext storage value must be Uint8Array, ArrayBuffer, Buffer, null, or undefined.',\n\t)\n}\n\n/**\n * Reads plain text from a richtext Yjs state update.\n */\nexport function richtextToPlainText(value: RichtextInput): string {\n\tconst encoded = encodeRichtext(value)\n\tif (!encoded) return ''\n\n\tconst doc = new Y.Doc()\n\tY.applyUpdate(doc, encoded)\n\treturn doc.getText(TEXT_KEY).toString()\n}\n\n/**\n * Compares two richtext values by decoded plain text.\n * Yjs update bytes are not stable across separate encodes of the same string.\n */\nexport function richtextStatesEqual(a: unknown, b: unknown): boolean {\n\ttry {\n\t\treturn richtextToPlainText(a as RichtextInput) === richtextToPlainText(b as RichtextInput)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import { HybridLogicalClock, decodeStoredText, encodeStoredText } from '@korajs/core'\nimport type { CollectionDefinition, FieldDescriptor, Operation } from '@korajs/core'\nimport type { CollectionRecord, OperationRow, RawCollectionRow } from '../types'\nimport { decodeRichtext, encodeRichtext } from './richtext-serializer'\n\n/**\n * Serialize a JS record to SQL-compatible values for INSERT/UPDATE.\n * Transforms: boolean → 0/1, array → JSON string, richtext → Yjs binary update.\n *\n * @param data - The record data with JS-native types\n * @param fields - The field descriptors from the schema\n * @returns An object with SQL-compatible values\n */\nexport function serializeRecord(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tconst descriptor = fields[key]\n\t\tif (!descriptor) {\n\t\t\tresult[key] = value\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = serializeValue(value, descriptor)\n\t}\n\treturn result\n}\n\n/**\n * Deserialize a SQL row to JS-native types for the application layer.\n * Transforms: 0/1 → boolean, JSON string → array, strips _deleted, maps _created_at/_updated_at.\n *\n * @param row - The raw SQL row\n * @param fields - The field descriptors from the schema\n * @returns A CollectionRecord with JS-native types\n */\nexport function deserializeRecord(\n\trow: RawCollectionRow,\n\tfields: Record<string, FieldDescriptor>,\n): CollectionRecord {\n\tconst result: CollectionRecord = {\n\t\tid: row.id,\n\t\tcreatedAt: row._created_at,\n\t\tupdatedAt: row._updated_at,\n\t}\n\n\tfor (const [key, descriptor] of Object.entries(fields)) {\n\t\tconst rawValue = row[key]\n\t\tif (rawValue === undefined || rawValue === null) {\n\t\t\tresult[key] = rawValue ?? null\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = deserializeValue(rawValue, descriptor)\n\t}\n\n\treturn result\n}\n\n/**\n * Internal key used to embed atomicOps metadata in the data JSON column.\n * This avoids adding a new column to the ops table (no migration needed).\n */\nconst ATOMIC_OPS_KEY = '__kora_atomic_ops__'\n\n/**\n * Internal key used to embed transactionId in the data JSON column.\n */\nconst TX_ID_KEY = '__kora_tx_id__'\n\n/**\n * Internal key used to embed mutationName in the data JSON column.\n */\nconst MUTATION_NAME_KEY = '__kora_mutation__'\n\n/**\n * Internal key used to embed a scope-entry insert's per-field versions (RT-27) in the\n * data JSON column, so a later fold of the record's log places each field correctly.\n */\nconst FIELD_VERSIONS_KEY = '__kora_field_versions__'\n\n/**\n * Internal key used to embed the operation's content-hash version (CORE-1, protocol\n * v2) in the data JSON column. Absent means version 1. Kept in the row so id\n * verification and re-hashing (rebase, rotation, resequence) use the right version.\n */\nconst HASH_VERSION_KEY = '__kora_hash_version__'\n\n/**\n * Serialize an Operation to a row for the operations log table.\n *\n * @param op - The operation to serialize\n * @returns An OperationRow suitable for SQL INSERT\n */\nexport function serializeOperation(op: Operation): OperationRow {\n\tconst hasMetadata =\n\t\top.transactionId !== undefined || op.mutationName !== undefined || op.hashVersion !== undefined\n\tlet dataPayload: Record<string, unknown> | null = null\n\tif (op.data) {\n\t\t// Embed metadata in the data JSON when present\n\t\tdataPayload = { ...op.data }\n\t\tif (op.atomicOps !== undefined && Object.keys(op.atomicOps).length > 0) {\n\t\t\tdataPayload[ATOMIC_OPS_KEY] = op.atomicOps\n\t\t}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t\tif (op.fieldVersions !== undefined) {\n\t\t\tdataPayload[FIELD_VERSIONS_KEY] = op.fieldVersions\n\t\t}\n\t\tif (op.hashVersion !== undefined) {\n\t\t\tdataPayload[HASH_VERSION_KEY] = op.hashVersion\n\t\t}\n\t} else if (hasMetadata) {\n\t\t// For delete operations (data is null), we still need to store metadata\n\t\tdataPayload = {}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t\tif (op.hashVersion !== undefined) {\n\t\t\tdataPayload[HASH_VERSION_KEY] = op.hashVersion\n\t\t}\n\t}\n\n\treturn {\n\t\tid: op.id,\n\t\tnode_id: op.nodeId,\n\t\ttype: op.type,\n\t\trecord_id: op.recordId,\n\t\tdata: dataPayload ? JSON.stringify(dataPayload) : null,\n\t\tprevious_data: op.previousData ? JSON.stringify(op.previousData) : null,\n\t\ttimestamp: HybridLogicalClock.serialize(op.timestamp),\n\t\tsequence_number: op.sequenceNumber,\n\t\tcausal_deps: JSON.stringify(op.causalDeps),\n\t\tschema_version: op.schemaVersion,\n\t}\n}\n\n/**\n * Deserialize a row from the operations log table back to an Operation.\n *\n * @param row - The raw operation row from SQL\n * @returns The deserialized Operation object\n */\nexport function deserializeOperation(row: OperationRow): Operation {\n\tlet data: Record<string, unknown> | null = null\n\tlet atomicOps: Record<string, unknown> | undefined\n\tlet transactionId: string | undefined\n\tlet mutationName: string | undefined\n\tlet fieldVersions: Operation['fieldVersions']\n\tlet hashVersion: Operation['hashVersion']\n\n\tif (row.data) {\n\t\tconst parsed = JSON.parse(row.data) as Record<string, unknown>\n\t\t// Extract embedded metadata keys\n\t\tif (ATOMIC_OPS_KEY in parsed) {\n\t\t\tatomicOps = parsed[ATOMIC_OPS_KEY] as Record<string, unknown>\n\t\t}\n\t\tif (TX_ID_KEY in parsed) {\n\t\t\ttransactionId = parsed[TX_ID_KEY] as string\n\t\t}\n\t\tif (MUTATION_NAME_KEY in parsed) {\n\t\t\tmutationName = parsed[MUTATION_NAME_KEY] as string\n\t\t}\n\t\tif (FIELD_VERSIONS_KEY in parsed) {\n\t\t\tfieldVersions = parsed[FIELD_VERSIONS_KEY] as Operation['fieldVersions']\n\t\t}\n\t\tif (HASH_VERSION_KEY in parsed) {\n\t\t\thashVersion = parsed[HASH_VERSION_KEY] as Operation['hashVersion']\n\t\t}\n\t\t// Remove metadata keys from data\n\t\tconst {\n\t\t\t[ATOMIC_OPS_KEY]: _a,\n\t\t\t[TX_ID_KEY]: _t,\n\t\t\t[MUTATION_NAME_KEY]: _m,\n\t\t\t[FIELD_VERSIONS_KEY]: _f,\n\t\t\t[HASH_VERSION_KEY]: _h,\n\t\t\t...rest\n\t\t} = parsed\n\t\t// An insert or update always carries data, possibly `{}` (an insert of only\n\t\t// optional fields): its id covers `{}`, so `{}` is read back, never `null`. Only a\n\t\t// delete's payload is metadata alone (RT-80).\n\t\tdata = row.type !== 'delete' || Object.keys(rest).length > 0 ? rest : null\n\t}\n\n\treturn {\n\t\tid: row.id,\n\t\tnodeId: row.node_id,\n\t\ttype: row.type as Operation['type'],\n\t\tcollection: '', // Collection name is derived from the table name by the caller\n\t\trecordId: row.record_id,\n\t\tdata,\n\t\tpreviousData: row.previous_data\n\t\t\t? (JSON.parse(row.previous_data) as Record<string, unknown>)\n\t\t\t: null,\n\t\ttimestamp: HybridLogicalClock.deserialize(row.timestamp),\n\t\tsequenceNumber: row.sequence_number,\n\t\tcausalDeps: JSON.parse(row.causal_deps) as string[],\n\t\tschemaVersion: row.schema_version,\n\t\t...(atomicOps !== undefined ? { atomicOps: atomicOps as Operation['atomicOps'] } : {}),\n\t\t...(transactionId !== undefined ? { transactionId } : {}),\n\t\t...(mutationName !== undefined ? { mutationName } : {}),\n\t\t...(fieldVersions !== undefined ? { fieldVersions } : {}),\n\t\t...(hashVersion !== undefined ? { hashVersion } : {}),\n\t}\n}\n\n/**\n * Deserialize an operation row with collection name already known.\n */\nexport function deserializeOperationWithCollection(\n\trow: OperationRow,\n\tcollection: string,\n): Operation {\n\tconst op = deserializeOperation(row)\n\treturn { ...op, collection }\n}\n\n/**\n * The read form of record-shaped values the developer wrote: a richtext field written\n * as a string or ArrayBuffer is returned as the Yjs bytes it is stored (and read back)\n * as, so `insert()` / `update()` (and their transaction previews) return the same\n * value shape as `findById()` and queries. Other fields are returned as given.\n *\n * @param data - Record-shaped values (validated, at rest)\n * @param fields - The collection's field descriptors\n * @returns `data`, or a copy with richtext values in their read form\n */\nexport function toRichtextReadShape(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tlet out = data\n\tfor (const [name, descriptor] of Object.entries(fields)) {\n\t\tif (descriptor.kind !== 'richtext' || !(name in data)) continue\n\t\tconst value = data[name]\n\t\tif (value === null || value === undefined || value instanceof Uint8Array) continue\n\t\tif (out === data) out = { ...data }\n\t\tout[name] = encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t}\n\treturn out\n}\n\nfunction serializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value ? 1 : 0\n\t\tcase 'array':\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\t\treturn JSON.stringify(value)\n\t\tcase 'richtext':\n\t\t\t// May be a record-shaped value (string/bytes) or an op-data value\n\t\t\t// (tagged { $koraBytes }) — encodeRichtext accepts every form.\n\t\t\treturn encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t\tdefault:\n\t\t\t// Raw string columns: SQLite binds strings as UTF-8, which cannot hold a lone\n\t\t\t// surrogate (stored as U+FFFD) and SQLite WASM reads TEXT up to a NUL. The\n\t\t\t// shared stored-text codec keeps every JS string (RT-65); JSON columns above\n\t\t\t// need none (JSON.stringify escapes both).\n\t\t\treturn typeof value === 'string' && isRawTextKind(descriptor.kind)\n\t\t\t\t? encodeStoredText(value)\n\t\t\t\t: value\n\t}\n}\n\n/**\n * Field kinds whose column holds the raw string (the stored-text codec applies). Not\n * `enum`: its column holds the schema's literal values verbatim; an enum value SQL text\n * cannot store exactly (U+0000, U+FFFF, a lone surrogate) is refused by `t.enum()` itself\n * (the table no longer has a `CHECK`, RT-101).\n */\nconst RAW_TEXT_KINDS: ReadonlySet<string> = new Set(['string', 'secret'])\n\n/** True for a field kind stored as a raw string, encoded with the stored-text codec. */\nexport function isRawTextKind(kind: string): boolean {\n\treturn RAW_TEXT_KINDS.has(kind)\n}\n\n/**\n * Encode a filter value compared against a field's column: a raw-string field stores\n * the encoded form, and the codec is injective, so equality and `IN` stay exact.\n *\n * @param value - The value from the developer's `where`\n * @param descriptor - The field's descriptor, when the field is known\n */\nexport function encodeStoredFilterValue(\n\tvalue: unknown,\n\tdescriptor: FieldDescriptor | undefined,\n): unknown {\n\treturn typeof value === 'string' && descriptor !== undefined && isRawTextKind(descriptor.kind)\n\t\t? encodeStoredText(value)\n\t\t: value\n}\n\nfunction deserializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value === 1 || value === true\n\t\tcase 'array':\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn JSON.parse(value) as unknown[]\n\t\t\t}\n\t\t\treturn value\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn JSON.parse(value) as unknown\n\t\t\t}\n\t\t\treturn value\n\t\tcase 'richtext':\n\t\t\treturn decodeRichtext(value)\n\t\tdefault:\n\t\t\treturn typeof value === 'string' && isRawTextKind(descriptor.kind)\n\t\t\t\t? decodeStoredText(value)\n\t\t\t\t: value\n\t}\n}\n","import type { CollectionDefinition, FieldDescriptor } from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport { lwwVersionWhereClause } from '../lww/row-version'\nimport { encodeStoredFilterValue } from '../serialization/serializer'\nimport type { QueryDescriptor, WhereOperators } from '../types'\n\n/**\n * Result of building a SQL query: the parameterized SQL string and its bound values.\n */\nexport interface SqlQuery {\n\tsql: string\n\tparams: unknown[]\n}\n\n/**\n * Build a SELECT query from a QueryDescriptor.\n * Automatically adds `WHERE _deleted = 0` to exclude soft-deleted records.\n *\n * @param descriptor - The query descriptor\n * @param fields - The field descriptors from the collection schema\n * @returns A parameterized SQL query\n */\nexport function buildSelectQuery(\n\tdescriptor: QueryDescriptor,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery {\n\tconst params: unknown[] = []\n\tconst parts = [`SELECT * FROM ${quoteIdent(descriptor.collection)}`]\n\n\tconst whereClause = buildWhereClauseParts(descriptor.where, fields, params)\n\t// Always filter out soft-deleted records\n\tconst deletedFilter = '_deleted = 0'\n\tif (whereClause) {\n\t\tparts.push(`WHERE ${deletedFilter} AND ${whereClause}`)\n\t} else {\n\t\tparts.push(`WHERE ${deletedFilter}`)\n\t}\n\n\tif (descriptor.orderBy.length > 0) {\n\t\tconst orderParts = descriptor.orderBy.map((o) => {\n\t\t\tvalidateFieldName(o.field, fields)\n\t\t\t// SEC-7: the direction is whitelisted to a fixed keyword, never spliced from\n\t\t\t// the caller's string (a runtime value cast to the type is untrusted input).\n\t\t\treturn `${quoteIdent(resolveColumnName(o.field, fields))} ${sqlSortDirection(o.direction, o.field)}`\n\t\t})\n\t\tparts.push(`ORDER BY ${orderParts.join(', ')}`)\n\t}\n\n\t// SEC-7: LIMIT / OFFSET are bound as parameters after a safe-integer check, so a\n\t// value that only claims to be a number can never become SQL text.\n\tconst limit = descriptor.limit !== undefined ? assertQueryCount(descriptor.limit, 'limit') : null\n\tconst offset =\n\t\tdescriptor.offset !== undefined ? assertQueryCount(descriptor.offset, 'offset') : null\n\tif (limit !== null) {\n\t\tparts.push('LIMIT ?')\n\t\tparams.push(limit)\n\t}\n\tif (offset !== null) {\n\t\t// SQLite accepts OFFSET only after LIMIT; LIMIT -1 means \"no limit\".\n\t\tif (limit === null) parts.push('LIMIT -1')\n\t\tparts.push('OFFSET ?')\n\t\tparams.push(offset)\n\t}\n\n\treturn { sql: parts.join(' '), params }\n}\n\n/**\n * Build a COUNT query from a QueryDescriptor.\n * Automatically adds `WHERE _deleted = 0`.\n *\n * @param descriptor - The query descriptor\n * @param fields - The field descriptors from the collection schema\n * @returns A parameterized SQL query that returns { count: number }\n */\nexport function buildCountQuery(\n\tdescriptor: QueryDescriptor,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery {\n\tconst params: unknown[] = []\n\tconst parts = [`SELECT COUNT(*) as count FROM ${quoteIdent(descriptor.collection)}`]\n\n\tconst whereClause = buildWhereClauseParts(descriptor.where, fields, params)\n\tconst deletedFilter = '_deleted = 0'\n\tif (whereClause) {\n\t\tparts.push(`WHERE ${deletedFilter} AND ${whereClause}`)\n\t} else {\n\t\tparts.push(`WHERE ${deletedFilter}`)\n\t}\n\n\treturn { sql: parts.join(' '), params }\n}\n\n/**\n * Build an INSERT query for a collection record.\n *\n * @param collection - The collection name\n * @param record - The record data (already serialized with id, _created_at, _updated_at)\n * @returns A parameterized SQL query\n */\nexport function buildInsertQuery(collection: string, record: Record<string, unknown>): SqlQuery {\n\tconst columns = Object.keys(record)\n\tconst placeholders = columns.map(() => '?')\n\tconst params = Object.values(record)\n\n\tconst quotedColumns = columns.map((col) => quoteIdent(col))\n\tconst sql = `INSERT INTO ${quoteIdent(collection)} (${quotedColumns.join(', ')}) VALUES (${placeholders.join(', ')})`\n\treturn { sql, params }\n}\n\n/**\n * Build an UPDATE query for a collection record.\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param changes - The fields to update (already serialized)\n * @returns A parameterized SQL query\n */\nexport function buildUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tchanges: Record<string, unknown>,\n): SqlQuery {\n\tconst setClauses = Object.keys(changes).map((col) => `${quoteIdent(col)} = ?`)\n\tconst params = [...Object.values(changes), id]\n\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ?`\n\treturn { sql, params }\n}\n\n/**\n * Build a field-level fast-forward UPDATE: writes the changed field values\n * unconditionally (the caller has already proven per-field that the local value\n * still equals the base the remote wrote from, so the remote is the newest known\n * writer of those fields), while advancing the row's `_version` / `_updated_at`\n * watermark MONOTONICALLY — never regressing it below its current value.\n *\n * This is what makes per-field LWW correct on a per-row `_version` column: a\n * concurrent edit to a different field may have pushed `_version` past this\n * operation's timestamp, but that must not cause this operation's own field\n * change to be dropped, nor may materializing it move the watermark backward\n * (which would let a genuinely stale later operation win).\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param fieldChanges - Serialized field values to write unconditionally (must NOT include _version / _updated_at)\n * @param remoteVersion - The operation's serialized row version (lexicographically comparable)\n * @param wallTime - The operation's wall-clock time in ms\n * @param options - Optional extras. `maxCreatedAt` advances `_created_at` to the\n * greater of its current value and the given wall time — used for insert\n * collisions so every node converges on the max insert wall time regardless\n * of arrival order.\n */\nexport function buildFieldFastForwardUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tfieldChanges: Record<string, unknown>,\n\tremoteVersion: string,\n\twallTime: number,\n\toptions?: { maxCreatedAt?: number },\n): SqlQuery {\n\tconst fieldClauses = Object.keys(fieldChanges).map((col) => `${quoteIdent(col)} = ?`)\n\t// _version is a lexicographically-sortable string; _updated_at is a number.\n\t// Keep the greater of the current and incoming value for each (monotonic).\n\tconst setClauses = [\n\t\t...fieldClauses,\n\t\t'_version = CASE WHEN _version >= ? THEN _version ELSE ? END',\n\t\t'_updated_at = CASE WHEN _updated_at >= ? THEN _updated_at ELSE ? END',\n\t]\n\tconst params: unknown[] = [\n\t\t...Object.values(fieldChanges),\n\t\tremoteVersion,\n\t\tremoteVersion,\n\t\twallTime,\n\t\twallTime,\n\t]\n\tif (options?.maxCreatedAt !== undefined) {\n\t\tsetClauses.push('_created_at = CASE WHEN _created_at >= ? THEN _created_at ELSE ? END')\n\t\tparams.push(options.maxCreatedAt, options.maxCreatedAt)\n\t}\n\tparams.push(id)\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ?`\n\treturn { sql, params }\n}\n\n/**\n * Build a soft-delete query (SET _deleted = 1).\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param updatedAt - The timestamp to set on _updated_at\n * @returns A parameterized SQL query\n */\nexport function buildSoftDeleteQuery(\n\tcollection: string,\n\tid: string,\n\tupdatedAt: number,\n\tversion?: string,\n): SqlQuery {\n\tif (version !== undefined) {\n\t\treturn {\n\t\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ?`,\n\t\t\tparams: [updatedAt, version, id],\n\t\t}\n\t}\n\treturn {\n\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ? WHERE id = ?`,\n\t\tparams: [updatedAt, id],\n\t}\n}\n\n/**\n * Build an UPDATE that applies only when the row is missing or older than `remoteVersion`\n * (serialized HLC). Prevents stale remote sync from overwriting newer local materialized state.\n */\nexport function buildLwwUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tchanges: Record<string, unknown>,\n\tremoteVersion: string,\n): SqlQuery {\n\tconst setClauses = Object.keys(changes).map((col) => `${quoteIdent(col)} = ?`)\n\tconst lww = lwwVersionWhereClause(remoteVersion)\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ? AND ${lww.sql}`\n\tconst params = [...Object.values(changes), id, ...lww.params]\n\treturn { sql, params }\n}\n\n/**\n * Build a soft-delete that applies only when the row is older than `remoteVersion`.\n */\nexport function buildLwwSoftDeleteQuery(\n\tcollection: string,\n\tid: string,\n\tupdatedAt: number,\n\tversion: string,\n): SqlQuery {\n\tconst lww = lwwVersionWhereClause(version)\n\treturn {\n\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ? AND ${lww.sql}`,\n\t\tparams: [updatedAt, version, id, ...lww.params],\n\t}\n}\n\n/**\n * Build a WHERE clause from conditions, validating field names against the schema.\n *\n * @param where - The where conditions\n * @param fields - The field descriptors from the collection schema\n * @returns The SQL WHERE clause string and params, or null if no conditions\n */\nexport function buildWhereClause(\n\twhere: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery | null {\n\tconst params: unknown[] = []\n\tconst result = buildWhereClauseParts(where, fields, params)\n\tif (!result) return null\n\treturn { sql: result, params }\n}\n\n// --- Internal helpers ---\n\nconst VALID_OPERATORS = new Set(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in'])\n\nfunction buildWhereClauseParts(\n\twhere: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n\tparams: unknown[],\n): string | null {\n\tconst conditions: string[] = []\n\n\tfor (const [fieldName, value] of Object.entries(where)) {\n\t\tvalidateFieldName(fieldName, fields)\n\t\tconst descriptor = fields[fieldName]\n\t\tconst column = resolveColumnName(fieldName, fields)\n\n\t\tif (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// Operator object: { $gt: 5, $lt: 10 }\n\t\t\tconst ops = value as WhereOperators\n\t\t\tfor (const [op, opValue] of Object.entries(ops)) {\n\t\t\t\tif (!VALID_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new QueryError(`Unknown operator \"${op}\" on field \"${fieldName}\"`, {\n\t\t\t\t\t\tfield: fieldName,\n\t\t\t\t\t\toperator: op,\n\t\t\t\t\t\tvalidOperators: [...VALID_OPERATORS],\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconditions.push(buildOperatorCondition(fieldName, column, op, opValue, descriptor, params))\n\t\t\t}\n\t\t} else {\n\t\t\t// Shorthand: { completed: false } means { completed: { $eq: false } }\n\t\t\tconditions.push(buildOperatorCondition(fieldName, column, '$eq', value, descriptor, params))\n\t\t}\n\t}\n\n\tif (conditions.length === 0) return null\n\treturn conditions.join(' AND ')\n}\n\nfunction buildOperatorCondition(\n\tfieldName: string,\n\tcolumnName: string,\n\toperator: string,\n\tvalue: unknown,\n\tdescriptor: FieldDescriptor | undefined,\n\tparams: unknown[],\n): string {\n\t// Serialize boolean values to 0/1 and raw strings to their stored form (RT-65)\n\tconst sqlValue = toSqlFilterValue(value, descriptor)\n\n\tconst column = quoteIdent(columnName)\n\n\tswitch (operator) {\n\t\tcase '$eq':\n\t\t\tif (sqlValue === null) {\n\t\t\t\treturn `${column} IS NULL`\n\t\t\t}\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} = ?`\n\t\tcase '$ne':\n\t\t\tif (sqlValue === null) {\n\t\t\t\treturn `${column} IS NOT NULL`\n\t\t\t}\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} != ?`\n\t\tcase '$gt':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} > ?`\n\t\tcase '$gte':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} >= ?`\n\t\tcase '$lt':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} < ?`\n\t\tcase '$lte':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} <= ?`\n\t\tcase '$in': {\n\t\t\tif (!Array.isArray(sqlValue)) {\n\t\t\t\tthrow new QueryError(`$in operator requires an array value for field \"${fieldName}\"`, {\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\treceived: typeof sqlValue,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst placeholders = sqlValue.map(() => '?')\n\t\t\tfor (const item of sqlValue) {\n\t\t\t\tparams.push(toSqlFilterValue(item, descriptor))\n\t\t\t}\n\t\t\treturn `${column} IN (${placeholders.join(', ')})`\n\t\t}\n\t\tdefault:\n\t\t\tthrow new QueryError(`Unknown operator \"${operator}\"`, { operator })\n\t}\n}\n\nfunction toSqlFilterValue(value: unknown, descriptor: FieldDescriptor | undefined): unknown {\n\tif (descriptor?.kind === 'boolean' && typeof value === 'boolean') return value ? 1 : 0\n\treturn encodeStoredFilterValue(value, descriptor)\n}\n\n/**\n * Record metadata exposed on every record under a camelCase name and backed by a\n * system column (STORE-11): `where({ updatedAt: { $gt: t } })` and\n * `orderBy('createdAt', 'desc')` filter and sort on these columns. A schema field\n * declared with the same name wins and its own column is used instead.\n */\nexport const VIRTUAL_TIMESTAMP_FIELDS = Object.freeze({\n\tcreatedAt: '_created_at',\n\tupdatedAt: '_updated_at',\n} as const)\n\n/** Name of a virtual record-metadata field usable in `where` and `orderBy`. */\nexport type VirtualTimestampField = keyof typeof VIRTUAL_TIMESTAMP_FIELDS\n\n/** Every virtual record-metadata field name, for typing `where` / `orderBy` keys. */\nexport const VIRTUAL_TIMESTAMP_FIELD_NAMES: readonly VirtualTimestampField[] = Object.freeze([\n\t'createdAt',\n\t'updatedAt',\n] as const)\n\nconst SORT_DIRECTIONS: Readonly<Record<string, 'ASC' | 'DESC'>> = Object.freeze({\n\tasc: 'ASC',\n\tdesc: 'DESC',\n})\n\n/** Map a query field name to the column it reads (STORE-11 virtual fields). */\nfunction resolveColumnName(fieldName: string, fields: Record<string, FieldDescriptor>): string {\n\tif (Object.hasOwn(fields, fieldName)) return fieldName\n\tif (fieldName === 'createdAt' || fieldName === 'updatedAt') {\n\t\treturn VIRTUAL_TIMESTAMP_FIELDS[fieldName]\n\t}\n\treturn fieldName\n}\n\nfunction sqlSortDirection(direction: unknown, field: string): 'ASC' | 'DESC' {\n\tconst key = typeof direction === 'string' ? direction.toLowerCase() : ''\n\tconst keyword = Object.hasOwn(SORT_DIRECTIONS, key) ? SORT_DIRECTIONS[key] : undefined\n\tif (keyword === undefined) {\n\t\tthrow new QueryError(`Invalid sort direction for field \"${field}\". Use 'asc' or 'desc'.`, {\n\t\t\tfield,\n\t\t\tdirection: typeof direction === 'string' ? direction.slice(0, 64) : typeof direction,\n\t\t})\n\t}\n\treturn keyword\n}\n\nfunction assertQueryCount(value: unknown, clause: 'limit' | 'offset'): number {\n\tif (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new QueryError(\n\t\t\t`Invalid ${clause}: expected a non-negative safe integer. Pass a whole number, for example .${clause}(10).`,\n\t\t\t{ clause, received: typeof value === 'number' ? value : typeof value },\n\t\t)\n\t}\n\treturn value\n}\n\nfunction validateFieldName(fieldName: string, fields: Record<string, FieldDescriptor>): void {\n\t// Allow schema fields plus metadata fields that map to query-able columns\n\tconst allowedFields = new Set([\n\t\t...Object.keys(fields),\n\t\t'id',\n\t\t...VIRTUAL_TIMESTAMP_FIELD_NAMES,\n\t\t'_created_at',\n\t\t'_updated_at',\n\t])\n\tif (!allowedFields.has(fieldName)) {\n\t\tthrow new QueryError(\n\t\t\t`Unknown field \"${fieldName}\" in query. Available fields: ${[...allowedFields].join(', ')}`,\n\t\t\t{ field: fieldName },\n\t\t)\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { Operation } from '@korajs/core'\nimport { computeOperationId } from '@korajs/core/internal'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, Transaction } from '../types'\n\n/** Result of `Store.resequenceOperation` (RT-35 renumbering). */\nexport interface ResequenceResult {\n\t/** The renumbered operation (a version-2 one under a new id). */\n\toperation: Operation\n\t/** Never-sent dependents rewritten to name the new id (re-hashed), in sequence order. */\n\tdependents: Operation[]\n\t/** Old id -> new id, for the operation and every re-hashed dependent. */\n\tidMapping: Record<string, string>\n}\n\n/**\n * The content-addressed id of an operation whose stamp, node, sequence or causal deps\n * were rewritten locally before it was ever shared (clock rebase, node rotation,\n * SEQUENCE_CONFLICT renumbering). Uses the operation's own hash version: a version-2\n * operation (protocol v2) gets a version-2 id over all its semantic fields, and a\n * version-1 operation (written before beta.13) keeps the version-1 hash, so neither\n * fails id verification on its receivers.\n *\n * @param op - The operation with its new content (its `id` is ignored)\n * @returns The id matching that content under the operation's hash version\n */\nexport async function rehashOperation(op: Operation): Promise<string> {\n\treturn computeOperationId(\n\t\t{\n\t\t\tnodeId: op.nodeId,\n\t\t\ttype: op.type,\n\t\t\tcollection: op.collection,\n\t\t\trecordId: op.recordId,\n\t\t\tdata: op.data,\n\t\t\tpreviousData: op.previousData,\n\t\t\ttimestamp: op.timestamp,\n\t\t\tsequenceNumber: op.sequenceNumber,\n\t\t\tcausalDeps: op.causalDeps,\n\t\t\tschemaVersion: op.schemaVersion,\n\t\t\t...(op.atomicOps !== undefined ? { atomicOps: op.atomicOps } : {}),\n\t\t},\n\t\top.hashVersion === 2 ? 2 : 1,\n\t)\n}\n\n/**\n * Give a logged operation row a new sequence number inside `tx` (SEQUENCE_CONFLICT\n * recovery, RT-35; legacy duplicate repair, W6). A version-1 operation keeps its id:\n * its hash never covered the sequence number. A version-2 operation's id does cover it\n * (CORE-1), so it is re-hashed and its row replaced under the new id; it was never\n * stored by the server (that is why it is renumbered), so no replica knows the old id.\n *\n * @returns The operation as it is now logged\n */\nexport async function renumberOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\tsequenceNumber: number,\n): Promise<Operation> {\n\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\tconst current = deserializeOperationWithCollection(row, collection)\n\tconst renumbered: Operation = { ...current, sequenceNumber }\n\tif (current.hashVersion !== 2) {\n\t\tawait tx.execute(`UPDATE ${table} SET sequence_number = ? WHERE id = ?`, [\n\t\t\tsequenceNumber,\n\t\t\trow.id,\n\t\t])\n\t\treturn renumbered\n\t}\n\tconst id = await rehashOperation(renumbered)\n\tconst moved: Operation = { ...renumbered, id }\n\tawait replaceOperationRow(tx, collection, row.id, moved)\n\treturn moved\n}\n\nasync function replaceOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\toldId: string,\n\tnext: Operation,\n): Promise<void> {\n\tawait tx.execute(`DELETE FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`, [oldId])\n\tconst insert = buildInsertQuery(\n\t\t`_kora_ops_${collection}`,\n\t\tserializeOperation(next) as unknown as Record<string, unknown>,\n\t)\n\tawait tx.execute(insert.sql, insert.params)\n}\n\n/**\n * After operations were re-hashed under new ids (`idMapping`, old id -> new id), make\n * the local operations that name an old id in `causalDeps` name the new one, inside\n * `tx`. Only operations in `rewritable` are touched: those the server never stored\n * (never sent). Each rewritten operation covers its causalDeps in its id (version 2),\n * so it is re-hashed too and its own dependents follow, transitively, in sequence\n * order (sequence order is authoring order, so a dependency is always rewritten before\n * its dependents). A version-1 operation keeps its id (its hash does not cover\n * causalDeps) but still gets the new dep. `idMapping` is extended in place.\n *\n * An operation outside `rewritable` (already sent: the server may hold it under its\n * id) is never rewritten; its dep on an old id resolves through `_kora_seq_conflicts`\n * (`reemitted_as`) on this device.\n *\n * @returns The rewritten operations, in sequence order\n */\nexport async function rewriteDependentsInTx(\n\ttx: Transaction,\n\tcollections: readonly string[],\n\tnodeId: string,\n\tidMapping: Record<string, string>,\n\trewritable: ReadonlySet<string>,\n): Promise<Operation[]> {\n\tif (rewritable.size === 0) return []\n\tconst candidates: Array<{ collection: string; row: OperationRow; op: Operation }> = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tif (!rewritable.has(row.id)) continue\n\t\t\tcandidates.push({ collection, row, op: deserializeOperationWithCollection(row, collection) })\n\t\t}\n\t}\n\tcandidates.sort((a, b) => a.op.sequenceNumber - b.op.sequenceNumber)\n\tconst rewritten: Operation[] = []\n\tfor (const { collection, row, op } of candidates) {\n\t\tif (!op.causalDeps.some((dep) => idMapping[dep] !== undefined)) continue\n\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\tconst updated: Operation = { ...op, causalDeps }\n\t\tconst id = op.hashVersion === 2 ? await rehashOperation(updated) : op.id\n\t\tconst next: Operation = { ...updated, id }\n\t\tawait replaceOperationRow(tx, collection, row.id, next)\n\t\tif (id !== op.id) idMapping[op.id] = id\n\t\trewritten.push(next)\n\t}\n\treturn rewritten\n}\n","import type { StorageAdapter, Transaction } from '../types'\n\ninterface SequenceRow {\n\tsequence_number: number\n}\n\n/**\n * Reserve the next sequence number for a node inside a write transaction\n * (UPSERT ... RETURNING on `_kora_version_vector`).\n *\n * This is the ONLY way a local operation gets its number: the reservation\n * commits or rolls back with the operation that uses it, and transactions are\n * serialized, so the numbers of one commit are contiguous and never shared. There\n * is deliberately no variant that allocates outside a transaction (W6).\n */\nexport async function allocateNextSequenceInTransaction(\n\ttx: Transaction,\n\tnodeId: string,\n): Promise<number> {\n\tconst rows = await tx.query<SequenceRow>(\n\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, 1)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = sequence_number + 1\n RETURNING sequence_number`,\n\t\t[nodeId],\n\t)\n\tconst seq = rows[0]?.sequence_number\n\tif (seq === undefined) {\n\t\tthrow new Error(`Failed to allocate sequence number for node \"${nodeId}\" in transaction`)\n\t}\n\treturn seq\n}\n\n/**\n * Read the current sequence for a node without incrementing.\n */\nexport async function readSequenceNumber(adapter: StorageAdapter, nodeId: string): Promise<number> {\n\tconst rows = await adapter.query<SequenceRow>(\n\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t[nodeId],\n\t)\n\treturn rows[0]?.sequence_number ?? 0\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport { renumberOperationRow } from '../sync/rehash-operation'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport { allocateNextSequenceInTransaction } from './sequence-allocator'\n\n/**\n * Audit table for operation rows whose `(node_id, sequence_number)` identity\n * collided with another operation (STORE-1 / STORE-2 duplicates written by\n * beta.12, or a conflicting remote operation). Rows here are never deleted.\n *\n * - `reemitted_as` set: the operation was given a fresh sequence number and still\n * lives in the operation log under that number (`new_sequence_number`).\n * - `reemitted_as` NULL: the operation is kept ONLY here (another node's\n * operation whose number this log already holds). It still takes part in\n * dedup and in record folds, so no data is lost.\n */\nexport const SEQ_CONFLICTS_TABLE = '_kora_seq_conflicts'\n\nconst REPAIR_DONE_META_KEY = 'seq_unique_repair_v1'\n\n/** DDL for {@link SEQ_CONFLICTS_TABLE}. */\nconst CREATE_SEQ_CONFLICTS_SQL = `CREATE TABLE IF NOT EXISTS ${SEQ_CONFLICTS_TABLE} (\n id TEXT PRIMARY KEY NOT NULL,\n collection TEXT NOT NULL,\n node_id TEXT NOT NULL,\n type TEXT NOT NULL,\n record_id TEXT NOT NULL,\n data TEXT,\n previous_data TEXT,\n timestamp TEXT NOT NULL,\n sequence_number INTEGER NOT NULL,\n causal_deps TEXT NOT NULL,\n schema_version INTEGER NOT NULL,\n reason TEXT NOT NULL,\n reemitted_as TEXT,\n new_sequence_number INTEGER,\n recorded_at INTEGER NOT NULL\n)`\n\n/** Name of the unique `(node_id, sequence_number)` index on a collection's op log. */\nexport function uniqueSequenceIndexName(collection: string): string {\n\treturn `uidx_kora_ops_${collection.length}_${collection}_node_seq`\n}\n\n/** Outcome of {@link repairSequenceUniqueness}. */\nexport interface SequenceRepairResult {\n\t/** Own-node operations that were given a fresh sequence number. */\n\tresequenced: number\n\t/** Other nodes' operations moved out of the log into the conflicts table. */\n\tretained: number\n}\n\n/**\n * Make `(node_id, sequence_number)` unique in the local operation log, then\n * enforce it with a UNIQUE index on every operation table (W6 step 2).\n *\n * beta.12 could give two different operations of this device the same sequence\n * number (STORE-1/2). A plain UNIQUE index cannot be created over such a log, and\n * dropping either row would lose a write. The repair, in one transaction:\n *\n * 1. Raises this node's persisted counter to at least the highest sequence number\n * in its log (beta.12 could leave it behind, which would make the next write\n * collide).\n * 2. For every duplicated `(node, seq)` — across all collections, since one node\n * numbers all its operations in one sequence — keeps the first row by id.\n * 3. Every other row of THIS node is re-emitted with a fresh sequence number from\n * the counter, keeping its id and content (see the note below), and recorded\n * in {@link SEQ_CONFLICTS_TABLE}.\n * 4. Rows of OTHER nodes (this device cannot number them) move to\n * {@link SEQ_CONFLICTS_TABLE} with `reemitted_as` NULL; the store keeps using\n * them for dedup and record folds.\n * 5. Creates the UNIQUE index on every operation table.\n *\n * Why the re-emitted operation keeps its id: protocol v1 content-addresses\n * operations without the sequence number, and changing any hashed content (data\n * or HLC timestamp) would change what the write means under last-write-wins.\n * With the id kept, a server that already stored the operation deduplicates it\n * (acknowledging the new number), and a server that never got it — beta.12 could\n * skip the second of two same-numbered operations — stores it. Either way atomic\n * increments are never applied twice and no write is lost.\n *\n * Idempotent: the scan runs once per database (a meta flag records completion);\n * the index creation runs on every open so collections added later are covered.\n *\n * @param adapter - The store's adapter (already opened)\n * @param schema - The schema whose operation tables are repaired\n * @param nodeId - This device's node id\n */\nexport async function repairSequenceUniqueness(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\tawait adapter.execute(CREATE_SEQ_CONFLICTS_SQL)\n\tconst collections = Object.keys(schema.collections)\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\n\tconst done = await adapter.query<{ value: string }>(\n\t\t'SELECT value FROM _kora_meta WHERE key = ?',\n\t\t[REPAIR_DONE_META_KEY],\n\t)\n\tif (done.length === 0 && collections.length > 0) {\n\t\tawait runRepair(adapter, collections, nodeId, result)\n\t}\n\n\tfor (const collection of collections) {\n\t\tconst createIndex = `CREATE UNIQUE INDEX IF NOT EXISTS ${quoteIdent(uniqueSequenceIndexName(collection))} ON ${quoteIdent(`_kora_ops_${collection}`)} (node_id, sequence_number)`\n\t\ttry {\n\t\t\tawait adapter.execute(createIndex)\n\t\t} catch (error) {\n\t\t\t// Duplicates written after an earlier repair (for example by an older\n\t\t\t// Kora version opening this database again): repair once more, then\n\t\t\t// create the index. A second failure propagates.\n\t\t\tif (!/UNIQUE/i.test(error instanceof Error ? error.message : String(error))) throw error\n\t\t\tawait runRepair(adapter, collections, nodeId, result)\n\t\t\tawait adapter.execute(createIndex)\n\t\t}\n\t}\n\treturn result\n}\n\nasync function runRepair(\n\tadapter: StorageAdapter,\n\tcollections: string[],\n\tnodeId: string,\n\tresult: SequenceRepairResult,\n): Promise<void> {\n\tlet resequenced = 0\n\tlet retained = 0\n\tawait adapter.transaction(async (tx) => {\n\t\tawait raiseOwnCounterToLog(tx, collections, nodeId)\n\t\tconst repaired = await repairDuplicates(tx, collections, nodeId)\n\t\tresequenced = repaired.resequenced\n\t\tretained = repaired.retained\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tREPAIR_DONE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\tresult.resequenced += resequenced\n\tresult.retained += retained\n\tif (resequenced > 0 || retained > 0) {\n\t\tconsole.warn(\n\t\t\t`[kora] Repaired ${resequenced + retained} operation(s) that shared a sequence number (written by an earlier Kora version). ${resequenced} were given fresh sequence numbers; ${retained} from other devices were kept in ${SEQ_CONFLICTS_TABLE}. No data was removed.`,\n\t\t)\n\t}\n}\n\nasync function raiseOwnCounterToLog(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<void> {\n\tlet maxSeq = 0\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ max_seq: number | null }>(\n\t\t\t`SELECT MAX(sequence_number) AS max_seq FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tmaxSeq = Math.max(maxSeq, rows[0]?.max_seq ?? 0)\n\t}\n\tif (maxSeq > 0) {\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t[nodeId, maxSeq],\n\t\t)\n\t}\n}\n\ninterface LoggedIdentity {\n\tcollection: string\n\tid: string\n\tnode_id: string\n\tsequence_number: number\n}\n\nasync function repairDuplicates(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\t// One node numbers all its operations in one sequence, so duplicates are\n\t// found across every collection's table, not per table.\n\tconst all: LoggedIdentity[] = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<Omit<LoggedIdentity, 'collection'>>(\n\t\t\t`SELECT id, node_id, sequence_number FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t)\n\t\tfor (const row of rows) all.push({ collection, ...row })\n\t}\n\tconst groups = new Map<string, LoggedIdentity[]>()\n\tfor (const row of all) {\n\t\tconst key = `${row.node_id}\\u0000${row.sequence_number}`\n\t\tconst group = groups.get(key)\n\t\tif (group) group.push(row)\n\t\telse groups.set(key, [row])\n\t}\n\n\tconst losers: LoggedIdentity[] = []\n\tfor (const group of groups.values()) {\n\t\tif (group.length < 2) continue\n\t\t// A version-2 operation (beta.13+) keeps its place: renumbering would re-hash it\n\t\t// under a new id, and if the server already stored it under the old id the new\n\t\t// copy would be stored as a second write (an atomic increment applied twice). A\n\t\t// version-1 loser keeps its id, which the server deduplicates (RT-31). Ties by id.\n\t\tconst version2 = new Set<string>()\n\t\tfor (const member of group) {\n\t\t\tif (await isVersion2Row(tx, member)) version2.add(member.id)\n\t\t}\n\t\tgroup.sort((a, b) => {\n\t\t\tconst va = version2.has(a.id) ? 0 : 1\n\t\t\tconst vb = version2.has(b.id) ? 0 : 1\n\t\t\tif (va !== vb) return va - vb\n\t\t\treturn a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n\t\t})\n\t\tlosers.push(...group.slice(1))\n\t}\n\t// Re-emit in original order so the new numbers keep the authoring order.\n\tlosers.sort((a, b) =>\n\t\ta.sequence_number !== b.sequence_number\n\t\t\t? a.sequence_number - b.sequence_number\n\t\t\t: a.id < b.id\n\t\t\t\t? -1\n\t\t\t\t: a.id > b.id\n\t\t\t\t\t? 1\n\t\t\t\t\t: 0,\n\t)\n\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\tconst now = Date.now()\n\tfor (const loser of losers) {\n\t\tconst table = quoteIdent(`_kora_ops_${loser.collection}`)\n\t\tconst rows = await tx.query<OperationRow>(`SELECT * FROM ${table} WHERE id = ?`, [loser.id])\n\t\tconst row = rows[0]\n\t\tif (!row) continue\n\t\tif (loser.node_id === nodeId) {\n\t\t\tconst newSeq = await allocateNextSequenceInTransaction(tx, nodeId)\n\t\t\tconst moved = await renumberOperationRow(tx, loser.collection, row, newSeq)\n\t\t\tawait insertConflictRow(\n\t\t\t\ttx,\n\t\t\t\tloser.collection,\n\t\t\t\trow,\n\t\t\t\t'duplicate-sequence',\n\t\t\t\tmoved.id,\n\t\t\t\tnewSeq,\n\t\t\t\tnow,\n\t\t\t)\n\t\t\tresult.resequenced++\n\t\t} else {\n\t\t\tawait insertConflictRow(tx, loser.collection, row, 'duplicate-sequence', null, null, now)\n\t\t\tawait tx.execute(`DELETE FROM ${table} WHERE id = ?`, [loser.id])\n\t\t\tresult.retained++\n\t\t}\n\t}\n\treturn result\n}\n\n/** Whether a logged operation declares content-hash version 2. */\nasync function isVersion2Row(tx: Transaction, identity: LoggedIdentity): Promise<boolean> {\n\tconst rows = await tx.query<OperationRow>(\n\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${identity.collection}`)} WHERE id = ?`,\n\t\t[identity.id],\n\t)\n\tconst row = rows[0]\n\tif (!row) return false\n\treturn deserializeOperationWithCollection(row, identity.collection).hashVersion === 2\n}\n\n/**\n * Record an operation row in {@link SEQ_CONFLICTS_TABLE}.\n *\n * @param reemittedAs - Id of the operation that carries it in the log, or null\n * when the row is kept only in the conflicts table\n * @param newSequenceNumber - The sequence number it was re-emitted under\n */\nexport async function insertConflictRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\treason: string,\n\treemittedAs: string | null,\n\tnewSequenceNumber: number | null,\n\trecordedAt: number,\n): Promise<void> {\n\tawait tx.execute(\n\t\t`INSERT OR IGNORE INTO ${SEQ_CONFLICTS_TABLE} (id, collection, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version, reason, reemitted_as, new_sequence_number, recorded_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\trow.id,\n\t\t\tcollection,\n\t\t\trow.node_id,\n\t\t\trow.type,\n\t\t\trow.record_id,\n\t\t\trow.data,\n\t\t\trow.previous_data,\n\t\t\trow.timestamp,\n\t\t\trow.sequence_number,\n\t\t\trow.causal_deps,\n\t\t\trow.schema_version,\n\t\t\treason,\n\t\t\treemittedAs,\n\t\t\tnewSequenceNumber,\n\t\t\trecordedAt,\n\t\t],\n\t)\n}\n\n/**\n * Operation rows kept only in the conflicts table for a record (other nodes'\n * operations whose sequence number collided). Record folds include them.\n */\nexport async function loadRetainedConflictRows(\n\tquery: <T>(sql: string, params?: unknown[]) => Promise<T[]>,\n\tcollection: string,\n\trecordId: string,\n\ttypes?: readonly string[],\n): Promise<OperationRow[]> {\n\tconst typeFilter =\n\t\ttypes && types.length > 0 ? ` AND type IN (${types.map(() => '?').join(', ')})` : ''\n\treturn query<OperationRow>(\n\t\t`SELECT id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND record_id = ? AND reemitted_as IS NULL${typeFilter}`,\n\t\t[collection, recordId, ...(types ?? [])],\n\t)\n}\n\n/** Whether an operation id is already recorded (log or retained conflict). */\nexport async function isOperationLogged(\n\ttx: Transaction,\n\tcollection: string,\n\topId: string,\n): Promise<boolean> {\n\tconst inLog = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`,\n\t\t[opId],\n\t)\n\tif (inLog.length > 0) return true\n\tconst retained = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${SEQ_CONFLICTS_TABLE} WHERE id = ? AND reemitted_as IS NULL`,\n\t\t[opId],\n\t)\n\treturn retained.length > 0\n}\n","import type { Operation, VersionVector } from '@korajs/core'\nimport { createVersionVector } from '@korajs/core'\nimport type { MetaRow, StorageAdapter } from '../types'\n\nexport const LAST_ACKED_SERVER_VECTOR_META_KEY = 'last_acked_server_vector'\nexport const DELTA_CURSOR_META_KEY = 'delta_cursor'\nexport const DELIVERY_WATERMARK_META_KEY = 'delivery_watermark'\nexport const NODE_TOKEN_META_KEY = 'sync_node_token'\nexport const AUTHORITATIVE_NODE_IDS_META_KEY = 'sync_authoritative_node_ids'\n\n/**\n * Serialize a version vector for `_kora_meta` storage.\n */\nexport function serializeVersionVectorToMeta(vector: VersionVector): string {\n\tconst record: Record<string, number> = {}\n\tfor (const [nodeId, seq] of vector) {\n\t\trecord[nodeId] = seq\n\t}\n\treturn JSON.stringify(record)\n}\n\n/**\n * Deserialize a version vector from `_kora_meta`.\n */\nexport function deserializeVersionVectorFromMeta(value: string): VersionVector {\n\tconst parsed = JSON.parse(value) as Record<string, number>\n\tconst vector = createVersionVector()\n\tfor (const [nodeId, seq] of Object.entries(parsed)) {\n\t\tif (typeof seq === 'number' && seq >= 0) {\n\t\t\tvector.set(nodeId, seq)\n\t\t}\n\t}\n\treturn vector\n}\n\n/**\n * Merge two version vectors, keeping the maximum sequence per node.\n */\nexport function mergeVersionVectors(a: VersionVector, b: VersionVector): VersionVector {\n\tconst merged = new Map(a)\n\tfor (const [nodeId, seq] of b) {\n\t\tmerged.set(nodeId, Math.max(merged.get(nodeId) ?? 0, seq))\n\t}\n\treturn merged\n}\n\n/**\n * Operations present locally but not yet on the server (per server version vector).\n */\nexport async function collectOperationsAheadOfServer(\n\tlocalVector: VersionVector,\n\tserverVector: VersionVector,\n\tfetchRange: (nodeId: string, fromSeq: number, toSeq: number) => Promise<Operation[]>,\n): Promise<Operation[]> {\n\tconst missing: Operation[] = []\n\tfor (const [nodeId, localSeq] of localVector) {\n\t\tconst serverSeq = serverVector.get(nodeId) ?? 0\n\t\tif (localSeq > serverSeq) {\n\t\t\tconst ops = await fetchRange(nodeId, serverSeq + 1, localSeq)\n\t\t\tmissing.push(...ops)\n\t\t}\n\t}\n\tmissing.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\treturn missing\n}\n\n/**\n * Load persisted last-acked server vector from `_kora_meta`.\n */\nexport async function loadLastAckedServerVector(adapter: StorageAdapter): Promise<VersionVector> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\t])\n\tconst row = rows[0]\n\tif (!row?.value) {\n\t\treturn createVersionVector()\n\t}\n\ttry {\n\t\treturn deserializeVersionVectorFromMeta(row.value)\n\t} catch {\n\t\treturn createVersionVector()\n\t}\n}\n\n/**\n * Persist the last-acked server version vector to `_kora_meta`.\n */\nexport async function saveLastAckedServerVector(\n\tadapter: StorageAdapter,\n\tvector: VersionVector,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\t\tserializeVersionVectorToMeta(vector),\n\t])\n}\n\n/**\n * Load the per-device node token the sync server issued for this node id (RT-12).\n */\nexport async function loadNodeToken(\n\tadapter: StorageAdapter,\n\tnodeId?: string,\n): Promise<string | null> {\n\tif (nodeId !== undefined) {\n\t\tconst own = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tnodeTokenKey(nodeId),\n\t\t])\n\t\tif (own[0]) return own[0].value\n\t\t// The legacy single key belongs to the database's node id (`_kora_meta.node_id`).\n\t\tconst meta = await adapter.query<MetaRow>(\"SELECT value FROM _kora_meta WHERE key = 'node_id'\")\n\t\tif (meta[0]?.value !== nodeId) return null\n\t}\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tNODE_TOKEN_META_KEY,\n\t])\n\treturn rows[0]?.value ?? null\n}\n\n/** `_kora_meta` key of one node id's token (RT-38/RT-40: a database may use several). */\nexport function nodeTokenKey(nodeId: string): string {\n\treturn `${NODE_TOKEN_META_KEY}:${nodeId}`\n}\n\n/**\n * Persist the per-device node token next to the node id in `_kora_meta`. With a node\n * id, the token is stored under that node's own key: a database that uses several node\n * ids (a rotated identity, per-tab isolation) keeps each node's token.\n */\nexport async function saveNodeToken(\n\tadapter: StorageAdapter,\n\ttoken: string,\n\tnodeId?: string,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tnodeId === undefined ? NODE_TOKEN_META_KEY : nodeTokenKey(nodeId),\n\t\ttoken,\n\t])\n}\n\n/**\n * Load a persisted delta cursor for resuming paginated initial sync.\n */\nexport async function loadDeltaCursor(adapter: StorageAdapter): Promise<string | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tDELTA_CURSOR_META_KEY,\n\t])\n\treturn rows[0]?.value ?? null\n}\n\n/**\n * Persist or clear the delta cursor in `_kora_meta`.\n */\nexport async function saveDeltaCursor(\n\tadapter: StorageAdapter,\n\tcursor: string | null,\n): Promise<void> {\n\tif (cursor === null) {\n\t\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\t\treturn\n\t}\n\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tDELTA_CURSOR_META_KEY,\n\t\tcursor,\n\t])\n}\n\n/**\n * The `_kora_meta` key for a view's delivery watermark. The default (empty) signature\n * uses the bare key for backward compatibility; other views suffix the signature.\n */\nexport function deliveryWatermarkKey(signature: string): string {\n\treturn signature === ''\n\t\t? DELIVERY_WATERMARK_META_KEY\n\t\t: `${DELIVERY_WATERMARK_META_KEY}:${signature}`\n}\n\n/**\n * Load the persisted delivery watermark for a view signature (0 when none recorded).\n */\nexport async function loadDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tdeliveryWatermarkKey(signature),\n\t])\n\tconst value = rows[0]?.value\n\tif (value === undefined || value === null) {\n\t\treturn 0\n\t}\n\tconst parsed = Number(value)\n\treturn Number.isFinite(parsed) && parsed >= 0 ? parsed : 0\n}\n\n/**\n * Persist the delivery watermark for a view signature in `_kora_meta`.\n */\nexport async function saveDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n\twatermark: number,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tdeliveryWatermarkKey(signature),\n\t\tString(watermark),\n\t])\n}\n\n/**\n * Delete a persisted view watermark. Dropping a watermark is always safe: the view simply\n * back-fills from 0 (deduplicated) the next time it is visited. This bounds the number of\n * `_kora_meta` rows an app that churns through many distinct views can accumulate.\n */\nexport async function deleteDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n): Promise<void> {\n\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [deliveryWatermarkKey(signature)])\n}\n\n/**\n * Load every persisted view watermark, keyed by signature (the default view is '').\n */\nexport async function loadAllDeliveryWatermarks(\n\tadapter: StorageAdapter,\n): Promise<Record<string, number>> {\n\tconst rows = await adapter.query<MetaRow & { key: string }>(\n\t\t'SELECT key, value FROM _kora_meta WHERE key = ? OR key LIKE ?',\n\t\t[DELIVERY_WATERMARK_META_KEY, `${DELIVERY_WATERMARK_META_KEY}:%`],\n\t)\n\tconst result: Record<string, number> = {}\n\tconst prefix = `${DELIVERY_WATERMARK_META_KEY}:`\n\tfor (const row of rows) {\n\t\tconst signature = row.key === DELIVERY_WATERMARK_META_KEY ? '' : row.key.slice(prefix.length)\n\t\tconst parsed = Number(row.value)\n\t\tif (Number.isFinite(parsed) && parsed >= 0) {\n\t\t\tresult[signature] = parsed\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Persist the node ids the sync server named authoritative (protocol v2): their\n * operations are server-authored. Stored as a JSON array in `_kora_meta`.\n */\nexport async function saveAuthoritativeNodeIds(\n\tadapter: StorageAdapter,\n\tnodeIds: string[],\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tAUTHORITATIVE_NODE_IDS_META_KEY,\n\t\tJSON.stringify(nodeIds),\n\t])\n}\n\n/** `_kora_meta` key of the explicit authoritative ids a server revoked (RT-81). */\nconst REVOKED_AUTHORITATIVE_NODE_IDS_META_KEY = 'sync_revoked_authoritative_node_ids'\n\n/**\n * Persist the explicit authoritative node ids a sync server revoked (RT-81). A revoked\n * id is never authoritative again on this device, whatever a later handshake lists.\n */\nexport async function saveRevokedAuthoritativeNodeIds(\n\tadapter: StorageAdapter,\n\tnodeIds: string[],\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tREVOKED_AUTHORITATIVE_NODE_IDS_META_KEY,\n\t\tJSON.stringify(nodeIds),\n\t])\n}\n\n/** Load the persisted revoked authoritative node ids (empty when none, or unreadable). */\nexport async function loadRevokedAuthoritativeNodeIds(adapter: StorageAdapter): Promise<string[]> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tREVOKED_AUTHORITATIVE_NODE_IDS_META_KEY,\n\t])\n\tconst raw = rows[0]?.value\n\tif (raw === undefined) return []\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw)\n\t\tif (Array.isArray(parsed)) return parsed.filter((id): id is string => typeof id === 'string')\n\t} catch {\n\t\t// Unreadable: no revocation known; the next handshake that carries one rewrites it.\n\t}\n\treturn []\n}\n\n/**\n * Load the persisted authoritative node ids, or null when no protocol-2 server ever\n * answered (or the stored value is unreadable).\n */\nexport async function loadAuthoritativeNodeIds(adapter: StorageAdapter): Promise<string[] | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tAUTHORITATIVE_NODE_IDS_META_KEY,\n\t])\n\tconst raw = rows[0]?.value\n\tif (raw === undefined) return null\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw)\n\t\tif (Array.isArray(parsed) && parsed.every((id) => typeof id === 'string')) {\n\t\t\treturn parsed as string[]\n\t\t}\n\t} catch {\n\t\t// Unreadable: treated as never received; the next handshake rewrites it.\n\t}\n\treturn null\n}\n","import type { Operation } from '@korajs/core'\nimport type { MetaRow, StorageAdapter } from '../types'\nimport { deliveryWatermarkKey } from './sync-state'\n\n/** `_kora_meta` key of this device's contiguous acknowledged own-operation prefix (W3). */\nexport const OWN_ACKED_THROUGH_META_KEY = 'own_acked_through'\n/** `_kora_meta` key of the downlink scope the sync server last accepted (SYNC-11). */\nexport const ACCEPTED_DOWNLINK_SCOPE_META_KEY = 'accepted_downlink_scope'\n\n/**\n * Durable inbound quarantine (W4): delivered operations the client deliberately did not\n * apply, kept so they are never silently lost and can be replayed. Created on first use\n * so existing databases need no migration.\n */\nconst UNAPPLIED_OPS_DDL =\n\t'CREATE TABLE IF NOT EXISTS _kora_unapplied_ops (\\n' +\n\t' op_id TEXT PRIMARY KEY NOT NULL,\\n' +\n\t' collection TEXT NOT NULL,\\n' +\n\t' delivery_seq INTEGER,\\n' +\n\t' code TEXT NOT NULL,\\n' +\n\t' message TEXT NOT NULL,\\n' +\n\t' payload TEXT NOT NULL,\\n' +\n\t' quarantined_at INTEGER NOT NULL\\n' +\n\t')'\n\n/** A delivered operation the client did not apply, as stored in `_kora_unapplied_ops`. */\nexport interface UnappliedOperation {\n\t/** The operation as delivered (still encrypted when decryption failed). */\n\toperation: Operation\n\t/** Delivery sequence of the batch that carried it, or null for a legacy batch. */\n\tdeliverySequence: number | null\n\t/** Machine-readable reason. */\n\tcode: string\n\t/** Human-readable explanation. */\n\tmessage: string\n\t/** Wall-clock time (ms) it was quarantined. Display only. */\n\tquarantinedAt: number\n}\n\ninterface UnappliedRow {\n\top_id: string\n\tdelivery_seq: number | null\n\tcode: string\n\tmessage: string\n\tpayload: string\n\tquarantined_at: number\n}\n\nconst ensuredAdapters = new WeakSet<StorageAdapter>()\n\nasync function ensureUnappliedTable(adapter: StorageAdapter): Promise<void> {\n\tif (ensuredAdapters.has(adapter)) return\n\tawait adapter.execute(UNAPPLIED_OPS_DDL)\n\tensuredAdapters.add(adapter)\n}\n\n/**\n * Record quarantined operations and, when given, advance a view's delivery watermark in\n * the SAME transaction, so the watermark can never pass an operation that is neither\n * applied nor recorded here (the W4 invariant).\n */\nexport async function saveUnappliedOperations(\n\tadapter: StorageAdapter,\n\tentries: UnappliedOperation[],\n\twatermark?: { signature: string; watermark: number },\n): Promise<void> {\n\tawait ensureUnappliedTable(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of entries) {\n\t\t\tawait tx.execute(\n\t\t\t\t'INSERT OR REPLACE INTO _kora_unapplied_ops (op_id, collection, delivery_seq, code, message, payload, quarantined_at) VALUES (?, ?, ?, ?, ?, ?, ?)',\n\t\t\t\t[\n\t\t\t\t\tentry.operation.id,\n\t\t\t\t\tentry.operation.collection,\n\t\t\t\t\tentry.deliverySequence,\n\t\t\t\t\tentry.code,\n\t\t\t\t\tentry.message,\n\t\t\t\t\tJSON.stringify(entry.operation),\n\t\t\t\t\tentry.quarantinedAt,\n\t\t\t\t],\n\t\t\t)\n\t\t}\n\t\tif (watermark) {\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tdeliveryWatermarkKey(watermark.signature),\n\t\t\t\tString(watermark.watermark),\n\t\t\t])\n\t\t}\n\t})\n}\n\n/** Every quarantined operation, oldest delivery first. */\nexport async function loadUnappliedOperations(\n\tadapter: StorageAdapter,\n): Promise<UnappliedOperation[]> {\n\tawait ensureUnappliedTable(adapter)\n\tconst rows = await adapter.query<UnappliedRow>(\n\t\t'SELECT op_id, delivery_seq, code, message, payload, quarantined_at FROM _kora_unapplied_ops ORDER BY delivery_seq ASC, quarantined_at ASC',\n\t)\n\treturn rows.map((row) => ({\n\t\toperation: JSON.parse(row.payload) as Operation,\n\t\tdeliverySequence: row.delivery_seq === null ? null : Number(row.delivery_seq),\n\t\tcode: row.code,\n\t\tmessage: row.message,\n\t\tquarantinedAt: Number(row.quarantined_at),\n\t}))\n}\n\n/** Remove quarantined operations by operation id (applied on replay, or reconciled). */\nexport async function removeUnappliedOperations(\n\tadapter: StorageAdapter,\n\toperationIds: string[],\n): Promise<void> {\n\tif (operationIds.length === 0) return\n\tawait ensureUnappliedTable(adapter)\n\tconst placeholders = operationIds.map(() => '?').join(', ')\n\tawait adapter.execute(\n\t\t`DELETE FROM _kora_unapplied_ops WHERE op_id IN (${placeholders})`,\n\t\toperationIds,\n\t)\n}\n\n/** `_kora_meta` key of a node's prefix when the legacy single key holds another node's. */\nexport function ownAckedThroughKey(nodeId: string): string {\n\treturn `${OWN_ACKED_THROUGH_META_KEY}:${nodeId}`\n}\n\nfunction parseLegacyPrefix(value: string | undefined): { nodeId: string; sequence: number } | null {\n\tif (value === undefined || value === null) return null\n\ttry {\n\t\tconst parsed = JSON.parse(value) as { nodeId?: unknown; sequence?: unknown }\n\t\tif (typeof parsed.nodeId !== 'string') return null\n\t\tconst sequence =\n\t\t\ttypeof parsed.sequence === 'number' && parsed.sequence >= 0 ? parsed.sequence : null\n\t\treturn sequence === null ? null : { nodeId: parsed.nodeId, sequence }\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/**\n * Load the acknowledged own-operation prefix for a node id. Null when none was ever\n * recorded for this node (an upgrade from a release that persisted a max instead).\n *\n * The first node a database tracks keeps the single legacy key (`own_acked_through`, as\n * earlier releases wrote it); any other local node (a rotated node, another tab's node\n * under per-tab isolation, RT-40) has its own key, so tracking one node never erases\n * another node's prefix.\n */\nexport async function loadOwnAckedThrough(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n): Promise<number | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tOWN_ACKED_THROUGH_META_KEY,\n\t])\n\tconst legacy = parseLegacyPrefix(rows[0]?.value)\n\tif (legacy && legacy.nodeId === nodeId) return legacy.sequence\n\tconst own = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\townAckedThroughKey(nodeId),\n\t])\n\tconst value = own[0]?.value\n\tif (value === undefined || value === null) return null\n\tconst sequence = Number(value)\n\treturn Number.isInteger(sequence) && sequence >= 0 ? sequence : null\n}\n\n/** Persist the acknowledged own-operation prefix for a node id. */\nexport async function saveOwnAckedThrough(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tsequence: number,\n): Promise<void> {\n\tawait adapter.transaction(async (tx) => {\n\t\tconst rows = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tOWN_ACKED_THROUGH_META_KEY,\n\t\t])\n\t\tconst legacy = parseLegacyPrefix(rows[0]?.value)\n\t\tif (legacy === null || legacy.nodeId === nodeId) {\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tOWN_ACKED_THROUGH_META_KEY,\n\t\t\t\tJSON.stringify({ nodeId, sequence }),\n\t\t\t])\n\t\t\treturn\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\townAckedThroughKey(nodeId),\n\t\t\tString(sequence),\n\t\t])\n\t})\n}\n\n/** Load the downlink scope the sync server last accepted (null when none). */\nexport async function loadAcceptedDownlinkScope(\n\tadapter: StorageAdapter,\n): Promise<Record<string, Record<string, unknown>> | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t])\n\tconst value = rows[0]?.value\n\tif (value === undefined || value === null) return null\n\ttry {\n\t\tconst parsed = JSON.parse(value) as unknown\n\t\treturn parsed !== null && typeof parsed === 'object'\n\t\t\t? (parsed as Record<string, Record<string, unknown>>)\n\t\t\t: null\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/** Persist (or clear) the downlink scope the sync server last accepted. */\nexport async function saveAcceptedDownlinkScope(\n\tadapter: StorageAdapter,\n\tscope: Record<string, Record<string, unknown>> | null,\n): Promise<void> {\n\tif (scope === null) {\n\t\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [\n\t\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t\t])\n\t\treturn\n\t}\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t\tJSON.stringify(scope),\n\t])\n}\n","import type { MetaRow, StorageAdapter, Transaction } from '../types'\nimport { OWN_ACKED_THROUGH_META_KEY } from './sync-durability'\nimport { NODE_TOKEN_META_KEY, nodeTokenKey } from './sync-state'\n\n/**\n * Durable sync bookkeeping that belongs to the device, not to the app (Phase 2 RT-36,\n * RT-38, RT-40): the operations the server refused for good, and the node ids this\n * database authored operations under.\n *\n * Both tables are created on first use, so existing databases need no migration.\n */\n\n/**\n * Operations the server refused with a non-retriable rejection (RT-36). Unlike\n * `_kora_sync_rejected` (the app's reconciliation list, which `clearRejectedOperations`\n * empties), a row here is never removed: a refused operation stays refused, so a later\n * rescan of the device's own history never submits it again.\n */\nexport const TERMINAL_REJECTIONS_TABLE = '_kora_terminal_rejections'\n\n/**\n * Node ids this database authored operations under (RT-38, RT-40): the node in use,\n * nodes it rotated away from, and other tabs' nodes under per-tab isolation.\n */\nexport const LOCAL_NODES_TABLE = '_kora_local_nodes'\n\n/** Meta key: count of accepted sync handshakes on this database (refusal cycles, RT-38). */\nexport const ACCEPTED_CYCLE_META_KEY = 'sync_accepted_cycle'\n\n/** Meta key: terminal rejections were seeded from the pre-Phase-2 rejected list once. */\nconst TERMINAL_SEED_META_KEY = 'terminal_rejections_seeded_v1'\n\n/**\n * Rejection codes that never become a terminal marker: the operation was not judged on\n * its content, so a later upload of it may be accepted.\n *\n * - `SEQUENCE_CONFLICT`: the device's sequence number collided with an operation the\n * server holds (a lost local tail, RT-35, or a beta.12 duplicate pair, RT-37); the\n * operation is renumbered and uploaded again.\n * - `NODE_ID_MISMATCH`: uploaded on another node's session.\n * - `OUT_OF_UPLINK_SCOPE`: judged by the client against the scope it had then.\n */\nexport const NON_TERMINAL_REJECTION_CODES: ReadonlySet<string> = new Set([\n\t'SEQUENCE_CONFLICT',\n\t'NODE_ID_MISMATCH',\n\t'OUT_OF_UPLINK_SCOPE',\n])\n\nconst TERMINAL_REJECTIONS_DDL = `CREATE TABLE IF NOT EXISTS ${TERMINAL_REJECTIONS_TABLE} (\n operation_id TEXT PRIMARY KEY NOT NULL,\n node_id TEXT,\n sequence_number INTEGER,\n code TEXT NOT NULL,\n rejected_at INTEGER NOT NULL\n)`\n\nconst LOCAL_NODES_DDL = `CREATE TABLE IF NOT EXISTS ${LOCAL_NODES_TABLE} (\n node_id TEXT PRIMARY KEY NOT NULL,\n created_at INTEGER NOT NULL,\n accepted INTEGER NOT NULL DEFAULT 0,\n held INTEGER NOT NULL DEFAULT 0,\n refused_cycle INTEGER,\n principal TEXT,\n binding TEXT,\n refused_principals TEXT\n)`\n\n/**\n * How a local node's {@link LocalNodeRecord.principal} was learned (RT-50):\n *\n * - `fresh`: the node had no writes when it was bound to the signed-in user, so every\n * write under it was made by that user.\n * - `server`: a sync handshake as the node was accepted for that user (the server's node\n * claims are authoritative).\n * - `app`: the app assigned a held node to the signed-in user\n * (`app.sync.assignHeld`). A guess: cleared if the server refuses the node for them.\n */\nexport type LocalNodeBinding = 'fresh' | 'server' | 'app'\n\nconst LOCAL_NODE_BINDINGS: readonly LocalNodeBinding[] = ['fresh', 'server', 'app']\n\n/** At most this many principals are remembered as refused for one node (RT-50). */\nconst MAX_REFUSED_PRINCIPALS = 32\n\n/** Meta key: per-node adoption schedule (parked adoptions, upload progress; RT-46). */\nexport const ADOPTION_SCHEDULE_META_KEY = 'sync_adoption_schedule_v1'\n\n/** Adapters whose `_kora_local_nodes` table is known to have every column (this process). */\nconst migratedAdapters = new WeakSet<StorageAdapter>()\n\n/** A terminal rejection to record (RT-36). */\nexport interface TerminalRejection {\n\toperationId: string\n\t/** Authoring node and sequence, when known (null for rows seeded from the old list). */\n\tnodeId: string | null\n\tsequenceNumber: number | null\n\tcode: string\n\trejectedAt: number\n}\n\n/** A node id this database authored operations under (RT-38, RT-40). */\nexport interface LocalNodeRecord {\n\tnodeId: string\n\t/** Wall-clock time (ms) the node was registered. Display only. */\n\tcreatedAt: number\n\t/** A sync handshake as this node was accepted at least once. */\n\taccepted: boolean\n\t/**\n\t * The server refused this node (`NODE_ID_CLAIMED`) after it had been accepted: it\n\t * belongs to a principal that is not signed in. Its unsynced operations are held for\n\t * that principal, never uploaded under another one.\n\t */\n\theld: boolean\n\t/** {@link ACCEPTED_CYCLE_META_KEY} value when the server last refused it, or null. */\n\trefusedCycle: number | null\n\t/**\n\t * The signed-in user the node's writes belong to (RT-42), or null when the app never\n\t * told the store who was signed in while it was in use. A node bound to one user is\n\t * never used for, uploaded under, or adopted by another user's session.\n\t */\n\tprincipal: string | null\n\t/**\n\t * How {@link principal} was learned (RT-50), or null when unbound, or bound by a release\n\t * that did not record it (treated as a guess).\n\t */\n\tbinding: LocalNodeBinding | null\n\t/**\n\t * Users the server refused this UNBOUND node for (`NODE_ID_CLAIMED`, RT-50): it is\n\t * not theirs, so it is never tried again on their sessions. An unbound node that was\n\t * accepted before belongs to whichever user the server accepts it for.\n\t */\n\trefusedPrincipals: string[]\n}\n\ninterface LocalNodeRow {\n\tnode_id: string\n\tcreated_at: number\n\taccepted: number\n\theld: number\n\trefused_cycle: number | null\n\tprincipal: string | null\n\tbinding: string | null\n\trefused_principals: string | null\n}\n\n/** A parked adoption (RT-46): the node made no upload progress in its last session. */\nexport interface ParkedAdoption {\n\t/** {@link AdoptionSchedule.progress} when it was parked: retried once it moves. */\n\tprogressMark: number\n\t/** Wall-clock time (ms) after which it is retried anyway. Scheduling only. */\n\tuntilMs: number\n\t/** Consecutive parks (backoff exponent). */\n\tcount: number\n\t/** Wall-clock time (ms) it was parked. Scheduling only. */\n\tparkedAtMs: number\n}\n\n/**\n * Which local nodes' adoptions are parked (RT-46), and a counter of upload progress on\n * this database: a parked node is retried once anything else uploaded (its deferral may\n * have depended on it) or after its backoff.\n */\nexport interface AdoptionSchedule {\n\tprogress: number\n\tparked: Record<string, ParkedAdoption>\n}\n\n/**\n * Create both tables. `Store.open` runs it (through {@link registerLocalNode}), so the\n * read paths, which run often, assume the tables exist and never issue DDL (on the\n * IndexedDB adapter every statement schedules a snapshot).\n */\nexport async function ensureLocalSyncRecordTables(adapter: StorageAdapter): Promise<void> {\n\tawait adapter.execute(TERMINAL_REJECTIONS_DDL)\n\tawait adapter.execute(LOCAL_NODES_DDL)\n\tif (migratedAdapters.has(adapter)) return\n\t// A table created by an earlier release lacks the principal column (RT-42).\n\t// ... and the binding columns (RT-50).\n\tconst columns = await adapter.query<{ name: string }>(`PRAGMA table_info(${LOCAL_NODES_TABLE})`)\n\tfor (const column of ['principal', 'binding', 'refused_principals']) {\n\t\tif (!columns.some((existing) => existing.name === column)) {\n\t\t\tawait adapter.execute(`ALTER TABLE ${LOCAL_NODES_TABLE} ADD COLUMN ${column} TEXT`)\n\t\t}\n\t}\n\tmigratedAdapters.add(adapter)\n}\n\n/** Record terminal rejections (idempotent by operation id; the first record wins). */\nexport async function recordTerminalRejections(\n\tadapter: StorageAdapter,\n\tentries: TerminalRejection[],\n): Promise<void> {\n\tconst recordable = entries.filter((entry) => !NON_TERMINAL_REJECTION_CODES.has(entry.code))\n\tif (recordable.length === 0) return\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of recordable) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\t})\n}\n\n/** Which of `operationIds` carry a terminal rejection marker. */\nexport async function findTerminalRejections(\n\tadapter: StorageAdapter,\n\toperationIds: string[],\n): Promise<Set<string>> {\n\tconst found = new Set<string>()\n\tif (operationIds.length === 0) return found\n\tconst CHUNK = 500\n\tfor (let i = 0; i < operationIds.length; i += CHUNK) {\n\t\tconst chunk = operationIds.slice(i, i + CHUNK)\n\t\tconst rows = await adapter.query<{ operation_id: string }>(\n\t\t\t`SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE} WHERE operation_id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\tchunk,\n\t\t)\n\t\tfor (const row of rows) found.add(row.operation_id)\n\t}\n\treturn found\n}\n\n/**\n * Seed terminal markers once from `_kora_sync_rejected`, the list earlier releases kept\n * (and the app may have cleared since). Rows whose code is not terminal are skipped:\n * in particular a pre-release device's `SEQUENCE_CONFLICT` rejections (RT-37) stay eligible\n * for the one-time re-upload, which is how those writes reach the server.\n */\nexport async function seedTerminalRejectionsOnce(adapter: StorageAdapter): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tconst done = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tTERMINAL_SEED_META_KEY,\n\t])\n\tif (done.length > 0) return\n\tconst tables = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_kora_sync_rejected'\",\n\t)\n\tawait adapter.transaction(async (tx) => {\n\t\tif (tables.length > 0) {\n\t\t\tconst placeholders = [...NON_TERMINAL_REJECTION_CODES].map(() => '?').join(', ')\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at)\n SELECT operation_id, NULL, NULL, code, rejected_at FROM _kora_sync_rejected\n WHERE retriable = 0 AND code NOT IN (${placeholders})`,\n\t\t\t\t[...NON_TERMINAL_REJECTION_CODES],\n\t\t\t)\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tTERMINAL_SEED_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n}\n\nfunction rowToRecord(row: LocalNodeRow): LocalNodeRecord {\n\treturn {\n\t\tnodeId: row.node_id,\n\t\tcreatedAt: Number(row.created_at),\n\t\taccepted: Number(row.accepted) === 1,\n\t\theld: Number(row.held) === 1,\n\t\trefusedCycle: row.refused_cycle === null ? null : Number(row.refused_cycle),\n\t\tprincipal: typeof row.principal === 'string' ? row.principal : null,\n\t\tbinding:\n\t\t\ttypeof row.principal === 'string' &&\n\t\t\tLOCAL_NODE_BINDINGS.includes(row.binding as LocalNodeBinding)\n\t\t\t\t? (row.binding as LocalNodeBinding)\n\t\t\t\t: null,\n\t\trefusedPrincipals: parsePrincipalList(row.refused_principals),\n\t}\n}\n\nfunction parsePrincipalList(value: string | null): string[] {\n\tif (typeof value !== 'string' || value.length === 0) return []\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn Array.isArray(parsed)\n\t\t\t? parsed.filter((entry): entry is string => typeof entry === 'string')\n\t\t\t: []\n\t} catch {\n\t\treturn []\n\t}\n}\n\n/**\n * Register a node id this database authors operations under. A node registered for the\n * first time that a claims-aware server already accepted here (a database from a build\n * with node claims) is recorded as accepted, so a later refusal holds its writes\n * instead of re-authoring them under another principal (RT-38).\n *\n * Sync history alone is not that evidence (RT-92): beta.12 and older servers recorded\n * no node claims, so a node only they accepted belongs to nobody on an upgraded server.\n * It registers as not accepted, and a refusal re-authors its never-sent writes under a\n * fresh node (RT-21) instead of holding them for an owner that does not exist.\n */\nexport async function registerLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tconst existing = await adapter.query<{ node_id: string }>(\n\t\t`SELECT node_id FROM ${LOCAL_NODES_TABLE} WHERE node_id = ?`,\n\t\t[nodeId],\n\t)\n\tif (existing.length > 0) return\n\tconst accepted = await hasSyncHistory(adapter, nodeId)\n\tawait adapter.execute(\n\t\t`INSERT OR IGNORE INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, ?, 0, NULL)`,\n\t\t[nodeId, Date.now(), accepted ? 1 : 0],\n\t)\n}\n\n/**\n * Whether a claims-aware server accepted `nodeId` on this database before the registry\n * existed: a node token it issued (anonymous claims), or the acknowledged-prefix record\n * builds with node claims keep. beta.12's `last_acked_server_vector` does not count: its\n * server recorded no claims (RT-92).\n */\nasync function hasSyncHistory(adapter: StorageAdapter, nodeId: string): Promise<boolean> {\n\tconst rows = await adapter.query<MetaRow & { key: string }>(\n\t\t'SELECT key, value FROM _kora_meta WHERE key IN (?, ?, ?)',\n\t\t[NODE_TOKEN_META_KEY, nodeTokenKey(nodeId), OWN_ACKED_THROUGH_META_KEY],\n\t)\n\tconst nodeIdRows = await adapter.query<MetaRow>(\n\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t)\n\tconst isMetaNode = nodeIdRows[0]?.value === nodeId\n\tfor (const row of rows) {\n\t\tif (row.key === nodeTokenKey(nodeId)) return true\n\t\tif (row.key === NODE_TOKEN_META_KEY) {\n\t\t\tif (isMetaNode) return true\n\t\t\tcontinue\n\t\t}\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(row.value) as Record<string, unknown>\n\t\t\tif (row.key === OWN_ACKED_THROUGH_META_KEY) {\n\t\t\t\tif (parsed.nodeId === nodeId && typeof parsed.sequence === 'number' && parsed.sequence > 0)\n\t\t\t\t\treturn true\n\t\t\t}\n\t\t} catch {\n\t\t\t// An unreadable row is no evidence either way.\n\t\t}\n\t}\n\treturn false\n}\n\n/** Every registered local node, oldest first. */\nexport async function listLocalNodes(adapter: StorageAdapter): Promise<LocalNodeRecord[]> {\n\tconst rows = await adapter.query<LocalNodeRow>(\n\t\t`SELECT node_id, created_at, accepted, held, refused_cycle, principal, binding, refused_principals FROM ${LOCAL_NODES_TABLE} ORDER BY created_at ASC, node_id ASC`,\n\t)\n\treturn rows.map(rowToRecord)\n}\n\nasync function readAcceptedCycle(tx: Transaction): Promise<number> {\n\tconst rows = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_CYCLE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/**\n * Record an accepted handshake as `nodeId`: the node is accepted and no longer held,\n * and a new refusal cycle starts (every node may be tried again after a refusal).\n */\nexport async function markLocalNodeAccepted(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst cycle = await readAcceptedCycle(tx)\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, 1, 0, NULL)\n ON CONFLICT(node_id) DO UPDATE SET accepted = 1, held = 0, refused_cycle = NULL`,\n\t\t\t[nodeId, Date.now()],\n\t\t)\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tACCEPTED_CYCLE_META_KEY,\n\t\t\tString(cycle + 1),\n\t\t])\n\t})\n}\n\n/**\n * Record that the server refused `nodeId` (`NODE_ID_CLAIMED`) in the current refusal\n * cycle. `held` marks its unsynced operations as held for the principal owning it.\n */\nexport async function markLocalNodeRefused(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\theld: boolean,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst cycle = await readAcceptedCycle(tx)\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, 0, ?, ?)\n ON CONFLICT(node_id) DO UPDATE SET held = MAX(held, excluded.held), refused_cycle = excluded.refused_cycle`,\n\t\t\t[nodeId, Date.now(), held ? 1 : 0, cycle],\n\t\t)\n\t})\n}\n\n/**\n * Forget a local node that has nothing left to upload (bounds the registry under per-tab\n * isolation, where every tab adds a node). A node that writes again is registered again\n * when its store opens. Never the database's own node id.\n */\nexport async function forgetLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`DELETE FROM ${LOCAL_NODES_TABLE} WHERE node_id = ? AND held = 0 AND node_id NOT IN (SELECT value FROM _kora_meta WHERE key = 'node_id')`,\n\t\t[nodeId],\n\t)\n}\n\n/**\n * Bind a local node to the signed-in user whose writes it carries (RT-42), recording how\n * that was learned (RT-50). The node is registered if it is not yet.\n */\nexport async function setLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n\tbinding: LocalNodeBinding,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle, principal, binding) VALUES (?, ?, 0, 0, NULL, ?, ?)\n ON CONFLICT(node_id) DO UPDATE SET principal = excluded.principal, binding = excluded.binding`,\n\t\t[nodeId, Date.now(), principal, binding],\n\t)\n}\n\n/** A binding that is only a guess: cleared when the server refuses the node (RT-50). */\nfunction isGuessedBinding(node: LocalNodeRecord): boolean {\n\treturn node.principal !== null && (node.binding === null || node.binding === 'app')\n}\n\nasync function findLocalNode(\n\tadapter: StorageAdapter | Transaction,\n\tnodeId: string,\n): Promise<LocalNodeRecord | null> {\n\tconst rows = await adapter.query<LocalNodeRow>(\n\t\t`SELECT node_id, created_at, accepted, held, refused_cycle, principal, binding, refused_principals FROM ${LOCAL_NODES_TABLE} WHERE node_id = ?`,\n\t\t[nodeId],\n\t)\n\tconst row = rows[0]\n\treturn row ? rowToRecord(row) : null\n}\n\n/**\n * A sync handshake as `nodeId` was accepted for `principal` (RT-50): the server's node\n * claims say the node is theirs. Binds an unbound node, or replaces a guessed binding,\n * as `server`. A node bound from evidence (`fresh` or `server`) to another user keeps\n * its binding: the engine never runs such a session.\n */\nexport async function confirmLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (node && node.principal !== null && node.principal !== principal && !isGuessedBinding(node))\n\t\t\treturn\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle, principal, binding) VALUES (?, ?, 0, 0, NULL, ?, 'server')\n ON CONFLICT(node_id) DO UPDATE SET principal = excluded.principal, binding = 'server', refused_principals = NULL`,\n\t\t\t[nodeId, Date.now(), principal],\n\t\t)\n\t})\n}\n\n/**\n * The server refused `nodeId` for `principal` (`NODE_ID_CLAIMED`, RT-50): another user\n * owns it. A guessed binding is cleared (it was wrong), and an unbound node remembers\n * that it is not `principal`'s, so it is tried on another user's session instead.\n */\nexport async function recordLocalNodeRefusedFor(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (!node) return\n\t\tif (node.principal !== null && !isGuessedBinding(node)) return\n\t\tconst refused = node.refusedPrincipals.filter((entry) => entry !== principal)\n\t\trefused.push(principal)\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${LOCAL_NODES_TABLE} SET principal = NULL, binding = NULL, refused_principals = ? WHERE node_id = ?`,\n\t\t\t[JSON.stringify(refused.slice(-MAX_REFUSED_PRINCIPALS)), nodeId],\n\t\t)\n\t})\n}\n\n/**\n * The app assigned a held, unbound local node to `principal` (RT-50,\n * `app.sync.assignHeld`): its writes upload on their sessions from now on. A guess, so\n * a later refusal by the server clears it again.\n *\n * @returns false when the node is unknown, already bound, or was refused for `principal`\n */\nexport async function assignLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<boolean> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tlet assigned = false\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (!node || node.principal !== null || node.refusedPrincipals.includes(principal)) return\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${LOCAL_NODES_TABLE} SET principal = ?, binding = 'app', held = 0, refused_cycle = NULL WHERE node_id = ?`,\n\t\t\t[principal, nodeId],\n\t\t)\n\t\tassigned = true\n\t})\n\treturn assigned\n}\n\n/** Forget a local node whatever its state (its writes were discarded by the app, RT-50). */\nexport async function dropLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`DELETE FROM ${LOCAL_NODES_TABLE} WHERE node_id = ? AND node_id NOT IN (SELECT value FROM _kora_meta WHERE key = 'node_id')`,\n\t\t[nodeId],\n\t)\n}\n\n/** The adoption schedule (RT-46); empty when none was saved. */\nexport async function loadAdoptionSchedule(adapter: StorageAdapter): Promise<AdoptionSchedule> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tADOPTION_SCHEDULE_META_KEY,\n\t])\n\tconst empty: AdoptionSchedule = { progress: 0, parked: {} }\n\tconst raw = rows[0]?.value\n\tif (!raw) return empty\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as Partial<AdoptionSchedule>\n\t\treturn {\n\t\t\tprogress: typeof parsed.progress === 'number' ? parsed.progress : 0,\n\t\t\tparked: parsed.parked && typeof parsed.parked === 'object' ? parsed.parked : {},\n\t\t}\n\t} catch {\n\t\t// An unreadable schedule only costs an earlier retry of a parked adoption.\n\t\treturn empty\n\t}\n}\n\n/** Persist the adoption schedule (RT-46). */\nexport async function saveAdoptionSchedule(\n\tadapter: StorageAdapter,\n\tschedule: AdoptionSchedule,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tADOPTION_SCHEDULE_META_KEY,\n\t\tJSON.stringify(schedule),\n\t])\n}\n\n/** The current refusal cycle (count of accepted handshakes on this database). */\nexport async function loadAcceptedCycle(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_CYCLE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/** Read access to a database (an open adapter, or a reader handed to a delete check). */\nexport interface DatabaseQuery {\n\tquery<T>(sql: string, params?: unknown[]): Promise<T[]>\n}\n\n/**\n * Whether any local node has operations above its contiguous acknowledged prefix that\n * the server did not refuse for good (RT-41): the authoritative \"unsynced\" (W3), which\n * the outbound queue only approximates. A local node is one in the registry, the\n * database's node id, or the node of the legacy prefix key; a node with no recorded\n * prefix counts from 0. Works on a database no store has opened in this release.\n */\nexport async function hasUnsyncedOwnOperations(db: DatabaseQuery): Promise<boolean> {\n\tconst tables = new Set(\n\t\t(await db.query<{ name: string }>(\"SELECT name FROM sqlite_master WHERE type = 'table'\")).map(\n\t\t\t(row) => row.name,\n\t\t),\n\t)\n\tconst opsTables = [...tables].filter((name) => name.startsWith('_kora_ops_'))\n\tif (opsTables.length === 0 || !tables.has('_kora_meta')) return false\n\n\tconst nodes = new Set<string>()\n\tif (tables.has(LOCAL_NODES_TABLE)) {\n\t\tfor (const row of await db.query<{ node_id: string }>(\n\t\t\t`SELECT node_id FROM ${LOCAL_NODES_TABLE}`,\n\t\t)) {\n\t\t\tnodes.add(row.node_id)\n\t\t}\n\t}\n\tconst meta = await db.query<{ key: string; value: string }>(\n\t\t\"SELECT key, value FROM _kora_meta WHERE key = 'node_id' OR key = ? OR key LIKE ?\",\n\t\t[OWN_ACKED_THROUGH_META_KEY, `${OWN_ACKED_THROUGH_META_KEY}:%`],\n\t)\n\tconst prefixes = new Map<string, number>()\n\tfor (const row of meta) {\n\t\tif (row.key === 'node_id') {\n\t\t\tnodes.add(row.value)\n\t\t} else if (row.key === OWN_ACKED_THROUGH_META_KEY) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(row.value) as { nodeId?: unknown; sequence?: unknown }\n\t\t\t\tif (typeof parsed.nodeId === 'string') {\n\t\t\t\t\tnodes.add(parsed.nodeId)\n\t\t\t\t\tif (typeof parsed.sequence === 'number') prefixes.set(parsed.nodeId, parsed.sequence)\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Unreadable: the node (if known otherwise) counts from 0.\n\t\t\t}\n\t\t} else {\n\t\t\tconst nodeId = row.key.slice(OWN_ACKED_THROUGH_META_KEY.length + 1)\n\t\t\t// The legacy key wins for its node (loadOwnAckedThrough reads it first).\n\t\t\tconst sequence = Number(row.value)\n\t\t\tif (!prefixes.has(nodeId) && Number.isInteger(sequence)) prefixes.set(nodeId, sequence)\n\t\t}\n\t}\n\tconst exclude = tables.has(TERMINAL_REJECTIONS_TABLE)\n\t\t? ` AND id NOT IN (SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE})`\n\t\t: ''\n\tfor (const nodeId of nodes) {\n\t\tconst prefix = prefixes.get(nodeId) ?? 0\n\t\tfor (const table of opsTables) {\n\t\t\tconst rows = await db.query<{ n: number }>(\n\t\t\t\t`SELECT COUNT(*) AS n FROM \"${table.replace(/\"/g, '\"\"')}\" WHERE node_id = ? AND sequence_number > ?${exclude}`,\n\t\t\t\t[nodeId, prefix],\n\t\t\t)\n\t\t\tif (Number(rows[0]?.n ?? 0) > 0) return true\n\t\t}\n\t}\n\treturn false\n}\n","import {\n\tFOLD_STATE_VERSION,\n\ttype FoldOptions,\n\ttype FoldState,\n\tFoldStateError,\n\ttype FoldTrace,\n\tHybridLogicalClock,\n\ttype MergeTrace,\n\ttype Operation,\n\ttype OperationTransform,\n\ttype SchemaDefinition,\n\tadaptFoldState,\n\tbase64ToBytes,\n\tcreateFoldState,\n\tdeserializeFoldState,\n\tgetFoldFieldVersionStrings,\n\tisFoldStateLive,\n\tjoinStates,\n\tmaterialize,\n\tmergeOp,\n\tmismatchedFoldFields,\n\tquoteIdent,\n\tserializeFoldState,\n\ttoMergeTrace,\n} from '@korajs/core'\nimport * as Y from 'yjs'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeRecord } from '../serialization/serializer'\nimport { loadRetainedConflictRows } from '../store/sequence-repair'\nimport { TERMINAL_REJECTIONS_TABLE } from '../sync/local-sync-records'\nimport type { OperationRow, RawCollectionRow, Transaction } from '../types'\n\n/** Per-record fold state (serialized `FoldState`) of every record this database holds. */\nexport const FOLD_STATE_TABLE = '_kora_fold_state'\n/**\n * Per-record base state of operations no longer in the log (compacted, or a snapshot\n * of a row whose history was compacted or quarantined before W7). A record's state\n * is always `join(base, fold(log))`.\n */\nexport const FOLD_BASE_TABLE = '_kora_fold_base'\n/** Per-node sequence prefix removed by compaction: ids at or below it are duplicates. */\nexport const COMPACTED_THROUGH_TABLE = '_kora_compacted_through'\n/**\n * Per-record row snapshots (RT-68): the base built from a materialized row when the\n * record's history is not all in the log (a pre-W7 compaction, quarantined log rows).\n * Kept apart from `_kora_fold_base` (which holds only exact, operation-built states)\n * so the approximation can be dropped once the record's history is complete again:\n * when the server's fold state arrives in a scope entry, or after a full resync.\n * A record's state is `join(base, snapshot, fold(log))`.\n */\nexport const FOLD_SNAPSHOT_TABLE = '_kora_fold_snapshot'\n/**\n * Local-only provisional side effects (RT-69): the cascades / set-nulls a device\n * derives for a REMOTE delete. They fold into the record like operations but are\n * never logged, sequenced or uploaded (the server derives and relays its own\n * copy); each is retired when the server's copy for the same parent and record\n * arrives, or when the device's delivery stream has caught up.\n\n */\nexport const PROVISIONAL_OPS_TABLE = '_kora_provisional_ops'\n/**\n * Terminal-rejection codes the fold does NOT exclude: the user discarded a held\n * node's writes (they stay in the local database; only their upload stops).\n */\nconst KEPT_REJECTION_CODES: readonly string[] = ['HELD_DISCARDED']\n/** `_kora_meta` key recording how the rows of this database are materialized. */\nexport const FOLD_MATERIALIZATION_META_KEY = 'fold_materialization'\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} once rows are materializations of the current fold. */\nexport const FOLD_MATERIALIZATION_CURRENT = `fold-v${FOLD_STATE_VERSION}`\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} while the legacy (beta.12) paths write rows. */\nexport const FOLD_MATERIALIZATION_LEGACY = 'legacy'\n\n/** DDL for the fold tables. Idempotent. */\nexport const FOLD_TABLES_DDL: readonly string[] = [\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_STATE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_BASE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${COMPACTED_THROUGH_TABLE} (node_id TEXT PRIMARY KEY, sequence_number INTEGER NOT NULL)`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_SNAPSHOT_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${PROVISIONAL_OPS_TABLE} (id TEXT PRIMARY KEY, collection TEXT NOT NULL, record_id TEXT NOT NULL, parent_id TEXT NOT NULL, operation TEXT NOT NULL)`,\n\t`CREATE INDEX IF NOT EXISTS ${PROVISIONAL_OPS_TABLE}_record ON ${PROVISIONAL_OPS_TABLE} (collection, record_id)`,\n]\n\n/**\n * Merges richtext Yjs updates for the fold (core has no Yjs dependency): applies\n * every update to one fresh document and encodes its state. The encoding depends\n * only on the document's content, not on how it was split into updates, so every\n * replica materializes byte-identical richtext.\n */\nexport function mergeYjsUpdates(updates: Uint8Array[]): Uint8Array {\n\tconst doc = new Y.Doc()\n\tfor (const update of updates) Y.applyUpdate(doc, update)\n\treturn Y.encodeStateAsUpdate(doc)\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n\tif (a.length !== b.length) return false\n\tfor (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\n\treturn true\n}\n\n/**\n * Whether Yjs update `a` adds nothing to update `b` (the fold's richtext space\n * bound): the canonical encoding of `b` alone equals that of `a` and `b` merged.\n */\nexport function yjsSubsumes(a: Uint8Array, b: Uint8Array): boolean {\n\treturn sameBytes(mergeYjsUpdates([b]), mergeYjsUpdates([a, b]))\n}\n\n/**\n * Whether an operation lies in a node's compacted prefix: its row is gone from the\n * log, but its effect is in the record's base state, so it is a duplicate (STORE-14).\n */\nexport async function isCompacted(tx: Transaction, op: Operation): Promise<boolean> {\n\tconst rows = await tx.query<{ sequence_number: number }>(\n\t\t`SELECT sequence_number FROM ${COMPACTED_THROUGH_TABLE} WHERE node_id = ?`,\n\t\t[op.nodeId],\n\t)\n\tconst through = rows[0]?.sequence_number\n\treturn through !== undefined && op.sequenceNumber <= through\n}\n\n/** Which fields of a row to (re)write from the fold state. */\nexport type MaterializeFields = 'all' | ReadonlySet<string>\n\n/** Result of merging one operation into its record. */\nexport interface FoldApplyOutcome {\n\t/** The merge changed the record's state. */\n\tchanged: boolean\n\t/** Merge traces (MergeTrace form), for `merge:*` events. */\n\ttraces: MergeTrace[]\n}\n\n/**\n * The client side of the W7 fold: every write to a materialized row — local\n * writes, remote operations, scope entries, rejection re-merges, re-materialization\n * — goes through this class, inside the write transaction that appends the\n * operation (\"append, then merge\"). A row is always the materialization of its\n * record's fold state.\n */\nexport class RecordFolder {\n\tprivate authoritative: ReadonlySet<string> = new Set()\n\n\tconstructor(\n\t\tprivate readonly schema: SchemaDefinition,\n\t\tprivate readonly transforms: readonly OperationTransform[] = [],\n\t) {}\n\n\t/** The schema transforms every merge applies (transforms at fold time, RT-84). */\n\tgetOperationTransforms(): readonly OperationTransform[] {\n\t\treturn this.transforms\n\t}\n\n\t/**\n\t * The fields an operation's merge can change: its own data's keys, or every field\n\t * when the fold reads it through a schema transform (whose view may name others).\n\t */\n\tprivate touchedFields(op: Operation): MaterializeFields {\n\t\tif (this.transforms.length > 0 && op.schemaVersion !== this.schema.version) return 'all'\n\t\treturn new Set(Object.keys(op.data ?? {}))\n\t}\n\n\t/** Node ids whose writes win `merge('server-authoritative')` fields. */\n\tgetAuthoritativeNodeIds(): ReadonlySet<string> {\n\t\treturn this.authoritative\n\t}\n\n\t/** @internal Set by the store from persisted meta / the sync handshake. */\n\tsetAuthoritativeNodeIds(ids: Iterable<string>): void {\n\t\tthis.authoritative = new Set(ids)\n\t}\n\n\t/** Fold options every merge of this database uses. */\n\toptions(traces: FoldOptions['traces'] = 'none'): FoldOptions {\n\t\treturn {\n\t\t\trichtext: mergeYjsUpdates,\n\t\t\trichtextSubsumes: yjsSubsumes,\n\t\t\ttraces,\n\t\t\t...(this.authoritative.size > 0 ? { authoritativeNodeIds: this.authoritative } : {}),\n\t\t\t...(this.transforms.length > 0 ? { transforms: this.transforms } : {}),\n\t\t}\n\t}\n\n\t/** Whether the schema has a `merge('server-authoritative')` field in `collection`. */\n\thasAuthoritativeFields(collection: string): boolean {\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return false\n\t\treturn Object.values(definition.fields).some(\n\t\t\t(field) => field.mergeStrategy === 'server-authoritative',\n\t\t)\n\t}\n\n\t/**\n\t * Merge one operation (already appended to the log) into its record and\n\t * re-materialize the row.\n\t *\n\t * @param tx - The write transaction that appended the operation\n\t * @param op - The operation\n\t * @param mode - 'remote' emits merge traces; 'local' does not (a local write is\n\t * computed from the row it updates, so it is never concurrent with it)\n\t */\n\tasync applyInTx(\n\t\ttx: Transaction,\n\t\top: Operation,\n\t\tmode: 'local' | 'remote',\n\t): Promise<FoldApplyOutcome> {\n\t\tconst scopeEntry = op.type === 'insert'\n\t\tif (mode === 'remote') {\n\t\t\t// The record's approximations end here: a provisional cascade of this parent\n\t\t\t// is replaced by the real one (RT-69), and a row snapshot by the server's\n\t\t\t// complete fold state (RT-68). The operation is already in the log, so the\n\t\t\t// record is re-folded without them.\n\t\t\tconst retired = await this.deleteProvisional(tx, op.collection, op.recordId, op.causalDeps)\n\t\t\tconst replaced = await this.dropSnapshotForCarriedState(tx, op)\n\t\t\tif (retired > 0 || replaced) {\n\t\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\t\treturn { changed: true, traces: [] }\n\t\t\t}\n\t\t}\n\t\t// A local insert has a fresh UUIDv7 record id: no state, log or row precedes it.\n\t\tconst fresh = mode === 'local' && op.type === 'insert'\n\t\tconst prior = fresh\n\t\t\t? { state: createFoldState(op.collection, op.recordId), rebuilt: false }\n\t\t\t: await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tlet result: ReturnType<typeof mergeOp>\n\t\ttry {\n\t\t\tresult = mergeOp(\n\t\t\t\tprior.state,\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(mode === 'remote' ? 'conflicts' : 'none'),\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof FoldStateError)) throw error\n\t\t\t// A stored state the current plan cannot take (RT-63): re-fold the record from\n\t\t\t// its base and log (the operation is already appended) once. A second\n\t\t\t// FoldStateError propagates; the sync engine then quarantines the operation\n\t\t\t// instead of stalling its delivery stream.\n\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\treturn { changed: true, traces: [] }\n\t\t}\n\t\tif (!result.changed && !prior.rebuilt && !scopeEntry) {\n\t\t\treturn { changed: false, traces: await this.toMergeTraces(tx, result.traces) }\n\t\t}\n\t\tawait this.saveState(tx, result.state)\n\t\tconst revived = isDeadState(prior.state) && !isDeadState(result.state)\n\t\tconst fields: MaterializeFields =\n\t\t\tprior.rebuilt || revived || op.foldState !== undefined ? 'all' : this.touchedFields(op)\n\t\tawait this.materializeRow(tx, result.state, fields, {\n\t\t\tclearRetraction: scopeEntry,\n\t\t\t...(fresh ? { absent: true } : {}),\n\t\t})\n\t\treturn { changed: result.changed, traces: await this.toMergeTraces(tx, result.traces) }\n\t}\n\n\t/**\n\t * Fold a record from its base state and its log, leaving out operations the\n\t * server terminally rejected, and re-materialize its row (all fields).\n\t *\n\t * @returns The new state (null when nothing of the record remains)\n\t */\n\tasync refoldInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\toptions: { clearRetraction?: boolean } = {},\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.foldFromLog(tx, collection, recordId)\n\t\tif (state === null) {\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t])\n\t\t\t// Nothing of the record remains (its insert was refused): hide the row.\n\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 1 WHERE id = ?`, [recordId])\n\t\t\treturn null\n\t\t}\n\t\tawait this.saveState(tx, state)\n\t\tawait this.materializeRow(tx, state, 'all', {\n\t\t\tclearRetraction: options.clearRetraction ?? false,\n\t\t})\n\t\treturn state\n\t}\n\n\t/**\n\t * `join(base, snapshot, fold(log - terminally rejected, provisional effects))`, or\n\t * null when none exists. Base and snapshot are adapted to the current fold plan\n\t * (RT-63): a field whose kind changed is rebuilt from its materialized value.\n\t */\n\tasync foldFromLog(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst ops = [\n\t\t\t...(await this.loadRecordOperations(tx, collection, recordId)),\n\t\t\t...(await this.loadProvisional(tx, collection, recordId)),\n\t\t]\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tconst snapshot = await this.loadSnapshot(tx, collection, recordId)\n\t\tlet state =\n\t\t\tbase !== null && snapshot !== null\n\t\t\t\t? joinStates(base, snapshot, this.schema)\n\t\t\t\t: (base ?? snapshot)\n\t\tfor (const op of ops) {\n\t\t\tif (rejected.has(op.id)) continue\n\t\t\tstate = mergeOp(\n\t\t\t\tstate ?? createFoldState(collection, recordId),\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(),\n\t\t\t).state\n\t\t}\n\t\treturn state\n\t}\n\n\t/** The record's operations (log + retained sequence-conflict rows). */\n\tasync loadRecordOperations(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = [\n\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t)),\n\t\t]\n\t\treturn rows.map((row) => deserializeOperationWithCollection(row, collection))\n\t}\n\n\t/**\n\t * Which of `ids` the fold leaves out: operations with a terminal-rejection marker\n\t * from the server (or quarantined by a scope retraction, which the server never\n\t * receives). Writes the user chose to discard from a held node are NOT left out:\n\t * discarding stops the upload, it is not a rollback.\n\t */\n\tasync loadTerminalRejections(tx: Transaction, ids: readonly string[]): Promise<Set<string>> {\n\t\tconst found = new Set<string>()\n\t\tconst CHUNK = 500\n\t\tfor (let i = 0; i < ids.length; i += CHUNK) {\n\t\t\tconst chunk = ids.slice(i, i + CHUNK)\n\t\t\tconst rows = await tx.query<{ operation_id: string }>(\n\t\t\t\t`SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE} WHERE code NOT IN (${KEPT_REJECTION_CODES.map(() => '?').join(', ')}) AND operation_id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t[...KEPT_REJECTION_CODES, ...chunk],\n\t\t\t)\n\t\t\tfor (const row of rows) found.add(row.operation_id)\n\t\t}\n\t\treturn found\n\t}\n\n\t/**\n\t * The record's stored state, or null (none, another format version, or a field\n\t * whose fold kind the schema has changed since: the caller re-folds, RT-63).\n\t */\n\tasync loadState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t\tif (state === null || mismatchedFoldFields(state, this.schema).length > 0) return null\n\t\treturn state\n\t}\n\n\t/** The stored state as it is, even when the plan changed (a snapshot seed). */\n\tasync loadStoredState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\treturn this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t}\n\n\t/** The record's compacted base, adapted to the current fold plan (RT-63). */\n\tasync loadBase(tx: Transaction, collection: string, recordId: string): Promise<FoldState | null> {\n\t\tconst base = await this.readStateRow(tx, FOLD_BASE_TABLE, collection, recordId)\n\t\treturn base === null ? null : adaptFoldState(base, this.schema, this.options()).state\n\t}\n\n\t/** The record's row snapshot (RT-68), adapted to the current fold plan. */\n\tasync loadSnapshot(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst snapshot = await this.readStateRow(tx, FOLD_SNAPSHOT_TABLE, collection, recordId)\n\t\treturn snapshot === null ? null : adaptFoldState(snapshot, this.schema, this.options()).state\n\t}\n\n\t/** Store `snapshot` as the record's row snapshot (joined with an existing one). */\n\tasync saveSnapshot(tx: Transaction, snapshot: FoldState): Promise<void> {\n\t\tconst existing = await this.loadSnapshot(tx, snapshot.c, snapshot.r)\n\t\tconst state = existing === null ? snapshot : joinStates(existing, snapshot, this.schema)\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_SNAPSHOT_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/**\n\t * A scope entry carrying the server's fold state (RT-29) replaces the record's row\n\t * snapshot (RT-68): the server's state is built from every operation of the record\n\t * the device was missing, so with the device's own log it is the exact state.\n\t * Only a carried state this schema can read and join counts (otherwise the entry\n\t * merges by its data and the snapshot stays).\n\t *\n\t * @returns Whether a snapshot was dropped\n\t */\n\tprivate async dropSnapshotForCarriedState(tx: Transaction, op: Operation): Promise<boolean> {\n\t\tif (op.type !== 'insert' || op.foldState === undefined) return false\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[op.collection, op.recordId],\n\t\t)\n\t\tif ((rows[0]?.n ?? 0) === 0) return false\n\t\tlet carried: FoldState\n\t\ttry {\n\t\t\tcarried = deserializeFoldState(op.foldState)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FoldStateError) return false\n\t\t\tthrow error\n\t\t}\n\t\tif (carried.c !== op.collection || carried.r !== op.recordId) return false\n\t\tif (mismatchedFoldFields(carried, this.schema).length > 0) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\top.collection,\n\t\t\top.recordId,\n\t\t])\n\t\treturn true\n\t}\n\n\t/** Records that still fold against a row snapshot (approximate, RT-68). */\n\tasync listSnapshotRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT collection, record_id FROM ${FOLD_SNAPSHOT_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\t/**\n\t * After a full resync, a record whose log holds its insert again no longer needs\n\t * its row snapshot: drop it and re-fold the record from base and log (RT-68).\n\t *\n\t * @returns Whether the snapshot was dropped\n\t */\n\tasync settleSnapshotInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst ops = await this.loadRecordOperations(tx, collection, recordId)\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst hasInsert = ops.some((op) => op.type === 'insert' && !rejected.has(op.id))\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tif (!hasInsert && (base?.cr ?? null) === null) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t])\n\t\tawait this.refoldInTx(tx, collection, recordId)\n\t\treturn true\n\t}\n\n\t/**\n\t * Fold a local-only provisional side effect (RT-69) into its record: stored apart\n\t * from the log (never sequenced, never uploaded) and kept until the real copy of\n\t * the effect arrives or the delivery stream catches up.\n\t *\n\t * @param parentId - The remote operation that caused it (the parent delete)\n\t */\n\tasync applyProvisionalInTx(tx: Transaction, op: Operation, parentId: string): Promise<void> {\n\t\tconst existing = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE id = ?`,\n\t\t\t[op.id],\n\t\t)\n\t\tif (existing.length > 0) return\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${PROVISIONAL_OPS_TABLE} (id, collection, record_id, parent_id, operation) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t[op.id, op.collection, op.recordId, parentId, JSON.stringify(op)],\n\t\t)\n\t\tconst prior = await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tconst result = mergeOp(prior.state, op, this.schema, this.options())\n\t\tif (!result.changed && !prior.rebuilt) return\n\t\tawait this.saveState(tx, result.state)\n\t\tawait this.materializeRow(tx, result.state, prior.rebuilt ? 'all' : this.touchedFields(op), {\n\t\t\tclearRetraction: false,\n\t\t})\n\t}\n\n\t/**\n\t * Remove provisional effects of a record (those caused by one of `parentIds`, or\n\t * all of them when null). The caller re-folds the record.\n\t *\n\t * @returns How many were removed\n\t */\n\tasync deleteProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tparentIds: readonly string[] | null,\n\t): Promise<number> {\n\t\tif (parentIds !== null && parentIds.length === 0) return 0\n\t\tconst filter =\n\t\t\tparentIds === null ? '' : ` AND parent_id IN (${parentIds.map(() => '?').join(', ')})`\n\t\tconst rows = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?${filter}`,\n\t\t\t[collection, recordId, ...(parentIds ?? [])],\n\t\t)\n\t\tif (rows.length === 0) return 0\n\t\tawait tx.execute(\n\t\t\t`DELETE FROM ${PROVISIONAL_OPS_TABLE} WHERE id IN (${rows.map(() => '?').join(', ')})`,\n\t\t\trows.map((row) => row.id),\n\t\t)\n\t\treturn rows.length\n\t}\n\n\t/** Records with provisional effects. */\n\tasync listProvisionalRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT DISTINCT collection, record_id FROM ${PROVISIONAL_OPS_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\tprivate async loadProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = await tx.query<{ operation: string }>(\n\t\t\t`SELECT operation FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn rows.map((row) => JSON.parse(row.operation) as Operation)\n\t}\n\n\tasync saveState(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_STATE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\tasync saveBase(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_BASE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/** Join `addition` into the record's base state. */\n\tasync joinIntoBase(tx: Transaction, addition: FoldState): Promise<void> {\n\t\tconst base = await this.loadBase(tx, addition.c, addition.r)\n\t\tawait this.saveBase(tx, base === null ? addition : joinStates(base, addition, this.schema))\n\t}\n\n\t/**\n\t * Write the row of a record from its fold state.\n\t *\n\t * - No insert merged: no row (an existing one is hidden).\n\t * - Otherwise the row holds the fold's values (also while deleted: a tombstone\n\t * keeps its last values), `_deleted` from the record's liveness, and versions\n\t * from the state: `_version` / `_updated_at` = newest operation, `_created_at` =\n\t * creation, `_field_versions` = each field's newest write.\n\t * - Only `fields` are written to an existing row; columns the fold never wrote\n\t * (a column a schema migration added with a default, a local-only backfill)\n\t * keep their stored value.\n\t * - A row hidden by a scope retraction stays hidden unless `clearRetraction`\n\t * (a scope-entry insert) is set.\n\t */\n\tasync materializeRow(\n\t\ttx: Transaction,\n\t\tstate: FoldState,\n\t\tfields: MaterializeFields,\n\t\toptions: { clearRetraction: boolean; absent?: boolean },\n\t): Promise<void> {\n\t\tconst collection = state.c\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return\n\t\tconst table = quoteIdent(collection)\n\t\tconst rows = options.absent\n\t\t\t? []\n\t\t\t: await tx.query<RawCollectionRow>(`SELECT id, _deleted FROM ${table} WHERE id = ?`, [\n\t\t\t\t\tstate.r,\n\t\t\t\t])\n\t\tconst existing = rows[0]\n\t\tif (state.cr === null || state.u === null) {\n\t\t\tif (existing && existing._deleted !== 1) {\n\t\t\t\tawait tx.execute(`UPDATE ${table} SET _deleted = 1 WHERE id = ?`, [state.r])\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst asLive: FoldState = { ...state, d: null }\n\t\tconst values = materialize(asLive, { richtext: mergeYjsUpdates }) ?? {}\n\t\tconst latest = HybridLogicalClock.deserialize(state.u.t)\n\t\tconst created = HybridLogicalClock.deserialize(state.cr.t)\n\t\t// Sorted keys: replicas holding the same state write byte-identical columns.\n\t\tconst fieldVersions = getFoldFieldVersionStrings(state)\n\t\tlet deleted = isDeadState(state) ? 1 : 0\n\t\tif (existing && deleted === 0) {\n\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t[collection, state.r],\n\t\t\t)\n\t\t\tif (retracted.length > 0) {\n\t\t\t\tif (options.clearRetraction) {\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, state.r],\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tdeleted = 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst known = Object.keys(definition.fields)\n\t\t// A tombstone keeps the values it had when it was deleted: a write that lost to\n\t\t// the delete never shows, not even in the hidden row. A revival rewrites them all.\n\t\tconst writable =\n\t\t\texisting && deleted === 1\n\t\t\t\t? []\n\t\t\t\t: known.filter((field) => field in state.f && (fields === 'all' || fields.has(field)))\n\t\tconst fieldValues: Record<string, unknown> = {}\n\t\tfor (const field of writable) {\n\t\t\tconst value = values[field] ?? null\n\t\t\t// A richtext field with a single live update materializes as that update's\n\t\t\t// own bytes; re-encode it so every replica stores the same canonical bytes,\n\t\t\t// however its state happens to be split into updates.\n\t\t\tfieldValues[field] =\n\t\t\t\tdefinition.fields[field]?.kind === 'richtext' &&\n\t\t\t\tvalue !== null &&\n\t\t\t\ttypeof value === 'object' &&\n\t\t\t\t'$koraBytes' in value\n\t\t\t\t\t? mergeYjsUpdates([base64ToBytes(String((value as { $koraBytes: string }).$koraBytes))])\n\t\t\t\t\t: value\n\t\t}\n\t\tconst serialized = serializeRecord(fieldValues, definition.fields)\n\t\tconst meta: Record<string, unknown> = {\n\t\t\t_updated_at: latest.wallTime,\n\t\t\t_version: state.u.t,\n\t\t\t_field_versions: JSON.stringify(fieldVersions),\n\t\t\t_deleted: deleted,\n\t\t}\n\t\tif (!existing) {\n\t\t\tconst insert = buildInsertQuery(collection, {\n\t\t\t\tid: state.r,\n\t\t\t\t...serialized,\n\t\t\t\t...meta,\n\t\t\t\t_created_at: created.wallTime,\n\t\t\t})\n\t\t\tawait tx.execute(insert.sql, insert.params)\n\t\t\treturn\n\t\t}\n\t\tconst changes: Record<string, unknown> = {\n\t\t\t...serialized,\n\t\t\t...meta,\n\t\t\t_created_at: created.wallTime,\n\t\t}\n\t\tconst columns = Object.keys(changes)\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${table} SET ${columns.map((c) => `${quoteIdent(c)} = ?`).join(', ')} WHERE id = ?`,\n\t\t\t[...columns.map((c) => changes[c]), state.r],\n\t\t)\n\t}\n\n\t/**\n\t * Load the record's state; rebuild it from base + log when it is missing or in\n\t * another format version. `rebuilt` tells the caller to rewrite the whole row.\n\t */\n\tprivate async loadOrRebuild(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tappendedId: string,\n\t): Promise<{ state: FoldState; rebuilt: boolean }> {\n\t\tconst stored = await this.loadState(tx, collection, recordId)\n\t\tif (stored !== null) return { state: stored, rebuilt: false }\n\t\tconst hasRow = await this.hasStateRow(tx, collection, recordId)\n\t\tconst others = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ? AND id != ?`,\n\t\t\t[recordId, appendedId],\n\t\t)\n\t\tconst retained = await loadRetainedConflictRows(\n\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t)\n\t\tconst hasBase =\n\t\t\t(await this.loadBase(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadSnapshot(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadProvisional(tx, collection, recordId)).some((p) => p.id !== appendedId)\n\t\tif (\n\t\t\t!hasRow &&\n\t\t\t!hasBase &&\n\t\t\t(others[0]?.n ?? 0) === 0 &&\n\t\t\tretained.every((row) => row.id === appendedId)\n\t\t) {\n\t\t\t// A new record: nothing to rebuild.\n\t\t\treturn { state: createFoldState(collection, recordId), rebuilt: false }\n\t\t}\n\t\tconst rebuilt = await this.foldFromLog(tx, collection, recordId)\n\t\treturn { state: rebuilt ?? createFoldState(collection, recordId), rebuilt: true }\n\t}\n\n\tprivate async hasStateRow(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn (rows[0]?.n ?? 0) > 0\n\t}\n\n\tprivate async readStateRow(\n\t\ttx: Transaction,\n\t\ttable: string,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst rows = await tx.query<{ state: string }>(\n\t\t\t`SELECT state FROM ${table} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\tconst raw = rows[0]?.state\n\t\tif (raw === undefined) return null\n\t\ttry {\n\t\t\treturn deserializeFoldState(raw)\n\t\t} catch (error) {\n\t\t\t// Another format version: the caller re-folds the record.\n\t\t\tif (error instanceof FoldStateError) return null\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprivate async toMergeTraces(tx: Transaction, traces: FoldTrace[]): Promise<MergeTrace[]> {\n\t\tconst out: MergeTrace[] = []\n\t\tfor (const trace of traces) {\n\t\t\tlet prior: Operation | null = null\n\t\t\tif (trace.priorOperationId !== null) {\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${trace.operation.collection}`)} WHERE id = ?`,\n\t\t\t\t\t[trace.priorOperationId],\n\t\t\t\t)\n\t\t\t\tconst row = rows[0]\n\t\t\t\tif (row) prior = deserializeOperationWithCollection(row, trace.operation.collection)\n\t\t\t}\n\t\t\tout.push(toMergeTrace(trace, prior))\n\t\t}\n\t\treturn out\n\t}\n}\n\n/** No insert merged yet, or the newest delete is later than the newest write. */\n/**\n * The stored form of a fold state: plain JSON, read back by `deserializeFoldState`.\n * The canonical form (`serializeFoldState`, sorted keys) is for comparing and\n * exchanging states; a local row only needs to round-trip, and plain JSON is several\n * times cheaper on the write path.\n */\nfunction persistedForm(state: FoldState): string {\n\treturn JSON.stringify(state)\n}\n\nfunction isDeadState(state: FoldState): boolean {\n\treturn !isFoldStateLive(state)\n}\n","import { HybridLogicalClock, quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport { deserializeOperation, serializeOperation } from '../serialization/serializer'\nimport type { MetaRow, OperationRow, StorageAdapter, Transaction } from '../types'\n\n/**\n * Log-integrity scan (W8 step 0).\n *\n * Every later fold of the operation log (W7 re-materialization, replay, compaction)\n * trusts that each stored row is a canonical operation. Two earlier releases could\n * break that:\n *\n * - beta.12's backup restore wrote `JSON.stringify(timestamp)` into the timestamp\n * column, which `HybridLogicalClock.deserialize` reads as `wallTime: NaN` (a `null`\n * once re-exported), and a second restore of such a backup nested the damage;\n * - compaction deletes acknowledged operations, leaving holes in a node's sequence.\n *\n * The scan detects rows that do not round-trip through `deserializeOperation` /\n * `serializeOperation`, repairs the ones whose original value is recoverable from the\n * row itself (the JSON-encoded timestamp), and moves the rest to\n * {@link LOG_QUARANTINE_TABLE} (never deleted), so no fold ever reads them. It also\n * reports sequence gaps in this database's own nodes. Remote nodes' gaps are normal\n * (scoped sync only delivers part of another device's log) and are not reported.\n */\n\n/** Rows that could not be repaired, kept verbatim. Never cleared automatically. */\nexport const LOG_QUARANTINE_TABLE = '_kora_log_quarantine'\n\nconst QUARANTINE_DDL = `CREATE TABLE IF NOT EXISTS ${LOG_QUARANTINE_TABLE} (\n collection TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n node_id TEXT,\n sequence_number INTEGER,\n problem TEXT NOT NULL,\n detail TEXT NOT NULL,\n row_json TEXT NOT NULL,\n quarantined_at INTEGER NOT NULL,\n PRIMARY KEY (collection, operation_id)\n)`\n\n/** What is wrong with an operation row. */\nexport type LogRowProblem =\n\t/** The timestamp is a JSON-encoded HLC (beta.12 backup restore). Repairable. */\n\t| 'timestamp-json'\n\t/** The timestamp cannot be read as an HLC and is not recoverable. */\n\t| 'timestamp-malformed'\n\t/** `id`, `node_id` or `record_id` is missing. */\n\t| 'identity-malformed'\n\t/** `type` is not insert, update or delete. */\n\t| 'type-invalid'\n\t/** `sequence_number` is not a positive integer. */\n\t| 'sequence-invalid'\n\t/** `data` or `previous_data` is not a JSON object. */\n\t| 'data-malformed'\n\t/** `causal_deps` is not a JSON array of operation ids. */\n\t| 'causal-deps-malformed'\n\t/** The row cannot be turned into an operation and back. */\n\t| 'round-trip-failed'\n\n/** One operation row the scan repaired or quarantined. */\nexport interface LogIntegrityRow {\n\tcollection: string\n\toperationId: string\n\tnodeId: string | null\n\tsequenceNumber: number | null\n\tproblem: LogRowProblem\n\t/** Human-readable detail: the bad value, or how it was repaired. */\n\tdetail: string\n}\n\n/** Sequence numbers missing from one of this database's own nodes. */\nexport interface LogSequenceGap {\n\tnodeId: string\n\t/** First missing sequence number (inclusive). */\n\tfrom: number\n\t/** Last missing sequence number (inclusive). */\n\tto: number\n}\n\n/**\n * Result of {@link scanLogIntegrity} / `Store.verifyLogIntegrity()`.\n *\n * `clean` is the precondition for rebuilding state from the log (W7): every row is\n * canonical, nothing is quarantined, and this database's own nodes have no holes\n * below their highest stored sequence number.\n */\nexport interface LogIntegrityReport {\n\t/** True when the log can be folded as-is (no quarantined rows, no own-node gaps). */\n\tclean: boolean\n\t/** `full`: every row was checked in JS. `quick`: SQL prefilter, suspects checked in JS. */\n\tmode: 'full' | 'quick'\n\t/** Rows checked in JS (all rows in full mode, suspects in quick mode). */\n\tcheckedRows: number\n\t/** Rows this scan repaired in place. */\n\trepaired: LogIntegrityRow[]\n\t/** Rows this scan moved to the quarantine table. */\n\tnewlyQuarantined: LogIntegrityRow[]\n\t/** Every row in the quarantine table (this scan's and earlier ones'). */\n\tquarantined: LogIntegrityRow[]\n\t/** Holes in this database's own nodes' sequences (compaction, a lost tail). */\n\tgaps: LogSequenceGap[]\n\t/** When the log was last compacted (epoch ms), or null when never. */\n\tcompactedAt: number | null\n\t/** False when the scan only reported (`repair: false`). */\n\trepairApplied: boolean\n}\n\n/** Options for {@link scanLogIntegrity}. */\nexport interface LogIntegrityScanOptions {\n\t/** Check every row in JS (default) or only the rows a SQL prefilter flags. */\n\tmode?: 'full' | 'quick'\n\t/** Repair and quarantine (default true). False only reports. */\n\trepair?: boolean\n\t/** Node ids this database authors under (gaps are reported for these only). */\n\tlocalNodeIds: readonly string[]\n}\n\nconst OPERATION_TYPES = new Set(['insert', 'update', 'delete'])\nconst CANONICAL_TIMESTAMP = /^\\d{15}:\\d{5}:.+$/\nconst PAGE_SIZE = 500\n\n/**\n * SQL prefilter: rows that cannot be canonical. Cheap enough to run on every open; the\n * JS check then confirms each suspect. `CASE` keeps `json_type` from seeing invalid JSON.\n */\nconst SUSPECT_WHERE = `id IS NULL OR node_id IS NULL OR record_id IS NULL\n OR type NOT IN ('insert', 'update', 'delete')\n OR typeof(sequence_number) != 'integer' OR sequence_number < 1\n OR typeof(timestamp) != 'text' OR length(timestamp) < 23\n OR substr(timestamp, 16, 1) != ':' OR substr(timestamp, 22, 1) != ':'\n OR substr(timestamp, 1, 15) GLOB '*[^0-9]*' OR substr(timestamp, 17, 5) GLOB '*[^0-9]*'\n OR causal_deps IS NULL\n OR (CASE WHEN json_valid(causal_deps) THEN json_type(causal_deps) != 'array' ELSE 1 END)\n OR (data IS NOT NULL AND (CASE WHEN json_valid(data) THEN json_type(data) != 'object' ELSE 1 END))\n OR (previous_data IS NOT NULL AND (CASE WHEN json_valid(previous_data) THEN json_type(previous_data) != 'object' ELSE 1 END))`\n\ntype RowWithRowid = OperationRow & { __rowid: number }\n\n/** Outcome of {@link checkOperationRow}. */\nexport type LogRowVerdict =\n\t| { kind: 'ok' }\n\t| { kind: 'repair'; problem: LogRowProblem; detail: string; timestamp: string }\n\t| { kind: 'quarantine'; problem: LogRowProblem; detail: string }\n\n/**\n * Scan the operation log of every schema collection; repair and quarantine (unless\n * `repair: false`), then report. Repairs and quarantine moves run in one transaction.\n *\n * @param adapter - An opened storage adapter\n * @param schema - The schema whose operation tables are scanned\n * @param options - Scan mode, repair switch and this database's own node ids\n */\nexport async function scanLogIntegrity(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\toptions: LogIntegrityScanOptions,\n): Promise<LogIntegrityReport> {\n\tconst repair = options.repair ?? true\n\tlet mode = options.mode ?? 'full'\n\tawait adapter.execute(QUARANTINE_DDL)\n\n\tconst actions: Array<{ collection: string; row: RowWithRowid; verdict: LogRowVerdict }> = []\n\tlet checkedRows = 0\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\tlet rows: RowWithRowid[] | null = null\n\t\tif (mode === 'quick') {\n\t\t\ttry {\n\t\t\t\trows = await adapter.query<RowWithRowid>(\n\t\t\t\t\t`SELECT rowid AS __rowid, * FROM ${table} WHERE ${SUSPECT_WHERE}`,\n\t\t\t\t)\n\t\t\t} catch {\n\t\t\t\t// No JSON functions in this SQLite build: check every row instead.\n\t\t\t\tmode = 'full'\n\t\t\t}\n\t\t}\n\t\tif (rows !== null) {\n\t\t\tfor (const row of rows) {\n\t\t\t\tcheckedRows++\n\t\t\t\tconst verdict = checkOperationRow(row)\n\t\t\t\tif (verdict.kind !== 'ok') actions.push({ collection, row, verdict })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tlet after = 0\n\t\tfor (;;) {\n\t\t\tconst page = await adapter.query<RowWithRowid>(\n\t\t\t\t`SELECT rowid AS __rowid, * FROM ${table} WHERE rowid > ? ORDER BY rowid LIMIT ${PAGE_SIZE}`,\n\t\t\t\t[after],\n\t\t\t)\n\t\t\tfor (const row of page) {\n\t\t\t\tcheckedRows++\n\t\t\t\tconst verdict = checkOperationRow(row)\n\t\t\t\tif (verdict.kind !== 'ok') actions.push({ collection, row, verdict })\n\t\t\t}\n\t\t\tif (page.length < PAGE_SIZE) break\n\t\t\tafter = page[page.length - 1]?.__rowid ?? after\n\t\t}\n\t}\n\n\tconst repaired: LogIntegrityRow[] = []\n\tconst newlyQuarantined: LogIntegrityRow[] = []\n\tfor (const { collection, row, verdict } of actions) {\n\t\tif (verdict.kind === 'ok') continue\n\t\tconst entry = describeRow(collection, row, verdict.problem, verdict.detail)\n\t\tif (verdict.kind === 'repair') repaired.push(entry)\n\t\telse newlyQuarantined.push(entry)\n\t}\n\n\tif (repair && actions.length > 0) {\n\t\tconst now = Date.now()\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tfor (const { collection, row, verdict } of actions) {\n\t\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\t\tif (verdict.kind === 'repair') {\n\t\t\t\t\tawait tx.execute(`UPDATE ${table} SET timestamp = ? WHERE rowid = ?`, [\n\t\t\t\t\t\tverdict.timestamp,\n\t\t\t\t\t\trow.__rowid,\n\t\t\t\t\t])\n\t\t\t\t} else if (verdict.kind === 'quarantine') {\n\t\t\t\t\tawait quarantineRow(tx, collection, row, verdict.problem, verdict.detail, now)\n\t\t\t\t\tawait tx.execute(`DELETE FROM ${table} WHERE rowid = ?`, [row.__rowid])\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tconst quarantined = await loadQuarantine(adapter)\n\tconst gaps = await findOwnSequenceGaps(adapter, schema, options.localNodeIds)\n\tconst compactedAt = await loadCompactedAt(adapter)\n\tconst pendingQuarantine = repair ? 0 : newlyQuarantined.length\n\treturn {\n\t\tclean: quarantined.length === 0 && pendingQuarantine === 0 && gaps.length === 0,\n\t\tmode,\n\t\tcheckedRows,\n\t\trepaired,\n\t\tnewlyQuarantined,\n\t\tquarantined,\n\t\tgaps,\n\t\tcompactedAt,\n\t\trepairApplied: repair,\n\t}\n}\n\n/**\n * Judge one operation row: canonical, repairable (with the repaired timestamp), or\n * to be quarantined.\n */\nexport function checkOperationRow(row: OperationRow): LogRowVerdict {\n\tif (\n\t\t!isNonEmptyString(row.id) ||\n\t\t!isNonEmptyString(row.node_id) ||\n\t\t!isNonEmptyString(row.record_id)\n\t) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'identity-malformed',\n\t\t\tdetail: 'id, node_id or record_id is missing',\n\t\t}\n\t}\n\tif (!OPERATION_TYPES.has(row.type)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'type-invalid',\n\t\t\tdetail: `type ${JSON.stringify(row.type)}`,\n\t\t}\n\t}\n\tif (!Number.isInteger(row.sequence_number) || row.sequence_number < 1) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'sequence-invalid',\n\t\t\tdetail: `sequence_number ${JSON.stringify(row.sequence_number)}`,\n\t\t}\n\t}\n\tif (!isJsonObjectOrNull(row.data) || !isJsonObjectOrNull(row.previous_data)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'data-malformed',\n\t\t\tdetail: 'data or previous_data is not a JSON object',\n\t\t}\n\t}\n\tif (!isJsonStringArray(row.causal_deps)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'causal-deps-malformed',\n\t\t\tdetail: `causal_deps ${truncate(String(row.causal_deps))}`,\n\t\t}\n\t}\n\n\tlet timestamp = row.timestamp\n\tlet repairedFrom: string | null = null\n\tif (!isCanonicalTimestamp(timestamp)) {\n\t\tconst recovered = recoverTimestamp(timestamp)\n\t\tif (recovered === null) {\n\t\t\treturn {\n\t\t\t\tkind: 'quarantine',\n\t\t\t\tproblem: 'timestamp-malformed',\n\t\t\t\tdetail: `timestamp ${truncate(String(timestamp))}`,\n\t\t\t}\n\t\t}\n\t\trepairedFrom = String(timestamp)\n\t\ttimestamp = recovered\n\t}\n\n\ttry {\n\t\tconst op = deserializeOperation({ ...row, timestamp })\n\t\tconst again = serializeOperation({ ...op, collection: '' })\n\t\tif (again.timestamp !== timestamp) {\n\t\t\tthrow new Error(`timestamp ${again.timestamp} != ${timestamp}`)\n\t\t}\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'round-trip-failed',\n\t\t\tdetail: error instanceof Error ? error.message : String(error),\n\t\t}\n\t}\n\n\tif (repairedFrom !== null) {\n\t\treturn {\n\t\t\tkind: 'repair',\n\t\t\tproblem: 'timestamp-json',\n\t\t\tdetail: `timestamp ${truncate(repairedFrom)} -> ${timestamp}`,\n\t\t\ttimestamp,\n\t\t}\n\t}\n\treturn { kind: 'ok' }\n}\n\n/** Whether `value` is the zero-padded `wall:logical:node` form that sorts like HLC order. */\nfunction isCanonicalTimestamp(value: unknown): value is string {\n\tif (typeof value !== 'string' || !CANONICAL_TIMESTAMP.test(value)) return false\n\ttry {\n\t\treturn HybridLogicalClock.serialize(HybridLogicalClock.deserialize(value)) === value\n\t} catch {\n\t\treturn false\n\t}\n}\n\ninterface LooseTimestamp {\n\twallTime: unknown\n\tlogical: unknown\n\tnodeId: unknown\n}\n\n/**\n * Recover the canonical timestamp from a JSON-encoded HLC (beta.12 restore wrote\n * `JSON.stringify(timestamp)`). A backup exported from such a database and restored\n * again nests the damage: `deserialize` read the JSON as `wallTime: NaN` (exported as\n * `null`), `logical: <wallTime>` and `nodeId: '<logical>,\"nodeId\":\"<nodeId>\"}'`, which\n * is undone level by level.\n */\nexport function recoverTimestamp(value: unknown): string | null {\n\tif (typeof value !== 'string' || !value.startsWith('{')) return null\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(value)\n\t} catch {\n\t\treturn null\n\t}\n\tlet candidate = parsed as LooseTimestamp\n\tfor (let depth = 0; depth < 8; depth++) {\n\t\tif (candidate === null || typeof candidate !== 'object') return null\n\t\tconst { wallTime, logical, nodeId } = candidate\n\t\tif (Number.isInteger(wallTime) && Number.isInteger(logical) && isNonEmptyString(nodeId)) {\n\t\t\ttry {\n\t\t\t\treturn HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: wallTime as number,\n\t\t\t\t\tlogical: logical as number,\n\t\t\t\t\tnodeId,\n\t\t\t\t})\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t}\n\t\t// One level of nesting: wallTime lost, logical holds the wall time, and nodeId\n\t\t// holds the rest of the inner JSON object.\n\t\tif (wallTime !== null || !Number.isInteger(logical) || typeof nodeId !== 'string') return null\n\t\tconst match = /^(\\d+),\"nodeId\":(\".*\")\\}$/.exec(nodeId)\n\t\tif (!match?.[1] || !match[2]) return null\n\t\tlet innerNode: unknown\n\t\ttry {\n\t\t\tinnerNode = JSON.parse(match[2])\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t\tcandidate = { wallTime: logical, logical: Number(match[1]), nodeId: innerNode }\n\t}\n\treturn null\n}\n\nasync function quarantineRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: RowWithRowid,\n\tproblem: LogRowProblem,\n\tdetail: string,\n\tnow: number,\n): Promise<void> {\n\tconst { __rowid: _rowid, ...original } = row\n\tawait tx.execute(\n\t\t`INSERT OR REPLACE INTO ${LOG_QUARANTINE_TABLE} (collection, operation_id, node_id, sequence_number, problem, detail, row_json, quarantined_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\tcollection,\n\t\t\ttypeof row.id === 'string' ? row.id : `rowid:${row.__rowid}`,\n\t\t\ttypeof row.node_id === 'string' ? row.node_id : null,\n\t\t\tNumber.isInteger(row.sequence_number) ? row.sequence_number : null,\n\t\t\tproblem,\n\t\t\tdetail,\n\t\t\tJSON.stringify(original, bytesReplacer),\n\t\t\tnow,\n\t\t],\n\t)\n}\n\ninterface QuarantineRow {\n\tcollection: string\n\toperation_id: string\n\tnode_id: string | null\n\tsequence_number: number | null\n\tproblem: string\n\tdetail: string\n}\n\nasync function loadQuarantine(adapter: StorageAdapter): Promise<LogIntegrityRow[]> {\n\tconst rows = await adapter.query<QuarantineRow>(\n\t\t`SELECT collection, operation_id, node_id, sequence_number, problem, detail FROM ${LOG_QUARANTINE_TABLE} ORDER BY quarantined_at ASC, collection ASC, operation_id ASC`,\n\t)\n\treturn rows.map((row) => ({\n\t\tcollection: row.collection,\n\t\toperationId: row.operation_id,\n\t\tnodeId: row.node_id,\n\t\tsequenceNumber: row.sequence_number,\n\t\tproblem: row.problem as LogRowProblem,\n\t\tdetail: row.detail,\n\t}))\n}\n\n/**\n * Holes in each own node's sequence below its highest stored number. Numbers held only\n * by `_kora_seq_conflicts` re-emissions are in the log under their new number, so the\n * log tables alone decide.\n */\nasync function findOwnSequenceGaps(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeIds: readonly string[],\n): Promise<LogSequenceGap[]> {\n\tconst collections = Object.keys(schema.collections)\n\tif (collections.length === 0) return []\n\tconst gaps: LogSequenceGap[] = []\n\tconst union = collections\n\t\t.map((c) => `SELECT sequence_number FROM ${quoteIdent(`_kora_ops_${c}`)} WHERE node_id = ?`)\n\t\t.join(' UNION ALL ')\n\tfor (const nodeId of [...new Set(nodeIds)]) {\n\t\tconst params = collections.map(() => nodeId)\n\t\tconst summary = await adapter.query<{ n: number; m: number | null }>(\n\t\t\t`SELECT COUNT(DISTINCT sequence_number) AS n, MAX(sequence_number) AS m FROM (${union})`,\n\t\t\tparams,\n\t\t)\n\t\tconst count = summary[0]?.n ?? 0\n\t\tconst max = summary[0]?.m ?? 0\n\t\tif (max === null || max === 0 || count === max) continue\n\t\tconst present = await adapter.query<{ sequence_number: number }>(\n\t\t\t`SELECT DISTINCT sequence_number FROM (${union}) ORDER BY sequence_number ASC`,\n\t\t\tparams,\n\t\t)\n\t\tlet expected = 1\n\t\tfor (const { sequence_number: seq } of present) {\n\t\t\tif (seq > expected) gaps.push({ nodeId, from: expected, to: seq - 1 })\n\t\t\texpected = Math.max(expected, seq + 1)\n\t\t}\n\t}\n\treturn gaps\n}\n\nasync function loadCompactedAt(adapter: StorageAdapter): Promise<number | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tCOMPACTION_BASELINE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value)\n\treturn rows[0] && Number.isFinite(value) ? value : null\n}\n\nfunction describeRow(\n\tcollection: string,\n\trow: OperationRow,\n\tproblem: LogRowProblem,\n\tdetail: string,\n): LogIntegrityRow {\n\treturn {\n\t\tcollection,\n\t\toperationId: typeof row.id === 'string' ? row.id : '',\n\t\tnodeId: typeof row.node_id === 'string' ? row.node_id : null,\n\t\tsequenceNumber: Number.isInteger(row.sequence_number) ? row.sequence_number : null,\n\t\tproblem,\n\t\tdetail,\n\t}\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === 'string' && value.length > 0\n}\n\nfunction isJsonObjectOrNull(value: unknown): boolean {\n\tif (value === null || value === undefined) return true\n\tif (typeof value !== 'string') return false\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction isJsonStringArray(value: unknown): boolean {\n\tif (typeof value !== 'string') return false\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn Array.isArray(parsed) && parsed.every((id) => typeof id === 'string')\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction truncate(value: string): string {\n\treturn value.length > 120 ? `${value.slice(0, 117)}...` : value\n}\n\nfunction bytesReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) return { $bytes: Array.from(value) }\n\treturn value\n}\n","import { HybridLogicalClock, KoraError, quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n} from '../fold/record-folder'\nimport { checkOperationRow, recoverTimestamp } from '../log-integrity/log-integrity'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE } from '../store/sequence-repair'\nimport { TERMINAL_REJECTIONS_TABLE, type TerminalRejection } from '../sync/local-sync-records'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport type { BackupManifest, BackupOptions, RestoreOptions, RestoreResult } from './types'\n\n// ── Format ──────────────────────────────────────────────────────────────────\n//\n// A backup is a sequence of sections `[u32 nameLen][u32 contentLen][name][content]`:\n//\n// manifest JSON BackupManifest (first section)\n// version_vector JSON { nodeId: maxSequence } of the exporting database\n// operations NDJSON, one canonical Operation per line (collection, data,\n// previousData, HLC timestamp object, atomicOps, transactionId,\n// mutationName, fieldVersions), in HLC order. Includes\n// operations kept only in the sequence-conflicts table.\n// terminal_rejections JSON TerminalRejection[] (operations the server refused for good)\n// fold_base NDJSON { collection, recordId, state }: per-record fold states of\n// compacted operations (W7, RT-66); a restore keeps them\n// fold_snapshot NDJSON { collection, recordId, state }: per-record row snapshots\n// (approximate bases, RT-68)\n// compacted_through JSON { nodeId: sequence }: per-node prefix folded into the bases\n// records:<name> NDJSON raw rows of the collection, tombstones included, bytes\n// tagged as { \"$bytes\": \"<base64>\" }\n// checksum SHA-256 hex over every section between manifest and checksum\n//\n// Version 2 (STORE-5) carries no `_kora_meta`: a device's identity (node id, node\n// tokens) and sync state never travel in a backup. Version 1 files are refused with\n// BACKUP_FORMAT_OUTDATED; {@link convertBackupV1} converts them.\n\n/** Current backup format version. */\nexport const BACKUP_VERSION = 2\n\n/** A backup file this release cannot restore as-is. */\nexport class BackupFormatError extends KoraError {\n\tconstructor(message: string, code: string, context?: Record<string, unknown>) {\n\t\tsuper(message, code, context)\n\t\tthis.name = 'BackupFormatError'\n\t}\n}\n\nfunction encodeSection(name: string, content: Uint8Array): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(name)\n\tconst result = new Uint8Array(8 + nameBytes.length + content.length)\n\tconst dv = new DataView(result.buffer)\n\tdv.setUint32(0, nameBytes.length, true)\n\tdv.setUint32(4, content.length, true)\n\tresult.set(nameBytes, 8)\n\tresult.set(content, 8 + nameBytes.length)\n\treturn result\n}\n\nfunction encodeJsonSection(name: string, data: unknown): Uint8Array {\n\treturn encodeSection(name, new TextEncoder().encode(JSON.stringify(data, bytesReplacer)))\n}\n\nfunction encodeNdjsonSection(name: string, items: unknown[]): Uint8Array {\n\tconst lines = items.map((item) => JSON.stringify(item, bytesReplacer)).join('\\n')\n\treturn encodeSection(name, new TextEncoder().encode(items.length > 0 ? `${lines}\\n` : ''))\n}\n\ninterface Section {\n\tname: string\n\tcontent: Uint8Array\n}\n\nfunction parseSections(data: Uint8Array): Section[] {\n\tconst sections: Section[] = []\n\tconst dv = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\tlet offset = 0\n\twhile (offset + 8 <= data.byteLength) {\n\t\tconst nameLen = dv.getUint32(offset, true)\n\t\tconst contentLen = dv.getUint32(offset + 4, true)\n\t\toffset += 8\n\t\tif (offset + nameLen + contentLen > data.byteLength) break\n\t\tconst name = new TextDecoder().decode(data.slice(offset, offset + nameLen))\n\t\toffset += nameLen\n\t\tsections.push({ name, content: data.slice(offset, offset + contentLen) })\n\t\toffset += contentLen\n\t}\n\treturn sections\n}\n\nfunction findSection(sections: Section[], name: string): Uint8Array | null {\n\treturn sections.find((section) => section.name === name)?.content ?? null\n}\n\nfunction parseJsonSection<T>(sections: Section[], name: string): T | null {\n\tconst content = findSection(sections, name)\n\tif (!content) return null\n\treturn JSON.parse(new TextDecoder().decode(content), bytesReviver) as T\n}\n\nfunction parseNdjson<T>(content: Uint8Array | null): T[] {\n\tif (!content) return []\n\treturn new TextDecoder()\n\t\t.decode(content)\n\t\t.split('\\n')\n\t\t.filter((line) => line.trim().length > 0)\n\t\t.map((line) => JSON.parse(line, bytesReviver) as T)\n}\n\nfunction concat(parts: Uint8Array[]): Uint8Array {\n\tconst total = parts.reduce((sum, part) => sum + part.length, 0)\n\tconst result = new Uint8Array(total)\n\tlet pos = 0\n\tfor (const part of parts) {\n\t\tresult.set(part, pos)\n\t\tpos += part.length\n\t}\n\treturn result\n}\n\n// ── Export ──────────────────────────────────────────────────────────────────\n\n/**\n * Export a backup (format version 2) from an opened database.\n *\n * Everything is read inside one transaction, so the backup is a consistent snapshot.\n * Operations are exported in canonical form (exactly what `deserializeOperation` reads\n * back), including tombstones, so a restore rebuilds the same log.\n *\n * @param adapter - The storage adapter\n * @param schema - The schema definition\n * @param nodeId - Node id of the exporting device (informational only; never imported)\n * @param schemaVersion - Schema version\n * @param options - Backup options\n * @returns Backup as a Uint8Array\n */\nexport async function exportBackup(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n\tschemaVersion: number,\n\toptions?: BackupOptions,\n): Promise<Uint8Array> {\n\tconst onProgress = options?.onProgress ?? (() => {})\n\tconst includeRecords = options?.includeRecords ?? true\n\tconst filter = options?.collections\n\tconst collections = Object.keys(schema.collections).filter(\n\t\t(name) => !filter || filter.includes(name),\n\t)\n\n\tconst snapshot: {\n\t\tvector: Record<string, number>\n\t\toperations: Operation[]\n\t\tterminal: TerminalRejection[]\n\t\trecords: Map<string, Array<Record<string, unknown>>>\n\t\tbases: FoldStateRow[]\n\t\tsnapshots: FoldStateRow[]\n\t\tcompactedThrough: Record<string, number>\n\t\tcompacted: boolean\n\t} = {\n\t\tvector: {},\n\t\toperations: [],\n\t\tterminal: [],\n\t\trecords: new Map(),\n\t\tbases: [],\n\t\tsnapshots: [],\n\t\tcompactedThrough: {},\n\t\tcompacted: false,\n\t}\n\n\tonProgress({ phase: 'reading', progress: 0, message: 'Reading the local database' })\n\tawait adapter.transaction(async (tx) => {\n\t\tconst vector = await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tfor (const row of vector) snapshot.vector[row.node_id] = row.sequence_number\n\t\tsnapshot.operations = await readOperations(tx, collections)\n\t\tsnapshot.terminal = await readTerminalRejections(tx)\n\t\t// W7 (RT-66): compacted history lives only in the base states; without them a\n\t\t// restore on another device would rebuild records from an incomplete log.\n\t\tsnapshot.bases = await readFoldStateRows(tx, FOLD_BASE_TABLE, collections)\n\t\tsnapshot.snapshots = await readFoldStateRows(tx, FOLD_SNAPSHOT_TABLE, collections)\n\t\tif (await hasTable(tx, COMPACTED_THROUGH_TABLE)) {\n\t\t\tfor (const row of await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t\t`SELECT node_id, sequence_number FROM ${COMPACTED_THROUGH_TABLE}`,\n\t\t\t)) {\n\t\t\t\tsnapshot.compactedThrough[row.node_id] = row.sequence_number\n\t\t\t}\n\t\t}\n\t\tsnapshot.compacted =\n\t\t\tsnapshot.bases.length > 0 ||\n\t\t\tObject.keys(snapshot.compactedThrough).length > 0 ||\n\t\t\t(\n\t\t\t\tawait tx.query<{ value: string }>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\t\t])\n\t\t\t).length > 0\n\t\tif (includeRecords) {\n\t\t\tfor (const collection of collections) {\n\t\t\t\tsnapshot.records.set(\n\t\t\t\t\tcollection,\n\t\t\t\t\tawait tx.query<Record<string, unknown>>(`SELECT * FROM ${quoteIdent(collection)}`),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t})\n\tonProgress({ phase: 'reading', progress: 0.7, message: 'Encoding' })\n\n\tconst content: Uint8Array[] = [\n\t\tencodeJsonSection('version_vector', snapshot.vector),\n\t\tencodeNdjsonSection('operations', snapshot.operations),\n\t\tencodeJsonSection('terminal_rejections', snapshot.terminal),\n\t\tencodeNdjsonSection('fold_base', snapshot.bases),\n\t\tencodeNdjsonSection('fold_snapshot', snapshot.snapshots),\n\t\tencodeJsonSection('compacted_through', snapshot.compactedThrough),\n\t]\n\tfor (const [collection, rows] of snapshot.records) {\n\t\tif (rows.length > 0) content.push(encodeNdjsonSection(`records:${collection}`, rows))\n\t}\n\tconst body = concat(content)\n\tconst checksum = await computeSha256(body)\n\tonProgress({ phase: 'writing', progress: 1, message: 'Finalizing' })\n\n\tconst manifest: BackupManifest = {\n\t\tversion: BACKUP_VERSION,\n\t\tcreatedAt: Date.now(),\n\t\tnodeId,\n\t\tschemaVersion,\n\t\toperationCount: snapshot.operations.length,\n\t\tcollections,\n\t\tincludesRecords: includeRecords,\n\t\tincludesTombstones: true,\n\t\tincludesFoldState: true,\n\t\tcompacted: snapshot.compacted,\n\t\tchecksum,\n\t}\n\treturn concat([\n\t\tencodeJsonSection('manifest', manifest),\n\t\tbody,\n\t\tencodeSection('checksum', new TextEncoder().encode(checksum)),\n\t])\n}\n\n/** Operations of `collections` in canonical form and HLC order (causal order). */\nasync function readOperations(tx: Transaction, collections: string[]): Promise<Operation[]> {\n\tconst operations: Operation[] = []\n\tconst seen = new Set<string>()\n\tconst retained = await hasTable(tx, SEQ_CONFLICTS_TABLE)\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} ORDER BY sequence_number ASC`,\n\t\t)\n\t\t// Other nodes' operations kept only in the sequence-conflicts table still belong\n\t\t// to the log (record folds and dedup use them).\n\t\tif (retained) {\n\t\t\trows.push(\n\t\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND reemitted_as IS NULL`,\n\t\t\t\t\t[collection],\n\t\t\t\t)),\n\t\t\t)\n\t\t}\n\t\tfor (const row of rows) {\n\t\t\tif (seen.has(row.id)) continue\n\t\t\tseen.add(row.id)\n\t\t\toperations.push(deserializeOperationWithCollection(row, collection))\n\t\t}\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\treturn operations\n}\n\n/** One per-record fold state row (`_kora_fold_base` / `_kora_fold_snapshot`) in a backup. */\nexport interface FoldStateRow {\n\tcollection: string\n\trecordId: string\n\t/** The serialized `FoldState`, as stored. */\n\tstate: string\n}\n\nasync function readFoldStateRows(\n\ttx: Transaction,\n\ttable: string,\n\tcollections: string[],\n): Promise<FoldStateRow[]> {\n\tif (!(await hasTable(tx, table))) return []\n\tconst out: FoldStateRow[] = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ record_id: string; state: string }>(\n\t\t\t`SELECT record_id, state FROM ${table} WHERE collection = ? ORDER BY record_id`,\n\t\t\t[collection],\n\t\t)\n\t\tfor (const row of rows) out.push({ collection, recordId: row.record_id, state: row.state })\n\t}\n\treturn out\n}\n\nasync function readTerminalRejections(tx: Transaction): Promise<TerminalRejection[]> {\n\tif (!(await hasTable(tx, TERMINAL_REJECTIONS_TABLE))) return []\n\tconst rows = await tx.query<{\n\t\toperation_id: string\n\t\tnode_id: string | null\n\t\tsequence_number: number | null\n\t\tcode: string\n\t\trejected_at: number\n\t}>(\n\t\t`SELECT operation_id, node_id, sequence_number, code, rejected_at FROM ${TERMINAL_REJECTIONS_TABLE} ORDER BY operation_id`,\n\t)\n\treturn rows.map((row) => ({\n\t\toperationId: row.operation_id,\n\t\tnodeId: row.node_id,\n\t\tsequenceNumber: row.sequence_number,\n\t\tcode: row.code,\n\t\trejectedAt: row.rejected_at,\n\t}))\n}\n\nasync function hasTable(tx: Transaction, name: string): Promise<boolean> {\n\tconst rows = await tx.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[name],\n\t)\n\treturn rows.length > 0\n}\n\n// ── Parse ───────────────────────────────────────────────────────────────────\n\n/** A verified, parsed version-2 backup. */\nexport interface ParsedBackup {\n\tmanifest: BackupManifest\n\t/** Canonical operations of the requested collections, in HLC order. */\n\toperations: Operation[]\n\t/** Version vector of the exporting database. */\n\tversionVector: Map<string, number>\n\tterminalRejections: TerminalRejection[]\n\t/** Raw rows per collection (present only when the manifest includes records). */\n\trecords: Map<string, Array<Record<string, unknown>>>\n\t/** Per-record compacted base states of the requested collections (RT-66). */\n\tfoldBases: FoldStateRow[]\n\t/** Per-record row snapshots of the requested collections (RT-68). */\n\tfoldSnapshots: FoldStateRow[]\n\t/** Per node, the sequence prefix compacted into the bases. */\n\tcompactedThrough: Map<string, number>\n}\n\n/**\n * Read backup manifest without loading the entire backup.\n *\n * @param data - The raw backup data\n * @returns The backup manifest\n */\nexport function readBackupManifest(data: Uint8Array): BackupManifest {\n\tconst manifest = parseJsonSection<BackupManifest>(parseSections(data), 'manifest')\n\tif (!manifest) {\n\t\tthrow new BackupFormatError('Invalid backup: manifest section not found', 'BACKUP_INVALID')\n\t}\n\treturn manifest\n}\n\n/**\n * Validate the backup checksum.\n *\n * @param data - The raw backup data\n * @returns True if the checksum is valid\n */\nexport async function verifyBackupChecksum(data: Uint8Array): Promise<boolean> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest?.checksum) return false\n\tconst body = concat(\n\t\tsections\n\t\t\t.filter((s) => s.name !== 'manifest' && s.name !== 'checksum')\n\t\t\t.map((s) => encodeSection(s.name, s.content)),\n\t)\n\treturn (await computeSha256(body)) === manifest.checksum\n}\n\n/**\n * Parse and verify a backup: format version, checksum, and every operation must be\n * canonical (it round-trips through the operation serializer). Throws\n * {@link BackupFormatError}; nothing is written.\n *\n * @param data - The raw backup data\n * @param options - `collections` keeps only those collections\n */\nexport async function parseBackup(\n\tdata: Uint8Array,\n\toptions?: { collections?: string[] },\n): Promise<ParsedBackup> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest) {\n\t\tthrow new BackupFormatError('Invalid backup: manifest section not found', 'BACKUP_INVALID')\n\t}\n\tif (manifest.version === 1) {\n\t\tthrow new BackupFormatError(\n\t\t\t'This backup was written by Kora 1.0.0-beta.12 or earlier (format version 1), whose restore corrupted operation timestamps and copied the exporting device identity. Convert it first: `restoreBackup`/`importBackup(await convertBackupV1(data))`.',\n\t\t\t'BACKUP_FORMAT_OUTDATED',\n\t\t\t{ version: 1, fix: 'Call convertBackupV1(data) and import the result.' },\n\t\t)\n\t}\n\tif (manifest.version !== BACKUP_VERSION) {\n\t\tthrow new BackupFormatError(\n\t\t\t`Unsupported backup version: ${String(manifest.version)} (this release reads version ${BACKUP_VERSION}).`,\n\t\t\t'BACKUP_VERSION_UNSUPPORTED',\n\t\t\t{ version: manifest.version },\n\t\t)\n\t}\n\tif (!(await verifyBackupChecksum(data))) {\n\t\tthrow new BackupFormatError(\n\t\t\t'Backup checksum mismatch: data may be corrupted',\n\t\t\t'BACKUP_CHECKSUM_MISMATCH',\n\t\t)\n\t}\n\n\tconst keep = (collection: string): boolean =>\n\t\t!options?.collections || options.collections.includes(collection)\n\tconst operations: Operation[] = []\n\tfor (const raw of parseNdjson<Operation>(findSection(sections, 'operations'))) {\n\t\tif (!keep(raw.collection)) continue\n\t\toperations.push(canonicalOperation(raw))\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst vector = new Map<string, number>()\n\tfor (const [nodeId, seq] of Object.entries(\n\t\tparseJsonSection<Record<string, number>>(sections, 'version_vector') ?? {},\n\t)) {\n\t\tif (Number.isInteger(seq) && seq > 0) vector.set(nodeId, seq)\n\t}\n\n\tconst records = new Map<string, Array<Record<string, unknown>>>()\n\tif (manifest.includesRecords) {\n\t\tfor (const collection of manifest.collections) {\n\t\t\tif (!keep(collection)) continue\n\t\t\trecords.set(\n\t\t\t\tcollection,\n\t\t\t\tparseNdjson<Record<string, unknown>>(findSection(sections, `records:${collection}`)),\n\t\t\t)\n\t\t}\n\t}\n\n\tconst foldRows = (name: string): FoldStateRow[] =>\n\t\tparseNdjson<FoldStateRow>(findSection(sections, name)).filter(\n\t\t\t(row) =>\n\t\t\t\ttypeof row?.collection === 'string' &&\n\t\t\t\ttypeof row.recordId === 'string' &&\n\t\t\t\ttypeof row.state === 'string' &&\n\t\t\t\tkeep(row.collection),\n\t\t)\n\tconst compactedThrough = new Map<string, number>()\n\tfor (const [nodeId, seq] of Object.entries(\n\t\tparseJsonSection<Record<string, number>>(sections, 'compacted_through') ?? {},\n\t)) {\n\t\tif (Number.isInteger(seq) && seq > 0) compactedThrough.set(nodeId, seq)\n\t}\n\n\treturn {\n\t\tmanifest,\n\t\toperations,\n\t\tversionVector: vector,\n\t\tterminalRejections:\n\t\t\tparseJsonSection<TerminalRejection[]>(sections, 'terminal_rejections') ?? [],\n\t\trecords,\n\t\tfoldBases: foldRows('fold_base'),\n\t\tfoldSnapshots: foldRows('fold_snapshot'),\n\t\tcompactedThrough,\n\t}\n}\n\n/** Re-read an exported operation through the log serializer; refuse a damaged one. */\nfunction canonicalOperation(raw: Operation): Operation {\n\tlet row: OperationRow\n\ttry {\n\t\trow = serializeOperation(raw)\n\t} catch (error) {\n\t\tthrow new BackupFormatError(\n\t\t\t`Backup operation ${String(raw?.id)} is not a valid operation: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationId: raw?.id },\n\t\t)\n\t}\n\tconst verdict = checkOperationRow(row)\n\tif (verdict.kind !== 'ok' || typeof raw.collection !== 'string' || raw.collection === '') {\n\t\tthrow new BackupFormatError(\n\t\t\t`Backup operation ${String(raw.id)} is not canonical (${verdict.kind === 'ok' ? 'no collection' : verdict.problem}).`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationId: raw.id },\n\t\t)\n\t}\n\treturn deserializeOperationWithCollection(row, raw.collection)\n}\n\n// ── Version 1 conversion ────────────────────────────────────────────────────\n\n/** Options for {@link convertBackupV1}. */\nexport interface ConvertBackupV1Options {\n\t/**\n\t * Drop operations whose timestamp cannot be recovered instead of refusing the file.\n\t * Default false.\n\t */\n\tdropUnrecoverable?: boolean\n}\n\n/**\n * Convert a version-1 backup (Kora 1.0.0-beta.12 and earlier) to version 2.\n *\n * - Operations: a v1 file exported from a database that a v1 restore had damaged holds\n * misread timestamps (`wallTime: null`); they are recovered from the misread values\n * (the same rule as the log-integrity scan). An unrecoverable one refuses the file\n * unless `dropUnrecoverable` is set.\n * - The `meta` section (the exporting device's node id, node tokens, sync state) is\n * dropped: it must never be imported into another database.\n * - Record rows are kept; v1 exported live rows only, so the manifest records\n * `includesTombstones: false`. Bytes that v1 serialized as `{\"0\":..,\"1\":..}` objects\n * are decoded on restore.\n *\n * @throws {BackupFormatError} When the input is not a valid version-1 backup\n */\nexport async function convertBackupV1(\n\tdata: Uint8Array,\n\toptions?: ConvertBackupV1Options,\n): Promise<Uint8Array> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest || manifest.version !== 1) {\n\t\tthrow new BackupFormatError('convertBackupV1 expects a version-1 backup.', 'BACKUP_INVALID', {\n\t\t\tversion: manifest?.version,\n\t\t})\n\t}\n\tif (!(await verifyBackupChecksum(data))) {\n\t\tthrow new BackupFormatError(\n\t\t\t'Backup checksum mismatch: data may be corrupted',\n\t\t\t'BACKUP_CHECKSUM_MISMATCH',\n\t\t)\n\t}\n\tconst operations: Operation[] = []\n\tconst dropped: string[] = []\n\tfor (const raw of parseNdjson<Operation>(findSection(sections, 'operations'))) {\n\t\tconst fixed = recoverV1Operation(raw)\n\t\tif (fixed) operations.push(fixed)\n\t\telse dropped.push(String(raw?.id))\n\t}\n\tif (dropped.length > 0 && !options?.dropUnrecoverable) {\n\t\tthrow new BackupFormatError(\n\t\t\t`${dropped.length} operation(s) in this version-1 backup have unrecoverable timestamps (first: ${dropped[0]}). Pass { dropUnrecoverable: true } to convert without them.`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationIds: dropped.slice(0, 20) },\n\t\t)\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst content: Uint8Array[] = [\n\t\tencodeJsonSection(\n\t\t\t'version_vector',\n\t\t\tparseJsonSection<Record<string, number>>(sections, 'version_vector') ?? {},\n\t\t),\n\t\tencodeNdjsonSection('operations', operations),\n\t\tencodeJsonSection('terminal_rejections', []),\n\t]\n\tfor (const section of sections) {\n\t\tif (section.name.startsWith('records:')) {\n\t\t\tconst rows = parseNdjson<Record<string, unknown>>(section.content).map(decodeV1Bytes)\n\t\t\tcontent.push(encodeNdjsonSection(section.name, rows))\n\t\t}\n\t}\n\tconst body = concat(content)\n\tconst checksum = await computeSha256(body)\n\tconst converted: BackupManifest = {\n\t\tversion: BACKUP_VERSION,\n\t\tcreatedAt: manifest.createdAt,\n\t\tnodeId: manifest.nodeId,\n\t\tschemaVersion: manifest.schemaVersion,\n\t\toperationCount: operations.length,\n\t\tcollections: manifest.collections,\n\t\tincludesRecords: manifest.includesRecords,\n\t\tincludesTombstones: false,\n\t\tchecksum,\n\t\tconvertedFrom: 1,\n\t}\n\treturn concat([\n\t\tencodeJsonSection('manifest', converted),\n\t\tbody,\n\t\tencodeSection('checksum', new TextEncoder().encode(checksum)),\n\t])\n}\n\nfunction recoverV1Operation(raw: Operation): Operation | null {\n\tif (!raw || typeof raw !== 'object' || typeof raw.id !== 'string') return null\n\tconst ts = raw.timestamp as unknown\n\tlet timestamp = ts as Operation['timestamp']\n\tconst valid =\n\t\tts !== null &&\n\t\ttypeof ts === 'object' &&\n\t\tNumber.isInteger((ts as { wallTime: unknown }).wallTime) &&\n\t\tNumber.isInteger((ts as { logical: unknown }).logical)\n\tif (!valid) {\n\t\tconst recovered = recoverTimestamp(JSON.stringify(ts))\n\t\tif (!recovered) return null\n\t\ttimestamp = HybridLogicalClock.deserialize(recovered)\n\t}\n\ttry {\n\t\treturn canonicalOperation({ ...raw, timestamp })\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/** v1 wrote Uint8Array columns through JSON.stringify: `{\"0\":1,\"1\":2}`. */\nfunction decodeV1Bytes(row: Record<string, unknown>): Record<string, unknown> {\n\tconst out: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(row)) {\n\t\tout[key] = looksLikeSerializedBytes(value) ? toBytes(value as Record<string, number>) : value\n\t}\n\treturn out\n}\n\nfunction looksLikeSerializedBytes(value: unknown): boolean {\n\tif (value === null || typeof value !== 'object' || Array.isArray(value)) return false\n\tconst entries = Object.entries(value as Record<string, unknown>)\n\tif (entries.length === 0) return false\n\treturn entries.every(\n\t\t([key, byte], index) =>\n\t\t\tkey === String(index) &&\n\t\t\tNumber.isInteger(byte) &&\n\t\t\t(byte as number) >= 0 &&\n\t\t\t(byte as number) < 256,\n\t)\n}\n\nfunction toBytes(value: Record<string, number>): Uint8Array {\n\tconst length = Object.keys(value).length\n\tconst bytes = new Uint8Array(length)\n\tfor (let i = 0; i < length; i++) bytes[i] = value[String(i)] ?? 0\n\treturn bytes\n}\n\n// ── Low-level restore (deprecated entry point) ─────────────────────────────\n\n/**\n * Restore a backup into the database behind `adapter`.\n *\n * @deprecated Use `store.importBackup()` / `app.importBackup()`: restoring needs the\n * store (the device's identity, version vector, clock and live queries). This entry\n * point opens a temporary `Store` on `adapter`, imports, and CLOSES the adapter.\n *\n * @param adapter - A storage adapter no store is using\n * @param schema - The schema definition\n * @param data - The backup data\n * @param options - Restore options\n */\nexport async function restoreBackup(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tdata: Uint8Array,\n\toptions?: RestoreOptions,\n): Promise<RestoreResult> {\n\tconst { Store } = await import('../store/store')\n\tconst store = new Store({ schema, adapter })\n\tawait store.open()\n\ttry {\n\t\treturn await store.importBackup(data, options)\n\t} finally {\n\t\tawait store.close()\n\t}\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction bytesReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) return { $bytes: toBase64(value) }\n\treturn value\n}\n\nfunction bytesReviver(_key: string, value: unknown): unknown {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\t!Array.isArray(value) &&\n\t\tObject.keys(value).length === 1 &&\n\t\ttypeof (value as { $bytes?: unknown }).$bytes === 'string'\n\t) {\n\t\treturn fromBase64((value as { $bytes: string }).$bytes)\n\t}\n\treturn value\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n\tlet binary = ''\n\tconst CHUNK = 0x8000\n\tfor (let i = 0; i < bytes.length; i += CHUNK) {\n\t\tbinary += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n\t}\n\treturn btoa(binary)\n}\n\nfunction fromBase64(text: string): Uint8Array {\n\tconst binary = atob(text)\n\tconst bytes = new Uint8Array(binary.length)\n\tfor (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n\treturn bytes\n}\n\nasync function computeSha256(data: Uint8Array): Promise<string> {\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', new Uint8Array(data))\n\treturn Array.from(new Uint8Array(hashBuffer))\n\t\t.map((b) => b.toString(16).padStart(2, '0'))\n\t\t.join('')\n}\n","import type {\n\tCausalTracker,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { RecordFolder } from '../fold/record-folder'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport type { Transaction } from '../types'\n\n/**\n * Called inside the write transaction for every local delete, after the delete\n * operation is built and before referential side effects run. Lets the unified\n * apply pipeline run its referential checks (and emit their traces) against the\n * rows the transaction sees. Throwing aborts the whole write.\n */\nexport type LocalDeleteHook = (operation: Operation, tx: Transaction) => Promise<void>\n\n/**\n * Everything the single local write path needs to build and persist an\n * operation inside a storage transaction. One environment serves single-record\n * writes, `app.transaction` commits and referential cascades, so every local\n * operation is built the same way (W6).\n */\nexport interface WriteEnv {\n\treadonly schema: SchemaDefinition\n\treadonly clock: HybridLogicalClock\n\treadonly nodeId: string\n\treadonly relationEnforcer: RelationEnforcer | null\n\treadonly secretKeyProvider?: SecretKeyProvider\n\t/** Shared by every operation of an `app.transaction` / `app.mutation` commit. */\n\treadonly transactionId?: string\n\t/** Human-readable mutation name propagated to every operation (DevTools). */\n\treadonly mutationName?: string\n\t/** See {@link LocalDeleteHook}. */\n\treadonly beforeLocalDelete?: LocalDeleteHook\n\t/**\n\t * The W7 record fold. When set, a local write appends its operation and then\n\t * merges it into the record's fold state, which re-materializes the row (the\n\t * same path remote operations take). Absent only under\n\t * `experimental.legacyMerge` (and while a pre-W7 database is migrated, before its\n\t * re-materialization): the row is then written directly, as in beta.12.\n\t */\n\treadonly fold?: RecordFolder\n\t/**\n\t * Largest operation a local write may produce (RT-86), the server's\n\t * `maxOperationBytes`. Default `DEFAULT_MAX_OPERATION_BYTES` (256 KiB).\n\t */\n\treadonly maxOperationBytes?: number\n}\n\n/**\n * Causal bookkeeping for the operations built inside ONE storage transaction.\n *\n * Dependencies are computed from the committed causal heads (the shared\n * {@link CausalTracker}) overlaid with the operations already built in this\n * transaction. Heads are published to the shared tracker only after the\n * transaction commits, so a rolled-back write never leaves a dependency on an\n * operation that does not exist.\n */\nexport class CausalScope {\n\tprivate readonly lastByCollection = new Map<string, string>()\n\tprivate lastInScope: string | null = null\n\tprivate readonly recorded: Array<{ collection: string; id: string }> = []\n\n\tconstructor(\n\t\tprivate readonly tracker: CausalTracker | null,\n\t\t/** When true, every operation also depends on the previous one in this scope. */\n\t\tprivate readonly chainOperations: boolean,\n\t) {}\n\n\t/**\n\t * Direct causal parents for the next operation in `collection`.\n\t *\n\t * @param collection - Collection of the operation being built\n\t * @param extra - Explicit parents (e.g. the delete that caused a cascade)\n\t */\n\tdepsFor(collection: string, extra: readonly string[] = []): string[] {\n\t\tconst deps: string[] = []\n\t\tconst add = (id: string | undefined | null): void => {\n\t\t\tif (id && !deps.includes(id)) deps.push(id)\n\t\t}\n\t\tfor (const id of extra) add(id)\n\t\tconst local = this.lastByCollection.get(collection)\n\t\tif (local !== undefined) {\n\t\t\tadd(local)\n\t\t} else {\n\t\t\tfor (const id of this.tracker?.nextCausalDeps(collection, false) ?? []) add(id)\n\t\t}\n\t\tif (this.chainOperations) add(this.lastInScope)\n\t\treturn deps\n\t}\n\n\t/** Record an operation built in this scope. */\n\trecord(collection: string, operationId: string): void {\n\t\tthis.lastByCollection.set(collection, operationId)\n\t\tthis.lastInScope = operationId\n\t\tthis.recorded.push({ collection, id: operationId })\n\t}\n\n\t/** Publish this scope's heads to the shared tracker. Call only after commit. */\n\tpublish(): void {\n\t\tfor (const { collection, id } of this.recorded) {\n\t\t\tthis.tracker?.afterOperation(collection, id, false)\n\t\t}\n\t}\n}\n\n/**\n * The sequence-number block of ONE write transaction.\n *\n * The first number is reserved with one `UPSERT ... RETURNING` on\n * `_kora_version_vector`, inside the transaction; later numbers continue the block\n * in memory, and {@link SequenceBlock.close} persists the block's end with one\n * write before the transaction commits. Write transactions are serialized and no\n * code path allocates numbers outside one, so the block is contiguous and never\n * shared; the UNIQUE `(node_id, sequence_number)` index on every op table is the\n * backstop. A rollback discards the reservation with everything else.\n */\nexport class SequenceBlock {\n\tprivate last: number | null = null\n\tprivate persisted = 0\n\n\tconstructor(\n\t\tprivate readonly tx: Transaction,\n\t\tprivate readonly nodeId: string,\n\t) {}\n\n\t/** The next number of the block. */\n\tasync take(): Promise<number> {\n\t\tif (this.last === null) {\n\t\t\tconst rows = await this.tx.query<{ sequence_number: number }>(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, 1)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = sequence_number + 1\n RETURNING sequence_number`,\n\t\t\t\t[this.nodeId],\n\t\t\t)\n\t\t\tconst first = rows[0]?.sequence_number\n\t\t\tif (first === undefined) {\n\t\t\t\tthrow new KoraError(\n\t\t\t\t\t`Failed to reserve a sequence number for node \"${this.nodeId}\"`,\n\t\t\t\t\t'SEQUENCE_RESERVATION_FAILED',\n\t\t\t\t\t{ nodeId: this.nodeId },\n\t\t\t\t)\n\t\t\t}\n\t\t\tthis.last = first\n\t\t\tthis.persisted = first\n\t\t\treturn first\n\t\t}\n\t\tthis.last += 1\n\t\treturn this.last\n\t}\n\n\t/** Persist the end of the block. Must run inside the transaction, before commit. */\n\tasync close(): Promise<void> {\n\t\tif (this.last === null || this.last === this.persisted) return\n\t\tawait this.tx.execute(\n\t\t\t'UPDATE _kora_version_vector SET sequence_number = MAX(sequence_number, ?) WHERE node_id = ?',\n\t\t\t[this.last, this.nodeId],\n\t\t)\n\t\tthis.persisted = this.last\n\t}\n}\n\n/**\n * The per-transaction state of a local write: the transaction handle, its\n * sequence block and its causal scope. Every operation built in one transaction\n * takes the next number of the same contiguous block.\n */\nexport interface WriteScope {\n\treadonly tx: Transaction\n\treadonly sequence: SequenceBlock\n\treadonly causal: CausalScope\n}\n\n/**\n * Run `write` with a fresh {@link WriteScope} on `tx`, then close the sequence\n * block (still inside the transaction).\n */\nexport async function withWriteScope<T>(\n\ttx: Transaction,\n\tnodeId: string,\n\tcausal: CausalScope,\n\twrite: (scope: WriteScope) => Promise<T>,\n): Promise<T> {\n\tconst scope: WriteScope = { tx, sequence: new SequenceBlock(tx, nodeId), causal }\n\tconst result = await write(scope)\n\tawait scope.sequence.close()\n\treturn result\n}\n\n/**\n * Whether a storage error means the device ran out of space: SQLite's\n * `SQLITE_FULL` (\"database or disk is full\") or a browser quota error from OPFS /\n * IndexedDB. The store maps these to a `store:quota-exceeded` event (STORE-15).\n */\nexport function isStorageFullError(error: unknown): boolean {\n\tif (error === null || typeof error !== 'object') return false\n\tconst candidate = error as { name?: unknown; code?: unknown; message?: unknown; cause?: unknown }\n\tif (candidate.name === 'QuotaExceededError') return true\n\tif (candidate.code === 'SQLITE_FULL' || candidate.code === 'QUOTA_EXCEEDED') return true\n\tconst message = typeof candidate.message === 'string' ? candidate.message : ''\n\tif (/SQLITE_FULL|database or disk is full|quota ?exceeded/i.test(message)) return true\n\treturn candidate.cause !== undefined && candidate.cause !== error\n\t\t? isStorageFullError(candidate.cause)\n\t\t: false\n}\n","import type { Operation } from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { LocalMutationContext } from './types'\nimport { CausalScope, type WriteScope, withWriteScope } from './write-context'\nimport type { WriteResult } from './write-ops'\n\n/**\n * Run one local write in its own storage transaction, then publish it.\n *\n * Post-commit work (causal heads, in-memory version vector, subscriptions,\n * `operation:created`) runs only after the transaction commits, so nothing\n * observable ever points at an operation that was rolled back (STORE-15).\n */\nexport async function runLocalWrite(\n\tctx: LocalMutationContext,\n\twrite: (scope: WriteScope) => Promise<WriteResult>,\n): Promise<WriteResult> {\n\tconst causal = new CausalScope(ctx.causalTracker, false)\n\tlet result: WriteResult | undefined\n\ttry {\n\t\tawait ctx.adapter.transaction(async (tx) => {\n\t\t\tresult = await withWriteScope(tx, ctx.nodeId, causal, write)\n\t\t})\n\t} catch (error) {\n\t\tctx.onStorageError?.(error)\n\t\tthrow error\n\t}\n\tif (!result) {\n\t\tthrow new KoraError('Local write transaction completed without a result', 'WRITE_INCOMPLETE', {\n\t\t\tcollection: ctx.collection,\n\t\t})\n\t}\n\tcausal.publish()\n\tpublishOperations(ctx, result)\n\treturn result\n}\n\n/** Notify the store about every operation of a committed write, in creation order. */\nfunction publishOperations(ctx: LocalMutationContext, result: WriteResult): void {\n\tconst ops: Operation[] = []\n\tif (result.operation) ops.push(result.operation)\n\tops.push(...result.sideEffects)\n\tfor (const op of ops) {\n\t\tctx.onMutation(op.collection, op)\n\t}\n}\n","import { EMPTY_ROW_VERSION } from './row-version'\n\n/**\n * Per-field last-writer versions for a materialized row.\n *\n * Each entry maps a field name to a serialized HLC timestamp (the same\n * lexicographically-sortable form used by the row `_version` column). Because\n * the serialized form sorts identically to {@link HybridLogicalClock.compare},\n * per-field last-write-wins is a plain string comparison: the greater string is\n * the newer writer. This makes field-level convergence deterministic and\n * independent of the order operations happen to arrive in.\n */\nexport type FieldVersions = Record<string, string>\n\n/**\n * Parse the `_field_versions` JSON column into a map. Tolerates null, empty,\n * and malformed values by returning an empty map — a row that predates\n * per-field tracking simply has no field versions and falls back to `_version`.\n */\nexport function parseFieldVersions(raw: unknown): FieldVersions {\n\tif (typeof raw !== 'string' || raw.length === 0) {\n\t\treturn {}\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown\n\t\tif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n\t\t\treturn {}\n\t\t}\n\t\tconst result: FieldVersions = {}\n\t\tfor (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tresult[key] = value\n\t\t\t}\n\t\t}\n\t\treturn result\n\t} catch {\n\t\treturn {}\n\t}\n}\n\n/**\n * Serialize a field-version map for storage in the `_field_versions` column.\n */\nexport function serializeFieldVersions(versions: FieldVersions): string {\n\treturn JSON.stringify(versions)\n}\n\n/**\n * Build the initial field-version map for an insert: every supplied field is\n * stamped with the operation's version.\n */\nexport function fieldVersionsForFields(\n\tfieldNames: Iterable<string>,\n\tversion: string,\n): FieldVersions {\n\tconst versions: FieldVersions = {}\n\tfor (const field of fieldNames) {\n\t\tversions[field] = version\n\t}\n\treturn versions\n}\n\n/**\n * The effective stored version for a field: its own tracked version if present,\n * otherwise the row-level `_version` (so rows written before per-field tracking\n * still compare correctly), otherwise the empty sentinel (older than anything).\n */\nexport function effectiveFieldVersion(\n\tcurrent: FieldVersions,\n\tfield: string,\n\trowVersion: string | undefined,\n): string {\n\tconst own = current[field]\n\tif (own !== undefined) {\n\t\treturn own\n\t}\n\treturn rowVersion ?? EMPTY_ROW_VERSION\n}\n\n/**\n * Result of resolving an incoming operation against the current per-field\n * versions of a row.\n */\nexport interface PerFieldLwwResult {\n\t/** Fields the incoming operation wins (strictly newer than the stored version). */\n\twinners: string[]\n\t/** The merged field-version map to persist (winners advanced to `incomingVersion`). */\n\tmerged: FieldVersions\n}\n\n/**\n * Resolve per-field last-write-wins for an incoming operation.\n *\n * For each incoming field, the operation wins only when its version is strictly\n * greater than the field's effective stored version. Ties (identical version,\n * i.e. the same operation re-applied) are losses, keeping the resolution\n * idempotent. The comparison is a total order, so every node resolves the same\n * winner regardless of the order operations arrive.\n *\n * @param current - Parsed `_field_versions` of the target row\n * @param incomingFields - Field names carried by the incoming operation\n * @param incomingVersion - Serialized HLC version of the incoming operation\n * @param rowVersion - The row's `_version` (fallback for untracked fields)\n */\nexport function resolvePerFieldLww(\n\tcurrent: FieldVersions,\n\tincomingFields: Iterable<string>,\n\tincomingVersion: string,\n\trowVersion: string | undefined,\n): PerFieldLwwResult {\n\tconst winners: string[] = []\n\tconst merged: FieldVersions = { ...current }\n\tfor (const field of incomingFields) {\n\t\tconst stored = effectiveFieldVersion(current, field, rowVersion)\n\t\tif (incomingVersion > stored) {\n\t\t\twinners.push(field)\n\t\t\tmerged[field] = incomingVersion\n\t\t}\n\t\t// Losing fields are left untouched: their existing tracked version (or the\n\t\t// row-level `_version` fallback) already reflects the newer writer.\n\t}\n\treturn { winners, merged }\n}\n\n/**\n * Stamp `fields` with `version` on top of a stored `_field_versions` value and\n * return the serialized column. This is the one per-field stamp every local\n * write uses (insert, update, transaction entries, cascades), so every field a\n * device writes carries the HLC of the operation that wrote it.\n *\n * Stamps only move forward: a field already holding a newer version keeps it.\n * The map is keyed by field name with one HLC register per field, the shape the\n * per-field fold (W7) builds on.\n *\n * @param currentRaw - The stored `_field_versions` column (or null for a new row)\n * @param fields - Field names this write sets\n * @param version - The writing operation's serialized HLC version\n */\nexport function stampFieldVersions(\n\tcurrentRaw: unknown,\n\tfields: Iterable<string>,\n\tversion: string,\n): string {\n\tconst versions = parseFieldVersions(currentRaw)\n\tfor (const field of fields) {\n\t\tconst existing = versions[field]\n\t\tif (existing === undefined || existing < version) {\n\t\t\tversions[field] = version\n\t\t}\n\t}\n\treturn serializeFieldVersions(versions)\n}\n","import { KoraError, validateTransition } from '@korajs/core'\nimport type {\n\tCollectionDefinition,\n\tStateMachineConstraint,\n\tStateMachineDefinition,\n} from '@korajs/core'\n\n/**\n * Error thrown when a local mutation attempts an invalid state transition.\n *\n * Contains enough context to debug without reproduction:\n * the collection, record, field, current state, attempted state, and allowed transitions.\n */\nexport class InvalidStateTransitionError extends KoraError {\n\tconstructor(\n\t\tpublic readonly collection: string,\n\t\tpublic readonly recordId: string,\n\t\tpublic readonly field: string,\n\t\tpublic readonly fromState: string,\n\t\tpublic readonly toState: string,\n\t\tpublic readonly allowedStates: string[],\n\t) {\n\t\tsuper(\n\t\t\t`Invalid state transition in collection \"${collection}\": ` +\n\t\t\t\t`cannot transition field \"${field}\" from \"${fromState}\" to \"${toState}\". ` +\n\t\t\t\t`Allowed transitions from \"${fromState}\": ${allowedStates.length > 0 ? allowedStates.join(', ') : '(none -- terminal state)'}`,\n\t\t\t'INVALID_STATE_TRANSITION',\n\t\t\t{ collection, recordId, field, fromState, toState, allowedStates },\n\t\t)\n\t\tthis.name = 'InvalidStateTransitionError'\n\t}\n}\n\n/**\n * Validates a state machine transition for a local mutation (insert or update).\n *\n * For inserts: validates that the initial state (from the data or the default value)\n * is a known state in the state machine.\n *\n * For updates: looks up the current state field value and checks whether\n * the transition to the new value is allowed.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being mutated\n * @param stateMachine - The state machine definition\n * @param currentState - The current value of the state field (null for inserts)\n * @param newState - The new value being set for the state field\n * @returns An object indicating whether the transition is valid, and if not, the allowed states.\n * When `onInvalidTransition` is 'last-valid-state', callers should suppress the field update\n * rather than throwing.\n */\nexport function validateStateTransition(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentState: string | null,\n\tnewState: string,\n): { valid: boolean; allowedStates: string[] } {\n\t// For inserts, any valid enum value is acceptable as the initial state\n\t// (schema validation already ensures the value is a valid enum value)\n\tif (currentState === null) {\n\t\treturn { valid: true, allowedStates: [] }\n\t}\n\n\t// Same-state transitions are always valid (idempotent updates)\n\tif (currentState === newState) {\n\t\treturn { valid: true, allowedStates: stateMachine.transitions[currentState] ?? [] }\n\t}\n\n\tconst constraint: StateMachineConstraint = {\n\t\tfield: stateMachine.field,\n\t\tcollection: collectionName,\n\t\ttransitions: stateMachine.transitions,\n\t}\n\tconst transitionResult = validateTransition(constraint, currentState, newState)\n\tif (transitionResult.valid) {\n\t\treturn { valid: true, allowedStates: transitionResult.allowedTargets }\n\t}\n\n\tconst allowedStates = transitionResult.allowedTargets\n\n\tif (stateMachine.onInvalidTransition === 'reject') {\n\t\tthrow new InvalidStateTransitionError(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\tstateMachine.field,\n\t\t\tcurrentState,\n\t\t\tnewState,\n\t\t\tallowedStates,\n\t\t)\n\t}\n\n\t// 'last-valid-state': return invalid so the caller can suppress the field update\n\treturn { valid: false, allowedStates }\n}\n\n/**\n * Checks whether a collection update data object contains a change to the state machine field,\n * and if so, validates the transition.\n *\n * If the state field is not in the update data, returns the data unchanged.\n * If the transition is invalid and mode is 'last-valid-state', removes the field from the data.\n * If the transition is invalid and mode is 'reject', throws InvalidStateTransitionError.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being updated\n * @param collectionDef - The collection definition from the schema\n * @param currentRecord - The current record data (must include the state field)\n * @param updateData - The partial update data\n * @returns The update data, potentially with the state field removed if invalid and mode is 'last-valid-state'\n */\nexport function validateUpdateStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tcollectionDef: CollectionDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tlet result = updateData\n\tconst stateMachine = collectionDef.stateMachine\n\tif (stateMachine !== undefined) {\n\t\tresult = applyStateMachine(collectionName, recordId, stateMachine, currentRecord, result)\n\t}\n\t// Field-level `t.enum(...).transitions()` maps are state machines too, in the\n\t// default 'reject' mode (NEW-STORE-3). A collection-level machine on the same\n\t// field takes precedence.\n\tfor (const [field, descriptor] of Object.entries(collectionDef.fields)) {\n\t\tif (descriptor.kind !== 'enum' || !descriptor.transitions) continue\n\t\tif (stateMachine?.field === field) continue\n\t\tresult = applyStateMachine(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\t{ field, transitions: descriptor.transitions, onInvalidTransition: 'reject' },\n\t\t\tcurrentRecord,\n\t\t\tresult,\n\t\t)\n\t}\n\treturn result\n}\n\nfunction applyStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst stateField = stateMachine.field\n\tif (!(stateField in updateData)) {\n\t\t// State field not being changed -- no validation needed\n\t\treturn updateData\n\t}\n\n\tconst currentState = currentRecord[stateField]\n\tconst newState = updateData[stateField]\n\n\t// Both values must be strings for state machine validation\n\tif (typeof currentState !== 'string' || typeof newState !== 'string') {\n\t\treturn updateData\n\t}\n\n\tconst result = validateStateTransition(\n\t\tcollectionName,\n\t\trecordId,\n\t\tstateMachine,\n\t\tcurrentState,\n\t\tnewState,\n\t)\n\n\tif (result.valid) {\n\t\treturn updateData\n\t}\n\n\t// Mode is 'last-valid-state': silently remove the state field from the update\n\tconst filtered = { ...updateData }\n\tdelete filtered[stateField]\n\n\t// If no fields remain after removing the state field, the update becomes a no-op.\n\t// Return the empty object -- the caller can decide whether to proceed.\n\treturn filtered\n}\n","import type { CollectionDefinition, SecretKeyProvider } from '@korajs/core'\nimport { transformSecretFieldsForWrite } from '@korajs/core'\n\n/**\n * Convert the values a local write is about to persist into their at-rest form.\n *\n * Every local write path (single-record insert/update and the buffered\n * `TransactionContext` used by `app.transaction` / `app.mutation`) MUST route\n * its data through this helper BEFORE the operation is built, so plaintext\n * secrets never reach the operation log, the materialized row, or the wire.\n * Keeping one helper means a new write path cannot forget the transform\n * without also bypassing this function (STORE-4).\n *\n * @param data - Validated (and atomic-op-resolved) field values for the write\n * @param definition - The collection definition, used to find secret fields\n * @param secretKeyProvider - Key provider for `t.secret()` encrypted fields\n * @returns A copy of `data` with secret fields hashed or encrypted\n */\nexport function toAtRestWriteData(\n\tdata: Record<string, unknown>,\n\tdefinition: CollectionDefinition,\n\tsecretKeyProvider: SecretKeyProvider | undefined,\n): Promise<Record<string, unknown>> {\n\treturn transformSecretFieldsForWrite(data, definition, secretKeyProvider)\n}\n","import type { AtomicOp, CollectionDefinition, Operation } from '@korajs/core'\nimport {\n\tDEFAULT_MAX_OPERATION_BYTES,\n\tKoraError,\n\tOperationTooLargeError,\n\tassertResolvedFieldValue,\n\tcreateOperation,\n\tgenerateUUIDv7,\n\tisAtomicOp,\n\tmeasureOperationBytes,\n\tquoteIdent,\n\tresolveAtomicOp,\n\ttoAtomicOp,\n\tvalidateRecord,\n} from '@korajs/core'\nimport { RecordNotFoundError } from '../errors'\nimport { stampFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery, buildSoftDeleteQuery, buildUpdateQuery } from '../query/sql-builder'\nimport { encodeRichtextFieldsForOpData } from '../serialization/op-data-encoding'\nimport {\n\tdeserializeRecord,\n\tserializeOperation,\n\tserializeRecord,\n\ttoRichtextReadShape,\n} from '../serialization/serializer'\nimport { validateUpdateStateMachine } from '../state-machine/state-validator'\nimport type { CollectionRecord, RawCollectionRow } from '../types'\nimport { toAtRestWriteData } from './secret-write'\nimport type { WriteEnv, WriteScope } from './write-context'\n\n/*\n * THE local write path (W6). Every local operation — a single-record write, each\n * entry of an `app.transaction` / `app.mutation` commit, and every referential\n * cascade — is built and persisted by the functions in this file, inside the\n * storage transaction that commits it:\n *\n * 1. the current row is read through the transaction handle, so validation\n * (existence, state machine) and atomic ops resolve against committed state;\n * 2. the sequence number comes from the transaction's SequenceBlock (reserved\n * with UPSERT ... RETURNING on `_kora_version_vector` inside the transaction,\n * end persisted before commit); transactions are serialized, so the numbers of\n * one commit form one contiguous block and two commits can never share one;\n * 3. the operation is built only AFTER its sequence number is reserved, and is\n * never re-stamped (protocol v2 hashes the sequence number into the id);\n * 4. the row is written with per-field version stamps and the operation row is\n * appended, in the same transaction.\n */\n\n/** An insert whose values are validated and in their at-rest form. */\nexport interface PreparedInsert {\n\treadonly collection: string\n\treadonly recordId: string\n\t/** Record-shaped, at-rest values (secret fields hashed / encrypted). */\n\treadonly data: Record<string, unknown>\n}\n\n/**\n * Validate insert data, fill auto fields and transform secrets. Pure with\n * respect to storage, so `app.transaction` can do it when the developer calls\n * `insert` (returning the new id immediately) and write it at commit.\n */\nexport async function prepareInsert(\n\tenv: WriteEnv,\n\tcollection: string,\n\tdata: Record<string, unknown>,\n): Promise<PreparedInsert> {\n\tconst definition = requireDefinition(env, collection)\n\tconst validated = validateRecord(collection, definition, data, 'insert')\n\tconst now = Date.now()\n\tfor (const [fieldName, descriptor] of Object.entries(definition.fields)) {\n\t\tif (descriptor.auto && descriptor.kind === 'timestamp') {\n\t\t\tvalidated[fieldName] = now\n\t\t}\n\t}\n\t// Secret fields reach their at-rest form BEFORE the operation is built, so\n\t// plaintext never enters the op log, the row, or the wire (STORE-4).\n\tconst writeData = await toAtRestWriteData(validated, definition, env.secretKeyProvider)\n\treturn { collection, recordId: generateUUIDv7(), data: writeData }\n}\n\n/** Result of writing one local operation. */\nexport interface WriteResult {\n\t/** The operation, or null when the write turned out to be a no-op. */\n\treadonly operation: Operation | null\n\t/** The record as stored after the write. */\n\treadonly record: CollectionRecord\n\t/** Operations created as side effects (referential cascades), in creation order. */\n\treadonly sideEffects: Operation[]\n}\n\n/**\n * Write a prepared insert inside `scope.tx`.\n */\nexport async function writeInsertInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinsert: PreparedInsert,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, insert.collection)\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'insert',\n\t\tcollection: insert.collection,\n\t\trecordId: insert.recordId,\n\t\t// Binary richtext values are tagged as canonical JSON BEFORE hashing, so the\n\t\t// hash input, persisted JSON and wire payload are the identical value.\n\t\tdata: encodeRichtextFieldsForOpData(insert.data, definition.fields),\n\t\tpreviousData: null,\n\t\textraCausalDeps,\n\t})\n\n\tif (env.fold) {\n\t\t// Append, then merge: the row is the materialization of the record's state.\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serialized = serializeRecord(insert.data, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst row: Record<string, unknown> = {\n\t\t\tid: insert.recordId,\n\t\t\t...serialized,\n\t\t\t_created_at: operation.timestamp.wallTime,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t// Every inserted field is stamped with this operation's version, so later\n\t\t\t// per-field LWW compares against a real writer, not the row fallback.\n\t\t\t_field_versions: stampFieldVersions(null, Object.keys(serialized), version),\n\t\t}\n\t\tconst rowInsert = buildInsertQuery(insert.collection, row)\n\t\tawait scope.tx.execute(rowInsert.sql, rowInsert.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: {\n\t\t\tid: insert.recordId,\n\t\t\t// A richtext value written as a string returns as the bytes reads return.\n\t\t\t...toRichtextReadShape(insert.data, definition.fields),\n\t\t\tcreatedAt: operation.timestamp.wallTime,\n\t\t\tupdatedAt: operation.timestamp.wallTime,\n\t\t},\n\t\tsideEffects: [],\n\t}\n}\n\n/**\n * Write a local update inside `scope.tx`.\n *\n * `data` must already be schema-validated (it may contain atomic op descriptors).\n * The state machine, atomic ops and `previousData` are all resolved against the\n * row read through the transaction, so concurrent writers serialize correctly\n * (STORE-9, NEW-STORE-2).\n */\nexport async function writeUpdateInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\tdata: Record<string, unknown>,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst currentRecord = deserializeRecord(currentRow, definition.fields)\n\tconst allowed = validateUpdateStateMachine(collection, id, definition, currentRecord, data)\n\tif (Object.keys(allowed).length === 0) {\n\t\treturn { operation: null, record: currentRecord, sideEffects: [] }\n\t}\n\n\tconst previousData: Record<string, unknown> = {}\n\tconst resolved: Record<string, unknown> = {}\n\tconst atomicOps: Record<string, AtomicOp> = {}\n\tfor (const [key, value] of Object.entries(allowed)) {\n\t\tpreviousData[key] = currentRecord[key]\n\t\tif (isAtomicOp(value)) {\n\t\t\tresolved[key] = resolveAtomicOp(currentRecord[key], value)\n\t\t\t// The resolved value must be in the field's domain like any written value\n\t\t\t// (RT-87): `op.increment(0.5)` on a timestamp, an increment past the largest\n\t\t\t// finite number.\n\t\t\tconst descriptor = definition.fields[key]\n\t\t\tif (descriptor) assertResolvedFieldValue(collection, key, descriptor, resolved[key])\n\t\t\tatomicOps[key] = toAtomicOp(value)\n\t\t} else {\n\t\t\tresolved[key] = value\n\t\t}\n\t}\n\t// previousData already holds the stored (at-rest) values, so only the new\n\t// values need the secret transform.\n\tconst writeData = await toAtRestWriteData(resolved, definition, env.secretKeyProvider)\n\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'update',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: encodeRichtextFieldsForOpData(writeData, definition.fields),\n\t\tpreviousData: encodeRichtextFieldsForOpData(previousData, definition.fields),\n\t\textraCausalDeps,\n\t\t...(Object.keys(atomicOps).length > 0 ? { atomicOps } : {}),\n\t})\n\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serializedChanges = serializeRecord(writeData, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\t// A local edit is the newest writer of every field it touches (the HLC is past\n\t\t// every timestamp this device has seen), so each changed field gets its stamp.\n\t\tconst rowUpdate = buildUpdateQuery(collection, id, {\n\t\t\t...serializedChanges,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t_field_versions: stampFieldVersions(\n\t\t\t\tcurrentRow._field_versions,\n\t\t\t\tObject.keys(serializedChanges),\n\t\t\t\tversion,\n\t\t\t),\n\t\t})\n\t\tawait scope.tx.execute(rowUpdate.sql, rowUpdate.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst updatedRow = await readLiveRow(scope, collection, id)\n\tif (!updatedRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(updatedRow, definition.fields),\n\t\tsideEffects: [],\n\t}\n}\n\n/** Options for {@link writeDeleteInTx}. */\nexport interface WriteDeleteOptions {\n\t/** Skip referential checks and cascades (the caller already applied them). */\n\treadonly skipReferentialEnforcement?: boolean\n\t/** Explicit causal parents (e.g. the delete that caused this cascade). */\n\treadonly extraCausalDeps?: readonly string[]\n}\n\n/**\n * Soft-delete a record inside `scope.tx`, then apply the schema's referential\n * policies (cascade, set-null, restrict) in the same transaction. Cascaded\n * operations are built through this same write path, after the parent, so their\n * sequence numbers follow the parent's in the commit's block (STORE-2).\n */\nexport async function writeDeleteInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\toptions: WriteDeleteOptions = {},\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'delete',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: null,\n\t\tpreviousData: null,\n\t\textraCausalDeps: options.extraCausalDeps ?? [],\n\t})\n\n\tif (!options.skipReferentialEnforcement && env.beforeLocalDelete) {\n\t\tawait env.beforeLocalDelete(operation, scope.tx)\n\t}\n\n\t// The row is tombstoned BEFORE side effects run, so a reference cycle\n\t// (self-referencing or mutually-referencing records) cannot cascade back\n\t// into this record.\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst softDelete = buildSoftDeleteQuery(collection, id, operation.timestamp.wallTime, version)\n\t\tawait scope.tx.execute(softDelete.sql, softDelete.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst sideEffects: Operation[] = []\n\tif (!options.skipReferentialEnforcement && env.relationEnforcer) {\n\t\tconst result = await env.relationEnforcer.enforceDelete(\n\t\t\tcollection,\n\t\t\tid,\n\t\t\tscope,\n\t\t\tenv,\n\t\t\toperation.id,\n\t\t)\n\t\tsideEffects.push(...result.operations)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(currentRow, definition.fields),\n\t\tsideEffects,\n\t}\n}\n\ninterface LocalOperationInput {\n\ttype: Operation['type']\n\tcollection: string\n\trecordId: string\n\tdata: Record<string, unknown> | null\n\tpreviousData: Record<string, unknown> | null\n\textraCausalDeps: readonly string[]\n\tatomicOps?: Record<string, AtomicOp>\n}\n\n/**\n * Reserve the next sequence number through the transaction, THEN build the\n * operation. The order matters: the operation is final the moment it exists.\n */\nasync function buildLocalOperation(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinput: LocalOperationInput,\n): Promise<Operation> {\n\tconst sequenceNumber = await scope.sequence.take()\n\tconst causalDeps = scope.causal.depsFor(input.collection, input.extraCausalDeps)\n\tconst operation = await createOperation(\n\t\t{\n\t\t\tnodeId: env.nodeId,\n\t\t\ttype: input.type,\n\t\t\tcollection: input.collection,\n\t\t\trecordId: input.recordId,\n\t\t\tdata: input.data,\n\t\t\tpreviousData: input.previousData,\n\t\t\tsequenceNumber,\n\t\t\tcausalDeps,\n\t\t\tschemaVersion: env.schema.version,\n\t\t\t...(input.atomicOps !== undefined ? { atomicOps: input.atomicOps } : {}),\n\t\t\t...(env.transactionId !== undefined ? { transactionId: env.transactionId } : {}),\n\t\t\t...(env.mutationName !== undefined ? { mutationName: env.mutationName } : {}),\n\t\t},\n\t\tenv.clock,\n\t)\n\t// Every operation must fit the server's maxOperationBytes (RT-86): refused here, in\n\t// the write's transaction (nothing is written), rather than accepted and then refused\n\t// by the server.\n\tconst maxBytes = env.maxOperationBytes ?? DEFAULT_MAX_OPERATION_BYTES\n\tconst bytes = measureOperationBytes(operation)\n\tif (bytes > maxBytes) {\n\t\tthrow new OperationTooLargeError(input.collection, input.recordId, bytes, maxBytes)\n\t}\n\tscope.causal.record(input.collection, operation.id)\n\treturn operation\n}\n\nasync function appendOperationRow(scope: WriteScope, operation: Operation): Promise<void> {\n\tconst opInsert = buildInsertQuery(\n\t\t`_kora_ops_${operation.collection}`,\n\t\tserializeOperation(operation) as unknown as Record<string, unknown>,\n\t)\n\tawait scope.tx.execute(opInsert.sql, opInsert.params)\n}\n\nasync function readLiveRow(\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n): Promise<RawCollectionRow | undefined> {\n\tconst rows = await scope.tx.query<RawCollectionRow>(\n\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ? AND _deleted = 0`,\n\t\t[id],\n\t)\n\treturn rows[0]\n}\n\nfunction requireDefinition(env: WriteEnv, collection: string): CollectionDefinition {\n\tconst definition = env.schema.collections[collection]\n\tif (!definition) {\n\t\tthrow new KoraError(\n\t\t\t`Unknown collection \"${collection}\". Available: ${Object.keys(env.schema.collections).join(', ')}`,\n\t\t\t'UNKNOWN_COLLECTION',\n\t\t\t{ collection },\n\t\t)\n\t}\n\treturn definition\n}\n","import type { Operation } from '@korajs/core'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeDeleteInTx } from './write-ops'\n\nexport interface ExecuteDeleteOptions {\n\t/** When true, skip referential checks and cascades (caller already enforced them). */\n\tskipReferentialEnforcement?: boolean\n}\n\n/**\n * Soft-delete a record and persist the operation log entry atomically, together\n * with any referential side effects (cascades / set-null), in one transaction.\n * Returns the primary delete operation followed by the side-effect operations.\n */\nexport async function executeDelete(\n\tctx: LocalMutationContext,\n\tid: string,\n\toptions?: ExecuteDeleteOptions,\n): Promise<Operation[]> {\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteDeleteInTx(ctx, scope, ctx.collection, id, {\n\t\t\tskipReferentialEnforcement: options?.skipReferentialEnforcement ?? false,\n\t\t\textraCausalDeps: ctx.extraCausalDeps ?? [],\n\t\t}),\n\t)\n\treturn result.operation ? [result.operation, ...result.sideEffects] : result.sideEffects\n}\n","import type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { prepareInsert, writeInsertInTx } from './write-ops'\n\n/**\n * Insert a record and persist its operation, atomically, through the single\n * local write path (sequence reserved and operation built inside the write\n * transaction).\n */\nexport async function executeInsert(\n\tctx: LocalMutationContext,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst prepared = await prepareInsert(ctx, ctx.collection, data)\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteInsertInTx(ctx, scope, prepared, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n","import { validateRecord } from '@korajs/core'\nimport type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeUpdateInTx } from './write-ops'\n\n/**\n * Update a record and persist its operation, atomically. The row read, the\n * state-machine check and atomic-op resolution all happen inside the write\n * transaction, so concurrent increments compose (STORE-9).\n */\nexport async function executeUpdate(\n\tctx: LocalMutationContext,\n\tid: string,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst validated = validateRecord(ctx.collection, ctx.definition, data, 'update')\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteUpdateInTx(ctx, scope, ctx.collection, id, validated, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n","import type {\n\tCausalTracker,\n\tCollectionDefinition,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport type { RecordFolder } from '../fold/record-folder'\nimport { executeDelete } from '../mutations/execute-delete'\nimport { executeInsert } from '../mutations/execute-insert'\nimport { executeUpdate } from '../mutations/execute-update'\nimport type { LocalMutationContext } from '../mutations/types'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport { deserializeRecord } from '../serialization/serializer'\nimport type {\n\tCollectionRecord,\n\tLocalMutationHandler,\n\tRawCollectionRow,\n\tStorageAdapter,\n} from '../types'\n\n/**\n * Callback invoked after a mutation so the Store can notify subscriptions.\n */\nexport type MutationCallback = (collection: string, operation: Operation) => void\n\n/**\n * Collection provides CRUD operations on a single schema collection.\n * Delegates to {@link LocalMutationHandler} when configured (unified apply pipeline),\n * otherwise uses shared mutation executors directly.\n */\nexport class Collection {\n\tconstructor(\n\t\tprivate readonly name: string,\n\t\tprivate readonly definition: CollectionDefinition,\n\t\tprivate readonly schema: SchemaDefinition,\n\t\tprivate readonly adapter: StorageAdapter,\n\t\tprivate clock: HybridLogicalClock,\n\t\tprivate nodeId: string,\n\t\tprivate readonly onMutation: MutationCallback,\n\t\tprivate relationEnforcer: RelationEnforcer | null,\n\t\tprivate mutationHandler: LocalMutationHandler | null,\n\t\tprivate causalTracker: CausalTracker | null,\n\t\tprivate readonly secretKeyProvider?: SecretKeyProvider,\n\t\tprivate readonly onStorageError?: (error: unknown) => void,\n\t\tprivate readonly fold?: () => RecordFolder | undefined,\n\t\tprivate readonly maxOperationBytes?: number,\n\t) {}\n\n\t/**\n\t * Point this collection at the store's new device identity after a node-id\n\t * rotation (RT-21). Internal: called by the owning Store only.\n\t *\n\t * @internal\n\t */\n\trebindNode(\n\t\tclock: HybridLogicalClock,\n\t\tnodeId: string,\n\t\trelationEnforcer: RelationEnforcer | null,\n\t\tcausalTracker: CausalTracker | null,\n\t): void {\n\t\tthis.clock = clock\n\t\tthis.nodeId = nodeId\n\t\tthis.relationEnforcer = relationEnforcer\n\t\tthis.causalTracker = causalTracker\n\t}\n\n\tprivate mutationContext(): LocalMutationContext {\n\t\tconst fold = this.fold?.()\n\t\treturn {\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tcollection: this.name,\n\t\t\tdefinition: this.definition,\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\tonMutation: this.onMutation,\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(this.onStorageError ? { onStorageError: this.onStorageError } : {}),\n\t\t\t...(this.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t}\n\t}\n\n\tasync insert(data: Record<string, unknown>): Promise<CollectionRecord> {\n\t\tif (this.mutationHandler) {\n\t\t\treturn this.mutationHandler.insert(this.name, data)\n\t\t}\n\t\treturn executeInsert(this.mutationContext(), data)\n\t}\n\n\tasync findById(id: string): Promise<CollectionRecord | null> {\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(this.name)} WHERE id = ? AND _deleted = 0`,\n\t\t\t[id],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) return null\n\t\treturn deserializeRecord(row, this.definition.fields)\n\t}\n\n\tasync update(id: string, data: Record<string, unknown>): Promise<CollectionRecord> {\n\t\tif (this.mutationHandler) {\n\t\t\treturn this.mutationHandler.update(this.name, id, data)\n\t\t}\n\t\treturn executeUpdate(this.mutationContext(), id, data)\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tif (this.mutationHandler) {\n\t\t\tawait this.mutationHandler.delete(this.name, id)\n\t\t\treturn\n\t\t}\n\t\tawait executeDelete(this.mutationContext(), id)\n\t}\n\n\tgetName(): string {\n\t\treturn this.name\n\t}\n\n\tgetDefinition(): CollectionDefinition {\n\t\treturn this.definition\n\t}\n\n\t/** Replace the mutation handler (e.g. after ApplyPipeline is wired in createApp). */\n\tsetMutationHandler(handler: LocalMutationHandler | null): void {\n\t\tthis.mutationHandler = handler\n\t}\n}\n","import {\n\ttype FoldState,\n\tHybridLogicalClock,\n\ttype Operation,\n\ttype SchemaDefinition,\n\ttype VersionVector,\n\tcreateFoldState,\n\tcreateVersionVector,\n\tmergeOp,\n\tquoteIdent,\n} from '@korajs/core'\nimport { computeAckCompactionWatermark } from '../compaction/compact-operation-log'\nimport type { CompactionResult, CompactionStrategy } from '../compaction/types'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE } from '../store/sequence-repair'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport { COMPACTED_THROUGH_TABLE, type RecordFolder } from './record-folder'\n\n/**\n * Whether compaction must keep this operation in the log. The fold state alone is\n * enough to merge later operations, but the plan keeps the operations whose effect\n * cannot be rebuilt from a row snapshot should a future fold-state version need to\n * re-fold from the log: deletes (the tombstone register), atomic intents and writes\n * to custom-resolver fields.\n */\nfunction mustKeep(op: Operation, schema: SchemaDefinition): boolean {\n\tif (op.type === 'delete') return true\n\tif (op.atomicOps !== undefined && Object.keys(op.atomicOps).length > 0) return true\n\tconst resolvers = schema.collections[op.collection]?.resolvers ?? {}\n\treturn Object.keys(op.data ?? {}).some((field) => resolvers[field] !== undefined)\n}\n\n/**\n * Per node, the largest sequence k <= the server's acknowledged sequence such that\n * this database holds every operation 1..k (in some collection's log or the\n * retained sequence conflicts). Only such a prefix can be declared compacted:\n * an operation of that node at or below it is then known to be a duplicate.\n */\nasync function contiguousPrefixes(\n\ttx: Transaction,\n\tschema: SchemaDefinition,\n\tacked: VersionVector,\n): Promise<VersionVector> {\n\tconst out = createVersionVector()\n\tfor (const [nodeId, ackedSeq] of acked) {\n\t\tif (ackedSeq <= 0) continue\n\t\tconst seqs = new Set<number>()\n\t\tfor (const collection of Object.keys(schema.collections)) {\n\t\t\tconst rows = await tx.query<{ sequence_number: number }>(\n\t\t\t\t`SELECT sequence_number FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND sequence_number <= ?`,\n\t\t\t\t[nodeId, ackedSeq],\n\t\t\t)\n\t\t\tfor (const row of rows) seqs.add(row.sequence_number)\n\t\t}\n\t\tconst conflicts = await tx.query<{ sequence_number: number }>(\n\t\t\t`SELECT sequence_number FROM ${SEQ_CONFLICTS_TABLE} WHERE node_id = ? AND sequence_number <= ?`,\n\t\t\t[nodeId, ackedSeq],\n\t\t)\n\t\tfor (const row of conflicts) seqs.add(row.sequence_number)\n\t\tconst through = await tx.query<{ sequence_number: number }>(\n\t\t\t`SELECT sequence_number FROM ${COMPACTED_THROUGH_TABLE} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tlet k = through[0]?.sequence_number ?? 0\n\t\twhile (k < ackedSeq && seqs.has(k + 1)) k += 1\n\t\tif (k > 0) out.set(nodeId, k)\n\t}\n\treturn out\n}\n\n/**\n * Compaction under the W7 fold (STORE-14). For every node, operations within the\n * contiguous prefix the server acknowledged (and older than the age cutoff, for\n * `after-days`) are folded per record into the record's base state, then removed\n * from the log. The record's live fold state is unchanged (it already holds them):\n * `state = join(base, fold(log))` holds before and after.\n *\n * Operations the server terminally rejected are never folded into a base.\n */\nexport async function compactFoldedLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tfolder: RecordFolder,\n\tstrategy: CompactionStrategy,\n\tserverVector: VersionVector,\n): Promise<CompactionResult> {\n\tconst acked = computeAckCompactionWatermark(serverVector)\n\tif (acked.size === 0) return { deletedCount: 0, watermark: acked }\n\tconst cutoff =\n\t\tstrategy.mode === 'after-days'\n\t\t\t? HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: Date.now() - strategy.days * 24 * 60 * 60 * 1000,\n\t\t\t\t\tlogical: 0,\n\t\t\t\t\tnodeId: '',\n\t\t\t\t}).slice(0, 15)\n\t\t\t: null\n\n\tlet deletedCount = 0\n\tlet watermark = createVersionVector()\n\tawait adapter.transaction(async (tx) => {\n\t\twatermark = await contiguousPrefixes(tx, schema, acked)\n\t\tfor (const collection of Object.keys(schema.collections)) {\n\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\tconst byRecord = new Map<string, Operation[]>()\n\t\t\tfor (const [nodeId, maxSeq] of watermark) {\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${table} WHERE node_id = ? AND sequence_number <= ?${cutoff !== null ? ' AND SUBSTR(timestamp, 1, 15) < ?' : ''}`,\n\t\t\t\t\tcutoff !== null ? [nodeId, maxSeq, cutoff] : [nodeId, maxSeq],\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst op = deserializeOperationWithCollection(row, collection)\n\t\t\t\t\tif (mustKeep(op, schema)) continue\n\t\t\t\t\tconst list = byRecord.get(op.recordId) ?? []\n\t\t\t\t\tlist.push(op)\n\t\t\t\t\tbyRecord.set(op.recordId, list)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [recordId, ops] of byRecord) {\n\t\t\t\tconst rejected = await folder.loadTerminalRejections(\n\t\t\t\t\ttx,\n\t\t\t\t\tops.map((op) => op.id),\n\t\t\t\t)\n\t\t\t\tlet addition: FoldState = createFoldState(collection, recordId)\n\t\t\t\tlet any = false\n\t\t\t\tfor (const op of ops) {\n\t\t\t\t\tif (rejected.has(op.id)) continue\n\t\t\t\t\taddition = mergeOp(addition, op, schema, folder.options()).state\n\t\t\t\t\tany = true\n\t\t\t\t}\n\t\t\t\tif (any) await folder.joinIntoBase(tx, addition)\n\t\t\t\tfor (let i = 0; i < ops.length; i += 500) {\n\t\t\t\t\tconst chunk = ops.slice(i, i + 500)\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`DELETE FROM ${table} WHERE id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t\t\tchunk.map((op) => op.id),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tdeletedCount += ops.length\n\t\t\t}\n\t\t}\n\t\tfor (const [nodeId, seq] of watermark) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[nodeId, seq],\n\t\t\t)\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\treturn { deletedCount, watermark }\n}\n","import {\n\tcanonicalizeLegacyOperation,\n\tcanonicalizeProvenLegacyClear,\n\tquoteIdent,\n} from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, StorageAdapter } from '../types'\n\n/** `_kora_meta` key: the op log's legacy bodies were made canonical (RT-83, RT-85). */\nexport const LEGACY_BODIES_META_KEY = 'legacy_bodies_canonical'\n\n/** A log row rewritten into its canonical legacy body. */\nexport interface CanonicalizedLegacyBody {\n\tcollection: string\n\trecordId: string\n}\n\n/**\n * Make every genuine beta.12 clear in the operation log explicit, once per database\n * (RT-83, RT-85).\n *\n * beta.12 applied `update(id, { field: undefined })` as a clear, hashed the member as\n * `null`, and logged JSON without it. Every later replica folds a stored body as\n * written (the fold has no legacy rule: a body a schema transform rewrote must never be\n * read as a clear), so the clear is written into the logged body here, where its\n * provenance is known:\n * - this device's own operations that declare no hash version were written by its\n * beta.12 self (beta.13 always declares version 2): a `previousData` key absent from\n * `data` is always such a clear;\n * - any other node's undeclared update is rewritten only when its id PROVES the clear\n * (`canonicalizeProvenLegacyClear`), as on inbound delivery.\n * The restored body has the same id: version 1 hashes `undefined` and `null` alike.\n *\n * @param adapter - The storage adapter\n * @param schema - The schema (collections with a log)\n * @param ownNodeId - This device's node id\n * @returns The rewritten rows' records (to re-fold)\n */\nexport async function canonicalizeLegacyLogBodies(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\townNodeId: string,\n): Promise<CanonicalizedLegacyBody[]> {\n\tconst rewritten: CanonicalizedLegacyBody[] = []\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${table} WHERE type = 'update' AND previous_data IS NOT NULL`,\n\t\t)\n\t\tconst updates: Array<{ id: string; data: string | null }> = []\n\t\tfor (const row of rows) {\n\t\t\tlet op: Operation\n\t\t\ttry {\n\t\t\t\top = deserializeOperationWithCollection(row, collection)\n\t\t\t} catch {\n\t\t\t\t// An unreadable row is the log-integrity scan's business, not this one's.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (op.hashVersion === 2 || canonicalizeLegacyOperation(op) === op) continue\n\t\t\tconst canonical =\n\t\t\t\top.nodeId === ownNodeId\n\t\t\t\t\t? canonicalizeLegacyOperation(op)\n\t\t\t\t\t: await canonicalizeProvenLegacyClear(op)\n\t\t\tif (canonical === op) continue\n\t\t\tupdates.push({ id: op.id, data: serializeOperation(canonical).data })\n\t\t\trewritten.push({ collection, recordId: op.recordId })\n\t\t}\n\t\tif (updates.length === 0) continue\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tfor (const update of updates) {\n\t\t\t\tawait tx.execute(`UPDATE ${table} SET data = ? WHERE id = ?`, [update.data, update.id])\n\t\t\t}\n\t\t})\n\t}\n\treturn rewritten\n}\n","import {\n\ttype FoldState,\n\ttype HLCTimestamp,\n\tHybridLogicalClock,\n\ttype SchemaDefinition,\n\tcreateSnapshotState,\n\tjoinStates,\n\tquoteIdent,\n} from '@korajs/core'\nimport { deserializeRecord } from '../serialization/serializer'\nimport type { RawCollectionRow, StorageAdapter, Transaction } from '../types'\nimport {\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n\tFOLD_STATE_TABLE,\n\tPROVISIONAL_OPS_TABLE,\n\ttype RecordFolder,\n} from './record-folder'\n\n/**\n * How a database is re-materialized on its first open with the W7 fold:\n *\n * - `'log'`: the log is clean (W8 integrity scan): every record is rebuilt with the\n * fold from its operations. This also repairs replicas that diverged under the\n * pairwise merge of beta.12/13.\n * - `'snapshot+log'`: the log is not complete (it was compacted, or has sequence\n * gaps): each existing row becomes the record's row snapshot (its values at\n * their `_field_versions`, exact where a stored fold state still has them), and\n * the remaining operations are folded on top.\n * - `'kept'`: the log has quarantined rows (W8). Only the records that own a\n * quarantined row are kept exactly as they are (their row becomes their snapshot,\n * nothing is rebuilt from their log); every other record is rebuilt as in `'log'`\n * or `'snapshot+log'` (RT-68).\n *\n * Row snapshots are approximate (see `createSnapshotState`); records that fold\n * against one are listed in `_kora_fold_snapshot` until their history is complete\n * again (a scope entry with the server's fold state, or a full resync).\n */\nexport type RematerializationMode = 'log' | 'snapshot+log' | 'kept'\n\n/** Result of {@link rematerializeDatabase}. */\nexport interface RematerializationResult {\n\tmode: RematerializationMode\n\t/** Records whose state was rebuilt. */\n\trecords: number\n\t/** Rows whose visible values changed. */\n\tchangedRows: number\n\t/** Records that now fold against a row snapshot (approximate until settled). */\n\tsnapshots: number\n}\n\n/** Which records to keep as row snapshots (they own quarantined log rows). */\nexport interface KeptRecords {\n\t/** `collection` -> record ids. */\n\trecords: ReadonlyMap<string, ReadonlySet<string>>\n\t/** Collections with a quarantined row whose record id is unknown: kept whole. */\n\tcollections: ReadonlySet<string>\n}\n\nconst BATCH = 200\n\n/**\n * Rebuild every record's fold state and row. Runs once per database (the store\n * records completion in `_kora_meta`), after the W8 log-integrity scan and the\n * schema migrations. One write transaction per batch of records, so a crash\n * resumes from scratch safely (the rebuild is a pure function of the log and rows).\n *\n * @param mode - `'log'` or `'snapshot+log'` for the records that are not kept;\n * `'kept'` is reported when `kept` names any record\n * @param kept - Records owning quarantined log rows (kept as they are)\n * @param collections - Only these collections (default: all)\n */\nexport async function rematerializeDatabase(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tfolder: RecordFolder,\n\tmode: Exclude<RematerializationMode, 'kept'>,\n\tkept: KeptRecords = { records: new Map(), collections: new Set() },\n\tcollections?: readonly string[],\n): Promise<RematerializationResult> {\n\tlet records = 0\n\tlet changedRows = 0\n\tlet snapshots = 0\n\tconst authoritative = folder.getAuthoritativeNodeIds()\n\tfor (const [collection, definition] of Object.entries(schema.collections)) {\n\t\tif (collections && !collections.includes(collection)) continue\n\t\tconst ids = new Set<string>()\n\t\tfor (const row of await adapter.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${quoteIdent(collection)}`,\n\t\t)) {\n\t\t\tids.add(row.id)\n\t\t}\n\t\tfor (const row of await adapter.query<{ record_id: string }>(\n\t\t\t`SELECT DISTINCT record_id FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t)) {\n\t\t\tids.add(row.record_id)\n\t\t}\n\t\tconst keptIds = kept.records.get(collection)\n\t\tconst keepAll = kept.collections.has(collection)\n\t\tconst all = [...ids].sort()\n\t\tfor (let i = 0; i < all.length; i += BATCH) {\n\t\t\tconst batch = all.slice(i, i + BATCH)\n\t\t\tawait adapter.transaction(async (tx) => {\n\t\t\t\tfor (const recordId of batch) {\n\t\t\t\t\trecords += 1\n\t\t\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst row = rows[0]\n\t\t\t\t\tconst before = row ? JSON.stringify(deserializeRecord(row, definition.fields)) : null\n\t\t\t\t\tconst seed = await folder.loadStoredState(tx, collection, recordId)\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t\t\t\t[collection, recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst snapshotOf = (from: RawCollectionRow): FoldState =>\n\t\t\t\t\t\tsnapshotFromRow(from, collection, schema, { seed, authoritative })\n\t\t\t\t\tif (keepAll || keptIds?.has(recordId)) {\n\t\t\t\t\t\tif (row) {\n\t\t\t\t\t\t\t// Owns a quarantined row: never rebuilt from its log; the row stays as\n\t\t\t\t\t\t\t// it is and later operations merge onto it.\n\t\t\t\t\t\t\tconst snapshot = snapshotOf(row)\n\t\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshot)\n\t\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t\t\tconst base = await folder.loadBase(tx, collection, recordId)\n\t\t\t\t\t\t\tawait folder.saveState(tx, base ? joinStates(base, snapshot, schema) : snapshot)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (mode === 'snapshot+log' && row) {\n\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshotOf(row))\n\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t}\n\t\t\t\t\tconst state = await folder.foldFromLog(tx, collection, recordId)\n\t\t\t\t\tif (state === null) {\n\t\t\t\t\t\t// No operation and no base: a row the log never had (cannot happen on a\n\t\t\t\t\t\t// clean log; kept as a snapshot rather than dropped).\n\t\t\t\t\t\tif (row) {\n\t\t\t\t\t\t\tconst snapshot = snapshotOf(row)\n\t\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshot)\n\t\t\t\t\t\t\tawait folder.saveState(tx, snapshot)\n\t\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tawait folder.saveState(tx, state)\n\t\t\t\t\tawait folder.materializeRow(tx, state, 'all', { clearRetraction: false })\n\t\t\t\t\tconst afterRows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst after = afterRows[0]\n\t\t\t\t\t\t? JSON.stringify(deserializeRecord(afterRows[0], definition.fields))\n\t\t\t\t\t\t: null\n\t\t\t\t\tif (before !== after) changedRows += 1\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\tconst keptAny = kept.collections.size > 0 || [...kept.records.values()].some((s) => s.size > 0)\n\treturn { mode: keptAny ? 'kept' : mode, records, changedRows, snapshots }\n}\n\n/**\n * The base snapshot of a materialized row: its values at their `_field_versions`\n * (rows from before per-field versions fall back to `_version`, then `_updated_at`).\n * With a `seed` (the record's stored fold state), every field it still holds in\n * the current plan's kind is taken from it exactly (RT-68).\n */\nexport function snapshotFromRow(\n\trow: RawCollectionRow,\n\tcollection: string,\n\tschema: SchemaDefinition,\n\toptions: { seed?: FoldState | null; authoritative?: ReadonlySet<string> } = {},\n): FoldState {\n\tconst definition = schema.collections[collection]\n\tconst record = definition ? deserializeRecord(row, definition.fields) : { id: row.id }\n\tconst { id: _id, createdAt: _c, updatedAt: _u, ...values } = record as Record<string, unknown>\n\tconst latest = rowVersion(row)\n\tconst fieldVersions: Record<string, HLCTimestamp> = {}\n\tconst raw = typeof row._field_versions === 'string' ? row._field_versions : '{}'\n\ttry {\n\t\tfor (const [field, version] of Object.entries(JSON.parse(raw) as Record<string, unknown>)) {\n\t\t\tif (typeof version === 'string' && version.length > 0) {\n\t\t\t\tfieldVersions[field] = HybridLogicalClock.deserialize(version)\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Malformed versions: every field falls back to the row version.\n\t}\n\tconst createdAt = typeof row._created_at === 'number' ? row._created_at : latest.wallTime\n\treturn createSnapshotState(\n\t\t{\n\t\t\tcollection,\n\t\t\trecordId: row.id,\n\t\t\tvalues,\n\t\t\tfieldVersions,\n\t\t\tcreated: { wallTime: createdAt, logical: 0, nodeId: '' },\n\t\t\tlatest,\n\t\t\tdeleted: row._deleted === 1,\n\t\t},\n\t\tschema,\n\t\t{\n\t\t\t...(options.seed ? { seed: options.seed } : {}),\n\t\t\t...(options.authoritative ? { authoritativeNodeIds: options.authoritative } : {}),\n\t\t},\n\t)\n}\n\nfunction rowVersion(row: RawCollectionRow): HLCTimestamp {\n\tif (typeof row._version === 'string' && row._version.length > 0) {\n\t\ttry {\n\t\t\treturn HybridLogicalClock.deserialize(row._version)\n\t\t} catch {\n\t\t\t// fall through\n\t\t}\n\t}\n\tconst wall = typeof row._updated_at === 'number' ? row._updated_at : 0\n\treturn { wallTime: wall, logical: 0, nodeId: '' }\n}\n\n/** Remove every fold state, base, row snapshot and provisional effect (mode switch). */\nexport async function clearFoldTables(tx: Transaction): Promise<void> {\n\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${FOLD_BASE_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${PROVISIONAL_OPS_TABLE}`)\n}\n","import { KoraError, migrationStepsToSQL, quoteIdent, validateRecord } from '@korajs/core'\nimport type { CausalTracker, MigrationStep, Operation, SchemaDefinition } from '@korajs/core'\nimport {\n\tCausalScope,\n\ttype WriteEnv,\n\ttype WriteScope,\n\twithWriteScope,\n} from '../mutations/write-context'\nimport { writeUpdateInTx } from '../mutations/write-ops'\nimport { deserializeRecord, serializeRecord } from '../serialization/serializer'\nimport type { MetaRow, RawCollectionRow, StorageAdapter, Transaction } from '../types'\n\ntype BackfillStep = Extract<MigrationStep, { type: 'backfill' }>\n\n/** Keys every record carries besides its schema fields. */\nconst RECORD_KEYS: ReadonlySet<string> = new Set(['id', 'createdAt', 'updatedAt'])\n\n/** Everything the migration runner needs from the store. */\nexport interface MigrationRunContext {\n\treadonly adapter: StorageAdapter\n\treadonly schema: SchemaDefinition\n\t/** Write environment of the store's current node (clock, node id, secrets). */\n\treadonly env: Omit<WriteEnv, 'mutationName' | 'transactionId'>\n\treadonly causalTracker: CausalTracker | null\n\t/** Called after each version commits, once per operation its backfills wrote. */\n\treadonly onOperation: (operation: Operation) => void\n}\n\n/**\n * Bring the local database from its stored schema version to `schema.version`\n * (STORE-13, NEW-STORE-1).\n *\n * Each version runs in ONE transaction: its structural DDL, its backfills and the\n * `schema_version` write. A failure (a throwing transform, a crash) leaves no partial\n * effect, so a retry never applies a non-idempotent backfill twice.\n *\n * Backfill transforms receive the deserialized record (booleans, arrays, objects as the\n * app reads them). Every changed record is written through the single local write path\n * as an update operation with mutation name `migration:v<N>`, so the backfilled values\n * sync to the server and other devices; a step declared `localOnly` rewrites the rows\n * only. Fields the transform returns unchanged are not written.\n *\n * @returns The operations the backfills wrote, in commit order\n */\nexport async function runSchemaMigrations(ctx: MigrationRunContext): Promise<Operation[]> {\n\tconst stored = await readStoredSchemaVersion(ctx.adapter)\n\tconst target = ctx.schema.version\n\tif (stored >= target) {\n\t\tif (stored === 0) await writeSchemaVersion(ctx.adapter, target)\n\t\treturn []\n\t}\n\n\tconst written: Operation[] = []\n\tconst migrations = ctx.schema.migrations ?? {}\n\tfor (let version = stored + 1; version <= target; version++) {\n\t\tconst migration = migrations[version]\n\t\tconst steps = migration?.steps ?? []\n\t\tconst committed: Operation[] = []\n\t\tconst causal = new CausalScope(ctx.causalTracker, false)\n\t\tawait ctx.adapter.transaction(async (tx) => {\n\t\t\tfor (const step of steps) {\n\t\t\t\tif (step.type === 'renameField') {\n\t\t\t\t\tawait renameColumn(tx, step.collection, step.from, step.to)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor (const sql of migrationStepsToSQL([step])) {\n\t\t\t\t\tawait executeStructural(tx, sql)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst backfills = steps.filter((step): step is BackfillStep => step.type === 'backfill')\n\t\t\tif (backfills.length > 0) {\n\t\t\t\tconst env: WriteEnv = { ...ctx.env, mutationName: `migration:v${version}` }\n\t\t\t\tawait withWriteScope(tx, ctx.env.nodeId, causal, async (scope) => {\n\t\t\t\t\tfor (const step of backfills) {\n\t\t\t\t\t\tcommitted.push(...(await runBackfill(ctx.schema, env, scope, version, step)))\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\tawait tx.execute(\n\t\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('schema_version', ?)\",\n\t\t\t\t[String(version)],\n\t\t\t)\n\t\t})\n\t\tcausal.publish()\n\t\tfor (const operation of committed) ctx.onOperation(operation)\n\t\twritten.push(...committed)\n\t}\n\treturn written\n}\n\n/**\n * Structural DDL, tolerating \"duplicate column name\": the adapter's open already ran the\n * current schema's DDL, which adds the target schema's columns (`--kora:safe-alter`).\n * Inside a transaction a failed statement rolls back only itself.\n */\nasync function executeStructural(tx: Transaction, sql: string): Promise<void> {\n\ttry {\n\t\tawait tx.execute(sql)\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\tif (!message.includes('duplicate column name')) throw error\n\t}\n}\n\n/**\n * A `renameField` step. The adapter's open has already run the target schema's DDL, whose\n * `--kora:safe-alter` adds the renamed field's column (empty, or holding its default) and\n * creates the target schema's indexes on it; a plain `RENAME COLUMN` would then fail\n * \"duplicate column name\" and leave the values in the old column. The pre-added column is\n * dropped first (with the indexes on it, recreated afterwards), so the rename keeps the\n * values and the source column's constraints. Runs inside the version's transaction.\n */\nasync function renameColumn(\n\ttx: Transaction,\n\tcollection: string,\n\tfrom: string,\n\tto: string,\n): Promise<void> {\n\tconst table = quoteIdent(collection)\n\tconst columns = await tx.query<{ name: string }>(\n\t\t`SELECT name FROM pragma_table_info(${sqlText(collection)})`,\n\t)\n\tconst names = new Set(columns.map((column) => column.name))\n\t// A database created at (or past) this version: the open's DDL already made `to` and\n\t// there is no `from` to carry over (a fresh install of a schema whose history has\n\t// renames). Nothing to rename.\n\tif (!names.has(from) && names.has(to)) return\n\tif (names.has(from) && names.has(to)) {\n\t\tconst indexes = await tx.query<{ name: string; sql: string }>(\n\t\t\t`SELECT m.name AS name, m.sql AS sql FROM sqlite_master m WHERE m.type = 'index' AND m.tbl_name = ${sqlText(collection)} AND m.sql IS NOT NULL AND EXISTS (SELECT 1 FROM pragma_index_info(m.name) i WHERE i.name = ${sqlText(to)})`,\n\t\t)\n\t\tfor (const index of indexes) await tx.execute(`DROP INDEX ${quoteIdent(index.name)}`)\n\t\tawait tx.execute(`ALTER TABLE ${table} DROP COLUMN ${quoteIdent(to)}`)\n\t\tawait tx.execute(`ALTER TABLE ${table} RENAME COLUMN ${quoteIdent(from)} TO ${quoteIdent(to)}`)\n\t\tfor (const index of indexes) {\n\t\t\tawait tx.execute(index.sql.replace(/^CREATE INDEX /i, 'CREATE INDEX IF NOT EXISTS '))\n\t\t}\n\t\treturn\n\t}\n\tawait executeStructural(\n\t\ttx,\n\t\t`ALTER TABLE ${table} RENAME COLUMN ${quoteIdent(from)} TO ${quoteIdent(to)}`,\n\t)\n}\n\nfunction sqlText(value: string): string {\n\treturn `'${value.replaceAll(\"'\", \"''\")}'`\n}\n\nasync function runBackfill(\n\tschema: SchemaDefinition,\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tversion: number,\n\tstep: BackfillStep,\n): Promise<Operation[]> {\n\tconst definition = schema.collections[step.collection]\n\tif (!definition) {\n\t\tthrow new KoraError(\n\t\t\t`Migration v${version} backfills unknown collection \"${step.collection}\".`,\n\t\t\t'MIGRATION_UNKNOWN_COLLECTION',\n\t\t\t{ version, collection: step.collection },\n\t\t)\n\t}\n\tconst rows = await scope.tx.query<RawCollectionRow>(\n\t\t`SELECT * FROM ${quoteIdent(step.collection)} WHERE _deleted = 0 ORDER BY id`,\n\t)\n\tconst operations: Operation[] = []\n\tfor (const row of rows) {\n\t\tconst record = deserializeRecord(row, definition.fields)\n\t\tconst updates = step.transform({ ...record })\n\t\tif (updates === null || typeof updates !== 'object') continue\n\t\tconst changes: Record<string, unknown> = {}\n\t\tfor (const [field, value] of Object.entries(updates)) {\n\t\t\t// `{ ...record, x }` restates the record's own keys: unchanged ones are ignored.\n\t\t\tif (RECORD_KEYS.has(field) && sameValue(record[field], value)) continue\n\t\t\tif (!(field in definition.fields)) {\n\t\t\t\tthrow new KoraError(\n\t\t\t\t\t`Migration v${version} backfill of \"${step.collection}\" returned unknown field \"${field}\".`,\n\t\t\t\t\t'MIGRATION_UNKNOWN_FIELD',\n\t\t\t\t\t{ version, collection: step.collection, field, fix: 'Return only schema fields.' },\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!sameValue(record[field], value)) changes[field] = value\n\t\t}\n\t\tif (Object.keys(changes).length === 0) continue\n\n\t\tif (step.localOnly) {\n\t\t\tconst serialized = serializeRecord(changes, definition.fields)\n\t\t\tconst columns = Object.keys(serialized)\n\t\t\tawait scope.tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(step.collection)} SET ${columns.map((c) => `${quoteIdent(c)} = ?`).join(', ')} WHERE id = ?`,\n\t\t\t\t[...columns.map((c) => serialized[c]), row.id],\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\tconst validated = validateRecord(step.collection, definition, changes, 'update')\n\t\tconst result = await writeUpdateInTx(env, scope, step.collection, row.id, validated)\n\t\tif (result.operation) operations.push(result.operation)\n\t}\n\treturn operations\n}\n\n/** Structural equality for record values (JSON-shaped; bytes compared bytewise). */\nfunction sameValue(a: unknown, b: unknown): boolean {\n\tif (Object.is(a, b)) return true\n\tif (a instanceof Uint8Array || b instanceof Uint8Array) {\n\t\tif (!(a instanceof Uint8Array) || !(b instanceof Uint8Array) || a.length !== b.length) {\n\t\t\treturn false\n\t\t}\n\t\treturn a.every((byte, index) => byte === b[index])\n\t}\n\tif (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {\n\t\t// A missing value and null are the same stored value.\n\t\treturn (a ?? null) === (b ?? null)\n\t}\n\tif (Array.isArray(a) !== Array.isArray(b)) return false\n\tconst keysA = Object.keys(a)\n\tconst keysB = Object.keys(b)\n\tif (keysA.length !== keysB.length) return false\n\treturn keysA.every((key) =>\n\t\tsameValue((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]),\n\t)\n}\n\nasync function readStoredSchemaVersion(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>(\n\t\t\"SELECT value FROM _kora_meta WHERE key = 'schema_version'\",\n\t)\n\treturn rows[0] ? Number(rows[0].value) : 0\n}\n\nasync function writeSchemaVersion(adapter: StorageAdapter, version: number): Promise<void> {\n\tawait adapter.execute(\n\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('schema_version', ?)\",\n\t\t[String(version)],\n\t)\n}\n","/**\n * The schema-version ceiling (RT-109): a build never runs against a database a newer\n * build already migrated.\n *\n * `generateFullDDL` emits `--kora:schema-ceiling <version>` right after `_kora_meta`, before\n * any other DDL. It is a SQL comment; Kora's DDL executors (the native adapter, the SQLite\n * WASM worker, the test bridge) stop there with {@link schemaAheadMessage} when the\n * database's stored schema version is newer, so not even this build's additive DDL touches\n * it. The store then maps the failure to `SchemaVersionAheadError` and checks again after\n * every open (adapters that restore data after their DDL, such as the IndexedDB fallback).\n *\n * No imports: the SQLite WASM worker bundles this file.\n */\n\nconst DIRECTIVE = /^--kora:schema-ceiling (\\d+)$/\nconst AHEAD = /KORA_SCHEMA_VERSION_AHEAD stored=(\\d+) code=(\\d+)/\n\n/** The version a `--kora:schema-ceiling <version>` DDL statement names, or null. */\nexport function parseSchemaCeiling(sql: string): number | null {\n\tconst match = DIRECTIVE.exec(sql.trim())\n\treturn match ? Number(match[1]) : null\n}\n\n/** The stored version from a `_kora_meta` row read, or 0 when none is stored. */\nexport function storedSchemaVersion(rows: ReadonlyArray<{ value: unknown }>): number {\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/** The message a DDL executor throws when the database is ahead (parsed back by the store). */\nexport function schemaAheadMessage(stored: number, code: number): string {\n\treturn `KORA_SCHEMA_VERSION_AHEAD stored=${stored} code=${code}: the database was migrated by a newer build (schema version ${stored}); this build's schema version is ${code}.`\n}\n\n/** The versions in an error raised by {@link schemaAheadMessage}, wherever it was wrapped. */\nexport function parseSchemaAhead(error: unknown): { stored: number; code: number } | null {\n\tconst seen = new Set<unknown>()\n\tlet current: unknown = error\n\twhile (current !== null && current !== undefined && !seen.has(current)) {\n\t\tseen.add(current)\n\t\tconst text =\n\t\t\tcurrent instanceof Error ? current.message : typeof current === 'string' ? current : ''\n\t\tconst match = AHEAD.exec(text)\n\t\tif (match) return { stored: Number(match[1]), code: Number(match[2]) }\n\t\tcurrent = current instanceof Error ? (current as { cause?: unknown }).cause : null\n\t}\n\treturn null\n}\n\n/** Query the stored schema version through a synchronous runner (DDL executors). */\nexport const STORED_SCHEMA_VERSION_SQL = \"SELECT value FROM _kora_meta WHERE key = 'schema_version'\"\n","import type { FieldDescriptor, FieldKind } from '@korajs/core'\nimport type { CollectionRecord } from '../types'\n\n/** Compares two query result sets; true means subscribers need not be notified. */\nexport type ResultsEqual = (\n\tprev: readonly CollectionRecord[],\n\tnext: readonly CollectionRecord[],\n) => boolean\n\ntype ValueEqual = (a: unknown, b: unknown) => boolean\n\n/**\n * Structural equality for any value a deserialized record can hold: primitives\n * (with `Object.is`, so NaN equals NaN), arrays, byte views (richtext and blob\n * state), Dates and plain objects (own enumerable keys, order-insensitive).\n *\n * Deserialization builds fresh arrays and objects on every query run, so a\n * reference comparison reports every structured field as changed (STORE-12) and\n * every subscriber re-renders on every unrelated write to the collection.\n */\nexport function structurallyEqual(a: unknown, b: unknown): boolean {\n\tif (Object.is(a, b)) return true\n\tif (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n\n\tif (ArrayBuffer.isView(a) || ArrayBuffer.isView(b)) {\n\t\tif (!ArrayBuffer.isView(a) || !ArrayBuffer.isView(b)) return false\n\t\treturn bytesEqual(a, b)\n\t}\n\tif (Array.isArray(a) || Array.isArray(b)) {\n\t\tif (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tif (!structurallyEqual(a[i], b[i])) return false\n\t\t}\n\t\treturn true\n\t}\n\tif (a instanceof Date || b instanceof Date) {\n\t\treturn a instanceof Date && b instanceof Date && Object.is(a.getTime(), b.getTime())\n\t}\n\n\tconst objA = a as Record<string, unknown>\n\tconst objB = b as Record<string, unknown>\n\tconst keysA = Object.keys(objA)\n\tif (keysA.length !== Object.keys(objB).length) return false\n\tfor (const key of keysA) {\n\t\tif (!Object.hasOwn(objB, key)) return false\n\t\tif (!structurallyEqual(objA[key], objB[key])) return false\n\t}\n\treturn true\n}\n\nfunction bytesEqual(a: ArrayBufferView, b: ArrayBufferView): boolean {\n\tif (a.byteLength !== b.byteLength) return false\n\tconst x = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n\tconst y = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n\tfor (let i = 0; i < x.length; i++) {\n\t\tif (x[i] !== y[i]) return false\n\t}\n\treturn true\n}\n\nfunction scalarEqual(a: unknown, b: unknown): boolean {\n\treturn Object.is(a, b)\n}\n\n/**\n * The comparator for one field kind. Scalars deserialize to primitives, so\n * identity is exact for them; structured kinds deserialize to fresh containers\n * and need a structural comparison.\n */\nfunction equalityForKind(kind: FieldKind): ValueEqual {\n\tswitch (kind) {\n\t\tcase 'string':\n\t\tcase 'number':\n\t\tcase 'boolean':\n\t\tcase 'timestamp':\n\t\tcase 'enum':\n\t\t\treturn scalarEqual\n\t\tcase 'array':\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\tcase 'richtext':\n\t\tcase 'secret':\n\t\t\treturn structurallyEqual\n\t\tdefault:\n\t\t\treturn structurallyEqual\n\t}\n}\n\n/**\n * Build the result-set comparator for a collection's records: per schema field,\n * the comparator for its kind; for every other key (id, createdAt, updatedAt and\n * included relations) a structural comparison.\n *\n * @param fields - The collection's field descriptors\n * @returns A comparator that is true when both result sets hold the same records,\n * in the same order, with structurally equal values\n */\nexport function createResultsEqual(fields: Record<string, FieldDescriptor>): ResultsEqual {\n\tconst perField = new Map<string, ValueEqual>()\n\tfor (const [name, descriptor] of Object.entries(fields)) {\n\t\tperField.set(name, equalityForKind(descriptor.kind))\n\t}\n\n\tconst recordEqual = (a: CollectionRecord, b: CollectionRecord): boolean => {\n\t\tconst recA = a as Record<string, unknown>\n\t\tconst recB = b as Record<string, unknown>\n\t\tconst keysA = Object.keys(recA)\n\t\tif (keysA.length !== Object.keys(recB).length) return false\n\t\tfor (const key of keysA) {\n\t\t\tif (!Object.hasOwn(recB, key)) return false\n\t\t\tconst eq = perField.get(key) ?? structurallyEqual\n\t\t\tif (!eq(recA[key], recB[key])) return false\n\t\t}\n\t\treturn true\n\t}\n\n\treturn (prev, next) => {\n\t\tif (prev === next) return true\n\t\tif (prev.length !== next.length) return false\n\t\t// Cheap pass first: a different id at any position means the set changed.\n\t\tfor (let i = 0; i < prev.length; i++) {\n\t\t\tif (prev[i]?.id !== next[i]?.id) return false\n\t\t}\n\t\tfor (let i = 0; i < prev.length; i++) {\n\t\t\tconst a = prev[i]\n\t\t\tconst b = next[i]\n\t\t\tif (a === undefined || b === undefined) return a === b\n\t\t\tif (!recordEqual(a, b)) return false\n\t\t}\n\t\treturn true\n\t}\n}\n\n/**\n * Comparator used when the collection's schema is unknown (a subscription\n * registered directly on the manager): structural comparison of every value.\n */\nexport const defaultResultsEqual: ResultsEqual = createResultsEqual({})\n","/**\n * Minimal pluralization/singularization utilities for relation name resolution.\n * Handles common English patterns — not meant to be exhaustive.\n */\n\nfunction isVowel(char: string | undefined): boolean {\n\tif (!char) return false\n\treturn 'aeiouAEIOU'.includes(char)\n}\n\n/**\n * Pluralize a word using common English rules.\n *\n * @example\n * ```\n * pluralize('project') // 'projects'\n * pluralize('category') // 'categories'\n * pluralize('match') // 'matches'\n * ```\n */\nexport function pluralize(word: string): string {\n\tif (word.endsWith('s')) return word\n\tif (word.endsWith('y') && !isVowel(word[word.length - 2])) {\n\t\treturn `${word.slice(0, -1)}ies`\n\t}\n\tif (word.endsWith('sh') || word.endsWith('ch') || word.endsWith('x') || word.endsWith('z')) {\n\t\treturn `${word}es`\n\t}\n\treturn `${word}s`\n}\n\n/**\n * Singularize a word using common English rules.\n *\n * @example\n * ```\n * singularize('projects') // 'project'\n * singularize('categories') // 'category'\n * singularize('matches') // 'match'\n * ```\n */\nexport function singularize(word: string): string {\n\tif (word.endsWith('ies') && !isVowel(word[word.length - 4])) {\n\t\treturn `${word.slice(0, -3)}y`\n\t}\n\tif (\n\t\tword.endsWith('shes') ||\n\t\tword.endsWith('ches') ||\n\t\tword.endsWith('xes') ||\n\t\tword.endsWith('zes')\n\t) {\n\t\treturn word.slice(0, -2)\n\t}\n\tif (word.endsWith('ses')) {\n\t\treturn word.slice(0, -2)\n\t}\n\tif (word.endsWith('s') && !word.endsWith('ss')) {\n\t\treturn word.slice(0, -1)\n\t}\n\treturn word\n}\n","import { QueryError } from '../errors'\nimport type { QueryDescriptor, WhereClause } from '../types'\n\n/**\n * Normalise a `where` clause to its canonical form (RT-102). This is the ONE place that\n * decides what a where value means, so the SQL the store runs, the descriptor and the\n * query key (store cache, React/Vue/Svelte bindings) always agree:\n *\n * - `undefined` means \"no condition\": `where({ projectId: undefined })` is `where({})`\n * (the usual \"nothing selected yet\" pattern), and an operator whose operand is\n * `undefined` (`{ $gt: undefined }`) is dropped; a field left with no operator is\n * dropped. A later `.where({ x: undefined })` therefore does not remove an earlier\n * condition on `x`.\n * - `null` means SQL `IS NULL` (`$ne: null` means `IS NOT NULL`).\n * - Non-finite numbers (`NaN`, `Infinity`) have no stored representation: refused.\n * - `undefined` inside a `$in` list is refused (ambiguous: no condition cannot be one\n * element of a list).\n *\n * @param where - The clause as the developer wrote it\n * @returns A new clause with the rules above applied\n * @throws {QueryError} For a non-finite number or an `undefined` `$in` element\n */\nexport function normalizeWhere(where: WhereClause): WhereClause {\n\tconst out: WhereClause = {}\n\tfor (const [field, value] of Object.entries(where)) {\n\t\tif (value === undefined) continue\n\t\tif (isOperatorObject(value)) {\n\t\t\tconst operators: Record<string, unknown> = {}\n\t\t\tfor (const [operator, operand] of Object.entries(value)) {\n\t\t\t\tif (operand === undefined) continue\n\t\t\t\toperators[operator] = normalizeOperand(field, operator, operand)\n\t\t\t}\n\t\t\tif (Object.keys(operators).length === 0) continue\n\t\t\tout[field] = operators\n\t\t\tcontinue\n\t\t}\n\t\tout[field] = normalizeOperand(field, '$eq', value)\n\t}\n\treturn out\n}\n\nfunction normalizeOperand(field: string, operator: string, operand: unknown): unknown {\n\tif (Array.isArray(operand)) {\n\t\treturn operand.map((item) => {\n\t\t\tif (item === undefined) {\n\t\t\t\tthrow new QueryError(\n\t\t\t\t\t`Invalid ${operator} list for field \"${field}\": it contains undefined. Remove the undefined element, or use null to match missing values.`,\n\t\t\t\t\t{ field, operator },\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn assertFinite(field, operator, item)\n\t\t})\n\t}\n\treturn assertFinite(field, operator, operand)\n}\n\nfunction assertFinite(field: string, operator: string, value: unknown): unknown {\n\tif (typeof value === 'number' && !Number.isFinite(value)) {\n\t\tthrow new QueryError(\n\t\t\t`Invalid value for field \"${field}\" (${operator}): ${String(value)} is not a finite number and cannot match a stored value.`,\n\t\t\t{ field, operator, value: String(value) },\n\t\t)\n\t}\n\treturn value\n}\n\nfunction isOperatorObject(value: unknown): value is Record<string, unknown> {\n\tif (value === null || typeof value !== 'object' || Array.isArray(value)) return false\n\tif (value instanceof Date || ArrayBuffer.isView(value)) return false\n\treturn true\n}\n\n/**\n * The canonical identity of a query: equal keys if and only if the descriptors run the\n * same query (RT-102). Used by the store's query-store cache and by every framework\n * binding to decide when to share a store or re-subscribe.\n *\n * Unlike `JSON.stringify`, nothing is dropped or conflated: `where` keys are sorted\n * (their order does not change the query), `undefined` is dropped exactly as\n * {@link normalizeWhere} drops it, and `NaN`, `Date` and byte values keep distinct,\n * typed encodings.\n *\n * @param descriptor - The query descriptor (`queryBuilder.getDescriptor()`)\n * @returns A string key\n */\nexport function queryKey(descriptor: QueryDescriptor): string {\n\treturn canonical({\n\t\tcollection: descriptor.collection,\n\t\twhere: normalizeWhere(descriptor.where),\n\t\torderBy: descriptor.orderBy.map((clause) => [clause.field, clause.direction]),\n\t\tlimit: descriptor.limit,\n\t\toffset: descriptor.offset,\n\t\tinclude: descriptor.include,\n\t})\n}\n\nfunction canonical(value: unknown): string {\n\tif (value === undefined) return 'u'\n\tif (value === null) return 'n'\n\tswitch (typeof value) {\n\t\tcase 'string':\n\t\t\treturn JSON.stringify(value)\n\t\tcase 'number':\n\t\t\t// Distinguishes NaN, Infinity and -0 (never equal to another stored number).\n\t\t\treturn Object.is(value, -0) ? 'num:-0' : `num:${String(value)}`\n\t\tcase 'boolean':\n\t\t\treturn value ? 'true' : 'false'\n\t\tcase 'bigint':\n\t\t\treturn `big:${value.toString()}`\n\t\tdefault:\n\t\t\tbreak\n\t}\n\tif (value instanceof Date) return `date:${value.getTime()}`\n\tif (ArrayBuffer.isView(value)) {\n\t\tconst bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\n\t\treturn `bytes:${Array.from(bytes).join(',')}`\n\t}\n\tif (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`\n\tif (typeof value === 'object') {\n\t\tconst entries = Object.entries(value as Record<string, unknown>)\n\t\t\t.filter(([, item]) => item !== undefined)\n\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\treturn `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(',')}}`\n\t}\n\treturn `?:${typeof value}`\n}\n","import type { CollectionDefinition, SchemaDefinition } from '@korajs/core'\nimport { encodeStoredText, quoteIdent } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport { deserializeRecord } from '../serialization/serializer'\nimport { type ResultsEqual, createResultsEqual } from '../subscription/result-equality'\nimport type { SubscriptionManager } from '../subscription/subscription-manager'\nimport type {\n\tCollectionRecord,\n\tOrderByDirection,\n\tQueryDescriptor,\n\tRawCollectionRow,\n\tStorageAdapter,\n\tSubscribeOptions,\n\tSubscriptionCallback,\n\tWhereClause,\n} from '../types'\nimport { pluralize, singularize } from './pluralize'\nimport { normalizeWhere } from './query-key'\nimport { buildCountQuery, buildSelectQuery } from './sql-builder'\n\nconst RESULTS_EQUAL_CACHE = new WeakMap<CollectionDefinition, ResultsEqual>()\n\n/**\n * Fluent query builder for constructing and executing collection queries.\n * Supports where, orderBy, limit, offset, include, exec, count, and subscribe.\n *\n * The generic parameter `T` defaults to `CollectionRecord` for backward compatibility\n * but can be narrowed to a specific record type for full type inference.\n *\n * @example\n * ```typescript\n * const todos = await app.todos\n * .where({ completed: false })\n * .orderBy('createdAt', 'desc')\n * .limit(10)\n * .exec()\n * ```\n */\nexport class QueryBuilder<T = CollectionRecord> {\n\tprivate descriptor: QueryDescriptor\n\n\tconstructor(\n\t\tprivate readonly collectionName: string,\n\t\tprivate readonly definition: CollectionDefinition,\n\t\tprivate readonly adapter: StorageAdapter,\n\t\tprivate readonly subscriptionManager: SubscriptionManager,\n\t\tinitialWhere: WhereClause = {},\n\t\tprivate readonly schema?: SchemaDefinition,\n\t) {\n\t\tthis.descriptor = {\n\t\t\tcollection: collectionName,\n\t\t\twhere: normalizeWhere(initialWhere),\n\t\t\torderBy: [],\n\t\t}\n\t}\n\n\t/**\n\t * Add WHERE conditions (AND semantics, merged with existing conditions).\n\t *\n\t * A field whose value is `undefined` adds no condition (it does not remove an\n\t * earlier one); `null` matches missing values (`IS NULL`). Non-finite numbers are\n\t * refused. See {@link normalizeWhere} (RT-102).\n\t */\n\twhere(conditions: WhereClause): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\twhere: { ...clone.descriptor.where, ...normalizeWhere(conditions) },\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Add ORDER BY clause.\n\t */\n\torderBy(field: string, direction: OrderByDirection = 'asc'): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\torderBy: [...clone.descriptor.orderBy, { field, direction }],\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Set result limit.\n\t */\n\tlimit(n: number): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = { ...clone.descriptor, limit: n }\n\t\treturn clone\n\t}\n\n\t/**\n\t * Set result offset.\n\t */\n\toffset(n: number): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = { ...clone.descriptor, offset: n }\n\t\treturn clone\n\t}\n\n\t/**\n\t * Include related records in the query results.\n\t * Follows relations defined in the schema to batch-fetch related data.\n\t *\n\t * @param targets - Relation target names (collection names or relation names)\n\t * @returns A new QueryBuilder with include targets added\n\t *\n\t * @example\n\t * ```typescript\n\t * const todosWithProject = await app.todos\n\t * .where({ completed: false })\n\t * .include('project')\n\t * .exec()\n\t * ```\n\t */\n\tinclude(...targets: string[]): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tconst existing = clone.descriptor.include ?? []\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\tinclude: [...existing, ...targets],\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Execute the query and return results.\n\t */\n\tasync exec(): Promise<T[]> {\n\t\tconst { sql, params } = buildSelectQuery(this.descriptor, this.definition.fields)\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(sql, params)\n\t\tconst records = rows.map((row) => deserializeRecord(row, this.definition.fields))\n\n\t\t// Resolve includes if any\n\t\tif (this.descriptor.include && this.descriptor.include.length > 0 && this.schema) {\n\t\t\tawait this.resolveIncludes(records)\n\t\t}\n\n\t\treturn records as T[]\n\t}\n\n\t/**\n\t * Execute a COUNT query and return the count.\n\t */\n\tasync count(): Promise<number> {\n\t\tconst { sql, params } = buildCountQuery(this.descriptor, this.definition.fields)\n\t\tconst rows = await this.adapter.query<{ count: number }>(sql, params)\n\t\treturn rows[0]?.count ?? 0\n\t}\n\n\t/**\n\t * Subscribe to query results. Callback is called immediately with current results,\n\t * then again whenever the results change due to mutations.\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tsubscribe(callback: SubscriptionCallback<T>, options?: SubscribeOptions): () => void {\n\t\tconst executeFn = () => this.exec()\n\n\t\t// Resolve includeCollections for subscription tracking\n\t\tconst descriptorCopy = { ...this.descriptor }\n\t\tif (descriptorCopy.include && descriptorCopy.include.length > 0 && this.schema) {\n\t\t\tdescriptorCopy.includeCollections = this.resolveIncludeCollections(descriptorCopy.include)\n\t\t}\n\n\t\t// Use registerAndFetch to execute immediately, set lastResults,\n\t\t// and call callback — ensuring subsequent flushes diff correctly.\n\t\treturn this.subscriptionManager.registerAndFetch(\n\t\t\tdescriptorCopy,\n\t\t\tcallback as SubscriptionCallback<CollectionRecord>,\n\t\t\texecuteFn as () => Promise<CollectionRecord[]>,\n\t\t\t{ onError: options?.onError, resultsEqual: this.getResultsEqual() },\n\t\t)\n\t}\n\n\t/** Comparator built once per collection definition and shared by its queries. */\n\tprivate getResultsEqual(): ResultsEqual {\n\t\tlet cached = RESULTS_EQUAL_CACHE.get(this.definition)\n\t\tif (!cached) {\n\t\t\tcached = createResultsEqual(this.definition.fields)\n\t\t\tRESULTS_EQUAL_CACHE.set(this.definition, cached)\n\t\t}\n\t\treturn cached\n\t}\n\n\t/** Get the internal descriptor (for testing/debugging) */\n\tgetDescriptor(): QueryDescriptor {\n\t\treturn { ...this.descriptor }\n\t}\n\n\tprivate clone(): QueryBuilder<T> {\n\t\tconst qb = new QueryBuilder<T>(\n\t\t\tthis.collectionName,\n\t\t\tthis.definition,\n\t\t\tthis.adapter,\n\t\t\tthis.subscriptionManager,\n\t\t\t{},\n\t\t\tthis.schema,\n\t\t)\n\t\tqb.descriptor = {\n\t\t\t...this.descriptor,\n\t\t\twhere: { ...this.descriptor.where },\n\t\t\torderBy: [...this.descriptor.orderBy],\n\t\t\tinclude: this.descriptor.include ? [...this.descriptor.include] : undefined,\n\t\t\tincludeCollections: this.descriptor.includeCollections\n\t\t\t\t? [...this.descriptor.includeCollections]\n\t\t\t\t: undefined,\n\t\t}\n\t\treturn qb\n\t}\n\n\t/**\n\t * Resolve include targets to their actual collection names for subscription tracking.\n\t */\n\tprivate resolveIncludeCollections(targets: string[]): string[] {\n\t\tif (!this.schema) return []\n\t\tconst collections: string[] = []\n\n\t\tfor (const target of targets) {\n\t\t\tconst relation = this.findRelation(target)\n\t\t\tif (relation) {\n\t\t\t\t// For many-to-one: the related collection is `relation.to`\n\t\t\t\t// For one-to-many: the related collection is `relation.from`\n\t\t\t\tif (relation.from === this.collectionName) {\n\t\t\t\t\tcollections.push(relation.to)\n\t\t\t\t} else {\n\t\t\t\t\tcollections.push(relation.from)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn collections\n\t}\n\n\t/**\n\t * Resolve includes after primary query, batch-fetching related records.\n\t */\n\tprivate async resolveIncludes(records: CollectionRecord[]): Promise<void> {\n\t\tif (!this.schema || !this.descriptor.include || records.length === 0) return\n\n\t\tfor (const target of this.descriptor.include) {\n\t\t\tconst relation = this.findRelation(target)\n\t\t\tif (!relation) {\n\t\t\t\tthrow new QueryError(\n\t\t\t\t\t`No relation found for include target \"${target}\" on collection \"${this.collectionName}\". ` +\n\t\t\t\t\t\t`Check that a relation is defined in your schema that connects \"${this.collectionName}\" to \"${target}\".`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (relation.from === this.collectionName) {\n\t\t\t\t// Many-to-one or one-to-one: primary has FK → fetch parent records\n\t\t\t\tawait this.resolveManyToOneInclude(records, relation, target)\n\t\t\t} else {\n\t\t\t\t// One-to-many: related collection has FK → fetch children\n\t\t\t\tawait this.resolveOneToManyInclude(records, relation, target)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Many-to-one: collect FK values from primary results, batch-fetch related, attach as singular.\n\t */\n\tprivate async resolveManyToOneInclude(\n\t\trecords: CollectionRecord[],\n\t\trelation: { from: string; to: string; field: string },\n\t\ttarget: string,\n\t): Promise<void> {\n\t\tconst fkField = relation.field\n\t\tconst fkValues = records\n\t\t\t.map((r) => r[fkField])\n\t\t\t.filter((v): v is string => v !== null && v !== undefined && typeof v === 'string')\n\n\t\tif (fkValues.length === 0) {\n\t\t\t// All null FKs — set property to null on all records\n\t\t\tconst propName = singularize(target)\n\t\t\tfor (const record of records) {\n\t\t\t\t;(record as Record<string, unknown>)[propName] = null\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst uniqueFks = [...new Set(fkValues)]\n\t\tconst relatedCollection = relation.to\n\t\tconst relatedDef = this.schema?.collections[relatedCollection]\n\t\tif (!relatedDef) return\n\n\t\t// Batch fetch: SELECT * FROM <to> WHERE id IN (...) AND _deleted = 0\n\t\tconst placeholders = uniqueFks.map(() => '?').join(', ')\n\t\tconst sql = `SELECT * FROM ${quoteIdent(relatedCollection)} WHERE id IN (${placeholders}) AND _deleted = 0`\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(sql, uniqueFks)\n\t\tconst relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields))\n\n\t\t// Build lookup\n\t\tconst lookup = new Map<string, CollectionRecord>()\n\t\tfor (const r of relatedRecords) {\n\t\t\tlookup.set(r.id, r)\n\t\t}\n\n\t\t// Attach as singular property\n\t\tconst propName = singularize(target)\n\t\tfor (const record of records) {\n\t\t\tconst fk = record[fkField] as string | null\n\t\t\t;(record as Record<string, unknown>)[propName] = fk ? (lookup.get(fk) ?? null) : null\n\t\t}\n\t}\n\n\t/**\n\t * One-to-many: collect primary IDs, batch-fetch children, attach as array.\n\t */\n\tprivate async resolveOneToManyInclude(\n\t\trecords: CollectionRecord[],\n\t\trelation: { from: string; to: string; field: string },\n\t\ttarget: string,\n\t): Promise<void> {\n\t\tconst primaryIds = records.map((r) => r.id)\n\t\tconst relatedCollection = relation.from\n\t\tconst relatedDef = this.schema?.collections[relatedCollection]\n\t\tif (!relatedDef) return\n\n\t\tconst fkField = relation.field\n\t\tconst placeholders = primaryIds.map(() => '?').join(', ')\n\t\tconst sql = `SELECT * FROM ${quoteIdent(relatedCollection)} WHERE ${quoteIdent(fkField)} IN (${placeholders}) AND _deleted = 0`\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\tsql,\n\t\t\tprimaryIds.map((id) => encodeStoredText(id)),\n\t\t)\n\t\tconst relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields))\n\n\t\t// Group by FK\n\t\tconst grouped = new Map<string, CollectionRecord[]>()\n\t\tfor (const r of relatedRecords) {\n\t\t\tconst fk = r[fkField] as string\n\t\t\tif (!grouped.has(fk)) {\n\t\t\t\tgrouped.set(fk, [])\n\t\t\t}\n\t\t\tgrouped.get(fk)?.push(r)\n\t\t}\n\n\t\t// Attach as array property\n\t\tconst propName = pluralize(target)\n\t\tfor (const record of records) {\n\t\t\t;(record as Record<string, unknown>)[propName] = grouped.get(record.id) ?? []\n\t\t}\n\t}\n\n\t/**\n\t * Find a relation definition matching the include target.\n\t * Searches by relation name, target collection name, and singularized/pluralized variants.\n\t */\n\tprivate findRelation(\n\t\ttarget: string,\n\t): { from: string; to: string; field: string; type: string } | null {\n\t\tif (!this.schema) return null\n\n\t\tfor (const [_name, rel] of Object.entries(this.schema.relations)) {\n\t\t\t// Direct match: target is the related collection name\n\t\t\tif (rel.from === this.collectionName && rel.to === target) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === target) return rel\n\n\t\t\t// Singularized match: \"project\" matches relation to \"projects\"\n\t\t\tif (rel.from === this.collectionName && rel.to === pluralize(target)) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === pluralize(target)) return rel\n\n\t\t\t// Pluralized match: \"todos\" matches relation from \"todos\"\n\t\t\tif (rel.from === this.collectionName && rel.to === singularize(target)) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === singularize(target)) return rel\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import type { OnDeleteAction, RelationDefinition, SchemaDefinition } from '@korajs/core'\n\n/**\n * A resolved relation reference: describes a relation that points TO a given collection.\n * When a record in `targetCollection` is deleted, we must handle records in\n * `sourceCollection` that reference it via `foreignKeyField`.\n */\nexport interface IncomingRelation {\n\t/** Name of the relation in the schema */\n\trelationName: string\n\t/** Collection that holds the foreign key (the \"from\" side) */\n\tsourceCollection: string\n\t/** Field in the source collection that references the target */\n\tforeignKeyField: string\n\t/** What to do when the referenced record is deleted */\n\tonDelete: OnDeleteAction\n\t/** The full relation definition */\n\trelation: RelationDefinition\n}\n\n/**\n * Builds an efficient lookup from target collection to all relations that reference it.\n *\n * Given a schema with relations like:\n * ```\n * todoBelongsToProject: { from: 'todos', to: 'projects', field: 'projectId', onDelete: 'cascade' }\n * ```\n *\n * The lookup for 'projects' would return:\n * ```\n * [{ sourceCollection: 'todos', foreignKeyField: 'projectId', onDelete: 'cascade', ... }]\n * ```\n *\n * This enables O(1) lookup when deleting a record to find all dependent relations.\n *\n * @param schema - The full schema definition containing relations\n * @returns A map from target collection name to its incoming relations\n */\nexport function buildRelationLookup(schema: SchemaDefinition): Map<string, IncomingRelation[]> {\n\tconst lookup = new Map<string, IncomingRelation[]>()\n\n\tfor (const [relationName, relation] of Object.entries(schema.relations)) {\n\t\tconst targetCollection = relation.to\n\t\tconst existing = lookup.get(targetCollection) ?? []\n\t\texisting.push({\n\t\t\trelationName,\n\t\t\tsourceCollection: relation.from,\n\t\t\tforeignKeyField: relation.field,\n\t\t\tonDelete: relation.onDelete,\n\t\t\trelation,\n\t\t})\n\t\tlookup.set(targetCollection, existing)\n\t}\n\n\treturn lookup\n}\n\n/**\n * Get all incoming relations for a given collection.\n * Returns an empty array if no relations reference the collection.\n *\n * @param lookup - The pre-built relation lookup map\n * @param collection - The target collection name\n * @returns Array of incoming relations\n */\nexport function getIncomingRelations(\n\tlookup: Map<string, IncomingRelation[]>,\n\tcollection: string,\n): IncomingRelation[] {\n\treturn lookup.get(collection) ?? []\n}\n","import type { Operation, SchemaDefinition } from '@korajs/core'\nimport { KoraError, encodeStoredText, quoteIdent } from '@korajs/core'\nimport type { WriteEnv, WriteScope } from '../mutations/write-context'\nimport { writeDeleteInTx, writeUpdateInTx } from '../mutations/write-ops'\nimport type { Transaction } from '../types'\nimport type { IncomingRelation } from './relation-lookup'\nimport { buildRelationLookup, getIncomingRelations } from './relation-lookup'\n\n/**\n * Error thrown when a delete is refused due to a 'restrict' referential integrity policy.\n * The error includes context about which relation caused the restriction and\n * how many referencing records exist.\n */\nexport class ReferentialIntegrityError extends KoraError {\n\tconstructor(\n\t\tcollection: string,\n\t\trecordId: string,\n\t\treferencingCollection: string,\n\t\trelationName: string,\n\t\treferencingCount: number,\n\t) {\n\t\tsuper(\n\t\t\t`Cannot delete record \"${recordId}\" from \"${collection}\": ${referencingCount} record(s) in \"${referencingCollection}\" reference it via relation \"${relationName}\" with onDelete: 'restrict'. Delete or reassign the referencing records first.`,\n\t\t\t'REFERENTIAL_INTEGRITY',\n\t\t\t{\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t\treferencingCollection,\n\t\t\t\trelationName,\n\t\t\t\treferencingCount,\n\t\t\t},\n\t\t)\n\t\tthis.name = 'ReferentialIntegrityError'\n\t}\n}\n\n/**\n * Configuration for the RelationEnforcer.\n */\nexport interface RelationEnforcerConfig {\n\tschema: SchemaDefinition\n}\n\n/**\n * Result of enforcing referential integrity on a delete operation.\n * Contains all additional operations that were created as side effects\n * (cascaded deletes and set-null updates).\n */\nexport interface EnforcementResult {\n\t/** Additional operations created by cascading deletes and set-null updates */\n\toperations: Operation[]\n}\n\n/**\n * Enforces referential integrity constraints during local delete operations.\n *\n * When a record is deleted, this enforcer checks all relations that reference\n * the deleted record's collection and applies the appropriate onDelete policy:\n *\n * - **cascade**: Recursively deletes all referencing records\n * - **set-null**: Sets the foreign key to null on all referencing records\n * - **restrict**: Throws a ReferentialIntegrityError if any references exist\n * - **no-action**: Does nothing (the foreign key is left dangling)\n *\n * The enforcer runs inside the delete's write transaction and writes every side\n * effect through the single local write path (`writeDeleteInTx` /\n * `writeUpdateInTx`), so cascaded operations reserve their sequence numbers in\n * the same contiguous block as the parent and carry per-field version stamps\n * (STORE-2, STORE-3). Every generated operation depends causally on the delete\n * that caused it.\n *\n * @example\n * ```typescript\n * const enforcer = new RelationEnforcer({ schema })\n * // inside a write transaction, after building the parent delete operation:\n * const result = await enforcer.enforceDelete('projects', 'proj-1', scope, env, deleteOp.id)\n * // result.operations contains any cascaded delete/update ops\n * ```\n */\nexport class RelationEnforcer {\n\tprivate readonly lookup: Map<string, IncomingRelation[]>\n\n\tconstructor(config: RelationEnforcerConfig) {\n\t\tthis.lookup = buildRelationLookup(config.schema)\n\t}\n\n\t/**\n\t * Enforce referential integrity for a record being deleted.\n\t *\n\t * @param collection - The collection the deleted record belongs to\n\t * @param recordId - The ID of the deleted record\n\t * @param scope - The active write scope (transaction + causal scope)\n\t * @param env - The write environment of the delete\n\t * @param parentOpId - Id of the delete operation; every side effect depends on it\n\t * @returns All additional operations created as side effects\n\t * @throws {ReferentialIntegrityError} If a 'restrict' policy is violated\n\t */\n\tasync enforceDelete(\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<EnforcementResult> {\n\t\tconst incomingRelations = getIncomingRelations(this.lookup, collection)\n\t\tif (incomingRelations.length === 0) {\n\t\t\treturn { operations: [] }\n\t\t}\n\n\t\tconst allOperations: Operation[] = []\n\n\t\t// Process relations in a deterministic order (sorted by relation name)\n\t\t// to ensure identical results regardless of Map iteration order.\n\t\tconst sortedRelations = [...incomingRelations].sort((a, b) =>\n\t\t\ta.relationName.localeCompare(b.relationName),\n\t\t)\n\n\t\tfor (const incoming of sortedRelations) {\n\t\t\tconst ops = await this.enforceRelation(incoming, recordId, scope, env, parentOpId)\n\t\t\tallOperations.push(...ops)\n\t\t}\n\n\t\treturn { operations: allOperations }\n\t}\n\n\t/**\n\t * Enforce a single relation's onDelete policy.\n\t */\n\tprivate async enforceRelation(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tswitch (incoming.onDelete) {\n\t\t\tcase 'cascade':\n\t\t\t\treturn this.enforceCascade(incoming, deletedRecordId, scope, env, parentOpId)\n\t\t\tcase 'set-null':\n\t\t\t\treturn this.enforceSetNull(incoming, deletedRecordId, scope, env, parentOpId)\n\t\t\tcase 'restrict':\n\t\t\t\treturn this.enforceRestrict(incoming, deletedRecordId, scope.tx)\n\t\t\tcase 'no-action':\n\t\t\t\treturn []\n\t\t}\n\t}\n\n\t/**\n\t * Cascade: delete every live record that references the deleted record. Each\n\t * cascaded delete runs the full delete path, so it recurses into its own\n\t * referencing records.\n\t */\n\tprivate async enforceCascade(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tconst referencingIds = await this.findReferencing(incoming, deletedRecordId, scope.tx)\n\t\tconst operations: Operation[] = []\n\t\tfor (const id of referencingIds) {\n\t\t\tconst result = await writeDeleteInTx(env, scope, incoming.sourceCollection, id, {\n\t\t\t\textraCausalDeps: [parentOpId],\n\t\t\t})\n\t\t\tif (result.operation) operations.push(result.operation)\n\t\t\toperations.push(...result.sideEffects)\n\t\t}\n\t\treturn operations\n\t}\n\n\t/**\n\t * Set-null: set the foreign key to null on every live referencing record.\n\t */\n\tprivate async enforceSetNull(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tconst referencingIds = await this.findReferencing(incoming, deletedRecordId, scope.tx)\n\t\tconst operations: Operation[] = []\n\t\tfor (const id of referencingIds) {\n\t\t\tconst result = await writeUpdateInTx(\n\t\t\t\tenv,\n\t\t\t\tscope,\n\t\t\t\tincoming.sourceCollection,\n\t\t\t\tid,\n\t\t\t\t{ [incoming.foreignKeyField]: null },\n\t\t\t\t[parentOpId],\n\t\t\t)\n\t\t\tif (result.operation) operations.push(result.operation)\n\t\t}\n\t\treturn operations\n\t}\n\n\t/**\n\t * Restrict: refuse the delete if any referencing records exist.\n\t */\n\tprivate async enforceRestrict(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\ttx: Transaction,\n\t): Promise<Operation[]> {\n\t\tconst { sourceCollection, foreignKeyField, relationName } = incoming\n\n\t\tconst countRows = await tx.query<{ cnt: number }>(\n\t\t\t`SELECT COUNT(*) as cnt FROM ${quoteIdent(sourceCollection)} WHERE ${quoteIdent(foreignKeyField)} = ? AND _deleted = 0`,\n\t\t\t// The foreign key column holds the stored-text form (RT-65).\n\t\t\t[encodeStoredText(deletedRecordId)],\n\t\t)\n\t\tconst count = countRows[0]?.cnt ?? 0\n\n\t\tif (count > 0) {\n\t\t\tthrow new ReferentialIntegrityError(\n\t\t\t\tincoming.relation.to,\n\t\t\t\tdeletedRecordId,\n\t\t\t\tsourceCollection,\n\t\t\t\trelationName,\n\t\t\t\tcount,\n\t\t\t)\n\t\t}\n\n\t\treturn []\n\t}\n\n\t/** Ids of live records referencing `deletedRecordId`, in id order (deterministic). */\n\tprivate async findReferencing(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\ttx: Transaction,\n\t): Promise<string[]> {\n\t\tconst rows = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${quoteIdent(incoming.sourceCollection)} WHERE ${quoteIdent(incoming.foreignKeyField)} = ? AND _deleted = 0 ORDER BY id`,\n\t\t\t// The foreign key column holds the stored-text form (RT-65).\n\t\t\t[encodeStoredText(deletedRecordId)],\n\t\t)\n\t\treturn rows.map((row) => row.id)\n\t}\n\n\t/**\n\t * Get the relation lookup map for external use (e.g., by the merge engine).\n\t */\n\tgetRelationLookup(): Map<string, IncomingRelation[]> {\n\t\treturn this.lookup\n\t}\n}\n","import {\n\tHybridLogicalClock,\n\tOperationError,\n\tfoldRecord,\n\tisFoldStateLive,\n\tmaterialize,\n} from '@korajs/core'\nimport type {\n\tCollectionDefinition,\n\tOperation,\n\tOperationTransform,\n\tSchemaDefinition,\n} from '@korajs/core'\nimport { topologicalSort } from '@korajs/core/internal'\nimport { mergeYjsUpdates } from '../fold/record-folder'\nimport { decodeRichtextFieldsFromOpData } from '../serialization/op-data-encoding'\nimport type { CollectionRecord } from '../types'\n\n/**\n * In-memory materialized state at a causal cut in the operation log.\n * Read-only — does not mutate the live store.\n */\nexport interface ReplaySnapshot {\n\t/** The operation whose causal past was replayed (inclusive). */\n\ttargetOperation: Operation\n\t/** Operations applied in causal order (ancestors + target). */\n\toperationsApplied: Operation[]\n\t/** Non-deleted records per collection after replay. */\n\tcollections: Record<string, CollectionRecord[]>\n\t/** Look up a single record at the replay cut. Returns null if deleted or missing. */\n\tfindRecord(collection: string, recordId: string): CollectionRecord | null\n}\n\ninterface MutableReplayRecord {\n\tid: string\n\tfields: Record<string, unknown>\n\tdeleted: boolean\n\tcreatedAt: number\n\tupdatedAt: number\n}\n\ntype ReplayMemoryState = Map<string, Map<string, MutableReplayRecord>>\n\n/**\n * Collect the target operation and all causal ancestors present in `allOps`.\n *\n * @param aliases - Old operation id -> the id it was re-emitted under (a renumbered\n * version-2 operation, `_kora_seq_conflicts.reemitted_as`). A dependent the server\n * already stored keeps naming the old id; the alias resolves it.\n */\nexport function collectCausalClosure(\n\tallOps: Operation[],\n\ttargetOperationId: string,\n\taliases: ReadonlyMap<string, string> = new Map(),\n): Operation[] {\n\tconst opMap = new Map<string, Operation>()\n\tfor (const op of allOps) {\n\t\topMap.set(op.id, op)\n\t}\n\n\tconst target = opMap.get(targetOperationId)\n\tif (!target) {\n\t\tthrow new OperationError(\n\t\t\t`Operation \"${targetOperationId}\" not found in the local operation log`,\n\t\t\t{\n\t\t\t\toperationId: targetOperationId,\n\t\t\t},\n\t\t)\n\t}\n\n\tconst included = new Set<string>()\n\tconst stack: string[] = [targetOperationId]\n\n\twhile (stack.length > 0) {\n\t\tconst id = stack.pop()\n\t\tif (id === undefined || included.has(id)) {\n\t\t\tcontinue\n\t\t}\n\t\tincluded.add(id)\n\t\tconst op = opMap.get(id)\n\t\tif (!op) {\n\t\t\tcontinue\n\t\t}\n\t\tfor (const dep of op.causalDeps) {\n\t\t\tlet depId = dep\n\t\t\t// Follow re-emissions (a renumbered op may itself have been renumbered again).\n\t\t\tfor (let hops = 0; !opMap.has(depId) && aliases.has(depId) && hops < 8; hops++) {\n\t\t\t\tdepId = aliases.get(depId) ?? depId\n\t\t\t}\n\t\t\tif (opMap.has(depId)) {\n\t\t\t\tstack.push(depId)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst subset = allOps.filter((op) => included.has(op.id))\n\treturn topologicalSort(subset)\n}\n\n/**\n * Replay a causal subset of operations into an in-memory materialized snapshot.\n * Does not use the merge engine — concurrent ops outside the causal cut are excluded.\n */\nexport function buildReplaySnapshot(\n\tschema: SchemaDefinition,\n\tallOps: Operation[],\n\ttargetOperationId: string,\n\taliases: ReadonlyMap<string, string> = new Map(),\n\ttransforms: readonly OperationTransform[] = [],\n): ReplaySnapshot {\n\tconst operationsApplied = collectCausalClosure(allOps, targetOperationId, aliases)\n\tconst targetOperation = operationsApplied.find((op) => op.id === targetOperationId)\n\tif (!targetOperation) {\n\t\tthrow new OperationError(`Operation \"${targetOperationId}\" not found after causal sort`, {\n\t\t\toperationId: targetOperationId,\n\t\t})\n\t}\n\n\tconst memory = foldIntoMemory(operationsApplied, schema, transforms)\n\n\tconst collections = materializeCollections(schema, memory)\n\n\treturn {\n\t\ttargetOperation,\n\t\toperationsApplied,\n\t\tcollections,\n\t\tfindRecord(collection: string, recordId: string): CollectionRecord | null {\n\t\t\tconst colMap = memory.get(collection)\n\t\t\tconst record = colMap?.get(recordId)\n\t\t\tif (!record || record.deleted) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst definition = schema.collections[collection]\n\t\t\tif (!definition) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn toCollectionRecord(record, definition)\n\t\t},\n\t}\n}\n\n/**\n * Fold every record of the causal cut with the W7 fold, exactly as the live store\n * materializes it (the cut may hold concurrent branches: the fold, not the\n * application order, decides).\n */\nfunction foldIntoMemory(\n\tops: readonly Operation[],\n\tschema: SchemaDefinition,\n\ttransforms: readonly OperationTransform[],\n): ReplayMemoryState {\n\tconst byRecord = new Map<string, Operation[]>()\n\tfor (const op of ops) {\n\t\tif (!schema.collections[op.collection]) continue\n\t\tconst key = `${op.collection}\\u0000${op.recordId}`\n\t\tconst list = byRecord.get(key) ?? []\n\t\tlist.push(op)\n\t\tbyRecord.set(key, list)\n\t}\n\tconst state: ReplayMemoryState = new Map()\n\tfor (const recordOps of byRecord.values()) {\n\t\tconst first = recordOps[0] as Operation\n\t\tconst definition = schema.collections[first.collection] as CollectionDefinition\n\t\t// The live store folds with the schema transforms (RT-84): so does time travel.\n\t\tconst folded = foldRecord(recordOps, schema, {\n\t\t\trichtext: mergeYjsUpdates,\n\t\t\t...(transforms.length > 0 ? { transforms } : {}),\n\t\t}).state\n\t\tif (folded === null || folded.cr === null || folded.u === null) continue\n\t\tconst values = materialize({ ...folded, d: null }, { richtext: mergeYjsUpdates }) ?? {}\n\t\tlet colMap = state.get(first.collection)\n\t\tif (!colMap) {\n\t\t\tcolMap = new Map()\n\t\t\tstate.set(first.collection, colMap)\n\t\t}\n\t\tcolMap.set(first.recordId, {\n\t\t\tid: first.recordId,\n\t\t\t// The fold materializes op-data form (tagged binary); snapshots expose\n\t\t\t// record-shaped values (Uint8Array / string).\n\t\t\tfields: decodeRichtextFieldsFromOpData(values, definition.fields),\n\t\t\tdeleted: !isFoldStateLive(folded),\n\t\t\tcreatedAt: HybridLogicalClock.deserialize(folded.cr.t).wallTime,\n\t\t\tupdatedAt: HybridLogicalClock.deserialize(folded.u.t).wallTime,\n\t\t})\n\t}\n\treturn state\n}\n\nfunction materializeCollections(\n\tschema: SchemaDefinition,\n\tmemory: ReplayMemoryState,\n): Record<string, CollectionRecord[]> {\n\tconst collections: Record<string, CollectionRecord[]> = {}\n\n\tfor (const [collectionName, definition] of Object.entries(schema.collections)) {\n\t\tconst colMap = memory.get(collectionName)\n\t\tconst records: CollectionRecord[] = []\n\t\tif (colMap) {\n\t\t\tfor (const record of colMap.values()) {\n\t\t\t\tif (!record.deleted) {\n\t\t\t\t\trecords.push(toCollectionRecord(record, definition))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcollections[collectionName] = records\n\t}\n\n\treturn collections\n}\n\nfunction toCollectionRecord(\n\trecord: MutableReplayRecord,\n\tdefinition: CollectionDefinition,\n): CollectionRecord {\n\tconst result: CollectionRecord = {\n\t\tid: record.id,\n\t\tcreatedAt: record.createdAt,\n\t\tupdatedAt: record.updatedAt,\n\t}\n\tfor (const [fieldName] of Object.entries(definition.fields)) {\n\t\tif (fieldName in record.fields) {\n\t\t\tresult[fieldName] = record.fields[fieldName]\n\t\t}\n\t}\n\treturn result\n}\n","import type { SequenceConfig } from '@korajs/core'\nimport { defaultSequenceFormat, formatSequenceValue } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\n\ninterface SequenceRow {\n\tcounter: number\n}\n\n/**\n * Manages offline-safe sequences backed by a `_kora_sequences` table.\n *\n * Each sequence counter is scoped by (name, scope, nodeId), ensuring\n * that different devices never collide. The counter is atomically\n * incremented within a database transaction.\n *\n * @example\n * ```typescript\n * const mgr = new SequenceManager(adapter, 'node-abc')\n *\n * const receipt = await mgr.next('receipt', {\n * scope: 'store-1',\n * format: 'S-{date}-{node4}-{seq}',\n * })\n * // → \"S-20260508-node-0001\"\n * ```\n */\nexport class SequenceManager {\n\tprivate readonly adapter: StorageAdapter\n\tprivate readonly nodeId: string\n\n\tconstructor(adapter: StorageAdapter, nodeId: string) {\n\t\tthis.adapter = adapter\n\t\tthis.nodeId = nodeId\n\t}\n\n\t/**\n\t * Get the next value in a sequence, atomically incrementing the counter.\n\t *\n\t * @param name - The sequence name (e.g., 'receipt', 'invoice')\n\t * @param config - Optional configuration for scope, format, and starting value\n\t * @returns The formatted sequence value\n\t */\n\tasync next(name: string, config?: SequenceConfig): Promise<string> {\n\t\tconst scope = config?.scope ?? ''\n\t\tconst startAt = config?.startAt ?? 1\n\t\tconst format = config?.format ?? defaultSequenceFormat(name)\n\n\t\tlet counter = 0\n\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t// Try to read the current counter\n\t\t\tconst rows = await tx.query<SequenceRow>(\n\t\t\t\t'SELECT counter FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t\t[name, scope, this.nodeId],\n\t\t\t)\n\n\t\t\tif (rows.length > 0) {\n\t\t\t\tconst row = rows[0] as SequenceRow\n\t\t\t\tcounter = row.counter + 1\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'UPDATE _kora_sequences SET counter = ? WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t\t\t[counter, name, scope, this.nodeId],\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\t// First use — initialize with startAt\n\t\t\t\tcounter = startAt\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'INSERT INTO _kora_sequences (name, scope, node_id, counter) VALUES (?, ?, ?, ?)',\n\t\t\t\t\t[name, scope, this.nodeId, counter],\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn formatSequenceValue(format, counter, this.nodeId)\n\t}\n\n\t/**\n\t * Get the current counter value without incrementing.\n\t *\n\t * @param name - The sequence name\n\t * @param config - Optional scope\n\t * @returns The current counter value, or 0 if the sequence has never been used\n\t */\n\tasync current(name: string, config?: { scope?: string }): Promise<number> {\n\t\tconst scope = config?.scope ?? ''\n\n\t\tconst rows = await this.adapter.query<SequenceRow>(\n\t\t\t'SELECT counter FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t[name, scope, this.nodeId],\n\t\t)\n\n\t\tif (rows.length > 0) {\n\t\t\treturn (rows[0] as SequenceRow).counter\n\t\t}\n\t\treturn 0\n\t}\n\n\t/**\n\t * Reset a sequence counter.\n\t *\n\t * @param name - The sequence name\n\t * @param config - Optional scope and target value\n\t */\n\tasync reset(name: string, config?: { scope?: string; to?: number }): Promise<void> {\n\t\tconst scope = config?.scope ?? ''\n\t\tconst to = config?.to ?? 0\n\n\t\tawait this.adapter.execute(\n\t\t\t'DELETE FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t[name, scope, this.nodeId],\n\t\t)\n\n\t\tif (to > 0) {\n\t\t\tawait this.adapter.execute(\n\t\t\t\t'INSERT INTO _kora_sequences (name, scope, node_id, counter) VALUES (?, ?, ?, ?)',\n\t\t\t\t[name, scope, this.nodeId, to],\n\t\t\t)\n\t\t}\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\nimport { isRawTextKind } from './serializer'\n\n/** `_kora_meta` key: raw-string columns hold the stored-text codec's form (RT-65). */\nexport const STORED_TEXT_CODEC_META_KEY = 'stored_text_codec'\n\n/** Version of the codec the rows are written with. */\nconst STORED_TEXT_CODEC_VERSION = '1'\n\n/**\n * Once per database: re-encode the U+FFFF of rows written before the stored-text codec\n * (RT-65) so the decoder returns them unchanged. A row written before the codec holds\n * the raw string; the only code unit whose meaning changes under the decoder is the\n * escape introducer U+FFFF (`U+FFFF` -> `U+FFFF F`). NUL needs no rewrite (better-sqlite3\n * stored it as is), and a lone surrogate a pre-codec row held was already replaced by\n * U+FFFD when it was bound, so nothing is left to recover.\n *\n * Every collection table of the schema that exists is rewritten, for the columns of its\n * raw-string fields that exist. One transaction; the meta key makes it idempotent.\n *\n * @param adapter - An open storage adapter\n * @param schema - The schema whose collection tables to migrate\n */\nexport async function ensureStoredTextCodec(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<void> {\n\tconst rows = await adapter.query<{ value: string }>(\n\t\t'SELECT value FROM _kora_meta WHERE key = ?',\n\t\t[STORED_TEXT_CODEC_META_KEY],\n\t)\n\tif (rows[0]?.value === STORED_TEXT_CODEC_VERSION) return\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const [name, collection] of Object.entries(schema.collections)) {\n\t\t\tconst columns = new Set(\n\t\t\t\t(await tx.query<{ name: string }>(`PRAGMA table_info(${quoteIdent(name)})`)).map(\n\t\t\t\t\t(column) => column.name,\n\t\t\t\t),\n\t\t\t)\n\t\t\tif (columns.size === 0) continue\n\t\t\tfor (const [field, descriptor] of Object.entries(collection.fields)) {\n\t\t\t\tif (!isRawTextKind(descriptor.kind) || !columns.has(field)) continue\n\t\t\t\tconst column = quoteIdent(field)\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(name)} SET ${column} = replace(${column}, char(65535), char(65535) || 'F') WHERE instr(${column}, char(65535)) > 0`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tSTORED_TEXT_CODEC_META_KEY,\n\t\t\tSTORED_TEXT_CODEC_VERSION,\n\t\t])\n\t})\n}\n","/**\n * Bloom filter for fast subscription dependency pre-checking.\n *\n * When the SubscriptionManager has many active subscriptions, checking whether a\n * mutation might affect any subscription requires scanning all subscriptions.\n * This bloom filter provides a fast O(k) pre-check: if the filter says \"definitely\n * not present\", we can skip the subscription entirely. If it says \"maybe present\",\n * we fall through to the precise collection/field matching.\n *\n * Uses FNV-1a for hashing and Kirsch-Mitzenmacker double hashing to derive k\n * hash functions from two base hashes.\n */\n\n// FNV-1a constants for 32-bit hashes\nconst FNV_OFFSET_BASIS = 0x811c9dc5\nconst FNV_PRIME = 0x01000193\n\n/**\n * Compute FNV-1a 32-bit hash of a string.\n *\n * FNV-1a is a non-cryptographic hash function optimized for speed and distribution.\n * It processes one byte at a time: XOR then multiply, which gives better avalanche\n * behavior than the original FNV-1 (multiply then XOR).\n *\n * @param input - The string to hash\n * @returns A 32-bit unsigned integer hash\n */\nexport function fnv1a32(input: string): number {\n\tlet hash = FNV_OFFSET_BASIS\n\tfor (let i = 0; i < input.length; i++) {\n\t\thash ^= input.charCodeAt(i)\n\t\t// Math.imul gives true 32-bit integer multiplication without overflow issues\n\t\thash = Math.imul(hash, FNV_PRIME)\n\t}\n\t// Ensure unsigned 32-bit result\n\treturn hash >>> 0\n}\n\n/**\n * Calculate the optimal number of bits for a bloom filter.\n *\n * Formula: m = -(n * ln(p)) / (ln(2)^2)\n * Rounded up to the nearest multiple of 32 for Uint32Array alignment.\n *\n * @param expectedItems - Expected number of items to insert\n * @param falsePositiveRate - Desired false positive rate (0-1)\n * @returns Number of bits, rounded to nearest 32-bit multiple (minimum 32)\n */\nexport function optimalBitCount(expectedItems: number, falsePositiveRate: number): number {\n\tif (expectedItems <= 0) return 32\n\tif (falsePositiveRate <= 0 || falsePositiveRate >= 1) return 32\n\n\tconst ln2Squared = Math.LN2 * Math.LN2\n\tconst rawBits = -(expectedItems * Math.log(falsePositiveRate)) / ln2Squared\n\n\t// Round up to nearest 32-bit multiple for Uint32Array alignment\n\tconst aligned = Math.ceil(rawBits / 32) * 32\n\treturn Math.max(32, aligned)\n}\n\n/**\n * Calculate the optimal number of hash functions for a bloom filter.\n *\n * Formula: k = (m/n) * ln(2)\n * Clamped to [1, 30] to avoid degenerate cases.\n *\n * @param bitCount - Total number of bits in the filter\n * @param expectedItems - Expected number of items to insert\n * @returns Number of hash functions, clamped to [1, 30]\n */\nexport function optimalHashCount(bitCount: number, expectedItems: number): number {\n\tif (expectedItems <= 0) return 1\n\tconst raw = (bitCount / expectedItems) * Math.LN2\n\treturn Math.max(1, Math.min(30, Math.round(raw)))\n}\n\n/**\n * Bloom filter for subscription dependency tracking.\n *\n * Each subscription adds its watched collection (and optionally fields) to the\n * filter. When a mutation arrives, we check \"collection\" and \"collection:field\"\n * keys against the filter. A negative result means no subscription cares about\n * this mutation, so we can skip the expensive per-subscription scan.\n *\n * @example\n * ```typescript\n * const filter = new SubscriptionBloomFilter(100, 0.01)\n * filter.add('todos')\n * filter.add('todos', 'completed')\n *\n * filter.mightContain('todos') // true (definitely added)\n * filter.mightContain('projects') // false (definitely not added)\n * filter.mightContain('todos', 'completed') // true (definitely added)\n * ```\n */\nexport class SubscriptionBloomFilter {\n\tprivate bits: Uint32Array\n\tprivate readonly bitCount: number\n\tprivate readonly hashCount: number\n\tprivate itemCount = 0\n\n\tconstructor(expectedItems: number, falsePositiveRate = 0.01) {\n\t\tthis.bitCount = optimalBitCount(expectedItems, falsePositiveRate)\n\t\tthis.hashCount = optimalHashCount(this.bitCount, expectedItems)\n\t\tthis.bits = new Uint32Array(this.bitCount / 32)\n\t}\n\n\t/**\n\t * Add a collection (and optional field) to the bloom filter.\n\t *\n\t * @param collection - Collection name (e.g., \"todos\")\n\t * @param field - Optional field name (e.g., \"completed\")\n\t */\n\tadd(collection: string, field?: string): void {\n\t\tconst key = field !== undefined ? `${collection}:${field}` : collection\n\t\tconst positions = this.getPositions(key)\n\t\tfor (const pos of positions) {\n\t\t\tconst wordIndex = pos >>> 5 // equivalent to Math.floor(pos / 32)\n\t\t\tconst bitIndex = pos & 31 // equivalent to pos % 32\n\t\t\tconst current = this.bits[wordIndex] ?? 0\n\t\t\tthis.bits[wordIndex] = current | (1 << bitIndex)\n\t\t}\n\t\tthis.itemCount++\n\t}\n\n\t/**\n\t * Check if a collection (and optional field) might be in the filter.\n\t *\n\t * A return value of `false` means the item is DEFINITELY NOT in the filter.\n\t * A return value of `true` means the item MIGHT be in the filter (possible false positive).\n\t *\n\t * @param collection - Collection name to check\n\t * @param field - Optional field name to check\n\t * @returns false = definitely absent, true = possibly present\n\t */\n\tmightContain(collection: string, field?: string): boolean {\n\t\tconst key = field !== undefined ? `${collection}:${field}` : collection\n\t\tconst positions = this.getPositions(key)\n\t\tfor (const pos of positions) {\n\t\t\tconst wordIndex = pos >>> 5\n\t\t\tconst bitIndex = pos & 31\n\t\t\tif (((this.bits[wordIndex] ?? 0) & (1 << bitIndex)) === 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\n\t/**\n\t * Reset the bloom filter, clearing all bits and the item count.\n\t */\n\tclear(): void {\n\t\tthis.bits.fill(0)\n\t\tthis.itemCount = 0\n\t}\n\n\t/**\n\t * Estimate the current false positive rate based on the number of items inserted.\n\t *\n\t * Formula: (1 - e^(-kn/m))^k\n\t * where k = hash count, n = item count, m = bit count.\n\t *\n\t * @returns Estimated false positive rate as a number between 0 and 1\n\t */\n\testimatedFalsePositiveRate(): number {\n\t\tif (this.itemCount === 0) return 0\n\t\tconst exponent = -(this.hashCount * this.itemCount) / this.bitCount\n\t\treturn (1 - Math.exp(exponent)) ** this.hashCount\n\t}\n\n\t/**\n\t * @returns The number of items that have been added to the filter\n\t */\n\tgetItemCount(): number {\n\t\treturn this.itemCount\n\t}\n\n\t/**\n\t * @returns The total number of bits in the filter\n\t */\n\tgetBitCount(): number {\n\t\treturn this.bitCount\n\t}\n\n\t/**\n\t * @returns The number of hash functions used\n\t */\n\tgetHashCount(): number {\n\t\treturn this.hashCount\n\t}\n\n\t/**\n\t * Count the number of bits currently set to 1.\n\t * Uses Brian Kernighan's algorithm: each iteration clears the lowest set bit,\n\t * so the loop runs exactly as many times as there are set bits.\n\t *\n\t * @returns Number of bits set to 1\n\t */\n\tgetSetBitCount(): number {\n\t\tlet count = 0\n\t\tfor (let i = 0; i < this.bits.length; i++) {\n\t\t\tlet word = this.bits[i] ?? 0\n\t\t\twhile (word !== 0) {\n\t\t\t\t// Clear the lowest set bit: n & (n - 1) removes the rightmost 1-bit\n\t\t\t\tword &= word - 1\n\t\t\t\tcount++\n\t\t\t}\n\t\t}\n\t\treturn count\n\t}\n\n\t/**\n\t * Compute k bit positions for a given key using Kirsch-Mitzenmacker double hashing.\n\t *\n\t * Instead of computing k independent hash functions, we compute two base hashes\n\t * (h1 and h2) and derive the rest as: h_i = (h1 + i * h2) mod m.\n\t * This technique is proven to have the same asymptotic false positive rate as\n\t * k independent hash functions.\n\t *\n\t * We derive h1 and h2 from a single FNV-1a hash by splitting and mixing:\n\t * h1 = fnv1a(key), h2 = fnv1a(key + \"\\0salt\") to ensure independence.\n\t */\n\tprivate getPositions(key: string): number[] {\n\t\tconst h1 = fnv1a32(key)\n\t\t// Use a null-byte separator + salt suffix to derive a second independent hash\n\t\tconst h2 = fnv1a32(`${key}\\0bloom`)\n\n\t\tconst positions = new Array<number>(this.hashCount)\n\t\tfor (let i = 0; i < this.hashCount; i++) {\n\t\t\t// Combine h1 and h2 with Kirsch-Mitzenmacker technique\n\t\t\tpositions[i] = ((h1 + Math.imul(i, h2)) >>> 0) % this.bitCount\n\t\t}\n\t\treturn positions\n\t}\n}\n","import type { Operation } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport type {\n\tCollectionRecord,\n\tQueryDescriptor,\n\tQueryErrorPhase,\n\tQuerySubscriptionError,\n\tSubscribeOptions,\n\tSubscription,\n\tSubscriptionCallback,\n} from '../types'\nimport { SubscriptionBloomFilter } from './bloom-filter'\nimport { type ResultsEqual, defaultResultsEqual } from './result-equality'\n\n/**\n * Per-subscription options accepted by `register` / `registerAndFetch`.\n */\nexport interface RegisterOptions extends SubscribeOptions {\n\t/** Result-set comparator; defaults to structural comparison of every value. */\n\tresultsEqual?: ResultsEqual\n}\n\nlet nextSubId = 0\n\n/**\n * Default threshold for activating bloom filter-based dependency tracking.\n * Below this count, linear scanning is faster due to bloom filter rebuild overhead.\n */\nconst DEFAULT_BLOOM_THRESHOLD = 100\n\n/**\n * Default expected items for bloom filter sizing.\n * Sized to handle typical subscription dependency counts with headroom.\n */\nconst DEFAULT_BLOOM_EXPECTED_ITEMS = 500\n\n/**\n * Default false positive rate for bloom filter.\n * 1% provides a good balance between filter size and accuracy.\n */\nconst DEFAULT_BLOOM_FALSE_POSITIVE_RATE = 0.01\n\n/**\n * Configuration options for the SubscriptionManager.\n */\nexport interface SubscriptionManagerOptions {\n\t/**\n\t * Minimum number of subscriptions before activating bloom filter.\n\t * Below this threshold, linear scanning is used (bloom filter overhead not worth it).\n\t * @default 100\n\t */\n\tbloomThreshold?: number\n\n\t/**\n\t * Expected number of unique collection+field dependencies for bloom filter sizing.\n\t * @default 500\n\t */\n\tbloomExpectedItems?: number\n\n\t/**\n\t * Target false positive rate for the bloom filter.\n\t * Lower values require more memory but reduce unnecessary precise checks.\n\t * @default 0.01\n\t */\n\tbloomFalsePositiveRate?: number\n\n\t/** Called when a query subscription is registered (e.g. to register sync query subsets). */\n\tonQuerySubscribed?: (descriptor: QueryDescriptor) => () => void\n\n\t/**\n\t * Called for every subscription failure (the store emits `query:error`), in\n\t * addition to the subscriber's own `onError`.\n\t */\n\tonQueryError?: (failure: QuerySubscriptionError) => void\n}\n\n/**\n * A committed change to the rows of one collection that can affect query results\n * (RT-98). Every invalidation the store makes produces one: local writes and remote\n * applies (with the operation), and changes made without a new operation (rejection\n * re-folds, scope retraction, cascade settling, rematerialization, backup restore,\n * held/discarded writes).\n */\nexport interface RecordsChange {\n\t/** Collection whose rows changed */\n\treadonly collection: string\n\t/** Changed record ids, or null when unknown (treat the whole collection as changed) */\n\treadonly ids: readonly string[] | null\n\t/** The operation that caused the change, when there is one */\n\treadonly operation?: Operation\n}\n\n/** Listener for {@link RecordsChange}s made by this runtime (not those relayed from peers). */\nexport type RecordsChangeListener = (change: RecordsChange) => void\n\n/**\n * Performance statistics for monitoring subscription checking efficiency.\n */\nexport interface SubscriptionStats {\n\t/** Total number of mutation notifications processed */\n\ttotalChecks: number\n\t/** Number of times bloom filter said \"maybe\" (proceeded to precise check) */\n\tbloomFilterHits: number\n\t/** Number of times bloom filter said \"definitely not\" (skipped all subscriptions) */\n\tbloomFilterMisses: number\n\t/** Number of times bloom filter said \"maybe\" but precise check found no match */\n\tfalsePositives: number\n\t/** Average time per check in milliseconds */\n\taverageCheckTimeMs: number\n\t/** Whether bloom filter is currently active */\n\tbloomFilterActive: boolean\n\t/** Current subscription count */\n\tsubscriptionCount: number\n}\n\n/**\n * Manages reactive subscriptions with two-level dependency checking.\n *\n * When a mutation occurs on a collection, affected subscriptions are re-evaluated\n * in a microtask batch and callbacks are invoked only if results actually changed.\n *\n * For large subscription counts (>= bloomThreshold), a bloom filter provides O(k)\n * pre-filtering to avoid scanning all subscriptions on every mutation:\n *\n * Level 1 (Bloom filter): Fast O(k) check -- does this mutation potentially affect\n * any subscription? If NO: skip all subscriptions (guaranteed correct).\n * If MAYBE: proceed to Level 2.\n *\n * Level 2 (Precise check): Only evaluate subscriptions that match the mutated\n * collection, including included (related) collection tracking.\n */\nexport class SubscriptionManager {\n\tprivate subscriptions = new Map<string, Subscription>()\n\tprivate pendingCollections = new Set<string>()\n\tprivate flushScheduled = false\n\tprivate readonly onQuerySubscribed?: (descriptor: QueryDescriptor) => () => void\n\tprivate readonly onQueryError?: (failure: QuerySubscriptionError) => void\n\tprivate readonly changeListeners = new Set<RecordsChangeListener>()\n\t/**\n\t * Collections changed before the first change listener attached (a store's open:\n\t * rematerialization, migration backfills). Replayed to that listener, so other tabs\n\t * hear about changes made while this tab was still opening. Bounded by the schema.\n\t */\n\tprivate unheardCollections: Set<string> | null = new Set()\n\n\t// Bloom filter state\n\tprivate bloomFilter: SubscriptionBloomFilter | null = null\n\tprivate bloomDirty = false\n\tprivate readonly bloomThreshold: number\n\tprivate readonly bloomExpectedItems: number\n\tprivate readonly bloomFalsePositiveRate: number\n\n\t// Performance stats\n\tprivate totalChecks = 0\n\tprivate bloomFilterHits = 0\n\tprivate bloomFilterMisses = 0\n\tprivate falsePositives = 0\n\tprivate totalCheckTimeMs = 0\n\n\tconstructor(options?: SubscriptionManagerOptions) {\n\t\tthis.bloomThreshold = options?.bloomThreshold ?? DEFAULT_BLOOM_THRESHOLD\n\t\tthis.bloomExpectedItems = options?.bloomExpectedItems ?? DEFAULT_BLOOM_EXPECTED_ITEMS\n\t\tthis.bloomFalsePositiveRate =\n\t\t\toptions?.bloomFalsePositiveRate ?? DEFAULT_BLOOM_FALSE_POSITIVE_RATE\n\t\tthis.onQuerySubscribed = options?.onQuerySubscribed\n\t\tthis.onQueryError = options?.onQueryError\n\t}\n\n\t/**\n\t * Register a new subscription.\n\t *\n\t * @param descriptor - The query descriptor defining what this subscription watches\n\t * @param callback - Called with results whenever they change\n\t * @param executeFn - Function to re-execute the query and get current results\n\t * @returns An unsubscribe function\n\t */\n\tregister(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions?: RegisterOptions,\n\t): () => void {\n\t\t// No initial run: the empty baseline counts as delivered, so a flush only\n\t\t// notifies when the results differ from it.\n\t\tconst subscription = this.createSubscription(descriptor, callback, executeFn, options)\n\t\tsubscription.delivered = true\n\t\treturn this.track(subscription)\n\t}\n\n\t/**\n\t * Register a subscription and immediately execute the query.\n\t * The initial results are stored as lastResults so subsequent flushes\n\t * correctly diff against the initial state. A failing initial run is reported\n\t * through `options.onError` and the `query:error` hook, never as an unhandled\n\t * rejection (STORE-12).\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tregisterAndFetch(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions?: RegisterOptions,\n\t): () => void {\n\t\tconst subscription = this.createSubscription(descriptor, callback, executeFn, options)\n\t\tconst unsubscribe = this.track(subscription)\n\t\tvoid this.run(subscription)\n\t\treturn unsubscribe\n\t}\n\n\tprivate createSubscription(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions: RegisterOptions | undefined,\n\t): Subscription {\n\t\treturn {\n\t\t\tid: `sub_${++nextSubId}`,\n\t\t\tdescriptor,\n\t\t\tcallback,\n\t\t\texecuteFn,\n\t\t\tlastResults: [],\n\t\t\tresultsEqual: options?.resultsEqual ?? defaultResultsEqual,\n\t\t\tonError: options?.onError,\n\t\t\trunsStarted: 0,\n\t\t\tlastAppliedRun: 0,\n\t\t\terrored: false,\n\t\t\tdelivered: false,\n\t\t}\n\t}\n\n\tprivate track(subscription: Subscription): () => void {\n\t\tconst id = subscription.id\n\t\tthis.subscriptions.set(id, subscription)\n\n\t\t// Mark bloom filter as needing rebuild since dependencies changed\n\t\tthis.bloomDirty = true\n\n\t\tconst externalCleanup = this.onQuerySubscribed?.(subscription.descriptor)\n\n\t\treturn () => {\n\t\t\tif (!this.subscriptions.delete(id)) return\n\t\t\tthis.bloomDirty = true\n\t\t\texternalCleanup?.()\n\t\t}\n\t}\n\n\t/**\n\t * Run a subscription's query and deliver the result when it changed. Never\n\t * throws: failures go to the error channel. Runs are numbered so a slow,\n\t * older run never overwrites the result of a newer one.\n\t */\n\tprivate async run(sub: Subscription): Promise<void> {\n\t\tconst runNumber = (sub.runsStarted ?? 0) + 1\n\t\tsub.runsStarted = runNumber\n\t\tlet results: CollectionRecord[]\n\t\ttry {\n\t\t\tresults = await sub.executeFn()\n\t\t} catch (error) {\n\t\t\tif (!this.isCurrent(sub, runNumber)) return\n\t\t\tsub.lastAppliedRun = runNumber\n\t\t\tsub.errored = true\n\t\t\tthis.reportError(sub, error, sub.delivered ? 'refresh' : 'initial')\n\t\t\treturn\n\t\t}\n\t\tif (!this.isCurrent(sub, runNumber)) return\n\t\tsub.lastAppliedRun = runNumber\n\n\t\t// After a failure, the next success is always delivered (even when equal to\n\t\t// the last results) so bindings can leave their error state.\n\t\tconst equal = sub.resultsEqual ?? defaultResultsEqual\n\t\tif (sub.delivered && !sub.errored && equal(sub.lastResults, results)) return\n\n\t\tsub.lastResults = results\n\t\tsub.delivered = true\n\t\tsub.errored = false\n\t\ttry {\n\t\t\tsub.callback(results)\n\t\t} catch (error) {\n\t\t\tthis.reportError(sub, error, 'callback')\n\t\t}\n\t}\n\n\tprivate isCurrent(sub: Subscription, runNumber: number): boolean {\n\t\treturn this.subscriptions.get(sub.id) === sub && runNumber > (sub.lastAppliedRun ?? 0)\n\t}\n\n\tprivate reportError(sub: Subscription, thrown: unknown, phase: QueryErrorPhase): void {\n\t\tconst error =\n\t\t\tthrown instanceof Error\n\t\t\t\t? thrown\n\t\t\t\t: new QueryError(`Query subscription failed: ${String(thrown)}`, {\n\t\t\t\t\t\tcollection: sub.descriptor.collection,\n\t\t\t\t\t})\n\t\tconst failure: QuerySubscriptionError = {\n\t\t\terror,\n\t\t\tphase,\n\t\t\tcollection: sub.descriptor.collection,\n\t\t\tqueryId: sub.id,\n\t\t}\n\t\ttry {\n\t\t\tthis.onQueryError?.(failure)\n\t\t} catch (hookError) {\n\t\t\tconsole.error('[kora] query:error listener threw', hookError)\n\t\t}\n\t\tif (sub.onError) {\n\t\t\ttry {\n\t\t\t\tsub.onError(failure)\n\t\t\t} catch (handlerError) {\n\t\t\t\tconsole.error('[kora] subscription onError handler threw', handlerError)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\t// No subscriber handler: log so the failure is never silent.\n\t\tconsole.error(\n\t\t\t`[kora] Query subscription ${sub.id} on \"${sub.descriptor.collection}\" failed (${phase}). Pass subscribe(cb, { onError }) to handle it.`,\n\t\t\terror,\n\t\t)\n\t}\n\n\t/**\n\t * Notify the manager that a mutation occurred on a collection.\n\t * Schedules a microtask flush to batch multiple mutations in the same tick.\n\t */\n\tnotify(collection: string, operation: Operation): void {\n\t\tthis.recordsChanged({ collection, ids: [operation.recordId], operation })\n\t}\n\n\t/**\n\t * Invalidate a collection after a local-view change that has no domain operation\n\t * (a re-fold, a retraction, a restore). Pass the record ids when known.\n\t */\n\tinvalidate(collection: string, ids: readonly string[] | null = null): void {\n\t\tthis.recordsChanged({ collection, ids })\n\t}\n\n\t/**\n\t * The single entry point for a committed change made by this runtime (RT-98): it\n\t * schedules the affected queries and tells every change listener (the cross-tab\n\t * bus), so no invalidation path can reach this tab's queries without reaching the\n\t * other tabs' too.\n\t */\n\trecordsChanged(change: RecordsChange): void {\n\t\tthis.pendingCollections.add(change.collection)\n\t\tthis.scheduleFlush()\n\t\tif (this.unheardCollections) this.unheardCollections.add(change.collection)\n\t\tfor (const listener of this.changeListeners) {\n\t\t\ttry {\n\t\t\t\tlistener(change)\n\t\t\t} catch (error) {\n\t\t\t\t// A failing listener must not stop this tab's queries or other listeners.\n\t\t\t\tconsole.error('[kora] records-change listener failed', error)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Invalidate a collection for a change another runtime made to the shared\n\t * database. Not relayed to change listeners (the peer already broadcast it).\n\t */\n\tinvalidateFromPeer(collection: string): void {\n\t\tthis.pendingCollections.add(collection)\n\t\tthis.scheduleFlush()\n\t}\n\n\t/**\n\t * Listen to every committed change this runtime makes.\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tonRecordsChanged(listener: RecordsChangeListener): () => void {\n\t\tthis.changeListeners.add(listener)\n\t\tconst unheard = this.unheardCollections\n\t\tthis.unheardCollections = null\n\t\tfor (const collection of unheard ?? []) {\n\t\t\ttry {\n\t\t\t\tlistener({ collection, ids: null })\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[kora] records-change listener failed', error)\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tthis.changeListeners.delete(listener)\n\t\t}\n\t}\n\n\t/**\n\t * Immediately flush all pending notifications.\n\t * Useful for testing. In production, flushing happens via microtask.\n\t */\n\tasync flush(): Promise<void> {\n\t\tif (this.pendingCollections.size === 0) return\n\n\t\tconst collections = new Set(this.pendingCollections)\n\t\tthis.pendingCollections.clear()\n\t\tthis.flushScheduled = false\n\n\t\tconst affected = this.findAffectedSubscriptions(collections)\n\n\t\t// Re-execute and diff. run() never throws: failures reach the error channel.\n\t\tfor (const sub of affected) {\n\t\t\tawait this.run(sub)\n\t\t}\n\t}\n\n\t/**\n\t * Remove all subscriptions. Called on store close.\n\t */\n\tclear(): void {\n\t\tthis.subscriptions.clear()\n\t\tthis.pendingCollections.clear()\n\t\tthis.flushScheduled = false\n\t\tthis.bloomFilter = null\n\t\tthis.bloomDirty = false\n\t\tthis.totalChecks = 0\n\t\tthis.bloomFilterHits = 0\n\t\tthis.bloomFilterMisses = 0\n\t\tthis.falsePositives = 0\n\t\tthis.totalCheckTimeMs = 0\n\t}\n\n\t/** Number of active subscriptions (for testing/debugging) */\n\tget size(): number {\n\t\treturn this.subscriptions.size\n\t}\n\n\t/**\n\t * Get performance statistics for monitoring subscription checking efficiency.\n\t * Useful for DevTools integration and performance tuning.\n\t */\n\tgetStats(): SubscriptionStats {\n\t\treturn {\n\t\t\ttotalChecks: this.totalChecks,\n\t\t\tbloomFilterHits: this.bloomFilterHits,\n\t\t\tbloomFilterMisses: this.bloomFilterMisses,\n\t\t\tfalsePositives: this.falsePositives,\n\t\t\taverageCheckTimeMs: this.totalChecks > 0 ? this.totalCheckTimeMs / this.totalChecks : 0,\n\t\t\tbloomFilterActive: this.isBloomActive(),\n\t\t\tsubscriptionCount: this.subscriptions.size,\n\t\t}\n\t}\n\n\t/**\n\t * Check if bloom filter is currently active.\n\t * Active when subscription count meets or exceeds the threshold.\n\t */\n\tisBloomActive(): boolean {\n\t\treturn this.subscriptions.size >= this.bloomThreshold\n\t}\n\n\t/**\n\t * Find subscriptions affected by mutations to the given collections.\n\t * Uses two-level checking when bloom filter is active:\n\t *\n\t * Level 1: Bloom filter pre-check -- if no subscription depends on any\n\t * of the mutated collections, skip everything (O(k) per collection).\n\t *\n\t * Level 2: Precise check -- linear scan of subscriptions, matching\n\t * against the mutated collections.\n\t */\n\tprivate findAffectedSubscriptions(collections: Set<string>): Subscription[] {\n\t\tconst startTime = performance.now()\n\t\tthis.totalChecks++\n\n\t\tconst useBloom = this.isBloomActive()\n\n\t\tif (useBloom) {\n\t\t\t// Rebuild bloom filter if dependencies have changed\n\t\t\tif (this.bloomDirty || this.bloomFilter === null) {\n\t\t\t\tthis.rebuildBloomFilter()\n\t\t\t}\n\n\t\t\tconst filter = this.bloomFilter\n\t\t\tif (filter !== null) {\n\t\t\t\t// Level 1: Bloom filter pre-check\n\t\t\t\tlet anyPossibleMatch = false\n\t\t\t\tfor (const col of collections) {\n\t\t\t\t\tif (filter.mightContain(col)) {\n\t\t\t\t\t\tanyPossibleMatch = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!anyPossibleMatch) {\n\t\t\t\t\t// Bloom filter guarantees no subscription depends on these collections\n\t\t\t\t\tthis.bloomFilterMisses++\n\t\t\t\t\tthis.totalCheckTimeMs += performance.now() - startTime\n\t\t\t\t\treturn []\n\t\t\t\t}\n\n\t\t\t\tthis.bloomFilterHits++\n\t\t\t}\n\t\t}\n\n\t\t// Level 2: Precise check (or only check when bloom is not active)\n\t\tconst affected: Subscription[] = []\n\t\tlet anyPreciseMatch = false\n\n\t\tfor (const sub of this.subscriptions.values()) {\n\t\t\tif (collections.has(sub.descriptor.collection)) {\n\t\t\t\taffected.push(sub)\n\t\t\t\tanyPreciseMatch = true\n\t\t\t} else if (sub.descriptor.includeCollections) {\n\t\t\t\t// Re-evaluate if a mutation affects an included (related) collection\n\t\t\t\tfor (const incCol of sub.descriptor.includeCollections) {\n\t\t\t\t\tif (collections.has(incCol)) {\n\t\t\t\t\t\taffected.push(sub)\n\t\t\t\t\t\tanyPreciseMatch = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Track false positives: bloom said \"maybe\" but precise check found nothing\n\t\tif (useBloom && !anyPreciseMatch) {\n\t\t\tthis.falsePositives++\n\t\t}\n\n\t\tthis.totalCheckTimeMs += performance.now() - startTime\n\t\treturn affected\n\t}\n\n\t/**\n\t * Rebuild the bloom filter from all current subscriptions.\n\t * Adds collection-level dependencies for every subscription, plus\n\t * any included collection dependencies.\n\t */\n\tprivate rebuildBloomFilter(): void {\n\t\tconst filter = new SubscriptionBloomFilter(this.bloomExpectedItems, this.bloomFalsePositiveRate)\n\n\t\tfor (const sub of this.subscriptions.values()) {\n\t\t\t// Add the primary collection dependency\n\t\t\tfilter.add(sub.descriptor.collection)\n\n\t\t\t// Add included (related) collection dependencies\n\t\t\tif (sub.descriptor.includeCollections) {\n\t\t\t\tfor (const incCol of sub.descriptor.includeCollections) {\n\t\t\t\t\tfilter.add(incCol)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.bloomFilter = filter\n\t\tthis.bloomDirty = false\n\t}\n\n\tprivate scheduleFlush(): void {\n\t\tif (this.flushScheduled) return\n\t\tthis.flushScheduled = true\n\t\tqueueMicrotask(() => {\n\t\t\t// flush() cannot reject: run() routes every failure to the error channel.\n\t\t\tvoid this.flush()\n\t\t})\n\t}\n}\n","import { HybridLogicalClock, MAX_LOGICAL, quoteIdent } from '@korajs/core'\nimport type { HLCTimestamp, Operation, SchemaDefinition } from '@korajs/core'\nimport { parseFieldVersions, serializeFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, RawCollectionRow, StorageAdapter } from '../types'\nimport { rehashOperation } from './rehash-operation'\n\n/**\n * Result of re-stamping unsynced operations after a clock correction.\n */\nexport interface ClockRebaseResult {\n\t/** The rewritten operations, in causal order (original HLC total order preserved). */\n\toperations: Operation[]\n\t/** Maps each old (pre-rebase) operation id to its new content-addressed id. */\n\tidMapping: Record<string, string>\n\t/** Number of operations that were re-stamped. */\n\trebasedCount: number\n\t/** Highest timestamp assigned during the rebase, or null when nothing was rebased. */\n\tnewMaxTimestamp: HLCTimestamp | null\n}\n\n/**\n * The serialized logical counter is zero-padded to 5 digits; a logical value\n * needing more digits would break the lexicographic ordering of the stored\n * timestamp / `_version` columns. Overflow spills into wallTime instead.\n * Derived from the clock's own cap so the two can never drift apart.\n */\nconst LOGICAL_COUNTER_LIMIT = MAX_LOGICAL + 1\n\nfunction emptyResult(): ClockRebaseResult {\n\treturn { operations: [], idMapping: {}, rebasedCount: 0, newMaxTimestamp: null }\n}\n\n/**\n * Re-stamp unsynced (never server-acknowledged) operations after a fast device\n * clock was corrected, so sync can resume immediately instead of waiting for\n * real time to catch up with the future timestamps.\n *\n * This is safe for exactly the same reason rewriting unpushed git commits is\n * safe: unacknowledged operations have never been shared, so no other replica\n * can hold a reference to their old ids or timestamps. Acknowledged operations\n * are immutable forever and are never touched here.\n *\n * The relative order of the rebased operations is preserved: they are sorted by\n * their original HLC total order and assigned consecutive logical counters on a\n * single new wall time, chosen to sort after every non-rebased operation in the\n * log (and after corrected \"now\").\n */\nexport async function rebaseUnsyncedOperationsInLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tunsyncedOpIds: string[],\n\tcorrectedNowMs: number,\n): Promise<ClockRebaseResult> {\n\tif (unsyncedOpIds.length === 0) {\n\t\treturn emptyResult()\n\t}\n\tconst rebaseIds = new Set(unsyncedOpIds)\n\n\t// Read phase. A single full scan per collection serves two purposes at once:\n\t// locating the rebased rows and finding the max timestamp of everything else.\n\t// This avoids SQL IN-list size limits and keeps the logic trivially correct\n\t// (correctness over performance; the op log is compacted periodically anyway).\n\tconst rebased: Operation[] = []\n\t// Serialized HLC strings sort lexicographically in the same order as\n\t// HybridLogicalClock.compare, so a plain string max is a timestamp max.\n\tlet maxOtherSerializedTs: string | null = null\n\n\tfor (const collectionName of Object.keys(schema.collections)) {\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)}`,\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tif (rebaseIds.has(row.id)) {\n\t\t\t\trebased.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t} else if (maxOtherSerializedTs === null || row.timestamp > maxOtherSerializedTs) {\n\t\t\t\tmaxOtherSerializedTs = row.timestamp\n\t\t\t}\n\t\t}\n\t}\n\n\tif (rebased.length === 0) {\n\t\treturn emptyResult()\n\t}\n\n\t// The new wall time must sort after both corrected real time and every\n\t// operation that stays in the log, or the rebased ops could lose LWW\n\t// conflicts they previously won locally (silent data reordering).\n\tconst maxOtherWallTime =\n\t\tmaxOtherSerializedTs === null\n\t\t\t? Number.NEGATIVE_INFINITY\n\t\t\t: HybridLogicalClock.deserialize(maxOtherSerializedTs).wallTime\n\tconst baseWallTime = Math.max(correctedNowMs, maxOtherWallTime + 1)\n\n\t// Preserve the ORIGINAL total order so causal relationships (dep before\n\t// dependent) survive the re-stamp.\n\trebased.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst newTimestamps: HLCTimestamp[] = rebased.map((op, i) => ({\n\t\t// Spill into wallTime past the 5-digit logical serialization limit so the\n\t\t// serialized order stays correct even for enormous offline queues.\n\t\twallTime: baseWallTime + Math.floor(i / LOGICAL_COUNTER_LIMIT),\n\t\tlogical: i % LOGICAL_COUNTER_LIMIT,\n\t\tnodeId: op.nodeId,\n\t}))\n\n\t// Recompute content-addressed ids in the original (causal) order. A version-2 id\n\t// (protocol v2, CORE-1) covers causalDeps, so each dependency's new id must be known\n\t// before its dependents are hashed: deps among the rebased set are remapped first.\n\t// Deps on non-rebased (already acknowledged or foreign) operations keep their ids.\n\t// Each operation keeps its own hash version: a version-1 operation (written before\n\t// beta.13) is re-hashed with version 1. The deserialized `data` has the embedded\n\t// metadata keys already stripped, matching exactly what the creation path hashed.\n\tconst idMapping: Record<string, string> = {}\n\tconst newOperations: Operation[] = []\n\tfor (let i = 0; i < rebased.length; i++) {\n\t\tconst op = rebased[i]\n\t\tconst ts = newTimestamps[i]\n\t\tif (!op || !ts) {\n\t\t\tcontinue\n\t\t}\n\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\tconst newId = await rehashOperation({ ...op, timestamp: ts, causalDeps })\n\t\tidMapping[op.id] = newId\n\t\tnewOperations.push({ ...op, id: newId, timestamp: ts, causalDeps })\n\t}\n\n\t// Write phase: one transaction so a crash can never leave the log with a\n\t// mix of old and new stamps (which would corrupt causal deps).\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (let i = 0; i < rebased.length; i++) {\n\t\t\tconst oldOp = rebased[i]\n\t\t\tconst newOp = newOperations[i]\n\t\t\tif (!oldOp || !newOp) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst opsTable = `_kora_ops_${oldOp.collection}`\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(opsTable)} WHERE id = ?`, [oldOp.id])\n\t\t\tconst opInsert = buildInsertQuery(\n\t\t\t\topsTable,\n\t\t\t\tserializeOperation(newOp) as unknown as Record<string, unknown>,\n\t\t\t)\n\t\t\tawait tx.execute(opInsert.sql, opInsert.params)\n\n\t\t\t// Only touch materialized rows whose current version stamp came from\n\t\t\t// this exact operation — a row last written by a different (newer,\n\t\t\t// non-rebased) op must keep its version, or LWW guards would lie.\n\t\t\tconst oldVersion = serializeRowVersion(oldOp.timestamp)\n\t\t\tconst newVersion = serializeRowVersion(newOp.timestamp)\n\t\t\tawait tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,\n\t\t\t\t[newVersion, newOp.timestamp.wallTime, oldOp.recordId, oldVersion],\n\t\t\t)\n\n\t\t\t// Per-field versions stamped by this operation carry the same old (pre-\n\t\t\t// rebase) version string, so re-stamp them too — otherwise field-level\n\t\t\t// LWW would keep comparing against the uncorrected timestamp forever.\n\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t`SELECT _field_versions FROM ${quoteIdent(oldOp.collection)} WHERE id = ?`,\n\t\t\t\t[oldOp.recordId],\n\t\t\t)\n\t\t\tconst fieldVersions = parseFieldVersions(rows[0]?._field_versions)\n\t\t\tlet changed = false\n\t\t\tfor (const [field, version] of Object.entries(fieldVersions)) {\n\t\t\t\tif (version === oldVersion) {\n\t\t\t\t\tfieldVersions[field] = newVersion\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (changed) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,\n\t\t\t\t\t[serializeFieldVersions(fieldVersions), oldOp.recordId],\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// The insert op also stamped `_created_at` (the developer-visible\n\t\t\t// `createdAt`). Replicas materialize it from the rebased op's corrected\n\t\t\t// wallTime, so the originating device must re-stamp its own row too or\n\t\t\t// `createdAt` diverges forever after a clock rebase. Match on the old\n\t\t\t// (pre-rebase) created time so only rows this op created are touched.\n\t\t\tif (oldOp.type === 'insert') {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _created_at = ? WHERE id = ? AND _created_at = ?`,\n\t\t\t\t\t[newOp.timestamp.wallTime, oldOp.recordId, oldOp.timestamp.wallTime],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\t// sequenceNumbers are intentionally unchanged, so `_kora_version_vector`\n\t\t// needs no update: the version vector tracks sequences, not timestamps.\n\t})\n\n\tconst newMaxTimestamp = newTimestamps[newTimestamps.length - 1] ?? null\n\n\treturn {\n\t\toperations: newOperations,\n\t\tidMapping,\n\t\trebasedCount: newOperations.length,\n\t\tnewMaxTimestamp,\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { parseFieldVersions, serializeFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, RawCollectionRow, StorageAdapter } from '../types'\nimport { rehashOperation } from './rehash-operation'\nimport { NODE_TOKEN_META_KEY } from './sync-state'\n\n/** Result of {@link rotateUnsyncedOperationsInLog}. */\nexport interface NodeRotationResult {\n\t/** The node id the device uses from now on. */\n\tnodeId: string\n\t/** The rewritten operations under the new node id, in their original causal order. */\n\toperations: Operation[]\n\t/** Maps each old operation id to its new content-addressed id. */\n\tidMapping: Record<string, string>\n}\n\n/**\n * Move a device's never-acknowledged operations to a fresh node id (RT-21).\n *\n * The server refused this device's node id (`NODE_ID_CLAIMED`: another device holds\n * it, typically because the node token issued at the first claim was lost). The\n * device keeps its data by re-authoring its unsynced operations under a new node id:\n * same type, record, data and HLC wall time / counter, but the new node id in both\n * `nodeId` and `timestamp.nodeId`, sequence numbers 1..n in the original order, and\n * recomputed content-addressed ids (causal deps among them remapped). This is safe\n * for the same reason a clock rebase is: unacknowledged operations were never\n * shared, so no replica holds their old ids.\n *\n * Materialized rows are re-stamped so per-field LWW keeps comparing against the\n * rewritten timestamps; the version vector gets the new node's sequence (MAX with the\n * stored value) and the old node's entry is never lowered (W6). Everything, the scan\n * of the rotated operations included, runs in one transaction.\n *\n * @param adapter - The store's adapter\n * @param schema - The store schema (collections to scan)\n * @param unsyncedOpIds - Ids of the old node's operations the server never acknowledged\n * @param oldNodeId - The refused node id\n * @param newNodeId - The fresh node id\n */\nexport async function rotateUnsyncedOperationsInLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tunsyncedOpIds: string[],\n\toldNodeId: string,\n\tnewNodeId: string,\n): Promise<NodeRotationResult> {\n\tconst rotateIds = new Set(unsyncedOpIds)\n\tconst idMapping: Record<string, string> = {}\n\tconst rewritten: Operation[] = []\n\n\t// One transaction from the scan to the last write (W6): the rotated set is read in\n\t// the transaction that rewrites it, so nothing committed in between is missed.\n\tawait adapter.transaction(async (tx) => {\n\t\tconst rotated: Operation[] = []\n\t\tfor (const collectionName of Object.keys(schema.collections)) {\n\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} WHERE node_id = ?`,\n\t\t\t\t[oldNodeId],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (rotateIds.has(row.id)) {\n\t\t\t\t\trotated.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Original authoring order: sequence numbers are allocated in causal order.\n\t\trotated.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\n\t\tfor (let i = 0; i < rotated.length; i++) {\n\t\t\tconst op = rotated[i]\n\t\t\tif (!op) continue\n\t\t\tconst timestamp = { ...op.timestamp, nodeId: newNodeId }\n\t\t\t// Deps among the rotated set are remapped BEFORE hashing: a version-2 id covers\n\t\t\t// causalDeps, and sequence order is causal order, so every dep is already\n\t\t\t// mapped. Deps on acknowledged operations keep their ids.\n\t\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\t\tconst moved: Operation = {\n\t\t\t\t...op,\n\t\t\t\tnodeId: newNodeId,\n\t\t\t\ttimestamp,\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\tcausalDeps,\n\t\t\t}\n\t\t\tconst id = await rehashOperation(moved)\n\t\t\tidMapping[op.id] = id\n\t\t\trewritten.push({ ...moved, id })\n\t\t}\n\n\t\tfor (let i = 0; i < rotated.length; i++) {\n\t\t\tconst oldOp = rotated[i]\n\t\t\tconst newOp = rewritten[i]\n\t\t\tif (!oldOp || !newOp) continue\n\t\t\tconst opsTable = `_kora_ops_${oldOp.collection}`\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(opsTable)} WHERE id = ?`, [oldOp.id])\n\t\t\tconst insert = buildInsertQuery(\n\t\t\t\topsTable,\n\t\t\t\tserializeOperation(newOp) as unknown as Record<string, unknown>,\n\t\t\t)\n\t\t\tawait tx.execute(insert.sql, insert.params)\n\n\t\t\t// Re-stamp the row and field versions this operation wrote (the version\n\t\t\t// string carries the node id), exactly like a clock rebase.\n\t\t\tconst oldVersion = serializeRowVersion(oldOp.timestamp)\n\t\t\tconst newVersion = serializeRowVersion(newOp.timestamp)\n\t\t\tawait tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _version = ? WHERE id = ? AND _version = ?`,\n\t\t\t\t[newVersion, oldOp.recordId, oldVersion],\n\t\t\t)\n\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t`SELECT _field_versions FROM ${quoteIdent(oldOp.collection)} WHERE id = ?`,\n\t\t\t\t[oldOp.recordId],\n\t\t\t)\n\t\t\tconst fieldVersions = parseFieldVersions(rows[0]?._field_versions)\n\t\t\tlet changed = false\n\t\t\tfor (const [field, version] of Object.entries(fieldVersions)) {\n\t\t\t\tif (version === oldVersion) {\n\t\t\t\t\tfieldVersions[field] = newVersion\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (changed) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,\n\t\t\t\t\t[serializeFieldVersions(fieldVersions), oldOp.recordId],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tawait tx.execute(\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\", [\n\t\t\tnewNodeId,\n\t\t])\n\t\t// The node token belonged to the refused node id.\n\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [NODE_TOKEN_META_KEY])\n\t\t// The new node's counter covers the rewritten operations: MAX with the stored\n\t\t// value, in this transaction, like every sequence reservation (W6).\n\t\tif (rewritten.length > 0) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[newNodeId, rewritten.length],\n\t\t\t)\n\t\t}\n\t\t// The old node's counter is left as it is, never lowered: a rotated operation\n\t\t// may have reached the server unacknowledged, and a writer still on the old id\n\t\t// (another tab) must not reuse its number for different content. The numbers the\n\t\t// rotated operations held become holes in the old node's log, which upload\n\t\t// tracking treats as resolved.\n\t})\n\n\treturn { nodeId: newNodeId, operations: rewritten, idMapping }\n}\n","import type {\n\tCausalTracker,\n\tCollectionDefinition,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport {\n\tKoraError,\n\tgenerateUUIDv7,\n\tisAtomicOp,\n\tquoteIdent,\n\tresolveAtomicOp,\n\tvalidateRecord,\n} from '@korajs/core'\nimport { RecordNotFoundError } from '../errors'\nimport type { RecordFolder } from '../fold/record-folder'\nimport { toAtRestWriteData } from '../mutations/secret-write'\nimport {\n\tCausalScope,\n\ttype LocalDeleteHook,\n\ttype WriteEnv,\n\twithWriteScope,\n} from '../mutations/write-context'\nimport {\n\ttype PreparedInsert,\n\ttype WriteResult,\n\tprepareInsert,\n\twriteDeleteInTx,\n\twriteInsertInTx,\n\twriteUpdateInTx,\n} from '../mutations/write-ops'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport { deserializeRecord, toRichtextReadShape } from '../serialization/serializer'\nimport { validateUpdateStateMachine } from '../state-machine/state-validator'\nimport type { CollectionRecord, RawCollectionRow, StorageAdapter } from '../types'\n\n/**\n * A buffered mutation. Buffered entries hold the developer's INTENT, not built\n * operations: they are written at commit, inside the commit's storage\n * transaction, through the same single local write path as single-record writes\n * (W6). That is what gives transaction writes in-transaction sequence\n * reservation, per-field version stamps, state-machine validation and atomic ops\n * resolved against the committed row.\n */\ntype BufferedEntry =\n\t| { readonly kind: 'insert'; readonly collection: string; readonly insert: PreparedInsert }\n\t| {\n\t\t\treadonly kind: 'update'\n\t\t\treadonly collection: string\n\t\t\treadonly id: string\n\t\t\t/** Schema-validated update data; may contain atomic op descriptors. */\n\t\t\treadonly data: Record<string, unknown>\n\t }\n\t| { readonly kind: 'delete'; readonly collection: string; readonly id: string }\n\n/**\n * Internal configuration for creating a TransactionContext.\n * Passed from Store to avoid exposing Store internals publicly.\n */\nexport interface TransactionContextConfig {\n\tschema: SchemaDefinition\n\tadapter: StorageAdapter\n\tclock: HybridLogicalClock\n\tnodeId: string\n\trelationEnforcer: RelationEnforcer | null\n\tcausalTracker: CausalTracker | null\n\t/**\n\t * Key provider for `t.secret()` encrypted fields. Transaction writes transform\n\t * secret fields through the same helper as single-record writes (STORE-4).\n\t */\n\tsecretKeyProvider?: SecretKeyProvider\n\t/** Referential hook run for every local delete inside the commit (see {@link LocalDeleteHook}). */\n\tbeforeLocalDelete?: LocalDeleteHook\n\t/** Called when the commit's storage transaction fails, before the error propagates. */\n\tonStorageError?: (error: unknown) => void\n\t/** The W7 record fold (see `WriteEnv.fold`). */\n\tfold?: RecordFolder\n}\n\n/**\n * A collection accessor within a transaction.\n * Operations are buffered and committed atomically when the transaction completes.\n */\nexport interface TransactionCollectionAccessor {\n\tinsert(data: Record<string, unknown>): Promise<CollectionRecord>\n\tupdate(id: string, data: Record<string, unknown>): Promise<CollectionRecord>\n\tdelete(id: string): Promise<void>\n\tfindById(id: string): Promise<CollectionRecord | null>\n}\n\n/**\n * TransactionContext provides atomic multi-collection operations.\n *\n * Mutations are validated and buffered when called (so errors surface at the\n * call site and `insert` returns the new id immediately), then written in a\n * single `StorageAdapter.transaction()` at commit. All operations share the\n * same transactionId (UUID v7) and one contiguous block of sequence numbers.\n *\n * Subscription notifications are deferred until after commit.\n *\n * @example\n * ```typescript\n * const { operations, affectedCollections } = await txContext.commit()\n * // Notify subscriptions after commit\n * for (const op of operations) {\n * subscriptionManager.notify(op.collection, op)\n * }\n * ```\n */\nexport class TransactionContext {\n\tprivate readonly transactionId: string\n\tprivate mutationName: string | undefined\n\tprivate readonly buffer: BufferedEntry[] = []\n\tprivate committed = false\n\tprivate rolledBack = false\n\tprivate readonly config: TransactionContextConfig\n\n\tconstructor(config: TransactionContextConfig) {\n\t\tthis.config = config\n\t\tthis.transactionId = generateUUIDv7()\n\t}\n\n\t/**\n\t * Set a human-readable mutation name for this transaction.\n\t * Propagated to all operations for DevTools display.\n\t */\n\tsetMutationName(name: string): void {\n\t\tthis.mutationName = name\n\t}\n\n\t/**\n\t * Get the mutation name, if set.\n\t */\n\tgetMutationName(): string | undefined {\n\t\treturn this.mutationName\n\t}\n\n\t/**\n\t * Get a collection accessor for buffered operations within this transaction.\n\t */\n\tcollection(name: string): TransactionCollectionAccessor {\n\t\tconst definition = this.config.schema.collections[name]\n\t\tif (!definition) {\n\t\t\tthrow new KoraError(\n\t\t\t\t`Unknown collection \"${name}\". Available: ${Object.keys(this.config.schema.collections).join(', ')}`,\n\t\t\t\t'UNKNOWN_COLLECTION',\n\t\t\t\t{ collection: name },\n\t\t\t)\n\t\t}\n\n\t\treturn {\n\t\t\tinsert: (data: Record<string, unknown>) => this.insert(name, data),\n\t\t\tupdate: (id: string, data: Record<string, unknown>) =>\n\t\t\t\tthis.update(name, definition, id, data),\n\t\t\tdelete: (id: string) => this.deleteRecord(name, definition, id),\n\t\t\tfindById: (id: string) => this.getEffectiveRecord(name, definition, id),\n\t\t}\n\t}\n\n\t/**\n\t * Commit all buffered mutations atomically.\n\t *\n\t * Every entry is written, in call order, inside ONE storage transaction through\n\t * the single local write path: sequence numbers are reserved inside the\n\t * transaction (one contiguous block covering referential side effects too) and\n\t * each operation is built only after its number is reserved.\n\t *\n\t * Returns the list of operations and affected collections for subscription notification.\n\t */\n\tasync commit(): Promise<{ operations: Operation[]; affectedCollections: Set<string> }> {\n\t\tif (this.committed) {\n\t\t\tthrow new KoraError('Transaction already committed.', 'TRANSACTION_COMMITTED', {\n\t\t\t\ttransactionId: this.transactionId,\n\t\t\t})\n\t\t}\n\t\tif (this.rolledBack) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Transaction was rolled back and cannot be committed.',\n\t\t\t\t'TRANSACTION_ROLLED_BACK',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\n\t\tthis.committed = true\n\n\t\tif (this.buffer.length === 0) {\n\t\t\treturn { operations: [], affectedCollections: new Set() }\n\t\t}\n\n\t\tconst env = this.writeEnv()\n\t\tconst causal = new CausalScope(this.config.causalTracker, true)\n\t\tconst operations: Operation[] = []\n\n\t\ttry {\n\t\t\tawait this.config.adapter.transaction(async (tx) => {\n\t\t\t\tawait withWriteScope(tx, env.nodeId, causal, async (scope) => {\n\t\t\t\t\tfor (const entry of this.buffer) {\n\t\t\t\t\t\tlet result: WriteResult\n\t\t\t\t\t\tswitch (entry.kind) {\n\t\t\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\t\t\tresult = await writeInsertInTx(env, scope, entry.insert)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\tcase 'update':\n\t\t\t\t\t\t\t\tresult = await writeUpdateInTx(env, scope, entry.collection, entry.id, entry.data)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\t\t\tresult = await writeDeleteInTx(env, scope, entry.collection, entry.id)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (result.operation) operations.push(result.operation)\n\t\t\t\t\t\toperations.push(...result.sideEffects)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.config.onStorageError?.(error)\n\t\t\tthrow error\n\t\t}\n\n\t\tcausal.publish()\n\t\tconst affectedCollections = new Set(operations.map((op) => op.collection))\n\t\treturn { operations, affectedCollections }\n\t}\n\n\t/**\n\t * Mark the transaction as rolled back. No operations will be committed.\n\t */\n\trollback(): void {\n\t\tthis.rolledBack = true\n\t\tthis.buffer.length = 0\n\t}\n\n\t/**\n\t * Get the transaction ID shared by all operations in this transaction.\n\t */\n\tgetTransactionId(): string {\n\t\treturn this.transactionId\n\t}\n\n\tprivate writeEnv(): WriteEnv {\n\t\treturn {\n\t\t\tschema: this.config.schema,\n\t\t\tclock: this.config.clock,\n\t\t\tnodeId: this.config.nodeId,\n\t\t\trelationEnforcer: this.config.relationEnforcer,\n\t\t\ttransactionId: this.transactionId,\n\t\t\t...(this.config.secretKeyProvider\n\t\t\t\t? { secretKeyProvider: this.config.secretKeyProvider }\n\t\t\t\t: {}),\n\t\t\t...(this.mutationName !== undefined ? { mutationName: this.mutationName } : {}),\n\t\t\t...(this.config.beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: this.config.beforeLocalDelete }\n\t\t\t\t: {}),\n\t\t\t...(this.config.fold ? { fold: this.config.fold } : {}),\n\t\t}\n\t}\n\n\tprivate ensureActive(): void {\n\t\tif (this.committed) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Cannot perform operations on a committed transaction.',\n\t\t\t\t'TRANSACTION_COMMITTED',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\t\tif (this.rolledBack) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Cannot perform operations on a rolled-back transaction.',\n\t\t\t\t'TRANSACTION_ROLLED_BACK',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate async insert(\n\t\tcollectionName: string,\n\t\tdata: Record<string, unknown>,\n\t): Promise<CollectionRecord> {\n\t\tthis.ensureActive()\n\t\tconst insert = await prepareInsert(this.writeEnv(), collectionName, data)\n\t\tthis.buffer.push({ kind: 'insert', collection: collectionName, insert })\n\t\tconst now = Date.now()\n\t\t// The returned record carries the at-rest form (secrets hashed/encrypted) and the\n\t\t// read form of richtext (bytes), exactly like a single-record insert.\n\t\tconst fields = this.config.schema.collections[collectionName]?.fields ?? {}\n\t\treturn {\n\t\t\tid: insert.recordId,\n\t\t\t...toRichtextReadShape(insert.data, fields),\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t}\n\t}\n\n\tprivate async update(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t\tdata: Record<string, unknown>,\n\t): Promise<CollectionRecord> {\n\t\tthis.ensureActive()\n\n\t\tconst currentRecord = await this.getEffectiveRecord(collectionName, definition, id)\n\t\tif (!currentRecord) {\n\t\t\tthrow new RecordNotFoundError(collectionName, id)\n\t\t}\n\n\t\tconst validated = validateRecord(collectionName, definition, data, 'update')\n\t\t// Early check so an invalid transition fails at the call site. The commit\n\t\t// re-validates against the row read inside the write transaction, which is\n\t\t// authoritative.\n\t\tconst allowed = validateUpdateStateMachine(\n\t\t\tcollectionName,\n\t\t\tid,\n\t\t\tdefinition,\n\t\t\tcurrentRecord,\n\t\t\tvalidated,\n\t\t)\n\t\tthis.buffer.push({ kind: 'update', collection: collectionName, id, data: validated })\n\n\t\tconst preview = await this.previewUpdate(definition, currentRecord, allowed)\n\t\treturn { ...currentRecord, ...preview, updatedAt: Date.now() } as CollectionRecord\n\t}\n\n\tprivate async deleteRecord(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t): Promise<void> {\n\t\tthis.ensureActive()\n\n\t\tconst currentRecord = await this.getEffectiveRecord(collectionName, definition, id)\n\t\tif (!currentRecord) {\n\t\t\tthrow new RecordNotFoundError(collectionName, id)\n\t\t}\n\t\tthis.buffer.push({ kind: 'delete', collection: collectionName, id })\n\t}\n\n\t/**\n\t * The values an update will write, resolved against `current` (the effective\n\t * record) for read-your-writes inside the transaction. Secret fields are shown\n\t * in their at-rest form, like the record a committed update returns.\n\t */\n\tprivate async previewUpdate(\n\t\tdefinition: CollectionDefinition,\n\t\tcurrent: CollectionRecord,\n\t\tdata: Record<string, unknown>,\n\t): Promise<Record<string, unknown>> {\n\t\tconst resolved: Record<string, unknown> = {}\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tresolved[key] = isAtomicOp(value) ? resolveAtomicOp(current[key], value) : value\n\t\t}\n\t\tconst atRest = await toAtRestWriteData(resolved, definition, this.config.secretKeyProvider)\n\t\treturn toRichtextReadShape(atRest, definition.fields)\n\t}\n\n\t/**\n\t * The effective state of a record: the committed row overlaid with this\n\t * transaction's buffered mutations, in call order.\n\t */\n\tprivate async getEffectiveRecord(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t): Promise<CollectionRecord | null> {\n\t\tconst rows = await this.config.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(collectionName)} WHERE id = ? AND _deleted = 0`,\n\t\t\t[id],\n\t\t)\n\t\tlet record: CollectionRecord | null = rows[0]\n\t\t\t? deserializeRecord(rows[0], definition.fields)\n\t\t\t: null\n\n\t\tfor (const entry of this.buffer) {\n\t\t\tif (entry.collection !== collectionName) continue\n\t\t\tif (entry.kind === 'insert') {\n\t\t\t\tif (entry.insert.recordId !== id) continue\n\t\t\t\tconst now = Date.now()\n\t\t\t\trecord = {\n\t\t\t\t\tid,\n\t\t\t\t\t...toRichtextReadShape(entry.insert.data, definition.fields),\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t}\n\t\t\t} else if (entry.id === id && entry.kind === 'update') {\n\t\t\t\tif (record) {\n\t\t\t\t\tlet allowed: Record<string, unknown>\n\t\t\t\t\ttry {\n\t\t\t\t\t\tallowed = validateUpdateStateMachine(collectionName, id, definition, record, entry.data)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Already reported to the caller when the update was buffered.\n\t\t\t\t\t\tallowed = {}\n\t\t\t\t\t}\n\t\t\t\t\tconst preview = await this.previewUpdate(definition, record, allowed)\n\t\t\t\t\trecord = { ...record, ...preview, updatedAt: Date.now() }\n\t\t\t\t}\n\t\t\t} else if (entry.id === id) {\n\t\t\t\trecord = null\n\t\t\t}\n\t\t}\n\n\t\treturn record\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { collectionIndexName, legacyCollectionIndexName } from '@korajs/core/internal'\nimport type { StorageAdapter } from '../types'\n\n/**\n * Retire indexes created under the pre-beta.13 naming scheme (STORE-15).\n *\n * `idx_<collection>_<field>` collided across collections (`a_b`.`c` and\n * `a`.`b_c`), so one of the two indexes was silently never created. The schema\n * DDL now creates collision-free names ({@link collectionIndexName}); this pass\n * drops each legacy index that sits on the table and column it was named for,\n * once its replacement exists. A legacy name that belongs to another table is\n * left to that table's own pass, so nothing a collection still needs is dropped.\n *\n * SQLite cannot rename an index; drop-and-recreate is the rename.\n *\n * @param adapter - The opened adapter (schema DDL already applied)\n * @param schema - The schema whose collections are checked\n */\nexport async function dropLegacyIndexes(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<void> {\n\tconst indexed = new Map<string, Set<string>>()\n\tfor (const [name, definition] of Object.entries(schema.collections)) {\n\t\tindexed.set(name, new Set(definition.indexes))\n\t}\n\tfor (const relation of Object.values(schema.relations)) {\n\t\tindexed.get(relation.from)?.add(relation.field)\n\t}\n\n\tconst existing = await adapter.query<{ name: string; tbl_name: string }>(\n\t\t\"SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' AND name LIKE 'idx_%'\",\n\t)\n\tconst byName = new Map(existing.map((row) => [row.name, row.tbl_name]))\n\n\tfor (const [collection, fields] of indexed) {\n\t\tfor (const field of fields) {\n\t\t\tconst legacy = legacyCollectionIndexName(collection, field)\n\t\t\tconst current = collectionIndexName(collection, field)\n\t\t\tif (legacy === current) continue\n\t\t\tif (byName.get(legacy) !== collection) continue\n\t\t\tif (byName.get(current) !== collection) continue\n\t\t\tconst columns = await adapter.query<{ name: string }>(\n\t\t\t\t`SELECT name FROM pragma_index_info(${sqlString(legacy)})`,\n\t\t\t)\n\t\t\tif (columns.length !== 1 || columns[0]?.name !== field) continue\n\t\t\tawait adapter.execute(`DROP INDEX IF EXISTS ${quoteIdent(legacy)}`)\n\t\t}\n\t}\n}\n\nfunction sqlString(value: string): string {\n\treturn `'${value.replace(/'/g, \"''\")}'`\n}\n","/**\n * Web Locks per local node id (RT-40). Under per-tab isolation every tab writes under\n * its own node id into one shared database; a live tab holds its node's lock for its\n * lifetime, so another tab can tell a closed tab's node (lock free: adopt its unsynced\n * writes) from a live one (lock held: leave it alone). An adopter holds the lock while\n * it uploads, so two tabs never adopt the same node at once.\n *\n * Without the Web Locks API (Node, workers without it) every node is reported free and\n * acquisition is a no-op: there is no other tab to coordinate with.\n */\n\ninterface LockLike {\n\tname?: string\n}\n\ninterface LockManagerLike {\n\trequest(\n\t\tname: string,\n\t\toptions: { mode?: 'exclusive' | 'shared'; ifAvailable?: boolean },\n\t\tcallback: (lock: LockLike | null) => Promise<void> | void,\n\t): Promise<unknown>\n\tquery?(): Promise<{ held?: LockLike[] }>\n}\n\nfunction lockManager(): LockManagerLike | null {\n\tconst nav = (globalThis as { navigator?: { locks?: LockManagerLike } }).navigator\n\treturn nav?.locks && typeof nav.locks.request === 'function' ? nav.locks : null\n}\n\n/** Lock name of a node id in a database. */\nexport function nodeLockName(dbName: string, nodeId: string): string {\n\treturn `kora-node:${dbName}:${nodeId}`\n}\n\n/**\n * Hold a node's lock until the returned function is called. Acquisition is\n * asynchronous (it waits while an adopter holds the lock); the caller never waits.\n */\nexport function acquireNodeLock(name: string): () => void {\n\tconst locks = lockManager()\n\tif (!locks) return () => {}\n\tlet release: () => void = () => {}\n\tlet released = false\n\tconst held = new Promise<void>((resolve) => {\n\t\trelease = () => {\n\t\t\treleased = true\n\t\t\tresolve()\n\t\t}\n\t})\n\tlocks\n\t\t.request(name, { mode: 'exclusive' }, async () => {\n\t\t\tif (released) return\n\t\t\tawait held\n\t\t})\n\t\t.catch(() => {\n\t\t\t// A lock that cannot be taken only weakens the liveness hint; never fatal.\n\t\t})\n\treturn () => release()\n}\n\n/**\n * Take a node's lock only when it is free. Resolves to a release function, or null\n * when another context (a live tab, another adopter) holds it.\n */\nexport function tryAcquireNodeLock(name: string): Promise<(() => void) | null> {\n\tconst locks = lockManager()\n\tif (!locks) return Promise.resolve(() => {})\n\treturn new Promise((resolveResult) => {\n\t\tlet release: () => void = () => {}\n\t\tconst held = new Promise<void>((resolve) => {\n\t\t\trelease = resolve\n\t\t})\n\t\tlocks\n\t\t\t.request(name, { mode: 'exclusive', ifAvailable: true }, async (lock) => {\n\t\t\t\tif (!lock) {\n\t\t\t\t\tresolveResult(null)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tresolveResult(() => release())\n\t\t\t\tawait held\n\t\t\t})\n\t\t\t.catch(() => resolveResult(null))\n\t})\n}\n\n/** Whether some context holds a node's lock. */\nexport async function isNodeLockHeld(name: string): Promise<boolean> {\n\tconst locks = lockManager()\n\tif (!locks?.query) return false\n\ttry {\n\t\tconst snapshot = await locks.query()\n\t\treturn (snapshot.held ?? []).some((lock) => lock.name === name)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import type { SchemaDefinition } from '@korajs/core'\nimport {\n\ttype SqliteQueryFn,\n\treadSqliteTableCatalog,\n\tsqliteConstraintRelaxationStatements,\n} from '@korajs/core/internal'\nimport type { StorageAdapter } from '../types'\n\n/**\n * One-time migration (RT-101): rebuild collection tables that still carry value-domain\n * constraints (an enum `CHECK`, `NOT NULL` on a schema field) created by beta.12 and\n * earlier DDL. Validation is the single authority for the value domain; a table\n * constraint cannot evolve with the schema, so it refused enum values added later and\n * nulls of fields made optional.\n *\n * Every table is rebuilt in ONE transaction (all or nothing), preserving rows, columns,\n * defaults, keys, indexes and triggers. Foreign key enforcement is switched off around\n * it when the database enforces foreign keys, as SQLite's table-rebuild procedure\n * requires. Idempotent: a relaxed table is left alone, so later opens do nothing;\n * resumable: an interrupted rebuild rolls back and runs again at the next open.\n *\n * Works for every client adapter (better-sqlite3, SQLite WASM/OPFS, and the IndexedDB\n * adapter, which runs SQLite in memory): they all store in SQLite.\n *\n * @param adapter - The opened adapter (schema DDL already applied)\n * @param schema - The schema whose collection tables are checked\n * @returns The collections whose tables were rebuilt\n */\nexport async function relaxValueDomainConstraints(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<string[]> {\n\tconst collections = Object.keys(schema.collections)\n\t// Only enum checks on the schema's enum fields are Kora's; any other CHECK was added\n\t// by hand and is kept through the rebuild, and never triggers one (RT-111).\n\tconst enumColumns = (collection: string): string[] =>\n\t\tObject.entries(schema.collections[collection]?.fields ?? {})\n\t\t\t.filter(([, descriptor]) => descriptor.kind === 'enum')\n\t\t\t.map(([field]) => field)\n\tconst viaAdapter: SqliteQueryFn = (sql) => adapter.query<Record<string, unknown>>(sql)\n\tconst pending: string[] = []\n\tfor (const collection of collections) {\n\t\tconst catalog = await readSqliteTableCatalog(viaAdapter, collection)\n\t\tif (\n\t\t\tcatalog &&\n\t\t\tsqliteConstraintRelaxationStatements(catalog, enumColumns(collection)).length > 0\n\t\t) {\n\t\t\tpending.push(collection)\n\t\t}\n\t}\n\tif (pending.length === 0) return []\n\n\tconst enforced = await adapter.query<{ foreign_keys: number }>('PRAGMA foreign_keys')\n\tconst foreignKeysOn = Number(enforced[0]?.foreign_keys) === 1\n\tif (foreignKeysOn) await adapter.execute('PRAGMA foreign_keys = OFF')\n\tconst rebuilt: string[] = []\n\ttry {\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tconst viaTx: SqliteQueryFn = (sql) => tx.query<Record<string, unknown>>(sql)\n\t\t\t// Re-read inside the transaction: another tab may have relaxed a table already.\n\t\t\tfor (const collection of pending) {\n\t\t\t\tconst catalog = await readSqliteTableCatalog(viaTx, collection)\n\t\t\t\tif (!catalog) continue\n\t\t\t\tconst statements = sqliteConstraintRelaxationStatements(catalog, enumColumns(collection))\n\t\t\t\tif (statements.length === 0) continue\n\t\t\t\tfor (const sql of statements) await tx.execute(sql)\n\t\t\t\trebuilt.push(collection)\n\t\t\t}\n\t\t})\n\t} finally {\n\t\tif (foreignKeysOn) await adapter.execute('PRAGMA foreign_keys = ON')\n\t}\n\treturn rebuilt\n}\n","import { generateUUIDv7 } from '@korajs/core'\n\nexport type StoreIsolation = 'shared' | 'per-tab'\n\nfunction perTabStorageKey(dbName: string): string {\n\treturn `kora-tab-node-${dbName}`\n}\n\n/**\n * Load a per-tab node id from sessionStorage (browser only).\n */\nexport function loadPerTabNodeId(dbName: string): string | null {\n\tif (typeof sessionStorage === 'undefined') {\n\t\treturn null\n\t}\n\treturn sessionStorage.getItem(perTabStorageKey(dbName))\n}\n\n/**\n * Persist a per-tab node id for this browser tab.\n */\nexport function savePerTabNodeId(dbName: string, nodeId: string): void {\n\tif (typeof sessionStorage === 'undefined') {\n\t\treturn\n\t}\n\tsessionStorage.setItem(perTabStorageKey(dbName), nodeId)\n}\n\n/**\n * Resolve or create a node id for `per-tab` isolation.\n */\nexport function resolvePerTabNodeId(dbName: string): string {\n\tconst existing = loadPerTabNodeId(dbName)\n\t// Never adopt an id in Kora's reserved `kora:` namespace (RT-61).\n\tif (existing && !existing.startsWith('kora:')) {\n\t\treturn existing\n\t}\n\tconst nodeId = generateUUIDv7()\n\tsavePerTabNodeId(dbName, nodeId)\n\treturn nodeId\n}\n","const WIRE_BYTES_KEY = '__kora_bytes__'\n\n/**\n * JSON.stringify replacer that preserves binary field values (e.g. richtext).\n */\nexport function auditJsonReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) {\n\t\tlet binary = ''\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tbinary += String.fromCharCode(value[i] as number)\n\t\t}\n\t\treturn { [WIRE_BYTES_KEY]: btoa(binary) }\n\t}\n\treturn value\n}\n\n/**\n * JSON.parse reviver that restores binary field values.\n */\nexport function auditJsonReviver(_key: string, value: unknown): unknown {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\tWIRE_BYTES_KEY in value &&\n\t\ttypeof (value as Record<string, unknown>)[WIRE_BYTES_KEY] === 'string'\n\t) {\n\t\tconst encoded = (value as Record<string, unknown>)[WIRE_BYTES_KEY]\n\t\tif (typeof encoded !== 'string') {\n\t\t\treturn value\n\t\t}\n\t\tconst binary = atob(encoded)\n\t\tconst bytes = new Uint8Array(binary.length)\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tbytes[i] = binary.charCodeAt(i)\n\t\t}\n\t\treturn bytes\n\t}\n\treturn value\n}\n\n/**\n * Serialize a value for durable audit storage or export.\n */\nexport function serializeAuditJson(value: unknown): string {\n\treturn JSON.stringify(value, auditJsonReplacer)\n}\n\n/**\n * Deserialize audit JSON back to typed values.\n */\nexport function deserializeAuditJson<T>(json: string): T {\n\treturn JSON.parse(json, auditJsonReviver) as T\n}\n","import { generateUUIDv7 } from '@korajs/core'\nimport type { KoraEvent, MergeTrace } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\nimport { deserializeAuditJson, serializeAuditJson } from './audit-json'\nimport type { AuditTraceQuery, PersistedAuditTrace } from './types'\n\ninterface AuditTraceRow {\n\tid: string\n\trecorded_at: number\n\tevent_type: string\n\tcollection: string\n\trecord_id: string\n\tfield: string\n\tstrategy: string\n\ttier: number\n\tconstraint_name: string | null\n\ttrace_json: string\n}\n\n/**\n * Build a {@link PersistedAuditTrace} from a merge-related Kora event.\n */\nexport function persistedAuditTraceFromEvent(\n\tevent: Extract<KoraEvent, { type: 'merge:completed' | 'merge:conflict' | 'constraint:violated' }>,\n): PersistedAuditTrace {\n\treturn {\n\t\tid: generateUUIDv7(),\n\t\trecordedAt: Date.now(),\n\t\teventType: event.type,\n\t\tconstraint: event.type === 'constraint:violated' ? event.constraint : undefined,\n\t\ttrace: event.trace,\n\t}\n}\n\n/**\n * Append a merge trace to the durable audit log.\n */\nexport async function appendAuditTrace(\n\tadapter: StorageAdapter,\n\ttrace: PersistedAuditTrace,\n): Promise<void> {\n\tconst collection = trace.trace.operationA.collection\n\tconst recordId = trace.trace.operationA.recordId\n\n\tawait adapter.execute(\n\t\t`INSERT INTO _kora_audit_traces (\n\t\t\tid, recorded_at, event_type, collection, record_id, field, strategy, tier, constraint_name, trace_json\n\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\ttrace.id,\n\t\t\ttrace.recordedAt,\n\t\t\ttrace.eventType,\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t\ttrace.trace.field,\n\t\t\ttrace.trace.strategy,\n\t\t\ttrace.trace.tier,\n\t\t\ttrace.constraint ?? null,\n\t\t\tserializeAuditJson(trace),\n\t\t],\n\t)\n}\n\n/**\n * Load persisted audit traces with optional filters.\n */\nexport async function readAuditTraces(\n\tadapter: StorageAdapter,\n\tquery?: AuditTraceQuery,\n): Promise<PersistedAuditTrace[]> {\n\tconst conditions: string[] = []\n\tconst params: unknown[] = []\n\n\tif (query?.collections && query.collections.length > 0) {\n\t\tconst placeholders = query.collections.map(() => '?').join(', ')\n\t\tconditions.push(`collection IN (${placeholders})`)\n\t\tparams.push(...query.collections)\n\t}\n\tif (query?.since !== undefined) {\n\t\tconditions.push('recorded_at >= ?')\n\t\tparams.push(query.since)\n\t}\n\tif (query?.until !== undefined) {\n\t\tconditions.push('recorded_at <= ?')\n\t\tparams.push(query.until)\n\t}\n\n\tconst whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''\n\tconst rows = await adapter.query<AuditTraceRow>(\n\t\t`SELECT * FROM _kora_audit_traces ${whereClause} ORDER BY recorded_at ASC, id ASC`,\n\t\tparams,\n\t)\n\n\treturn rows.map(rowToPersistedTrace)\n}\n\nfunction rowToPersistedTrace(row: AuditTraceRow): PersistedAuditTrace {\n\treturn deserializeAuditJson<PersistedAuditTrace>(row.trace_json)\n}\n\n/**\n * Count persisted audit traces (for diagnostics).\n */\nexport async function countAuditTraces(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<{ count: number }>(\n\t\t'SELECT COUNT(*) as count FROM _kora_audit_traces',\n\t)\n\treturn rows[0]?.count ?? 0\n}\n\n/**\n * Extract collection and record id from a merge trace for indexing.\n */\nexport function auditTraceIndexFields(trace: MergeTrace): {\n\tcollection: string\n\trecordId: string\n} {\n\treturn {\n\t\tcollection: trace.operationA.collection,\n\t\trecordId: trace.operationA.recordId,\n\t}\n}\n","import type { Operation, SchemaDefinition } from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport type { StorageAdapter } from '../types'\nimport type { OperationRow } from '../types'\nimport { deserializeAuditJson, serializeAuditJson } from './audit-json'\nimport { readAuditTraces } from './audit-trace-store'\nimport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './types'\n\nfunction encodeSection(name: string, content: Uint8Array): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(name)\n\tconst header = new Uint8Array(8)\n\tconst view = new DataView(header.buffer)\n\tview.setUint32(0, nameBytes.length, true)\n\tview.setUint32(4, content.length, true)\n\n\tconst result = new Uint8Array(header.length + nameBytes.length + content.length)\n\tresult.set(header, 0)\n\tresult.set(nameBytes, 8)\n\tresult.set(content, 8 + nameBytes.length)\n\treturn result\n}\n\nfunction encodeJsonSection(name: string, data: unknown): Uint8Array {\n\treturn encodeSection(name, new TextEncoder().encode(serializeAuditJson(data)))\n}\n\nfunction encodeNdjsonSection(name: string, records: unknown[]): Uint8Array {\n\tconst lines = `${records.map((record) => serializeAuditJson(record)).join('\\n')}\\n`\n\treturn encodeSection(name, new TextEncoder().encode(lines))\n}\n\nfunction readUint32(view: DataView, offset: number): number {\n\treturn view.getUint32(offset, true)\n}\n\ninterface Section {\n\tname: string\n\tcontent: Uint8Array\n}\n\nfunction parseSections(data: Uint8Array): Section[] {\n\tconst sections: Section[] = []\n\tconst view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\tlet offset = 0\n\n\twhile (offset + 8 <= data.byteLength) {\n\t\tconst nameLen = readUint32(view, offset)\n\t\tconst contentLen = readUint32(view, offset + 4)\n\t\toffset += 8\n\n\t\tif (offset + nameLen + contentLen > data.byteLength) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst name = new TextDecoder().decode(data.slice(offset, offset + nameLen))\n\t\toffset += nameLen\n\n\t\tconst content = data.slice(offset, offset + contentLen)\n\t\toffset += contentLen\n\n\t\tsections.push({ name, content })\n\t}\n\n\treturn sections\n}\n\nfunction findSection(sections: Section[], name: string): Uint8Array | null {\n\tfor (const section of sections) {\n\t\tif (section.name === name) {\n\t\t\treturn section.content\n\t\t}\n\t}\n\treturn null\n}\n\nasync function computeSha256(data: Uint8Array<ArrayBuffer>): Promise<string> {\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\n\treturn Array.from(new Uint8Array(hashBuffer))\n\t\t.map((byte) => byte.toString(16).padStart(2, '0'))\n\t\t.join('')\n}\n\nasync function readAllOperations(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tcollectionFilter?: string[],\n): Promise<Operation[]> {\n\tconst collections = collectionFilter\n\t\t? Object.keys(schema.collections).filter((name) => collectionFilter.includes(name))\n\t\t: Object.keys(schema.collections)\n\n\tconst allOps: Operation[] = []\n\tfor (const collectionName of collections) {\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`,\n\t\t)\n\n\t\tfor (const row of rows) {\n\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t}\n\t}\n\n\treturn allOps\n}\n\nfunction filterOperationsByCollections(\n\toperations: Operation[],\n\tcollectionFilter?: string[],\n): Operation[] {\n\tif (!collectionFilter || collectionFilter.length === 0) {\n\t\treturn operations\n\t}\n\tconst allowed = new Set(collectionFilter)\n\treturn operations.filter((op) => allowed.has(op.collection))\n}\n\n/**\n * Export operations and persisted merge traces as a portable binary audit bundle.\n */\nexport async function exportAudit(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n\tschemaVersion: number,\n\toptions?: AuditExportOptions,\n): Promise<Uint8Array> {\n\tconst onProgress = options?.onProgress ?? (() => {})\n\tconst traceQuery: AuditTraceQuery = {\n\t\tcollections: options?.collections,\n\t\tsince: options?.since,\n\t\tuntil: options?.until,\n\t}\n\n\tonProgress({ phase: 'reading', progress: 0, message: 'Reading operations' })\n\tconst operations = filterOperationsByCollections(\n\t\tawait readAllOperations(adapter, schema, options?.collections),\n\t\toptions?.collections,\n\t)\n\n\tonProgress({ phase: 'reading', progress: 0.4, message: 'Reading merge traces' })\n\tconst mergeTraces = await readAuditTraces(adapter, traceQuery)\n\n\tonProgress({ phase: 'writing', progress: 0.7, message: 'Encoding audit export' })\n\tconst sections: Uint8Array[] = []\n\tlet contentForChecksum = new Uint8Array(0)\n\n\tconst addSection = (section: Uint8Array): void => {\n\t\tsections.push(section)\n\t\tconst combined = new Uint8Array(contentForChecksum.length + section.length)\n\t\tcombined.set(contentForChecksum, 0)\n\t\tcombined.set(section, contentForChecksum.length)\n\t\tcontentForChecksum = combined\n\t}\n\n\taddSection(encodeNdjsonSection('operations', operations))\n\taddSection(encodeNdjsonSection('merge_traces', mergeTraces))\n\n\tonProgress({ phase: 'verifying', progress: 0.9, message: 'Computing checksum' })\n\tconst checksum = await computeSha256(contentForChecksum as Uint8Array<ArrayBuffer>)\n\n\tconst manifest: AuditExportManifest = {\n\t\tversion: 1,\n\t\texportedAt: Date.now(),\n\t\tnodeId,\n\t\tschemaVersion,\n\t\toperationCount: operations.length,\n\t\tmergeTraceCount: mergeTraces.length,\n\t\tchecksum,\n\t}\n\n\tconst manifestSection = encodeJsonSection('manifest', manifest)\n\tconst checksumSection = encodeSection('checksum', new TextEncoder().encode(checksum))\n\n\tonProgress({ phase: 'writing', progress: 1, message: 'Finalizing' })\n\n\tconst parts = [manifestSection, ...sections, checksumSection]\n\tconst finalOutput = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0))\n\tlet offset = 0\n\tfor (const part of parts) {\n\t\tfinalOutput.set(part, offset)\n\t\toffset += part.length\n\t}\n\n\treturn finalOutput\n}\n\n/**\n * Decode an audit export binary into structured data.\n */\nexport function decodeAuditExport(data: Uint8Array): AuditExportPayload {\n\tconst sections = parseSections(data)\n\tconst manifest = JSON.parse(\n\t\tnew TextDecoder().decode(findSection(sections, 'manifest') ?? new Uint8Array()),\n\t) as AuditExportManifest\n\n\tconst operationsContent = findSection(sections, 'operations')\n\tconst mergeTracesContent = findSection(sections, 'merge_traces')\n\n\tconst operations = parseNdjsonSection<Operation>(operationsContent)\n\tconst mergeTraces = parseNdjsonSection<PersistedAuditTrace>(mergeTracesContent)\n\n\treturn { manifest, operations, mergeTraces }\n}\n\n/**\n * Read only the manifest from an audit export without decoding all sections.\n */\nexport function readAuditExportManifest(data: Uint8Array): AuditExportManifest {\n\tconst sections = parseSections(data)\n\tconst manifestContent = findSection(sections, 'manifest')\n\tif (!manifestContent) {\n\t\tthrow new Error('Invalid audit export: missing manifest section')\n\t}\n\treturn JSON.parse(new TextDecoder().decode(manifestContent)) as AuditExportManifest\n}\n\n/**\n * Verify the checksum of an audit export file.\n */\nexport async function verifyAuditExportChecksum(data: Uint8Array): Promise<boolean> {\n\tconst sections = parseSections(data)\n\tconst manifest = readAuditExportManifest(data)\n\tconst contentSections = sections.filter(\n\t\t(section) => section.name !== 'manifest' && section.name !== 'checksum',\n\t)\n\n\tlet content = new Uint8Array(0)\n\tfor (const section of contentSections) {\n\t\tconst encoded = encodeSection(section.name, section.content)\n\t\tconst combined = new Uint8Array(content.length + encoded.length)\n\t\tcombined.set(content, 0)\n\t\tcombined.set(encoded, content.length)\n\t\tcontent = combined\n\t}\n\n\tconst checksum = await computeSha256(content as Uint8Array<ArrayBuffer>)\n\treturn checksum === manifest.checksum\n}\n\nfunction parseNdjsonSection<T>(content: Uint8Array | null): T[] {\n\tif (!content || content.length === 0) {\n\t\treturn []\n\t}\n\tconst text = new TextDecoder().decode(content).trim()\n\tif (text.length === 0) {\n\t\treturn []\n\t}\n\treturn text.split('\\n').map((line) => deserializeAuditJson<T>(line))\n}\n","import { HybridLogicalClock, quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n\tFOLD_STATE_TABLE,\n\tPROVISIONAL_OPS_TABLE,\n} from '../fold/record-folder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE, insertConflictRow } from '../store/sequence-repair'\nimport {\n\ttype LocalNodeRecord,\n\tTERMINAL_REJECTIONS_TABLE,\n\tensureLocalSyncRecordTables,\n} from '../sync/local-sync-records'\nimport { loadOwnAckedThrough } from '../sync/sync-durability'\nimport {\n\tDELIVERY_WATERMARK_META_KEY,\n\tDELTA_CURSOR_META_KEY,\n\tloadLastAckedServerVector,\n} from '../sync/sync-state'\nimport type { ApplyResult, OperationRow, StorageAdapter, Transaction } from '../types'\nimport type { ParsedBackup } from './backup'\n\n/** What a restore needs from the store it restores into. */\nexport interface RestoreHost {\n\treadonly adapter: StorageAdapter\n\treadonly schema: SchemaDefinition\n\t/** The normal remote-apply path (sync's): dedup by id, per-field merge, version vector. */\n\tapplyOperation(operation: Operation): Promise<ApplyResult>\n\t/** This database's own nodes (RT-38/40), never taken from a backup. */\n\tlistLocalNodes(): Promise<LocalNodeRecord[]>\n\t/**\n\t * Whether a node's writes would be authoritative here (Kora's reserved `kora:`\n\t * nodes, and the explicit server authorities this device learned). A merge import\n\t * never applies their operations: only the sync server delivers them.\n\t */\n\tisServerAuthority?(nodeId: string): boolean\n}\n\n/** Outcome counts of a restore. */\nexport interface RestoreCounts {\n\toperationsRestored: number\n\trecordsRestored: number\n\tunsyncedWritesKept: number\n\t/** Merge mode: operations of server-authority nodes left out (see `RestoreHost.isServerAuthority`). */\n\tserverOperationsSkipped?: number\n}\n\n/**\n * Merge a backup into the database (STORE-5): every operation goes through the normal\n * remote-apply path in HLC (causal) order, the version vector advances by MAX, the\n * terminal-rejection markers are added. Never imported: the node id, node tokens, local\n * node registry and principal bindings, sync watermarks, acknowledged prefixes.\n */\nexport async function restoreMerge(\n\thost: RestoreHost,\n\tbackup: ParsedBackup,\n\tfiltered: boolean,\n): Promise<RestoreCounts> {\n\tawait importTerminalRejections(host.adapter, backup)\n\tlet restored = 0\n\tlet skipped = 0\n\tconst authority = (nodeId: string): boolean => host.isServerAuthority?.(nodeId) ?? false\n\tfor (const operation of backup.operations) {\n\t\tif (!host.schema.collections[operation.collection]) continue\n\t\t// A server decision is applied only as the sync server delivers it: from a file,\n\t\t// an operation under a server node would win `merge('server-authoritative')`\n\t\t// fields on this device (and is never uploaded to be checked). One the server\n\t\t// already delivered is in the log anyway; the rest arrive by sync.\n\t\tif (authority(operation.nodeId)) {\n\t\t\tskipped++\n\t\t\tcontinue\n\t\t}\n\t\tif ((await host.applyOperation(operation)) === 'applied') restored++\n\t}\n\tif (!filtered && backup.versionVector.size > 0) {\n\t\t// With a collection filter the vector would claim other collections' operations.\n\t\tawait host.adapter.transaction(async (tx) => {\n\t\t\tfor (const [nodeId, sequence] of backup.versionVector) {\n\t\t\t\tif (authority(nodeId)) continue\n\t\t\t\tawait maxVector(tx, nodeId, sequence)\n\t\t\t}\n\t\t})\n\t}\n\treturn {\n\t\toperationsRestored: restored,\n\t\trecordsRestored: 0,\n\t\tunsyncedWritesKept: 0,\n\t\tserverOperationsSkipped: skipped,\n\t}\n}\n\n/**\n * Replace the database's data with a backup's (STORE-5), keeping this device's\n * identity:\n *\n * - The node id, node tokens, local node registry, principal bindings and acknowledged\n * prefixes are untouched; the exporting device's are never imported.\n * - This database's own nodes never move their sequence counters backwards (numbers the\n * server may hold are never reused). A node the server never accepted, whose unsynced\n * writes are not kept, restarts after its highest restored number (its numbers never\n * left the device), so its log stays contiguous.\n * - Unacknowledged writes of an accepted node, and with `keepUnsyncedWrites` every\n * unsynced own write, are re-applied on top of the restored data.\n * - Delivery watermarks restart at 0 and the delta cursor is dropped, so the sync server\n * re-sends everything in scope (deduplicated by id).\n * - Rows, operations, version vector and sync bookkeeping change in one transaction;\n * re-applied writes (and a backup without records, materialized through the\n * remote-apply path) follow it.\n */\nexport async function restoreReplace(\n\thost: RestoreHost,\n\tbackup: ParsedBackup,\n\toptions: { collections: string[] | null; keepUnsyncedWrites: boolean },\n): Promise<RestoreCounts> {\n\tconst { adapter, schema } = host\n\tconst targets = Object.keys(schema.collections).filter(\n\t\t(name) => !options.collections || options.collections.includes(name),\n\t)\n\tconst rawRecords = backup.manifest.includesRecords\n\tconst localNodes = await host.listLocalNodes()\n\tconst localIds = new Set(localNodes.map((node) => node.nodeId))\n\tconst acked = await loadAckedThrough(adapter, localNodes)\n\n\t// Writes that exist only on this device: re-applied after the replace.\n\tconst kept: Operation[] = []\n\tconst dropped = new Set<string>()\n\tfor (const node of localNodes) {\n\t\tconst keep = node.accepted || options.keepUnsyncedWrites\n\t\tconst floor = acked.get(node.nodeId) ?? 0\n\t\tfor (const collection of targets) {\n\t\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND sequence_number > ?`,\n\t\t\t\t[node.nodeId, floor],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (keep) kept.push(deserializeOperationWithCollection(row, collection))\n\t\t\t\telse dropped.add(node.nodeId)\n\t\t\t}\n\t\t}\n\t}\n\tkept.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\t// Counters that may restart: nodes the server never accepted whose writes are dropped.\n\tconst restartable = new Set(\n\t\tlocalNodes\n\t\t\t.filter((node) => !node.accepted && !options.keepUnsyncedWrites)\n\t\t\t.map((node) => node.nodeId),\n\t)\n\n\tawait ensureLocalSyncRecordTables(adapter)\n\tlet recordsRestored = 0\n\tconst hasConflicts = await tableExists(adapter, SEQ_CONFLICTS_TABLE)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const collection of targets) {\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(`_kora_ops_${collection}`)}`)\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(collection)}`)\n\t\t\tawait tx.execute('DELETE FROM _kora_scope_retractions WHERE collection = ?', [collection])\n\t\t\t// W7: the records' fold states go with their rows and log; the store\n\t\t\t// re-materializes the restored collections afterwards.\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_BASE_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ?`, [collection])\n\t\t\tif (hasConflicts) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`DELETE FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND reemitted_as IS NULL`,\n\t\t\t\t\t[collection],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Version vector. Without a collection filter, remote nodes take the backup's\n\t\t// values; this database's own nodes never go backwards. With a filter, MAX only.\n\t\tconst current = await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tif (!options.collections) {\n\t\t\tfor (const row of current) {\n\t\t\t\tif (!localIds.has(row.node_id)) {\n\t\t\t\t\tawait tx.execute('DELETE FROM _kora_version_vector WHERE node_id = ?', [row.node_id])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const [nodeId, sequence] of backup.versionVector) {\n\t\t\tif (restartable.has(nodeId)) continue\n\t\t\tawait maxVector(tx, nodeId, sequence)\n\t\t}\n\n\t\t// The server must re-send everything in scope: this database no longer holds what\n\t\t// it delivered before.\n\t\tawait tx.execute('UPDATE _kora_meta SET value = ? WHERE key = ? OR key LIKE ?', [\n\t\t\t'0',\n\t\t\tDELIVERY_WATERMARK_META_KEY,\n\t\t\t`${DELIVERY_WATERMARK_META_KEY}:%`,\n\t\t])\n\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\n\t\tfor (const entry of backup.terminalRejections) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\n\t\t// W7 (RT-66): the exporting device's compacted history (base states), its row\n\t\t// snapshots and compacted prefixes, so records rebuild from base + log exactly.\n\t\tfor (const row of backup.foldBases) {\n\t\t\tif (!targets.includes(row.collection)) continue\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR REPLACE INTO ${FOLD_BASE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t\t[row.collection, row.recordId, row.state],\n\t\t\t)\n\t\t}\n\t\tfor (const row of backup.foldSnapshots) {\n\t\t\tif (!targets.includes(row.collection)) continue\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR REPLACE INTO ${FOLD_SNAPSHOT_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t\t[row.collection, row.recordId, row.state],\n\t\t\t)\n\t\t}\n\t\tif (!options.collections) {\n\t\t\t// Per node and global; a collection filter would claim other collections' ops.\n\t\t\tawait tx.execute(`DELETE FROM ${COMPACTED_THROUGH_TABLE}`)\n\t\t\tfor (const [nodeId, sequence] of backup.compactedThrough) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)`,\n\t\t\t\t\t[nodeId, sequence],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (rawRecords) {\n\t\t\tfor (const operation of backup.operations) {\n\t\t\t\tif (!targets.includes(operation.collection)) continue\n\t\t\t\tawait insertOperationRow(tx, operation)\n\t\t\t}\n\t\t\tfor (const collection of targets) {\n\t\t\t\tconst rows = backup.records.get(collection) ?? []\n\t\t\t\tif (rows.length === 0) continue\n\t\t\t\tconst columns = new Set(\n\t\t\t\t\t(await tx.query<{ name: string }>(`PRAGMA table_info(${quoteIdent(collection)})`)).map(\n\t\t\t\t\t\t(column) => column.name,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst keys = Object.keys(row).filter((key) => columns.has(key))\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`INSERT OR REPLACE INTO ${quoteIdent(collection)} (${keys.map((k) => quoteIdent(k)).join(', ')}) VALUES (${keys.map(() => '?').join(', ')})`,\n\t\t\t\t\t\tkeys.map((key) => toSqlValue(row[key])),\n\t\t\t\t\t)\n\t\t\t\t\trecordsRestored++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\tlet restored = rawRecords\n\t\t? backup.operations.filter((operation) => targets.includes(operation.collection)).length\n\t\t: 0\n\tif (!rawRecords) {\n\t\t// No materialized rows in the backup: the remote-apply path rebuilds them.\n\t\tfor (const operation of backup.operations) {\n\t\t\tif (!targets.includes(operation.collection)) continue\n\t\t\tif ((await host.applyOperation(operation)) === 'applied') restored++\n\t\t}\n\t}\n\tlet unsyncedWritesKept = 0\n\tfor (const operation of kept) {\n\t\tif ((await host.applyOperation(operation)) === 'applied') unsyncedWritesKept++\n\t}\n\n\tawait adapter.transaction(async (tx) => {\n\t\t// Restartable counters continue after the highest number now in the log.\n\t\tfor (const nodeId of restartable) {\n\t\t\tconst highest = await highestSequence(tx, targets, nodeId)\n\t\t\tawait tx.execute('DELETE FROM _kora_version_vector WHERE node_id = ?', [nodeId])\n\t\t\tif (highest > 0) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)',\n\t\t\t\t\t[nodeId, highest],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\t// Nothing dropped may still wait to upload.\n\t\tif (dropped.size > 0 || !options.keepUnsyncedWrites) {\n\t\t\tconst union = targets\n\t\t\t\t.map((c) => `SELECT id FROM ${quoteIdent(`_kora_ops_${c}`)}`)\n\t\t\t\t.join(' UNION ')\n\t\t\tif (union) {\n\t\t\t\tawait tx.execute(`DELETE FROM _kora_sync_queue WHERE id NOT IN (${union})`)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn { operationsRestored: restored, recordsRestored, unsyncedWritesKept }\n}\n\nasync function importTerminalRejections(\n\tadapter: StorageAdapter,\n\tbackup: ParsedBackup,\n): Promise<void> {\n\tif (backup.terminalRejections.length === 0) return\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of backup.terminalRejections) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\t})\n}\n\n/** Append a canonical operation row; a taken `(node, sequence)` goes to the conflicts table. */\nasync function insertOperationRow(tx: Transaction, operation: Operation): Promise<void> {\n\tconst table = quoteIdent(`_kora_ops_${operation.collection}`)\n\tconst row = serializeOperation(operation)\n\tconst existing = await tx.query<{ id: string }>(`SELECT id FROM ${table} WHERE id = ?`, [row.id])\n\tif (existing.length > 0) return\n\tconst holder = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${table} WHERE node_id = ? AND sequence_number = ?`,\n\t\t[row.node_id, row.sequence_number],\n\t)\n\tif (holder.length > 0) {\n\t\tawait insertConflictRow(\n\t\t\ttx,\n\t\t\toperation.collection,\n\t\t\trow,\n\t\t\t'backup-sequence-conflict',\n\t\t\tnull,\n\t\t\tnull,\n\t\t\tDate.now(),\n\t\t)\n\t\treturn\n\t}\n\tawait tx.execute(\n\t\t`INSERT INTO ${table} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\trow.id,\n\t\t\trow.node_id,\n\t\t\trow.type,\n\t\t\trow.record_id,\n\t\t\trow.data,\n\t\t\trow.previous_data,\n\t\t\trow.timestamp,\n\t\t\trow.sequence_number,\n\t\t\trow.causal_deps,\n\t\t\trow.schema_version,\n\t\t],\n\t)\n}\n\nasync function maxVector(tx: Transaction, nodeId: string, sequence: number): Promise<void> {\n\tawait tx.execute(\n\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t[nodeId, sequence],\n\t)\n}\n\nasync function highestSequence(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<number> {\n\tlet highest = 0\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ m: number | null }>(\n\t\t\t`SELECT MAX(sequence_number) AS m FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\thighest = Math.max(highest, rows[0]?.m ?? 0)\n\t}\n\treturn highest\n}\n\n/**\n * Per own node, how far the sync server acknowledged its operations: the W3 contiguous\n * acknowledged prefix, else the last acknowledged server vector, else 0.\n */\nasync function loadAckedThrough(\n\tadapter: StorageAdapter,\n\tnodes: readonly LocalNodeRecord[],\n): Promise<Map<string, number>> {\n\tconst lastAcked = await loadLastAckedServerVector(adapter)\n\tconst result = new Map<string, number>()\n\tfor (const node of nodes) {\n\t\tconst prefix = await loadOwnAckedThrough(adapter, node.nodeId)\n\t\tresult.set(node.nodeId, prefix ?? lastAcked.get(node.nodeId) ?? 0)\n\t}\n\treturn result\n}\n\nasync function tableExists(adapter: StorageAdapter, name: string): Promise<boolean> {\n\tconst rows = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[name],\n\t)\n\treturn rows.length > 0\n}\n\nfunction toSqlValue(value: unknown): unknown {\n\tif (typeof value === 'boolean') return value ? 1 : 0\n\tif (value instanceof Uint8Array) return value\n\tif (value !== null && typeof value === 'object') return JSON.stringify(value)\n\treturn value\n}\n","import {\n\tCausalTracker,\n\tHybridLogicalClock,\n\tKoraError,\n\tassertOperationTransformCoverage,\n\tcreateVersionVector,\n\tderiveSideEffectOpId,\n\tdeserializeFoldState,\n\texpandFieldVersionedOperations,\n\tfoldPlanFingerprints,\n\tgenerateUUIDv7,\n\tisReservedNodeId,\n\tisServerNodeId,\n\tmismatchedFoldFields,\n\toperationSchemaView,\n\tquoteIdent,\n\treplayOperationsForRecord,\n} from '@korajs/core'\nimport type {\n\tFoldState,\n\tHLCTimestamp,\n\tKoraEventEmitter,\n\tMergeTrace,\n\tOperation,\n\tOperationLog,\n\tOperationTransform,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n\tVersionVector,\n} from '@korajs/core'\nimport { readBackupManifest as readManifest } from '../backup/backup'\nimport type { BackupManifest, BackupOptions, RestoreOptions, RestoreResult } from '../backup/types'\nimport { Collection } from '../collection/collection'\nimport { compactOperationLog } from '../compaction/compact-operation-log'\nimport type { CompactionResult, CompactionStrategy } from '../compaction/types'\nimport { OptimisticLockError, SchemaVersionAheadError, StoreNotOpenError } from '../errors'\nimport { compactFoldedLog } from '../fold/compact-folded-log'\nimport { LEGACY_BODIES_META_KEY, canonicalizeLegacyLogBodies } from '../fold/legacy-bodies'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_MATERIALIZATION_CURRENT,\n\tFOLD_MATERIALIZATION_LEGACY,\n\tFOLD_MATERIALIZATION_META_KEY,\n\tFOLD_STATE_TABLE,\n\tFOLD_TABLES_DDL,\n\tRecordFolder,\n\tisCompacted,\n} from '../fold/record-folder'\nimport {\n\ttype KeptRecords,\n\ttype RematerializationMode,\n\trematerializeDatabase,\n} from '../fold/rematerialize'\nimport {\n\tLOG_QUARANTINE_TABLE,\n\ttype LogIntegrityReport,\n\tscanLogIntegrity,\n} from '../log-integrity/log-integrity'\nimport {\n\ttype FieldVersions,\n\teffectiveFieldVersion,\n\tfieldVersionsForFields,\n\tparseFieldVersions,\n\tresolvePerFieldLww,\n\tserializeFieldVersions,\n} from '../lww/field-versions'\nimport { isIncomingNewerThanRow, serializeRowVersion } from '../lww/row-version'\nimport { runSchemaMigrations } from '../migrations/run-migrations'\nimport {\n\tSTORED_SCHEMA_VERSION_SQL,\n\tparseSchemaAhead,\n\tstoredSchemaVersion,\n} from '../migrations/schema-ceiling'\nimport type { LocalMutationContext } from '../mutations/types'\nimport { isStorageFullError } from '../mutations/write-context'\nimport { QueryBuilder } from '../query/query-builder'\nimport {\n\tbuildFieldFastForwardUpdateQuery,\n\tbuildInsertQuery,\n\tbuildLwwSoftDeleteQuery,\n\tbuildSoftDeleteQuery,\n} from '../query/sql-builder'\nimport { RelationEnforcer } from '../relations/relation-enforcer'\nimport { buildReplaySnapshot } from '../replay/replay-to'\nimport type { ReplaySnapshot } from '../replay/replay-to'\nimport { SequenceManager } from '../sequences/sequence-manager'\nimport {\n\tdeserializeOperationWithCollection,\n\tdeserializeRecord,\n\tserializeOperation,\n\tserializeRecord,\n} from '../serialization/serializer'\nimport { ensureStoredTextCodec } from '../serialization/stored-text-migration'\nimport {\n\ttype RecordsChangeListener,\n\tSubscriptionManager,\n} from '../subscription/subscription-manager'\nimport {\n\ttype AdoptionSchedule,\n\ttype LocalNodeRecord,\n\ttype TerminalRejection,\n\tassignLocalNodePrincipal,\n\tconfirmLocalNodePrincipal,\n\tdropLocalNode,\n\tfindTerminalRejections,\n\tforgetLocalNode,\n\tlistLocalNodes,\n\tloadAcceptedCycle,\n\tloadAdoptionSchedule,\n\tmarkLocalNodeAccepted,\n\tmarkLocalNodeRefused,\n\trecordLocalNodeRefusedFor,\n\trecordTerminalRejections,\n\tregisterLocalNode,\n\tsaveAdoptionSchedule,\n\tseedTerminalRejectionsOnce,\n\tsetLocalNodePrincipal,\n} from '../sync/local-sync-records'\nimport type { ClockRebaseResult } from '../sync/rebase-unsynced-operations'\nimport { rebaseUnsyncedOperationsInLog } from '../sync/rebase-unsynced-operations'\nimport { renumberOperationRow, rewriteDependentsInTx } from '../sync/rehash-operation'\nimport type { ResequenceResult } from '../sync/rehash-operation'\nimport type { NodeRotationResult } from '../sync/rotate-node-id'\nimport { rotateUnsyncedOperationsInLog } from '../sync/rotate-node-id'\nimport type { UnappliedOperation } from '../sync/sync-durability'\nimport {\n\tloadAcceptedDownlinkScope,\n\tloadOwnAckedThrough,\n\tloadUnappliedOperations,\n\tremoveUnappliedOperations,\n\tsaveAcceptedDownlinkScope,\n\tsaveOwnAckedThrough,\n\tsaveUnappliedOperations,\n} from '../sync/sync-durability'\nimport {\n\tDELIVERY_WATERMARK_META_KEY,\n\tDELTA_CURSOR_META_KEY,\n\tNODE_TOKEN_META_KEY,\n\tcollectOperationsAheadOfServer,\n\tdeleteDeliveryWatermark,\n\tloadAllDeliveryWatermarks,\n\tloadAuthoritativeNodeIds,\n\tloadDeliveryWatermark,\n\tloadDeltaCursor,\n\tloadLastAckedServerVector,\n\tloadNodeToken,\n\tloadRevokedAuthoritativeNodeIds,\n\tmergeVersionVectors,\n\tnodeTokenKey,\n\tsaveAuthoritativeNodeIds,\n\tsaveDeliveryWatermark,\n\tsaveDeltaCursor,\n\tsaveLastAckedServerVector,\n\tsaveNodeToken,\n\tsaveRevokedAuthoritativeNodeIds,\n} from '../sync/sync-state'\nimport { TransactionContext } from '../transaction/transaction-context'\nimport type {\n\tApplyRemoteOptions,\n\tApplyResult,\n\tLocalMutationHandler,\n\tMaterializedRowSnapshot,\n\tMetaRow,\n\tOperationRow,\n\tRawCollectionRow,\n\tRowVersionState,\n\tStorageAdapter,\n\tStoreConfig,\n\tStoreIsolation,\n\tTransaction,\n\tVersionVectorRow,\n} from '../types'\nimport { dropLegacyIndexes } from './legacy-indexes'\nimport { acquireNodeLock, isNodeLockHeld, nodeLockName, tryAcquireNodeLock } from './node-lock'\nimport { relaxValueDomainConstraints } from './relax-constraints'\nimport { allocateNextSequenceInTransaction } from './sequence-allocator'\nimport {\n\tSEQ_CONFLICTS_TABLE,\n\tinsertConflictRow,\n\tisOperationLogged,\n\tloadRetainedConflictRows,\n\trepairSequenceUniqueness,\n} from './sequence-repair'\nimport { savePerTabNodeId } from './tab-node-id'\nimport { resolvePerTabNodeId } from './tab-node-id'\n\n/**\n * Store is the main orchestrator. It owns a schema, a storage adapter,\n * a clock, and a subscription manager. It creates Collection instances\n * for each schema collection, and provides the sync contract via\n * applyRemoteOperation and getOperationRange.\n *\n * @example\n * ```typescript\n * const store = new Store({ schema, adapter })\n * await store.open()\n * const todo = await store.collection('todos').insert({ title: 'Hello' })\n * await store.close()\n * ```\n */\n/** `_kora_meta` key: per-collection fold plan fingerprints the rows were folded with (RT-63). */\nconst FOLD_PLAN_META_KEY = 'fold_plan_fingerprints'\n/** `_kora_meta` key: a full resync was requested to settle row snapshots (RT-68). */\nconst SNAPSHOT_RESYNC_META_KEY = 'fold_snapshot_resync'\n/**\n * Node id of provisional side effects (RT-69). In the reserved `kora:` namespace: no\n * device authors under it, and its effects never enter the log or the upload queue.\n */\nconst PROVISIONAL_NODE_ID = 'kora:provisional'\n\n/** A node id this client must never author under (RT-61): Kora's reserved namespace. */\nexport class ReservedNodeIdError extends KoraError {\n\tconstructor(nodeId: string, source: string) {\n\t\tsuper(\n\t\t\t`Node id \"${nodeId}\" (${source}) is in Kora's reserved \"kora:\" namespace; devices never author under it.`,\n\t\t\t'RESERVED_NODE_ID',\n\t\t\t{ nodeId, source, fix: 'Configure a node id that does not start with \"kora:\".' },\n\t\t)\n\t\tthis.name = 'ReservedNodeIdError'\n\t}\n}\n\n/**\n * Per collection, the record ids that own quarantined log rows (RT-68); a\n * quarantined row whose record id cannot be read keeps its whole collection.\n */\nasync function loadQuarantinedRecords(adapter: StorageAdapter): Promise<KeptRecords> {\n\tconst records = new Map<string, Set<string>>()\n\tconst collections = new Set<string>()\n\tconst exists = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[LOG_QUARANTINE_TABLE],\n\t)\n\tif (exists.length === 0) return { records, collections }\n\tconst rows = await adapter.query<{ collection: string; row_json: string }>(\n\t\t`SELECT collection, row_json FROM ${LOG_QUARANTINE_TABLE}`,\n\t)\n\tfor (const row of rows) {\n\t\tlet recordId: unknown = null\n\t\ttry {\n\t\t\trecordId = (JSON.parse(row.row_json) as { record_id?: unknown }).record_id\n\t\t} catch {\n\t\t\trecordId = null\n\t\t}\n\t\tif (typeof recordId === 'string' && recordId.length > 0) {\n\t\t\tconst set = records.get(row.collection) ?? new Set<string>()\n\t\t\tset.add(recordId)\n\t\t\trecords.set(row.collection, set)\n\t\t} else {\n\t\t\tcollections.add(row.collection)\n\t\t}\n\t}\n\treturn { records, collections }\n}\n\n/** Collections whose stored fold states hold a field of another fold kind than the schema's. */\nasync function collectionsWithMismatchedStates(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<string[]> {\n\tconst out: string[] = []\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst rows = await adapter.query<{ state: string }>(\n\t\t\t`SELECT state FROM ${FOLD_STATE_TABLE} WHERE collection = ?`,\n\t\t\t[collection],\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tlet state: FoldState\n\t\t\ttry {\n\t\t\t\tstate = deserializeFoldState(row.state)\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (mismatchedFoldFields(state, schema).length > 0) {\n\t\t\t\tout.push(collection)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Make `nodeId` the database's node id (`_kora_meta.node_id`). The unkeyed legacy node\n * token belongs to the node id it replaces, so it moves to that node's own key first:\n * it must never be presented as the new node's token.\n */\nasync function moveDatabaseNodeId(tx: Transaction, nodeId: string): Promise<void> {\n\tconst meta = await tx.query<MetaRow>(\"SELECT value FROM _kora_meta WHERE key = 'node_id'\")\n\tconst previous = meta[0]?.value\n\tif (previous === nodeId) return\n\tconst legacy = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tNODE_TOKEN_META_KEY,\n\t])\n\tif (legacy[0] && previous) {\n\t\tawait tx.execute('INSERT OR IGNORE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tnodeTokenKey(previous),\n\t\t\tlegacy[0].value,\n\t\t])\n\t}\n\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [NODE_TOKEN_META_KEY])\n\tawait tx.execute(\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\", [nodeId])\n}\n\n/** Result of {@link Store.bindPrincipal} (RT-42). */\nexport interface PrincipalBinding {\n\t/** The node id local writes use from now on. */\n\tnodeId: string\n\t/** The node id in use before the call. */\n\tpreviousNodeId: string\n\t/** The store moved to another node id. */\n\tswitched: boolean\n\t/** The node id is pinned and belongs to another user: nothing may upload it now. */\n\tconflict: boolean\n}\n\nexport class Store implements OperationLog {\n\tprivate opened = false\n\tprivate nodeId = ''\n\tprivate sequenceNumber = 0\n\tprivate versionVector: VersionVector = createVersionVector()\n\tprivate clock: HybridLogicalClock | null = null\n\tprivate collections = new Map<string, Collection>()\n\tprivate subscriptionManager: SubscriptionManager\n\tprivate sequenceManager: SequenceManager | null = null\n\n\tprivate readonly schema: SchemaDefinition\n\tprivate readonly adapter: StorageAdapter\n\tprivate readonly configNodeId: string | undefined\n\tprivate readonly dbName: string\n\tprivate readonly isolation: StoreIsolation\n\tprivate readonly emitter: KoraEventEmitter | null\n\tprivate localMutationHandler: LocalMutationHandler | null\n\tprivate relationEnforcer: RelationEnforcer | null = null\n\tprivate causalTracker: CausalTracker | null = null\n\tprivate readonly secretKeyProvider: SecretKeyProvider | undefined\n\t/** Releases the per-tab node lock (RT-40); null when none is held. */\n\tprivate releaseNodeLock: (() => void) | null = null\n\t/** How rows are materialized ({@link StoreConfig.materialization}). */\n\tprivate readonly materialization: 'fold' | 'legacy'\n\t/** The W7 record fold; null under legacy materialization. */\n\tprivate readonly folder: RecordFolder | null\n\t/** True once every row of the database is a materialization of its fold state. */\n\tprivate foldActive = false\n\t/** Schema transforms applied at fold time (RT-84); never to stored operations. */\n\tprivate readonly operationTransforms: readonly OperationTransform[]\n\t/** Largest operation a local write may produce (RT-86); default in the write path. */\n\tprivate readonly maxOperationBytes: number | undefined\n\n\tconstructor(config: StoreConfig) {\n\t\tthis.materialization = config.materialization ?? 'fold'\n\t\tthis.operationTransforms = config.operationTransforms ?? []\n\t\tthis.maxOperationBytes = config.maxOperationBytes\n\t\tthis.folder =\n\t\t\tthis.materialization === 'fold'\n\t\t\t\t? new RecordFolder(config.schema, this.operationTransforms)\n\t\t\t\t: null\n\t\tthis.schema = config.schema\n\t\tthis.adapter = config.adapter\n\t\tthis.configNodeId = config.nodeId\n\t\tthis.dbName = config.dbName ?? 'kora-db'\n\t\tthis.isolation = config.isolation ?? 'shared'\n\t\tthis.emitter = config.emitter ?? null\n\t\tthis.localMutationHandler = config.localMutationHandler ?? null\n\t\tthis.secretKeyProvider = config.secretKeyProvider\n\t\tthis.subscriptionManager = new SubscriptionManager({\n\t\t\tonQuerySubscribed: config.onQuerySubscribed,\n\t\t\t// STORE-12: every subscription failure is observable (DevTools, app listeners).\n\t\t\tonQueryError: (failure) => {\n\t\t\t\tconst code =\n\t\t\t\t\tfailure.error instanceof KoraError ? failure.error.code : failure.error.name || 'Error'\n\t\t\t\tthis.emitter?.emit({\n\t\t\t\t\ttype: 'query:error',\n\t\t\t\t\tqueryId: failure.queryId,\n\t\t\t\t\tcollection: failure.collection,\n\t\t\t\t\tphase: failure.phase,\n\t\t\t\t\tcode,\n\t\t\t\t\tmessage: failure.error.message,\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Open the store: initialize the database, load or generate a node ID,\n\t * restore the sequence number and version vector, and create Collection instances.\n\t */\n\tasync open(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.adapter.open(this.schema)\n\t\t} catch (error) {\n\t\t\tconst ahead =\n\t\t\t\terror instanceof SchemaVersionAheadError\n\t\t\t\t\t? { stored: error.storedVersion, code: error.codeVersion }\n\t\t\t\t\t: parseSchemaAhead(error)\n\t\t\tif (ahead !== null) throw this.schemaAhead(ahead.stored)\n\t\t\tthrow error\n\t\t}\n\t\t// A database a newer build already migrated is refused before anything here writes\n\t\t// to it (RT-109). The DDL executors refuse it before their DDL; this also covers\n\t\t// adapters that restore their data after it (the IndexedDB fallback).\n\t\tconst stored = storedSchemaVersion(\n\t\t\tawait this.adapter.query<{ value: unknown }>(STORED_SCHEMA_VERSION_SQL),\n\t\t)\n\t\tif (stored > this.schema.version) {\n\t\t\tawait this.adapter.close().catch(() => undefined)\n\t\t\tthrow this.schemaAhead(stored)\n\t\t}\n\t\tawait this.adapter.execute(\n\t\t\t'CREATE TABLE IF NOT EXISTS _kora_scope_retractions (collection TEXT NOT NULL, record_id TEXT NOT NULL, PRIMARY KEY (collection, record_id))',\n\t\t)\n\t\tfor (const ddl of FOLD_TABLES_DDL) await this.adapter.execute(ddl)\n\t\tthis.foldActive = false\n\n\t\t// Tables created before beta.13 restate enum membership and requiredness as CHECK /\n\t\t// NOT NULL constraints that cannot evolve with the schema: rebuild them once without\n\t\t// (RT-101). Validation is the single authority for the value domain.\n\t\tawait relaxValueDomainConstraints(this.adapter, this.schema)\n\t\t// Indexes named under the old, colliding scheme are replaced (STORE-15).\n\t\tawait dropLegacyIndexes(this.adapter, this.schema)\n\n\t\t// Load or generate node ID\n\t\tthis.nodeId = await this.loadOrGenerateNodeId()\n\t\t// Every node id this database authors under is registered (RT-38, RT-40).\n\t\tawait registerLocalNode(this.adapter, this.nodeId)\n\n\t\t// Log integrity first (W8 step 0): repair rows an earlier release damaged and\n\t\t// quarantine the unrecoverable ones, before anything reads or folds the log.\n\t\tawait this.scanLog('quick')\n\n\t\t// (node_id, sequence_number) is unique in the operation log: repair any\n\t\t// duplicates an earlier version wrote, then enforce it with an index (W6).\n\t\tawait repairSequenceUniqueness(this.adapter, this.schema, this.nodeId)\n\t\t// The terminal rejections an earlier release kept only in the app's list become\n\t\t// durable markers (RT-36).\n\t\tawait seedTerminalRejectionsOnce(this.adapter)\n\t\t// Raw-string columns use the lossless stored-text codec (RT-65); rows written\n\t\t// before it get their U+FFFF re-encoded once, before anything reads them.\n\t\tawait ensureStoredTextCodec(this.adapter, this.schema)\n\t\tif (this.isolation === 'per-tab' && !this.configNodeId) {\n\t\t\t// A live tab holds its node's lock, so a later tab adopts the node's unsynced\n\t\t\t// writes only after this tab is gone (RT-40).\n\t\t\tthis.releaseNodeLock = acquireNodeLock(nodeLockName(this.dbName, this.nodeId))\n\t\t}\n\t\tthis.clock = new HybridLogicalClock(this.nodeId)\n\t\tthis.causalTracker = new CausalTracker()\n\n\t\t// The fold is active for writes as soon as the database's rows are known to be\n\t\t// fold materializations (W7); a pre-W7 database is re-materialized after its\n\t\t// schema migrations, whose backfills then write the legacy way.\n\t\tif (this.folder) {\n\t\t\tthis.folder.setAuthoritativeNodeIds((await loadAuthoritativeNodeIds(this.adapter)) ?? [])\n\t\t\tthis.foldActive =\n\t\t\t\t(await this.readMeta(FOLD_MATERIALIZATION_META_KEY)) === FOLD_MATERIALIZATION_CURRENT\n\t\t}\n\n\t\t// Run schema migrations if needed. Backfills write operations through the local\n\t\t// write path, so the node id and clock must exist first (STORE-13).\n\t\ttry {\n\t\t\t// Transforms that cannot read the stored log would fold those operations as\n\t\t\t// absent and erase them from their records: refuse to open instead (RT-103).\n\t\t\tawait this.assertTransformCoverage()\n\t\t\tawait this.runMigrationsIfNeeded()\n\t\t\tawait this.ensureLegacyBodiesCanonical()\n\t\t\tawait this.ensureMaterialization()\n\t\t} catch (error) {\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = null\n\t\t\tthrow error\n\t\t}\n\n\t\t// Initialize sequence manager\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\n\t\t// Load sequence number and version vector\n\t\tthis.sequenceNumber = await this.loadSequenceNumber()\n\t\tthis.versionVector = await this.loadVersionVector()\n\n\t\t// Create RelationEnforcer if the schema has relations.\n\t\t// The enforcer is shared across all Collection instances so that\n\t\t// cascading deletes can cross collection boundaries.\n\t\tconst hasRelations = Object.keys(this.schema.relations).length > 0\n\t\tthis.relationEnforcer = hasRelations ? new RelationEnforcer({ schema: this.schema }) : null\n\n\t\t// Create collection instances\n\t\tfor (const [name, definition] of Object.entries(this.schema.collections)) {\n\t\t\tconst col = new Collection(\n\t\t\t\tname,\n\t\t\t\tdefinition,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.adapter,\n\t\t\t\tthis.clock,\n\t\t\t\tthis.nodeId,\n\t\t\t\t(collectionName, operation) => this.publishLocalOperation(collectionName, operation),\n\t\t\t\tthis.relationEnforcer,\n\t\t\t\tthis.localMutationHandler,\n\t\t\t\tthis.causalTracker,\n\t\t\t\tthis.secretKeyProvider,\n\t\t\t\t(error) => this.reportStorageError(error),\n\t\t\t\t() => this.activeFold(),\n\t\t\t\tthis.maxOperationBytes,\n\t\t\t)\n\t\t\tthis.collections.set(name, col)\n\t\t}\n\n\t\tthis.opened = true\n\t}\n\n\t/**\n\t * Close the store: clear subscriptions and close the adapter.\n\t */\n\tasync close(): Promise<void> {\n\t\tthis.subscriptionManager.clear()\n\t\tthis.collections.clear()\n\t\tthis.opened = false\n\t\ttry {\n\t\t\tawait this.adapter.close()\n\t\t} finally {\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = null\n\t\t}\n\t}\n\n\t/**\n\t * Check the operation log (W8 step 0): every row must round-trip through the\n\t * canonical operation serializer. Rows an earlier release damaged in a recoverable\n\t * way (a JSON-encoded timestamp written by a beta.12 backup restore) are repaired;\n\t * unrecoverable rows move to the quarantine table, where no fold reads them. Also\n\t * reports sequence gaps in this database's own nodes (compaction, a lost tail).\n\t *\n\t * The store runs a quick variant (SQL prefilter) on every open. Rebuilding state from\n\t * the log must only run on a `clean` report.\n\t *\n\t * @param options - `repair: false` only reports; `mode: 'quick'` checks only the rows\n\t * a SQL prefilter flags (default `'full'`: every row)\n\t * @returns The integrity report; emits `store:log-integrity` when rows changed\n\t */\n\tasync verifyLogIntegrity(options?: {\n\t\trepair?: boolean\n\t\tmode?: 'full' | 'quick'\n\t}): Promise<LogIntegrityReport> {\n\t\tthis.ensureOpen()\n\t\treturn this.scanLog(options?.mode ?? 'full', options?.repair ?? true)\n\t}\n\n\tprivate async scanLog(mode: 'full' | 'quick', repair = true): Promise<LogIntegrityReport> {\n\t\tconst localNodeIds = (await listLocalNodes(this.adapter)).map((node) => node.nodeId)\n\t\tconst report = await scanLogIntegrity(this.adapter, this.schema, {\n\t\t\tmode,\n\t\t\trepair,\n\t\t\tlocalNodeIds,\n\t\t})\n\t\tif (repair && (report.repaired.length > 0 || report.newlyQuarantined.length > 0)) {\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:log-integrity',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\trepaired: report.repaired.length,\n\t\t\t\tquarantined: report.newlyQuarantined.length,\n\t\t\t\tgaps: report.gaps.length,\n\t\t\t\tclean: report.clean,\n\t\t\t\tmessage: `Operation log of \"${this.dbName}\": ${report.repaired.length} row(s) repaired, ${report.newlyQuarantined.length} row(s) quarantined (${LOG_QUARANTINE_TABLE}).`,\n\t\t\t})\n\t\t}\n\t\treturn report\n\t}\n\n\t/**\n\t * Get a Collection instance for CRUD operations.\n\t * @throws {StoreNotOpenError} If the store is not open\n\t * @throws {Error} If the collection name is not in the schema\n\t */\n\tcollection(name: string): CollectionAccessor {\n\t\tthis.ensureOpen()\n\t\tconst col = this.collections.get(name)\n\t\tif (!col) {\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown collection \"${name}\". Available: ${[...this.collections.keys()].join(', ')}`,\n\t\t\t)\n\t\t}\n\n\t\tconst definition = this.schema.collections[name]\n\t\tif (!definition) {\n\t\t\tthrow new Error(`Collection definition not found for \"${name}\"`)\n\t\t}\n\n\t\treturn {\n\t\t\tinsert: (data: Record<string, unknown>) => col.insert(data),\n\t\t\tfindById: (id: string) => col.findById(id),\n\t\t\tupdate: (id: string, data: Record<string, unknown>) => col.update(id, data),\n\t\t\tdelete: (id: string) => col.delete(id),\n\t\t\twhere: (conditions) =>\n\t\t\t\tnew QueryBuilder(\n\t\t\t\t\tname,\n\t\t\t\t\tdefinition,\n\t\t\t\t\tthis.adapter,\n\t\t\t\t\tthis.subscriptionManager,\n\t\t\t\t\tconditions,\n\t\t\t\t\tthis.schema,\n\t\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the current version vector.\n\t */\n\tgetVersionVector(): VersionVector {\n\t\tthis.ensureOpen()\n\t\treturn new Map(this.versionVector)\n\t}\n\n\t/**\n\t * Get the node ID for this store instance.\n\t */\n\t/**\n\t * Records the offset between server time and this device's clock\n\t * (serverTime - localTime), learned at sync handshake. Lets the store's HLC\n\t * validate remote timestamps correctly even when the local clock is wrong.\n\t */\n\tsetClockReferenceOffset(offsetMs: number): void {\n\t\tthis.clock?.setReferenceOffset(offsetMs)\n\t}\n\n\tgetNodeId(): string {\n\t\tthis.ensureOpen()\n\t\treturn this.nodeId\n\t}\n\n\t/** The schema transforms the fold applies (transforms at fold time, RT-84). */\n\tgetOperationTransforms(): readonly OperationTransform[] {\n\t\treturn this.operationTransforms\n\t}\n\n\t/**\n\t * Apply a remote operation received from sync.\n\t * Checks for duplicates, applies to the data table, persists the operation,\n\t * and updates the version vector.\n\t */\n\tasync applyRemoteOperation(\n\t\tstored: Operation,\n\t\toptions?: ApplyRemoteOptions,\n\t): Promise<ApplyResult> {\n\t\tthis.ensureOpen()\n\n\t\tconst collection = stored.collection\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) {\n\t\t\treturn 'skipped'\n\t\t}\n\t\tconst fold = this.activeFold()\n\t\tif (fold) {\n\t\t\t// The fold reads the operation through the schema transforms itself (RT-84).\n\t\t\treturn this.applyRemoteFolded(stored, fold, options)\n\t\t}\n\t\t// Legacy materialization writes rows directly: it materializes the operation as\n\t\t// this schema reads it, and logs the operation exactly as written (RT-84).\n\t\tconst view = operationSchemaView(stored, this.schema.version, this.operationTransforms)\n\t\tif (view === null) return 'skipped'\n\t\tconst op = view\n\n\t\t// Materialization may use overridden data/timestamp (authoritative merge\n\t\t// results), but the LOG below always stores the canonical operation:\n\t\t// operations are immutable and content-addressed, so merged values must\n\t\t// never be persisted under the original operation's id.\n\t\tconst materializeTimestamp = options?.materializeTimestamp ?? op.timestamp\n\t\tconst remoteVersion = serializeRowVersion(materializeTimestamp)\n\t\tconst wallTime = materializeTimestamp.wallTime\n\t\tconst materializeSource = options?.materializeData ?? op.data\n\t\t// Duration is reported to DevTools only; it never orders anything.\n\t\tconst startedAt = Date.now()\n\t\tconst outcome = { duplicate: false, revived: false }\n\n\t\t// Apply the operation to the data table (LWW-guarded; op log always appended below)\n\t\ttry {\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\t// Content-addressed dedup INSIDE the write transaction: two concurrent\n\t\t\t\t// deliveries of one operation serialize here, and the second sees the\n\t\t\t\t// first's row instead of failing on the primary key (STORE-15).\n\t\t\t\tif (await isOperationLogged(tx, collection, op.id)) {\n\t\t\t\t\toutcome.duplicate = true\n\t\t\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tif (retracted.length > 0) {\n\t\t\t\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 0 WHERE id = ?`, [\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t])\n\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t)\n\t\t\t\t\t\toutcome.revived = true\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Advance the local HLC; severe clock drift throws ClockDriftError (surfaced as sync:apply-failed).\n\t\t\t\tif (this.clock) {\n\t\t\t\t\t// A scope entry's newest field version can be later than its timestamp (the\n\t\t\t\t\t// record's creation, RT-27): the clock must move past every version it carries.\n\t\t\t\t\tthis.clock.receive(op.fieldVersions ? newestFieldVersion(op) : op.timestamp)\n\t\t\t\t}\n\n\t\t\t\t// Optimistic-concurrency guard: if the caller computed its data from a\n\t\t\t\t// snapshot, verify the row hasn't changed since. Throwing rolls the\n\t\t\t\t// whole transaction back (nothing written, op NOT logged) so the caller\n\t\t\t\t// can recompute against fresh state and retry.\n\t\t\t\tconst checkGuard = (row: RawCollectionRow | undefined): void => {\n\t\t\t\t\tconst guard = options?.guardRowState\n\t\t\t\t\tif (!guard) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst version = typeof row?._version === 'string' ? row._version : null\n\t\t\t\t\tconst fieldVersions =\n\t\t\t\t\t\ttypeof row?._field_versions === 'string' ? row._field_versions : null\n\t\t\t\t\tif (version !== guard.version || fieldVersions !== guard.fieldVersions) {\n\t\t\t\t\t\tthrow new OptimisticLockError(collection, op.recordId)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (options?.logOnly) {\n\t\t\t\t\t// Append-only: the caller (after folding the record's log) determined\n\t\t\t\t\t// this op does not change the authoritative row. Persist it for future\n\t\t\t\t\t// folds but leave the row untouched. Fall through to op-log insert + VV.\n\t\t\t\t} else if (\n\t\t\t\t\top.type === 'insert' &&\n\t\t\t\t\top.data &&\n\t\t\t\t\top.fieldVersions &&\n\t\t\t\t\t!options?.materializeData &&\n\t\t\t\t\t!options?.forceMaterialize &&\n\t\t\t\t\t!options?.materializeTimestamp\n\t\t\t\t) {\n\t\t\t\t\t// Server scope-entry insert (RT-27): every field carries its own version.\n\t\t\t\t\tawait this.applyFieldVersionedInsert(tx, op, definition, op.data, checkGuard)\n\t\t\t\t} else if (op.type === 'insert' && materializeSource) {\n\t\t\t\t\tconst serializedData = serializeRecord(materializeSource, definition.fields)\n\t\t\t\t\tconst existing = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT _updated_at, _version, _field_versions, _deleted FROM ${collection} WHERE id = ?`,\n\t\t\t\t\t\t[op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst row = existing[0]\n\t\t\t\t\tcheckGuard(row)\n\n\t\t\t\t\tif (!row) {\n\t\t\t\t\t\tconst record: Record<string, unknown> = {\n\t\t\t\t\t\t\tid: op.recordId,\n\t\t\t\t\t\t\t...serializedData,\n\t\t\t\t\t\t\t_created_at: wallTime,\n\t\t\t\t\t\t\t_updated_at: wallTime,\n\t\t\t\t\t\t\t_version: remoteVersion,\n\t\t\t\t\t\t\t// Stamp every inserted field so per-field LWW has a real baseline.\n\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(\n\t\t\t\t\t\t\t\tfieldVersionsForFields(Object.keys(serializedData), remoteVersion),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst insertQuery = buildInsertQuery(collection, record)\n\t\t\t\t\t\tawait tx.execute(insertQuery.sql, insertQuery.params)\n\n\t\t\t\t\t\t// Catch up on operations delivered BEFORE this insert (transports may\n\t\t\t\t\t\t// reorder): any update/delete already logged for this record was\n\t\t\t\t\t\t// applied while no row existed, so it never materialized. The row is\n\t\t\t\t\t\t// a fold of the log — fold the orphans now, in timestamp order,\n\t\t\t\t\t\t// inside this same transaction. Per-field LWW makes the result\n\t\t\t\t\t\t// identical to what an in-order device computed.\n\t\t\t\t\t\tawait this.foldOrphanedOperations(tx, collection, definition, op.recordId, op)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\trow._deleted === 1 &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait tx.query<{ record_id: string }>(\n\t\t\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\t// The row is hidden by a scope retraction (a view change, not a domain\n\t\t\t\t\t\t// delete) and the record is entering the scope again, typically through\n\t\t\t\t\t\t// a server scope-entry insert (RT-19). Show it again and merge per field,\n\t\t\t\t\t\t// exactly like an insert collision on a live row: fields this device\n\t\t\t\t\t\t// holds newer versions of are kept.\n\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\tparseFieldVersions(row._field_versions),\n\t\t\t\t\t\t\tObject.keys(serializedData),\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\ttypeof row._version === 'string' ? row._version : undefined,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t_deleted: 0,\n\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// `_created_at` is left alone: the record was created long before it\n\t\t\t\t\t\t// re-entered this device's view.\n\t\t\t\t\t\tconst reactivate = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tawait tx.execute(reactivate.sql, reactivate.params)\n\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (row._deleted === 1) {\n\t\t\t\t\t\t// Insert vs tombstone: a strictly newer insert resurrects the record\n\t\t\t\t\t\t// with its full field set; an older one is stale (delete wins).\n\t\t\t\t\t\tif (isIncomingNewerThanRow(materializeTimestamp, row)) {\n\t\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t...serializedData,\n\t\t\t\t\t\t\t\t_deleted: 0,\n\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(\n\t\t\t\t\t\t\t\t\tfieldVersionsForFields(Object.keys(serializedData), remoteVersion),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst upsert = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t\t{ maxCreatedAt: wallTime },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tawait tx.execute(upsert.sql, upsert.params)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Insert collision on a LIVE row (relayed insert racing a local one,\n\t\t\t\t\t\t// or an insert-vs-insert merge). A plain INSERT would violate the\n\t\t\t\t\t\t// primary key; resolve per-field instead, exactly like an update, so\n\t\t\t\t\t\t// every node converges no matter which insert (or interleaved\n\t\t\t\t\t\t// update) it saw first. `_created_at` converges to the max insert\n\t\t\t\t\t\t// wall time seen, applied even when every field loses.\n\t\t\t\t\t\tconst currentVersions = parseFieldVersions(row._field_versions)\n\t\t\t\t\t\tconst rowVersion = typeof row._version === 'string' ? row._version : undefined\n\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {}\n\t\t\t\t\t\tlet fieldVersionsJson: string\n\t\t\t\t\t\tif (options?.forceMaterialize) {\n\t\t\t\t\t\t\t// Authoritative merged insert: every field is written.\n\t\t\t\t\t\t\tconst merged = { ...currentVersions }\n\t\t\t\t\t\t\tfor (const field of Object.keys(serializedData)) {\n\t\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t\t\tmerged[field] = remoteVersion\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfieldVersionsJson = serializeFieldVersions(merged)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\t\tcurrentVersions,\n\t\t\t\t\t\t\t\tObject.keys(serializedData),\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\trowVersion,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfieldVersionsJson = serializeFieldVersions(merged)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst upsert = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t{ ...fieldChanges, _field_versions: fieldVersionsJson },\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t{ maxCreatedAt: wallTime },\n\t\t\t\t\t\t)\n\t\t\t\t\t\tawait tx.execute(upsert.sql, upsert.params)\n\t\t\t\t\t}\n\t\t\t\t} else if (op.type === 'update' && materializeSource) {\n\t\t\t\t\tconst serializedChanges = serializeRecord(materializeSource, definition.fields)\n\t\t\t\t\tconst changedFields = Object.keys(serializedChanges)\n\n\t\t\t\t\t// Read the current per-field versions INSIDE the transaction so the\n\t\t\t\t\t// resolve-then-write is atomic with respect to any concurrent local\n\t\t\t\t\t// mutation — this is what prevents a relayed remote op from clobbering\n\t\t\t\t\t// a newer local edit that lands between the read and the write.\n\t\t\t\t\tconst currentRows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst currentRow = currentRows[0]\n\t\t\t\t\tcheckGuard(currentRow)\n\n\t\t\t\t\tif (currentRow) {\n\t\t\t\t\t\tconst currentVersions = parseFieldVersions(currentRow._field_versions)\n\t\t\t\t\t\tconst rowVersion =\n\t\t\t\t\t\t\ttypeof currentRow._version === 'string' ? currentRow._version : undefined\n\n\t\t\t\t\t\tif (options?.forceMaterialize) {\n\t\t\t\t\t\t\t// Authoritative merged result (richtext / add-wins-set / constraint\n\t\t\t\t\t\t\t// resolution computed by the merge engine): write every changed\n\t\t\t\t\t\t\t// field and stamp its per-field version to this op's version, while\n\t\t\t\t\t\t\t// advancing the row watermark monotonically.\n\t\t\t\t\t\t\tconst merged = { ...currentVersions }\n\t\t\t\t\t\t\tfor (const field of changedFields) {\n\t\t\t\t\t\t\t\tmerged[field] = remoteVersion\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t...serializedChanges,\n\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\tfieldChanges._deleted = 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst forceQuery = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tawait tx.execute(forceQuery.sql, forceQuery.params)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Deterministic field-level LWW: write only the fields this op\n\t\t\t\t\t\t\t// wins (strictly newer than the field's stored version). Same\n\t\t\t\t\t\t\t// result on every node regardless of arrival order.\n\t\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\t\tcurrentVersions,\n\t\t\t\t\t\t\t\tchangedFields,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\trowVersion,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tif (winners.length > 0 || options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\tconst winningChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\t\t\twinningChanges[field] = serializedChanges[field]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\t\twinningChanges._deleted = 0\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst forceQuery = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\t\twinningChanges,\n\t\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tawait tx.execute(forceQuery.sql, forceQuery.params)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// currentRow absent: nothing materialized to update (insert not yet\n\t\t\t\t\t// applied, or hard-absent). The op is still appended to the log below;\n\t\t\t\t\t// the pipeline handles tombstone reactivation separately.\n\t\t\t\t} else if (op.type === 'delete') {\n\t\t\t\t\tconst deleteQuery = buildLwwSoftDeleteQuery(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\twallTime,\n\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t)\n\t\t\t\t\tawait tx.execute(deleteQuery.sql, deleteQuery.params)\n\t\t\t\t}\n\n\t\t\t\t// Persist the operation\n\t\t\t\tawait this.appendRemoteOperationRow(tx, stored)\n\n\t\t\t\t// Version vector: MAX with the stored value, never a value computed outside\n\t\t\t\t// this transaction (another tab may have advanced it). The in-memory\n\t\t\t\t// vector is updated only after commit.\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t\t\t)\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.reportStorageError(error)\n\t\t\tthrow error\n\t\t}\n\n\t\t// Committed. A duplicate still advances this runtime's vector and refreshes\n\t\t// its queries: another tab sharing the database may have applied the\n\t\t// operation first, and this tab must not stay blind to it (STORE-10).\n\t\tthis.recordOperationSequence(op)\n\t\tif (outcome.duplicate) {\n\t\t\tif (outcome.revived) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t} else {\n\t\t\t\tthis.subscriptionManager.notify(collection, op)\n\t\t\t}\n\t\t\treturn 'duplicate'\n\t\t}\n\n\t\tthis.subscriptionManager.notify(collection, op)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'operation:applied',\n\t\t\toperation: op,\n\t\t\tduration: Date.now() - startedAt,\n\t\t})\n\n\t\treturn 'applied'\n\t}\n\n\t/**\n\t * W7 remote apply: append the operation, then merge it into its record's fold\n\t * state, which re-materializes the row, all in one write transaction. There is no\n\t * read-decide-write race to guard: the state is read and written inside the\n\t * transaction, and the merge does not depend on the order operations arrive in.\n\t */\n\tprivate async applyRemoteFolded(\n\t\top: Operation,\n\t\tfold: RecordFolder,\n\t\toptions: ApplyRemoteOptions | undefined,\n\t): Promise<ApplyResult> {\n\t\tconst collection = op.collection\n\t\tconst startedAt = Date.now()\n\t\tconst outcome = { duplicate: false, revived: false, traces: [] as MergeTrace[] }\n\t\ttry {\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tif ((await isOperationLogged(tx, collection, op.id)) || (await isCompacted(tx, op))) {\n\t\t\t\t\toutcome.duplicate = true\n\t\t\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tif (retracted.length > 0) {\n\t\t\t\t\t\t// The record re-enters the scope: show it again with every field of\n\t\t\t\t\t\t// its state (writes merged while it was hidden included).\n\t\t\t\t\t\tconst state = await fold.loadState(tx, collection, op.recordId)\n\t\t\t\t\t\tif (state) {\n\t\t\t\t\t\t\tawait fold.materializeRow(tx, state, 'all', { clearRetraction: true })\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutcome.revived = true\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (this.clock) {\n\t\t\t\t\t// A scope entry's newest field version can be later than its timestamp (the\n\t\t\t\t\t// record's creation, RT-27): the clock must move past every version it carries.\n\t\t\t\t\tthis.clock.receive(op.fieldVersions ? newestFieldVersion(op) : op.timestamp)\n\t\t\t\t}\n\t\t\t\tawait this.appendRemoteOperationRow(tx, op)\n\t\t\t\tconst applied = await fold.applyInTx(tx, op, 'remote')\n\t\t\t\toutcome.traces = applied.traces\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t\t\t)\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.reportStorageError(error)\n\t\t\tthrow error\n\t\t}\n\n\t\tthis.recordOperationSequence(op)\n\t\tif (outcome.duplicate) {\n\t\t\tif (outcome.revived) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t} else {\n\t\t\t\tthis.subscriptionManager.notify(collection, op)\n\t\t\t}\n\t\t\treturn 'duplicate'\n\t\t}\n\t\tthis.subscriptionManager.notify(collection, op)\n\t\tthis.emitMergeTraces(op, outcome.traces)\n\t\toptions?.onMergeTraces?.(outcome.traces)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'operation:applied',\n\t\t\toperation: op,\n\t\t\tduration: Date.now() - startedAt,\n\t\t})\n\t\treturn 'applied'\n\t}\n\n\t/** DevTools: every fold decision that was a conflict, plus one completion per merge. */\n\tprivate emitMergeTraces(op: Operation, traces: MergeTrace[]): void {\n\t\tif (!this.emitter || traces.length === 0) return\n\t\tconst first = traces[0] as MergeTrace\n\t\tthis.emitter.emit({ type: 'merge:started', operationA: first.operationA, operationB: op })\n\t\tfor (const trace of traces) this.emitter.emit({ type: 'merge:conflict', trace })\n\t\tthis.emitter.emit({ type: 'merge:completed', trace: first })\n\t}\n\n\t/** The record fold, once the database's rows are fold materializations. */\n\tprivate activeFold(): RecordFolder | undefined {\n\t\treturn this.foldActive && this.folder ? this.folder : undefined\n\t}\n\n\t/**\n\t * The record's W7 fold state (null under legacy materialization or when the\n\t * record has none). For DevTools, tests and the server-comparison harness.\n\t */\n\tasync getFoldState(collection: string, recordId: string): Promise<FoldState | null> {\n\t\tthis.ensureOpen()\n\t\tconst fold = this.activeFold()\n\t\tif (!fold) return null\n\t\tlet state: FoldState | null = null\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tstate = await fold.loadState(tx, collection, recordId)\n\t\t})\n\t\treturn state\n\t}\n\n\t/** Whether rows are materialized by the W7 fold (false under `materialization: 'legacy'`). */\n\tisFoldMaterialized(): boolean {\n\t\treturn this.activeFold() !== undefined\n\t}\n\n\tprivate async readMeta(key: string): Promise<string | null> {\n\t\tconst rows = await this.adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tkey,\n\t\t])\n\t\treturn rows[0]?.value ?? null\n\t}\n\n\tprivate async writeMeta(key: string, value: string): Promise<void> {\n\t\tawait this.adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tkey,\n\t\t\tvalue,\n\t\t])\n\t}\n\n\t/**\n\t * Write every genuine beta.12 clear of the op log into its logged body, once per\n\t * database (RT-83, RT-85): the fold folds bodies as written, so the clear must be in\n\t * the body. Records already materialized by the fold are re-folded.\n\t */\n\tprivate async ensureLegacyBodiesCanonical(): Promise<void> {\n\t\tconst folder = this.folder\n\t\tif (!folder) return\n\t\tif ((await this.readMeta(LEGACY_BODIES_META_KEY)) !== null) return\n\t\tconst rewritten = await canonicalizeLegacyLogBodies(this.adapter, this.schema, this.nodeId)\n\t\tif (rewritten.length > 0 && this.foldActive) {\n\t\t\tconst seen = new Set<string>()\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tfor (const { collection, recordId } of rewritten) {\n\t\t\t\t\tconst key = `${collection}\\u0000${recordId}`\n\t\t\t\t\tif (seen.has(key)) continue\n\t\t\t\t\tseen.add(key)\n\t\t\t\t\tawait folder.refoldInTx(tx, collection, recordId)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tawait this.writeMeta(LEGACY_BODIES_META_KEY, String(rewritten.length))\n\t}\n\n\t/**\n\t * Make every row a materialization of its record's fold state (W7), once per\n\t * database and fold-state version. Runs after the W8 log-integrity scan: a\n\t * clean log is rebuilt with the fold; an incomplete (compacted) log rebuilds on\n\t * top of the rows as base snapshots; a log with quarantined rows is never\n\t * rebuilt from (rows are kept and become base snapshots), and\n\t * `store:rematerialized` reports which happened.\n\t */\n\tprivate async ensureMaterialization(forceSnapshot = false): Promise<void> {\n\t\tconst current = await this.readMeta(FOLD_MATERIALIZATION_META_KEY)\n\t\tif (!this.folder) {\n\t\t\tif (current !== FOLD_MATERIALIZATION_LEGACY) {\n\t\t\t\tawait this.writeMeta(FOLD_MATERIALIZATION_META_KEY, FOLD_MATERIALIZATION_LEGACY)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (current === FOLD_MATERIALIZATION_CURRENT) {\n\t\t\tthis.foldActive = true\n\t\t\tawait this.ensureFoldPlan()\n\t\t\treturn\n\t\t}\n\t\tconst report = await this.scanLog('full')\n\t\t// Only the records that own a quarantined row are kept as they are (RT-68); the\n\t\t// rest are rebuilt from a log that is complete for them unless it was compacted\n\t\t// or has holes.\n\t\tconst kept = await loadQuarantinedRecords(this.adapter)\n\t\t// A hole in an own node's sequence that a quarantined row explains belongs to\n\t\t// that row's record (kept above), not to the whole log.\n\t\tconst quarantinedSeqs = new Set(\n\t\t\treport.quarantined.map((row) => `${row.nodeId ?? ''}\\u0000${row.sequenceNumber ?? ''}`),\n\t\t)\n\t\tconst unexplainedGaps = report.gaps.filter((gap) => {\n\t\t\tfor (let s = gap.from; s <= gap.to; s++) {\n\t\t\t\tif (!quarantinedSeqs.has(`${gap.nodeId}\\u0000${s}`)) return true\n\t\t\t}\n\t\t\treturn false\n\t\t})\n\t\tconst mode: Exclude<RematerializationMode, 'kept'> =\n\t\t\t!forceSnapshot && unexplainedGaps.length === 0 && report.compactedAt === null\n\t\t\t\t? 'log'\n\t\t\t\t: 'snapshot+log'\n\t\tconst result = await rematerializeDatabase(this.adapter, this.schema, this.folder, mode, kept)\n\t\tawait this.writeMeta(FOLD_MATERIALIZATION_META_KEY, FOLD_MATERIALIZATION_CURRENT)\n\t\tawait this.writeMeta(\n\t\t\tFOLD_PLAN_META_KEY,\n\t\t\tJSON.stringify(foldPlanFingerprints(this.schema, this.operationTransforms)),\n\t\t)\n\t\tthis.foldActive = true\n\t\tif (result.snapshots > 0) await this.requestSnapshotResync()\n\t\tif (result.changedRows > 0) {\n\t\t\t// Other tabs on this database hear about it once the bus is wired (RT-98).\n\t\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t}\n\t\t}\n\t\tif (result.records > 0) {\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:rematerialized',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\tmode: result.mode,\n\t\t\t\trecords: result.records,\n\t\t\t\tchangedRows: result.changedRows,\n\t\t\t\tmessage:\n\t\t\t\t\tresult.mode === 'kept'\n\t\t\t\t\t\t? `Operation log of \"${this.dbName}\" has quarantined rows: the records that own them were kept as they were (row snapshots); ${result.records} record(s) re-materialized, ${result.changedRows} row(s) changed.`\n\t\t\t\t\t\t: `Re-materialized ${result.records} record(s) of \"${this.dbName}\" with the per-field fold (${result.mode}); ${result.changedRows} row(s) changed.`,\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Refuse to open when a schema version in the local operation log has no transform\n\t * path to the current schema (RT-103). Operations of a NEWER schema (authored by an\n\t * upgraded peer) are not checked: they are kept aside until this device upgrades.\n\t */\n\tprivate async assertTransformCoverage(): Promise<void> {\n\t\tconst transforms = this.operationTransforms\n\t\tif (transforms === undefined || transforms.length === 0) return\n\t\tconst versions = new Set<number>()\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<{ v: number }>(\n\t\t\t\t`SELECT DISTINCT schema_version AS v FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst version = Number(row.v)\n\t\t\t\tif (version < this.schema.version) versions.add(version)\n\t\t\t}\n\t\t}\n\t\tassertOperationTransformCoverage(\n\t\t\tversions,\n\t\t\tthis.schema.version,\n\t\t\ttransforms,\n\t\t\t`local database \"${this.dbName}\"`,\n\t\t)\n\t}\n\n\t/**\n\t * Re-fold the records of every collection whose fold plan changed since the rows\n\t * were materialized (RT-63): a field that became `merge('counter')`, an array that\n\t * became append-only, a new or edited resolver. Their stored states hold fields of\n\t * the old kind, which the fold refuses (`FoldStateError`). Each record is rebuilt\n\t * from its log with the new plan; compacted bases and row snapshots are adapted\n\t * (a re-planned field restarts from its materialized value at its version). The\n\t * client's equivalent of the server stores' `fold_plan_fingerprint`.\n\t */\n\tprivate async ensureFoldPlan(): Promise<void> {\n\t\tconst folder = this.folder\n\t\tif (!folder) return\n\t\tconst current = foldPlanFingerprints(this.schema, this.operationTransforms)\n\t\tconst storedRaw = await this.readMeta(FOLD_PLAN_META_KEY)\n\t\tlet changed: string[]\n\t\tif (storedRaw === null) {\n\t\t\t// Materialized before the fingerprint was recorded: re-fold the collections\n\t\t\t// whose stored states actually hold a field of another kind.\n\t\t\tchanged = await collectionsWithMismatchedStates(this.adapter, this.schema)\n\t\t} else {\n\t\t\tlet stored: Record<string, unknown> = {}\n\t\t\ttry {\n\t\t\t\tstored = JSON.parse(storedRaw) as Record<string, unknown>\n\t\t\t} catch {\n\t\t\t\tstored = {}\n\t\t\t}\n\t\t\tchanged = Object.keys(current).filter((name) => stored[name] !== current[name])\n\t\t}\n\t\tif (changed.length > 0) {\n\t\t\tconst result = await rematerializeDatabase(\n\t\t\t\tthis.adapter,\n\t\t\t\tthis.schema,\n\t\t\t\tfolder,\n\t\t\t\t'log',\n\t\t\t\tundefined,\n\t\t\t\tchanged,\n\t\t\t)\n\t\t\tif (result.snapshots > 0) await this.requestSnapshotResync()\n\t\t\tfor (const collection of changed) this.subscriptionManager.invalidate(collection)\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:rematerialized',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\tmode: result.mode,\n\t\t\t\trecords: result.records,\n\t\t\t\tchangedRows: result.changedRows,\n\t\t\t\tmessage: `The fold plan of ${changed.map((name) => `\"${name}\"`).join(', ')} changed (schema): re-folded ${result.records} record(s) of \"${this.dbName}\"; ${result.changedRows} row(s) changed.`,\n\t\t\t})\n\t\t}\n\t\tawait this.writeMeta(FOLD_PLAN_META_KEY, JSON.stringify(current))\n\t}\n\n\t/**\n\t * Row snapshots were created (RT-68): ask the sync server for a full resync (the\n\t * delivery watermarks restart at 0, as after a restore), so each such record gets\n\t * its complete history back; {@link settleSnapshotRecords} then drops the\n\t * snapshots once the resync has caught up.\n\t */\n\tprivate async requestSnapshotResync(): Promise<void> {\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tawait tx.execute('UPDATE _kora_meta SET value = ? WHERE key = ? OR key LIKE ?', [\n\t\t\t\t'0',\n\t\t\t\tDELIVERY_WATERMARK_META_KEY,\n\t\t\t\t`${DELIVERY_WATERMARK_META_KEY}:%`,\n\t\t\t])\n\t\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tSNAPSHOT_RESYNC_META_KEY,\n\t\t\t\t'pending',\n\t\t\t])\n\t\t})\n\t}\n\n\t/**\n\t * Records whose state still folds against a row snapshot (approximate: a late\n\t * concurrent write older than a field's version is not folded, RT-68).\n\t */\n\tasync getSnapshotRecords(): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.folder\n\t\tif (!folder) return []\n\t\tlet out: Array<{ collection: string; recordId: string }> = []\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tout = await folder.listSnapshotRecords(tx)\n\t\t})\n\t\treturn out\n\t}\n\n\t/**\n\t * Called by sync when a delivery stream has caught up (its final batch fully\n\t * applied). After the full resync {@link requestSnapshotResync} asked for, every\n\t * row-snapshot record whose insert is back in the log is re-folded from its\n\t * complete history and stops being approximate (RT-68). Also retires the\n\t * provisional cascades of remote deletes (RT-69): the server's own copies were\n\t * delivered by now, and any it did not derive must not stay applied locally.\n\t *\n\t * With `provisionalOnly` only the provisional cascades are retired (RT-93: a stream\n\t * batch from a server that derives no cascades, which is not the end of a resync).\n\t *\n\t * @param options - `provisionalOnly`: leave row snapshots for the next catch-up\n\t * @returns How many snapshots were dropped\n\t */\n\tasync settleAfterCatchUp(options: { provisionalOnly?: boolean } = {}): Promise<number> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.activeFold()\n\t\tif (!folder) return 0\n\t\tconst pending =\n\t\t\toptions.provisionalOnly !== true &&\n\t\t\t(await this.readMeta(SNAPSHOT_RESYNC_META_KEY)) === 'pending'\n\t\tlet settled = 0\n\t\tconst touched = new Set<string>()\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const { collection, recordId } of await folder.listProvisionalRecords(tx)) {\n\t\t\t\tawait folder.deleteProvisional(tx, collection, recordId, null)\n\t\t\t\tawait folder.refoldInTx(tx, collection, recordId)\n\t\t\t\ttouched.add(collection)\n\t\t\t}\n\t\t\tif (pending) {\n\t\t\t\tfor (const { collection, recordId } of await folder.listSnapshotRecords(tx)) {\n\t\t\t\t\tif (await folder.settleSnapshotInTx(tx, collection, recordId)) {\n\t\t\t\t\t\tsettled += 1\n\t\t\t\t\t\ttouched.add(collection)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [SNAPSHOT_RESYNC_META_KEY])\n\t\t\t}\n\t\t})\n\t\tfor (const collection of touched) this.subscriptionManager.invalidate(collection)\n\t\treturn settled\n\t}\n\n\t/**\n\t * Apply the cascades / set-nulls of a REMOTE delete as local-only provisional\n\t * effects (RT-69): folded into the children like operations, but never logged,\n\t * sequenced or queued for upload. The server derives and relays its own copy;\n\t * when it arrives (same parent, same record) the provisional effect is retired.\n\t *\n\t * @param parent - The remote delete\n\t * @param effects - Its side effects, as the referential check derived them\n\t */\n\tasync applyProvisionalSideEffects(\n\t\tparent: Operation,\n\t\teffects: ReadonlyArray<{\n\t\t\ttype: 'delete' | 'update'\n\t\t\tcollection: string\n\t\t\trecordId: string\n\t\t\tdata: Record<string, unknown> | null\n\t\t\tpreviousData: Record<string, unknown> | null\n\t\t\truleId: string\n\t\t}>,\n\t): Promise<number> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.activeFold()\n\t\tif (!folder || effects.length === 0) return 0\n\t\tconst touched = new Set<string>()\n\t\tlet applied = 0\n\t\t// Stamped right after the parent (its HLC, next logical ticks), exactly like the\n\t\t// server's copy, so a write to the child later than the delete still wins.\n\t\tconst clock = new HybridLogicalClock(PROVISIONAL_NODE_ID, {\n\t\t\tnow: () => parent.timestamp.wallTime,\n\t\t})\n\t\tclock.advanceTo(parent.timestamp)\n\t\tconst built: Operation[] = []\n\t\tfor (const effect of effects) {\n\t\t\tif (!this.schema.collections[effect.collection]) continue\n\t\t\tconst op: Operation = {\n\t\t\t\tid: await deriveSideEffectOpId(parent.id, `provisional/${effect.ruleId}`, effect.recordId),\n\t\t\t\tnodeId: PROVISIONAL_NODE_ID,\n\t\t\t\ttype: effect.type,\n\t\t\t\tcollection: effect.collection,\n\t\t\t\trecordId: effect.recordId,\n\t\t\t\tdata: effect.type === 'delete' ? null : effect.data,\n\t\t\t\tpreviousData: effect.type === 'delete' ? null : effect.previousData,\n\t\t\t\ttimestamp: clock.now(),\n\t\t\t\tsequenceNumber: 0,\n\t\t\t\tcausalDeps: [parent.id],\n\t\t\t\tschemaVersion: this.schema.version,\n\t\t\t}\n\t\t\tbuilt.push(op)\n\t\t}\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const op of built) {\n\t\t\t\tawait folder.applyProvisionalInTx(tx, op, parent.id)\n\t\t\t\ttouched.add(op.collection)\n\t\t\t\tapplied += 1\n\t\t\t}\n\t\t})\n\t\tfor (const collection of touched) this.subscriptionManager.invalidate(collection)\n\t\treturn applied\n\t}\n\n\t/**\n\t * Node ids whose writes win `merge('server-authoritative')` fields (the server's,\n\t * from the sync handshake). Every `kora:server:` id is authoritative by prefix, so\n\t * only explicit ids (legacy server node ids, configured extras) are kept: the device\n\t * persists the UNION of every explicit id it has learned and never drops one (RT-75).\n\t * Handshakes differ per server instance (each lists what it knows), so a list that\n\t * omits an id is not a revocation.\n\t *\n\t * Revocation is explicit (RT-81): ids a handshake lists in `revokedAuthoritativeNodeIds`\n\t * are removed from the union, persisted as revoked, and never learned again. Records\n\t * of collections with such fields are re-folded only when the explicit set changes\n\t * (grows, or loses a revoked id).\n\t *\n\t * @param nodeIds - The server's authoritative node ids (one handshake's list)\n\t * @param revokedNodeIds - Explicit ids the server revoked (one handshake's list)\n\t */\n\tasync setAuthoritativeNodeIds(\n\t\tnodeIds: readonly string[],\n\t\trevokedNodeIds: readonly string[] = [],\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.folder\n\t\tconst persisted = await loadAuthoritativeNodeIds(this.adapter)\n\t\tconst persistedRevoked = await loadRevokedAuthoritativeNodeIds(this.adapter)\n\t\tconst revoked = new Set(\n\t\t\t[...persistedRevoked, ...revokedNodeIds].filter((id) => !isServerNodeId(id)),\n\t\t)\n\t\tif (revoked.size > persistedRevoked.length) {\n\t\t\tawait saveRevokedAuthoritativeNodeIds(this.adapter, [...revoked].sort())\n\t\t}\n\t\tconst previous = new Set(\n\t\t\t[...(persisted ?? []), ...(folder ? folder.getAuthoritativeNodeIds() : [])].filter(\n\t\t\t\t(id) => !isServerNodeId(id),\n\t\t\t),\n\t\t)\n\t\tconst known = new Set([...previous].filter((id) => !revoked.has(id)))\n\t\tconst dropped = previous.size - known.size\n\t\tconst learned = [...new Set(nodeIds)].filter(\n\t\t\t(id) => !isServerNodeId(id) && !known.has(id) && !revoked.has(id),\n\t\t)\n\t\tconst next = [...known, ...learned].sort()\n\t\tconst stored = persisted === null ? null : [...persisted].sort()\n\t\tif (stored === null || JSON.stringify(stored) !== JSON.stringify(next)) {\n\t\t\t// One persisted list (`sync_authoritative_node_ids`) serves the fold and the\n\t\t\t// sync engine's verification exemptions, so they can never disagree.\n\t\t\tawait saveAuthoritativeNodeIds(this.adapter, next)\n\t\t}\n\t\tif (!folder) return\n\t\tfolder.setAuthoritativeNodeIds(next)\n\t\tif (learned.length === 0 && dropped === 0) return\n\t\tconst fold = this.activeFold()\n\t\tif (!fold) return\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tif (!fold.hasAuthoritativeFields(collection)) continue\n\t\t\tconst ids = await this.adapter.query<{ record_id: string }>(\n\t\t\t\t`SELECT record_id FROM ${FOLD_STATE_TABLE} WHERE collection = ?`,\n\t\t\t\t[collection],\n\t\t\t)\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tfor (const { record_id } of ids) await fold.refoldInTx(tx, collection, record_id)\n\t\t\t})\n\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t}\n\t}\n\n\t/**\n\t * Re-fold the records of these operations from base + log (W7 exclusion: an\n\t * operation with a terminal-rejection marker is left out).\n\t */\n\tprivate async refoldRecordsOf(operationIds: readonly string[]): Promise<void> {\n\t\tconst fold = this.activeFold()\n\t\tif (!fold || operationIds.length === 0) return\n\t\tconst touched = new Map<string, Set<string>>()\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\tfor (let i = 0; i < operationIds.length; i += 500) {\n\t\t\t\tconst chunk = operationIds.slice(i, i + 500)\n\t\t\t\tconst rows = await this.adapter.query<{ record_id: string }>(\n\t\t\t\t\t`SELECT DISTINCT record_id FROM ${table} WHERE id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t\tchunk,\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst set = touched.get(collection) ?? new Set<string>()\n\t\t\t\t\tset.add(row.record_id)\n\t\t\t\t\ttouched.set(collection, set)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (touched.size === 0) return\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const [collection, records] of touched) {\n\t\t\t\tfor (const recordId of records) await fold.refoldInTx(tx, collection, recordId)\n\t\t\t}\n\t\t})\n\t\tfor (const [collection, records] of touched) {\n\t\t\tthis.subscriptionManager.invalidate(collection, [...records])\n\t\t}\n\t}\n\n\t/**\n\t * Append a remote operation to the log. If another operation of the same node\n\t * already holds its sequence number (a beta.12 device could produce such\n\t * pairs), the log keeps the existing row and this one is recorded in the\n\t * sequence-conflicts table, where dedup and record folds still see it.\n\t */\n\tprivate async appendRemoteOperationRow(tx: Transaction, op: Operation): Promise<void> {\n\t\tconst table = quoteIdent(`_kora_ops_${op.collection}`)\n\t\tconst holder = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${table} WHERE node_id = ? AND sequence_number = ?`,\n\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t)\n\t\tconst opRow = serializeOperation(op)\n\t\tif (holder.length > 0) {\n\t\t\tawait insertConflictRow(\n\t\t\t\ttx,\n\t\t\t\top.collection,\n\t\t\t\topRow,\n\t\t\t\t'remote-sequence-conflict',\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tDate.now(),\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst opInsert = buildInsertQuery(\n\t\t\t`_kora_ops_${op.collection}`,\n\t\t\topRow as unknown as Record<string, unknown>,\n\t\t)\n\t\tawait tx.execute(opInsert.sql, opInsert.params)\n\t}\n\n\t/**\n\t * Hide a record from this client's authorized materialized view. This writes no\n\t * replicated operation and therefore cannot be mistaken for a domain deletion.\n\t * The marker lets a later authoritative backfill reactivate the retained row.\n\t */\n\tasync applyScopeRetraction(collection: string, recordId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) return\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 1 WHERE id = ?`, [recordId])\n\t\t\tawait tx.execute(\n\t\t\t\t'INSERT OR REPLACE INTO _kora_scope_retractions (collection, record_id) VALUES (?, ?)',\n\t\t\t\t[collection, recordId],\n\t\t\t)\n\t\t})\n\t\tthis.subscriptionManager.invalidate(collection, [recordId])\n\t}\n\n\t/** Hide all live rows that no longer match a newly accepted server scope. */\n\tasync applyScopeNarrowing(\n\t\tscopes: Record<string, Record<string, unknown>>,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tthis.ensureOpen()\n\t\tconst retractions: Array<{ collection: string; recordId: string }> = []\n\t\tfor (const [collection, definition] of Object.entries(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE _deleted = 0`,\n\t\t\t)\n\t\t\tconst predicate = scopes[collection]\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst record = deserializeRecord(row, definition.fields)\n\t\t\t\tconst matches =\n\t\t\t\t\tpredicate !== undefined &&\n\t\t\t\t\tObject.entries(predicate).every(([field, expected]) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\texpected &&\n\t\t\t\t\t\t\ttypeof expected === 'object' &&\n\t\t\t\t\t\t\t!Array.isArray(expected) &&\n\t\t\t\t\t\t\t'$in' in expected\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst values = (expected as { $in?: unknown }).$in\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\tArray.isArray(values) && values.some((value) => Object.is(record[field], value))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn Object.is(record[field], expected)\n\t\t\t\t\t})\n\t\t\t\tif (!matches) {\n\t\t\t\t\tawait this.applyScopeRetraction(collection, String(record.id))\n\t\t\t\t\tretractions.push({ collection, recordId: String(record.id) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn retractions\n\t}\n\n\t/**\n\t * Materialize a server scope-entry insert (RT-19) whose fields each carry their\n\t * own version (RT-27). The entry restates the record's current server values; a\n\t * single whole-row stamp would let a field the server last wrote long ago\n\t * overwrite this device's newer unsynced edit of it, after which the device's own\n\t * operation uploads and wins on the server (divergence). So every field is resolved\n\t * on its own, by last-write-wins against this row's `_field_versions`:\n\t *\n\t * - no row: inserted with each field stamped at its own version, `_created_at`\n\t * at the record's creation (the entry's `timestamp`), then any orphaned\n\t * updates/deletes are folded in as for any insert;\n\t * - live row, or a row hidden by a scope retraction: per-field LWW (a retracted\n\t * row is shown again; `_created_at` is kept);\n\t * - domain tombstone: revived only when the entry's newest field version is\n\t * newer than the tombstone, then per-field LWW.\n\t *\n\t * Deterministic and idempotent: the outcome depends only on the stored and\n\t * incoming per-field versions, and a re-applied entry wins no field.\n\t */\n\tprivate async applyFieldVersionedInsert(\n\t\ttx: Transaction,\n\t\top: Operation,\n\t\tdefinition: NonNullable<SchemaDefinition['collections'][string]>,\n\t\tdata: Record<string, unknown>,\n\t\tcheckGuard: (row: RawCollectionRow | undefined) => void,\n\t): Promise<void> {\n\t\tconst collection = op.collection\n\t\tconst serialized = serializeRecord(data, definition.fields)\n\t\tconst versions = op.fieldVersions ?? {}\n\t\tconst latest = newestFieldVersion(op)\n\t\tconst latestVersion = serializeRowVersion(latest)\n\t\tconst incoming: FieldVersions = {}\n\t\tfor (const field of Object.keys(serialized)) {\n\t\t\t// A field without its own version (renamed by a schema transform) falls back\n\t\t\t// to the entry's newest version: the single-stamp rule of RT-19.\n\t\t\tconst version = versions[field]\n\t\t\tincoming[field] = version ? serializeRowVersion(version) : latestVersion\n\t\t}\n\n\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t`SELECT _updated_at, _version, _field_versions, _deleted FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[op.recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tcheckGuard(row)\n\n\t\tif (!row) {\n\t\t\tconst record: Record<string, unknown> = {\n\t\t\t\tid: op.recordId,\n\t\t\t\t...serialized,\n\t\t\t\t_created_at: op.timestamp.wallTime,\n\t\t\t\t_updated_at: latest.wallTime,\n\t\t\t\t_version: latestVersion,\n\t\t\t\t_field_versions: serializeFieldVersions(incoming),\n\t\t\t}\n\t\t\tconst insertQuery = buildInsertQuery(collection, record)\n\t\t\tawait tx.execute(insertQuery.sql, insertQuery.params)\n\t\t\tawait this.foldOrphanedOperations(tx, collection, definition, op.recordId, op)\n\t\t\treturn\n\t\t}\n\n\t\tlet retracted = false\n\t\tif (row._deleted === 1) {\n\t\t\tretracted =\n\t\t\t\t(\n\t\t\t\t\tawait tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t).length > 0\n\t\t\t// A domain delete newer than everything the entry carries still wins.\n\t\t\tif (!retracted && !isIncomingNewerThanRow(latest, row)) return\n\t\t}\n\n\t\tconst current = parseFieldVersions(row._field_versions)\n\t\tconst rowVersion = typeof row._version === 'string' ? row._version : undefined\n\t\tconst merged: FieldVersions = { ...current }\n\t\tconst changes: Record<string, unknown> = {}\n\t\tfor (const [field, version] of Object.entries(incoming)) {\n\t\t\tif (version > effectiveFieldVersion(current, field, rowVersion)) {\n\t\t\t\tchanges[field] = serialized[field]\n\t\t\t\tmerged[field] = version\n\t\t\t}\n\t\t}\n\t\tif (row._deleted === 1) {\n\t\t\tchanges._deleted = 0\n\t\t}\n\t\tchanges._field_versions = serializeFieldVersions(merged)\n\t\tconst update = buildFieldFastForwardUpdateQuery(\n\t\t\tcollection,\n\t\t\top.recordId,\n\t\t\tchanges,\n\t\t\tlatestVersion,\n\t\t\tlatest.wallTime,\n\t\t)\n\t\tawait tx.execute(update.sql, update.params)\n\t\tif (retracted) {\n\t\t\tawait tx.execute(\n\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t[collection, op.recordId],\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Materialize update/delete operations that were logged for a record BEFORE\n\t * its insert arrived (reordered delivery). Runs inside the insert's write\n\t * transaction, folding each orphan in timestamp order through the exact\n\t * per-field LWW / LWW-delete rules the normal apply paths use, so the final\n\t * row state equals what a device that received the operations in causal\n\t * order computed. Called only when the insert created a previously-absent\n\t * row — in that case every logged update/delete for the record is\n\t * necessarily an orphan (rows are soft-deleted, never removed, so a row\n\t * that is absent now was never materialized).\n\t */\n\tprivate async foldOrphanedOperations(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\tdefinition: NonNullable<SchemaDefinition['collections'][string]>,\n\t\trecordId: string,\n\t\tinsertOp: Operation,\n\t): Promise<void> {\n\t\tconst orphanRows = [\n\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ? AND type IN ('update', 'delete')`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t\t['update', 'delete'],\n\t\t\t)),\n\t\t]\n\t\tif (orphanRows.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst orphans = orphanRows\n\t\t\t.map((r) => deserializeOperationWithCollection(r, collection))\n\t\t\t.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\t\tfor (const orphan of orphans) {\n\t\t\tconst orphanVersion = serializeRowVersion(orphan.timestamp)\n\t\t\tconst orphanWall = orphan.timestamp.wallTime\n\n\t\t\tif (orphan.type === 'update' && orphan.data) {\n\t\t\t\tconst orphanChanges = serializeRecord(orphan.data, definition.fields)\n\t\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t[recordId],\n\t\t\t\t)\n\t\t\t\tconst current = rows[0]\n\t\t\t\tif (!current) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\tparseFieldVersions(current._field_versions),\n\t\t\t\t\tObject.keys(orphanChanges),\n\t\t\t\t\torphanVersion,\n\t\t\t\t\ttypeof current._version === 'string' ? current._version : undefined,\n\t\t\t\t)\n\t\t\t\tif (winners.length > 0) {\n\t\t\t\t\tconst winningChanges: Record<string, unknown> = {\n\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t}\n\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\twinningChanges[field] = orphanChanges[field]\n\t\t\t\t\t}\n\t\t\t\t\tconst query = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\trecordId,\n\t\t\t\t\t\twinningChanges,\n\t\t\t\t\t\torphanVersion,\n\t\t\t\t\t\torphanWall,\n\t\t\t\t\t)\n\t\t\t\t\tawait tx.execute(query.sql, query.params)\n\t\t\t\t}\n\t\t\t} else if (orphan.type === 'delete') {\n\t\t\t\tconst query = buildLwwSoftDeleteQuery(collection, recordId, orphanWall, orphanVersion)\n\t\t\t\tawait tx.execute(query.sql, query.params)\n\t\t\t}\n\t\t}\n\n\t\t// Atomic-op fields need composition, not last-write-wins: the per-field LWW\n\t\t// loop above would keep only one concurrent increment's resolved value and drop\n\t\t// the rest. Re-materialize just the atomic fields by folding [insert, ...orphans]\n\t\t// in HLC order through the shared atomic-aware replay — the same fold the server\n\t\t// and the live apply path use — so an atomic op that arrived before its insert\n\t\t// (reordered delivery) composes correctly instead of losing deltas. Only the\n\t\t// field VALUES are overwritten; their per-field versions were already stamped to\n\t\t// the latest writer by the loop above, so future LWW stays correct.\n\t\tconst atomicFields = new Set<string>()\n\t\tfor (const orphan of orphans) {\n\t\t\tif (orphan.type === 'update' && orphan.atomicOps) {\n\t\t\t\tfor (const field of Object.keys(orphan.atomicOps)) {\n\t\t\t\t\tatomicFields.add(field)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (atomicFields.size > 0) {\n\t\t\t// A scope-entry insert expands into its per-field writes (RT-27).\n\t\t\tconst ordered = expandFieldVersionedOperations([insertOp, ...orphans])\n\t\t\tconst folded = replayOperationsForRecord(ordered)\n\t\t\tif (folded) {\n\t\t\t\tconst composed: Record<string, unknown> = {}\n\t\t\t\tfor (const field of atomicFields) {\n\t\t\t\t\tif (field in folded) {\n\t\t\t\t\t\tcomposed[field] = folded[field]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst serialized = serializeRecord(composed, definition.fields)\n\t\t\t\tconst cols = Object.keys(serialized)\n\t\t\t\tif (cols.length > 0) {\n\t\t\t\t\tconst setClause = cols.map((c) => `${quoteIdent(c)} = ?`).join(', ')\n\t\t\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET ${setClause} WHERE id = ?`, [\n\t\t\t\t\t\t...cols.map((c) => serialized[c]),\n\t\t\t\t\t\trecordId,\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get operations from a node within a sequence number range.\n\t * Implements the OperationLog interface for computeDelta.\n\t */\n\tasync getRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]> {\n\t\treturn this.getOperationRange(nodeId, fromSeq, toSeq)\n\t}\n\n\t/**\n\t * Get operations from a node within a sequence number range.\n\t */\n\tasync getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst allOps: Operation[] = []\n\n\t\tfor (const collectionName of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,\n\t\t\t\t[nodeId, fromSeq, toSeq],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t}\n\t\t}\n\n\t\t// Sort by sequence number across collections\n\t\tallOps.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\t\treturn allOps\n\t}\n\n\t/**\n\t * Load every operation from the local append-only log across all collections.\n\t * Used by sync delta computation, backup export, and time-travel replay.\n\t */\n\tasync getAllOperations(): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst allOps: Operation[] = []\n\n\t\tfor (const collectionName of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`,\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t}\n\t\t}\n\n\t\treturn allOps\n\t}\n\n\t/**\n\t * Rebuild an in-memory snapshot of materialized state at a causal cut in the op log.\n\t * Does not mutate the live store — intended for DevTools time-travel inspection.\n\t *\n\t * @param operationId - Content-addressed id of the operation to replay through (inclusive)\n\t * @throws {OperationError} When the operation id is not present in the local log\n\t */\n\tasync replayTo(operationId: string): Promise<ReplaySnapshot> {\n\t\tthis.ensureOpen()\n\t\tconst start = Date.now()\n\t\tconst allOps = await this.getAllOperations()\n\t\tconst aliasRows = await this.adapter.query<{ id: string; reemitted_as: string }>(\n\t\t\t`SELECT id, reemitted_as FROM ${SEQ_CONFLICTS_TABLE} WHERE reemitted_as IS NOT NULL AND reemitted_as <> id`,\n\t\t)\n\t\tconst aliases = new Map(aliasRows.map((row) => [row.id, row.reemitted_as]))\n\t\tconst snapshot = buildReplaySnapshot(\n\t\t\tthis.schema,\n\t\t\tallOps,\n\t\t\toperationId,\n\t\t\taliases,\n\t\t\tthis.operationTransforms,\n\t\t)\n\n\t\tif (this.emitter) {\n\t\t\tthis.emitter.emit({\n\t\t\t\ttype: 'replay:completed',\n\t\t\t\ttargetOperationId: operationId,\n\t\t\t\toperationsApplied: snapshot.operationsApplied.length,\n\t\t\t\tduration: Date.now() - start,\n\t\t\t})\n\t\t}\n\n\t\treturn snapshot\n\t}\n\n\t/**\n\t * Persist a merge trace to the durable audit log.\n\t */\n\tasync appendAuditTrace(trace: import('../audit/types').PersistedAuditTrace): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tconst { appendAuditTrace: append } = await import('../audit/audit-trace-store')\n\t\tawait append(this.adapter, trace)\n\t}\n\n\t/**\n\t * Read persisted audit traces with optional filters.\n\t */\n\tasync getAuditTraces(\n\t\tquery?: import('../audit/types').AuditTraceQuery,\n\t): Promise<import('../audit/types').PersistedAuditTrace[]> {\n\t\tthis.ensureOpen()\n\t\tconst { readAuditTraces } = await import('../audit/audit-trace-store')\n\t\treturn readAuditTraces(this.adapter, query)\n\t}\n\n\t/**\n\t * Export operations and merge traces as a portable audit bundle.\n\t */\n\tasync exportAudit(options?: import('../audit/types').AuditExportOptions): Promise<Uint8Array> {\n\t\tthis.ensureOpen()\n\t\tconst { exportAudit: doExport } = await import('../audit/export-audit')\n\t\treturn doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options)\n\t}\n\n\t/**\n\t * Get the schema definition.\n\t */\n\tgetSchema(): SchemaDefinition {\n\t\treturn this.schema\n\t}\n\n\t/**\n\t * Route local CRUD through the unified apply pipeline (korajs ApplyPipeline).\n\t */\n\tsetLocalMutationHandler(handler: LocalMutationHandler | null): void {\n\t\tthis.localMutationHandler = handler\n\t\tfor (const col of this.collections.values()) {\n\t\t\tcol.setMutationHandler(handler)\n\t\t}\n\t}\n\n\t/**\n\t * Notify this store that another same-origin runtime committed an operation to\n\t * the shared local database. The operation has already been persisted and\n\t * materialized by the database owner; this method only advances in-memory causal\n\t * watermarks and invalidates local reactive queries so already-open tabs stay\n\t * live without reapplying or rewriting the operation.\n\t */\n\tnotifyExternalOperation(operation: Operation): void {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[operation.collection]\n\t\tif (!definition) {\n\t\t\treturn\n\t\t}\n\t\tthis.recordOperationSequence(operation)\n\t\tthis.subscriptionManager.invalidateFromPeer(operation.collection)\n\t}\n\n\t/**\n\t * Notify this store that another same-origin runtime changed rows of a collection\n\t * in the shared local database without an operation this tab can see (a re-fold,\n\t * a scope retraction, a restore; RT-98). Only re-runs the affected live queries.\n\t *\n\t * @param collection - The collection whose rows changed\n\t */\n\tnotifyExternalChange(collection: string): void {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) return\n\t\tthis.subscriptionManager.invalidateFromPeer(collection)\n\t}\n\n\t/**\n\t * Listen to every committed change this store makes to collection rows: local\n\t * writes, remote applies, and changes without a new operation (re-folds, scope\n\t * retraction, cascade settling, rematerialization, restore). The cross-tab bus\n\t * relays these to other tabs on the same database (RT-98).\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tonRecordsChanged(listener: RecordsChangeListener): () => void {\n\t\treturn this.subscriptionManager.onRecordsChanged(listener)\n\t}\n\n\t/**\n\t * Build the local write context for a collection: everything the single local\n\t * write path needs (used by Collection writes and by ApplyPipeline).\n\t */\n\tcreateMutationContext(\n\t\tcollection: string,\n\t\toptions?: {\n\t\t\textraCausalDeps?: string[]\n\t\t\t/**\n\t\t\t * Stamp the writes with this clock instead of the store's (it must be this\n\t\t\t * node's). Used for the side effects of a remote delete, stamped right after\n\t\t\t * the delete like the server's copy (seam 5), never with the device's \"now\".\n\t\t\t */\n\t\t\tclock?: HybridLogicalClock\n\t\t},\n\t): LocalMutationContext {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition || !this.clock) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\tconst beforeLocalDelete = this.localMutationHandler?.beforeLocalDelete\n\t\tconst fold = this.activeFold()\n\t\treturn {\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tcollection,\n\t\t\tdefinition,\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: options?.clock ?? this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\tonMutation: (collectionName, operation) =>\n\t\t\t\tthis.publishLocalOperation(collectionName, operation),\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(options?.extraCausalDeps ? { extraCausalDeps: options.extraCausalDeps } : {}),\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(this.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t\t...(beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: beforeLocalDelete.bind(this.localMutationHandler) }\n\t\t\t\t: {}),\n\t\t\tonStorageError: (error) => this.reportStorageError(error),\n\t\t}\n\t}\n\n\t/**\n\t * Load a materialized row by ID, including soft-deleted tombstones.\n\t */\n\tasync findMaterializedRow(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<MaterializedRowSnapshot | null> {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\n\t\treturn {\n\t\t\trecord: deserializeRecord(row, definition.fields),\n\t\t\tdeleted: row._deleted === 1,\n\t\t}\n\t}\n\n\t/**\n\t * Raw version state of a materialized row, for optimistic-concurrency guarded\n\t * applies: capture this snapshot before computing a merge, pass it as\n\t * `guardRowState`, and the apply refuses to write if the row changed since.\n\t * Returns null when no row exists (which is itself a valid guard state — the\n\t * apply then requires the row to still be absent).\n\t */\n\tasync getRowVersionState(collection: string, recordId: string): Promise<RowVersionState | null> {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) {\n\t\t\treturn null\n\t\t}\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\t\treturn {\n\t\t\tversion: typeof row._version === 'string' ? row._version : null,\n\t\t\tfieldVersions: typeof row._field_versions === 'string' ? row._field_versions : null,\n\t\t}\n\t}\n\n\t/**\n\t * Latest operation from this device for a record (used for delete-vs-update merge on sync).\n\t */\n\t/**\n\t * Load the last server version vector acknowledged by this client (persisted in `_kora_meta`).\n\t */\n\tasync loadLastAckedServerVector(): Promise<VersionVector> {\n\t\tthis.ensureOpen()\n\t\treturn loadLastAckedServerVector(this.adapter)\n\t}\n\n\t/**\n\t * Persist the last server version vector this client believes the server has applied.\n\t */\n\tasync saveLastAckedServerVector(vector: VersionVector): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveLastAckedServerVector(this.adapter, vector)\n\t}\n\n\t/**\n\t * Load the per-device node token the sync server issued for this node id (RT-12).\n\t */\n\tasync loadNodeToken(nodeId?: string): Promise<string | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadNodeToken(this.adapter, nodeId ?? this.nodeId)\n\t}\n\n\t/**\n\t * Persist the per-device node token under its node id (the current one by default).\n\t */\n\tasync saveNodeToken(token: string, nodeId?: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveNodeToken(this.adapter, token, nodeId ?? this.nodeId)\n\t}\n\n\t/**\n\t * Load the node ids the sync server named authoritative (protocol v2), or null when\n\t * no protocol-2 server ever answered.\n\t */\n\tasync loadAuthoritativeNodeIds(): Promise<string[] | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadAuthoritativeNodeIds(this.adapter)\n\t}\n\n\t/**\n\t * Persist the node ids the sync server named authoritative (protocol v2). Same as\n\t * {@link setAuthoritativeNodeIds}: merged into the union of learned explicit ids,\n\t * and the fold re-folds affected records only when that set grows.\n\t */\n\tasync saveAuthoritativeNodeIds(nodeIds: string[]): Promise<void> {\n\t\tawait this.setAuthoritativeNodeIds(nodeIds)\n\t}\n\n\t/**\n\t * Load persisted delta cursor for resuming paginated initial sync.\n\t */\n\tasync loadDeltaCursor(): Promise<string | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadDeltaCursor(this.adapter)\n\t}\n\n\t/**\n\t * Persist or clear the delta cursor for paginated initial sync resume.\n\t */\n\tasync saveDeltaCursor(cursor: string | null): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveDeltaCursor(this.adapter, cursor)\n\t}\n\n\t/**\n\t * Load the persisted delivery watermark for a view signature (0 when none recorded).\n\t * Defaults to the unfiltered view so existing single-watermark reads keep working.\n\t */\n\tasync loadDeliveryWatermark(signature = ''): Promise<number> {\n\t\tthis.ensureOpen()\n\t\treturn loadDeliveryWatermark(this.adapter, signature)\n\t}\n\n\t/**\n\t * Persist the delivery watermark for a view signature so it survives a client restart.\n\t */\n\tasync saveDeliveryWatermark(signature: string, watermark: number): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveDeliveryWatermark(this.adapter, signature, watermark)\n\t}\n\n\t/**\n\t * Load every persisted view watermark, keyed by signature.\n\t */\n\tasync loadAllDeliveryWatermarks(): Promise<Record<string, number>> {\n\t\tthis.ensureOpen()\n\t\treturn loadAllDeliveryWatermarks(this.adapter)\n\t}\n\n\t/**\n\t * Delete a persisted view watermark (safe: the view back-fills from 0 when next visited).\n\t */\n\tasync deleteDeliveryWatermark(signature: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait deleteDeliveryWatermark(this.adapter, signature)\n\t}\n\n\t/**\n\t * Record delivered operations the sync engine deliberately did not apply (inbound\n\t * quarantine, W4) and, when given, advance a view's delivery watermark in the same\n\t * transaction, so the watermark never passes an operation that is neither applied nor\n\t * recorded.\n\t */\n\tasync saveInboundQuarantine(\n\t\tentries: UnappliedOperation[],\n\t\twatermark?: { signature: string; watermark: number },\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveUnappliedOperations(this.adapter, entries, watermark)\n\t}\n\n\t/** Every quarantined inbound operation, oldest delivery first. */\n\tasync loadInboundQuarantine(): Promise<UnappliedOperation[]> {\n\t\tthis.ensureOpen()\n\t\treturn loadUnappliedOperations(this.adapter)\n\t}\n\n\t/** Remove quarantined inbound operations (applied on replay, or reconciled). */\n\tasync removeInboundQuarantine(operationIds: string[]): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait removeUnappliedOperations(this.adapter, operationIds)\n\t}\n\n\t/**\n\t * The contiguous acknowledged prefix of this device's own operations for a node id,\n\t * or null when none was recorded under that contract (W3).\n\t */\n\tasync loadOwnAckedThrough(nodeId: string): Promise<number | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadOwnAckedThrough(this.adapter, nodeId)\n\t}\n\n\t/** Persist the contiguous acknowledged own-operation prefix for a node id. */\n\tasync saveOwnAckedThrough(nodeId: string, sequence: number): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveOwnAckedThrough(this.adapter, nodeId, sequence)\n\t}\n\n\t/** The downlink scope the sync server last accepted (null when none). */\n\tasync loadAcceptedDownlinkScope(): Promise<Record<string, Record<string, unknown>> | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadAcceptedDownlinkScope(this.adapter)\n\t}\n\n\t/** Persist (or clear) the downlink scope the sync server last accepted. */\n\tasync saveAcceptedDownlinkScope(\n\t\tscope: Record<string, Record<string, unknown>> | null,\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveAcceptedDownlinkScope(this.adapter, scope)\n\t}\n\n\t/**\n\t * Local operations not yet reflected on the server version vector.\n\t */\n\tasync getUnsyncedOperations(serverVector: VersionVector): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\treturn collectOperationsAheadOfServer(\n\t\t\tthis.getVersionVector(),\n\t\t\tserverVector,\n\t\t\t(nodeId, fromSeq, toSeq) => this.getOperationRange(nodeId, fromSeq, toSeq),\n\t\t)\n\t}\n\n\t/**\n\t * Re-stamp never-acknowledged local operations after a fast device clock was\n\t * corrected, so sync can resume immediately. Safe because unacknowledged\n\t * operations are private to this device (like unpushed git commits);\n\t * acknowledged/shared operations are immutable and never touched.\n\t *\n\t * After the rewrite the store's HLC is advanced past the highest new\n\t * timestamp so subsequent local writes keep sorting after the rebased ops.\n\t * No data-change notifications are emitted: materialized values are\n\t * unchanged, only version stamps move.\n\t */\n\t/**\n\t * Move this device to a fresh node id, re-authoring its never-acknowledged\n\t * operations under it (RT-21). Used when the sync server refuses the current node\n\t * id (`NODE_ID_CLAIMED`): the device keeps every local write and uploads it under\n\t * the new id. Acknowledged history stays under the old id. Persisted atomically;\n\t * later writes use the new id.\n\t *\n\t * @param unsyncedOpIds - Ids of this node's operations the server never acknowledged\n\t * @returns The new node id and the rewritten operations (for the outbound queue)\n\t * @throws {KoraError} When the node id is pinned (`StoreConfig.nodeId`, or per-tab isolation)\n\t */\n\tasync rotateNodeId(unsyncedOpIds: string[]): Promise<NodeRotationResult> {\n\t\tthis.ensureOpen()\n\t\tif (this.configNodeId || this.isolation === 'per-tab') {\n\t\t\tthrow new KoraError(\n\t\t\t\t'This store uses a pinned node id, so it cannot move to a fresh one after the sync server refused it.',\n\t\t\t\t'NODE_ID_PINNED',\n\t\t\t\t{\n\t\t\t\t\tnodeId: this.nodeId,\n\t\t\t\t\tfix: 'Remove StoreConfig.nodeId, or give the device a node id no other device uses.',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tconst oldNodeId = this.nodeId\n\t\tconst oldClock = this.clock\n\t\tconst oldBinding = (await listLocalNodes(this.adapter)).find(\n\t\t\t(node) => node.nodeId === oldNodeId,\n\t\t)\n\t\tconst result = await rotateUnsyncedOperationsInLog(\n\t\t\tthis.adapter,\n\t\t\tthis.schema,\n\t\t\tunsyncedOpIds,\n\t\t\toldNodeId,\n\t\t\tgenerateUUIDv7(),\n\t\t)\n\t\tawait registerLocalNode(this.adapter, result.nodeId)\n\t\t// The re-authored writes keep their author (RT-50): the fresh node carries the old\n\t\t// node's binding, so they are never held as unassigned or given to another user.\n\t\tif (oldBinding?.principal) {\n\t\t\tawait setLocalNodePrincipal(\n\t\t\t\tthis.adapter,\n\t\t\t\tresult.nodeId,\n\t\t\t\toldBinding.principal,\n\t\t\t\toldBinding.binding ?? 'app',\n\t\t\t)\n\t\t}\n\t\tthis.nodeId = result.nodeId\n\t\tconst clock = new HybridLogicalClock(this.nodeId)\n\t\tif (oldClock) {\n\t\t\tconst last = oldClock.now()\n\t\t\tclock.advanceTo({ ...last, nodeId: this.nodeId })\n\t\t\tconst offset = oldClock.getReferenceOffset()\n\t\t\tif (offset !== null) clock.setReferenceOffset(offset)\n\t\t}\n\t\tthis.clock = clock\n\t\tthis.causalTracker = new CausalTracker()\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\t\tthis.versionVector = await this.loadVersionVector()\n\t\t// The persisted counter (MAX with the stored value, W6), not a local count.\n\t\tthis.sequenceNumber = this.versionVector.get(this.nodeId) ?? result.operations.length\n\t\tfor (const collection of this.collections.values()) {\n\t\t\tcollection.rebindNode(clock, this.nodeId, this.relationEnforcer, this.causalTracker)\n\t\t}\n\t\t// The re-authored operations have new ids: their records' fold states still name\n\t\t// the old ones, so they are re-folded from the log.\n\t\tawait this.refoldRecordsOf(result.operations.map((op) => op.id))\n\t\treturn result\n\t}\n\n\t/**\n\t * Move this database back to a node id it authored under before (RT-38): after the\n\t * sync server refused the current node, the device tries a node a returning user\n\t * owns. Nothing is rewritten; later writes use `nodeId`.\n\t *\n\t * @throws {KoraError} When the node id is pinned, or `nodeId` is not a local node\n\t */\n\tasync switchNodeId(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (this.configNodeId || this.isolation === 'per-tab') {\n\t\t\tthrow new KoraError(\n\t\t\t\t'This store uses a pinned node id, so it cannot switch to another one.',\n\t\t\t\t'NODE_ID_PINNED',\n\t\t\t\t{ nodeId: this.nodeId },\n\t\t\t)\n\t\t}\n\t\tif (nodeId === this.nodeId) return\n\t\tif (isReservedNodeId(nodeId)) throw new ReservedNodeIdError(nodeId, 'switchNodeId')\n\t\tconst known = (await listLocalNodes(this.adapter)).some((node) => node.nodeId === nodeId)\n\t\tif (!known) {\n\t\t\tthrow new KoraError(\n\t\t\t\t`Node id \"${nodeId}\" was never used by this database, so the store cannot switch to it.`,\n\t\t\t\t'NODE_ID_UNKNOWN',\n\t\t\t\t{ nodeId },\n\t\t\t)\n\t\t}\n\t\tawait this.adapter.transaction((tx) => moveDatabaseNodeId(tx, nodeId))\n\t\tawait this.rebindToNode(nodeId)\n\t}\n\n\t/** Point the clock, sequence counter and collections at `nodeId` (already persisted). */\n\tprivate async rebindToNode(nodeId: string): Promise<void> {\n\t\tconst oldClock = this.clock\n\t\tthis.nodeId = nodeId\n\t\tconst clock = new HybridLogicalClock(this.nodeId)\n\t\tif (oldClock) {\n\t\t\tconst last = oldClock.now()\n\t\t\tclock.advanceTo({ ...last, nodeId: this.nodeId })\n\t\t\tconst offset = oldClock.getReferenceOffset()\n\t\t\tif (offset !== null) clock.setReferenceOffset(offset)\n\t\t}\n\t\tthis.clock = clock\n\t\tthis.causalTracker = new CausalTracker()\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\t\tthis.versionVector = await this.loadVersionVector()\n\t\tthis.sequenceNumber = this.versionVector.get(this.nodeId) ?? 0\n\t\tfor (const collection of this.collections.values()) {\n\t\t\tcollection.rebindNode(clock, this.nodeId, this.relationEnforcer, this.causalTracker)\n\t\t}\n\t}\n\n\t/**\n\t * Bind this database's writes to the signed-in user (RT-42). Call it whenever the\n\t * signed-in user is known or changes, BEFORE the next local write (`createApp` does\n\t * so at start and on every auth change of `sync.authClient`).\n\t *\n\t * - The current node belongs to `principal`: nothing changes.\n\t * - The current node is unbound and has no history (no write, never synced): it is\n\t * bound to `principal` (every write under it from now on is theirs).\n\t * - The current node is unbound but has history (a database from before RT-42, or\n\t * writes made while nobody was signed in): its owner is NOT guessed (RT-50). The\n\t * store moves to `principal`'s own node, and the old node's owner is learned from\n\t * the sync server (the first accepted handshake as it binds it; a refusal rules\n\t * that user out). A node that never synced cannot be attributed by anyone: its\n\t * unsynced writes are held for the app to assign or discard (`app.sync.assignHeld`,\n\t * `app.sync.discardHeld`).\n\t * - It belongs to another user: the store moves to `principal`'s own local node (the\n\t * most recent one, not held), or to a fresh node bound to `principal`. Nothing is\n\t * rewritten: the other user's unsynced writes stay under their node, and sync never\n\t * uploads them on this user's session (they count as `heldOperations`).\n\t *\n\t * A pinned node id (`StoreConfig.nodeId`, such as an auth device id) cannot move:\n\t * `conflict` is then true when it belongs to another user, and sync refuses to\n\t * upload it under `principal`; an unbound pinned node with history stays unbound\n\t * until the server accepts it for a user. Under `per-tab` isolation the tab moves to\n\t * a fresh per-tab node.\n\t *\n\t * @param principal - The signed-in user id\n\t * @returns The node now in use and whether it changed\n\t */\n\tasync bindPrincipal(principal: string): Promise<PrincipalBinding> {\n\t\tthis.ensureOpen()\n\t\tconst previousNodeId = this.nodeId\n\t\tconst nodes = await listLocalNodes(this.adapter)\n\t\tconst current = nodes.find((node) => node.nodeId === this.nodeId)\n\t\tconst owner = current?.principal ?? null\n\t\tif (owner === principal) {\n\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t}\n\t\tif (owner === null) {\n\t\t\tconst written = (await this.loadVersionVector()).get(this.nodeId) ?? 0\n\t\t\tif (written === 0 && !(current?.accepted ?? false)) {\n\t\t\t\tawait setLocalNodePrincipal(this.adapter, this.nodeId, principal, 'fresh')\n\t\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t\t}\n\t\t\tif (this.configNodeId) {\n\t\t\t\t// Cannot move: the server decides whose it is at the first handshake.\n\t\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t\t}\n\t\t} else if (this.configNodeId) {\n\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: true }\n\t\t}\n\t\tif (this.isolation === 'per-tab') {\n\t\t\t// A per-tab node belongs to its tab; another user in this tab gets a fresh one.\n\t\t\tconst fresh = generateUUIDv7()\n\t\t\tawait registerLocalNode(this.adapter, fresh)\n\t\t\tawait setLocalNodePrincipal(this.adapter, fresh, principal, 'fresh')\n\t\t\tsavePerTabNodeId(this.dbName, fresh)\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = acquireNodeLock(nodeLockName(this.dbName, fresh))\n\t\t\tawait this.rebindToNode(fresh)\n\t\t\treturn { nodeId: fresh, previousNodeId, switched: true, conflict: false }\n\t\t}\n\t\tconst own = nodes\n\t\t\t.filter((node) => node.principal === principal && !node.held)\n\t\t\t.sort((a, b) => b.createdAt - a.createdAt)[0]\n\t\tif (own) {\n\t\t\tawait this.switchNodeId(own.nodeId)\n\t\t\treturn { nodeId: own.nodeId, previousNodeId, switched: true, conflict: false }\n\t\t}\n\t\tconst fresh = generateUUIDv7()\n\t\tawait this.adapter.transaction((tx) => moveDatabaseNodeId(tx, fresh))\n\t\tawait registerLocalNode(this.adapter, fresh)\n\t\tawait setLocalNodePrincipal(this.adapter, fresh, principal, 'fresh')\n\t\tawait this.rebindToNode(fresh)\n\t\treturn { nodeId: fresh, previousNodeId, switched: true, conflict: false }\n\t}\n\n\t/**\n\t * A sync handshake as `nodeId` was accepted for `principal` (RT-50): bind an unbound\n\t * node (or replace a guessed binding) from the server's answer.\n\t */\n\tasync confirmNodePrincipal(nodeId: string, principal: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait confirmLocalNodePrincipal(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * The sync server refused `nodeId` for `principal` (RT-50): clear a guessed binding,\n\t * and remember that an unbound node is not theirs.\n\t */\n\tasync recordNodeRefusedFor(nodeId: string, principal: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait recordLocalNodeRefusedFor(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * Assign a held, unbound local node's writes to `principal` (RT-50): an explicit app\n\t * decision for writes nobody can attribute (a database that never synced).\n\t *\n\t * @returns false when the node is unknown, the store's own, already bound, or was\n\t * refused for `principal` by the server\n\t */\n\tasync assignNodePrincipal(nodeId: string, principal: string): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return false\n\t\treturn assignLocalNodePrincipal(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * Forget a local node other than the store's own whatever it still holds (RT-50: the\n\t * app discarded its held writes, which were marked never to upload first).\n\t */\n\tasync dropLocalNode(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return\n\t\tawait dropLocalNode(this.adapter, nodeId)\n\t}\n\n\t/** The adoption schedule of this database's local nodes (RT-46). */\n\tasync loadAdoptionSchedule(): Promise<AdoptionSchedule> {\n\t\tthis.ensureOpen()\n\t\treturn loadAdoptionSchedule(this.adapter)\n\t}\n\n\t/** Persist the adoption schedule (RT-46). */\n\tasync saveAdoptionSchedule(schedule: AdoptionSchedule): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveAdoptionSchedule(this.adapter, schedule)\n\t}\n\n\t/**\n\t * Raise a local node's sequence counter to at least `floor`, in a transaction (the\n\t * same MAX every reservation uses, W6), so the next write never reuses a number the\n\t * server already holds (RT-35: the device lost the tail of its log, for example on a\n\t * reload inside the IndexedDB snapshot window or after restoring an older copy).\n\t *\n\t * @returns Whether the counter moved\n\t */\n\tasync raiseSequenceFloor(nodeId: string, floor: number): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tlet raised = false\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tconst rows = await tx.query<VersionVectorRow>(\n\t\t\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t\t\t[nodeId],\n\t\t\t)\n\t\t\tconst current = rows[0]?.sequence_number ?? 0\n\t\t\tif (floor <= current) return\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[nodeId, floor],\n\t\t\t)\n\t\t\traised = true\n\t\t})\n\t\tif (raised) {\n\t\t\tconst previous = this.versionVector.get(nodeId) ?? 0\n\t\t\tthis.versionVector.set(nodeId, Math.max(previous, floor))\n\t\t\tif (nodeId === this.nodeId) this.sequenceNumber = Math.max(this.sequenceNumber, floor)\n\t\t}\n\t\treturn raised\n\t}\n\n\t/**\n\t * Give one of a local node's operations a fresh sequence number above `floor`\n\t * (RT-35): the server refused it with `SEQUENCE_CONFLICT` because it holds another\n\t * operation of this node under that number (one this device lost). A version-1\n\t * operation keeps its id (its hash does not cover the sequence number), exactly like\n\t * the W6 sequence repair; a version-2 operation (protocol v2) is re-hashed under the\n\t * new number, so it carries a new id. The old identity is recorded in\n\t * `_kora_seq_conflicts` (`reemitted_as`).\n\t *\n\t * A new id would leave later operations naming the old one in `causalDeps`: those in\n\t * `rewritableDependents` (operations the server never stored: never sent) are\n\t * rewritten to name the new id, and re-hashed, transitively, in the same\n\t * transaction. Dependents already sent keep their ids (the server may hold them);\n\t * their dep resolves through the `_kora_seq_conflicts` record. Every touched record\n\t * is re-folded (fold stamps carry operation ids).\n\t *\n\t * @param rewritableDependents - Ids of this node's operations that were never sent\n\t * @returns The renumbered operation and the rewritten dependents, or null when the\n\t * operation is not in the log\n\t */\n\tasync resequenceOperation(\n\t\toperationId: string,\n\t\tnodeId: string,\n\t\tfloor: number,\n\t\trewritableDependents: readonly string[] = [],\n\t): Promise<ResequenceResult | null> {\n\t\tthis.ensureOpen()\n\t\tconst found: { result: ResequenceResult | null } = { result: null }\n\t\tconst collections = Object.keys(this.schema.collections)\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const collection of collections) {\n\t\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${table} WHERE id = ? AND node_id = ?`,\n\t\t\t\t\t[operationId, nodeId],\n\t\t\t\t)\n\t\t\t\tconst row = rows[0]\n\t\t\t\tif (!row) continue\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[nodeId, floor],\n\t\t\t\t)\n\t\t\t\tconst sequence = await allocateNextSequenceInTransaction(tx, nodeId)\n\t\t\t\t// A version-2 id covers the sequence number (CORE-1): such an operation is\n\t\t\t\t// re-hashed under the new number (the server never stored it).\n\t\t\t\tconst moved = await renumberOperationRow(tx, collection, row, sequence)\n\t\t\t\tawait insertConflictRow(\n\t\t\t\t\ttx,\n\t\t\t\t\tcollection,\n\t\t\t\t\trow,\n\t\t\t\t\t'server-sequence-conflict',\n\t\t\t\t\tmoved.id,\n\t\t\t\t\tsequence,\n\t\t\t\t\tDate.now(),\n\t\t\t\t)\n\t\t\t\tconst idMapping: Record<string, string> = moved.id !== row.id ? { [row.id]: moved.id } : {}\n\t\t\t\tconst rewritable = new Set(rewritableDependents)\n\t\t\t\trewritable.delete(row.id)\n\t\t\t\tconst dependents =\n\t\t\t\t\tmoved.id !== row.id\n\t\t\t\t\t\t? await rewriteDependentsInTx(tx, collections, nodeId, idMapping, rewritable)\n\t\t\t\t\t\t: []\n\t\t\t\tfound.result = { operation: moved, dependents, idMapping }\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t\tconst result = found.result\n\t\tif (!result) return null\n\t\tthis.recordOperationSequence(result.operation)\n\t\tif (Object.keys(result.idMapping).length > 0) {\n\t\t\tawait this.refoldRecordsOf([result.operation.id, ...result.dependents.map((op) => op.id)])\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Durability barrier (RT-35): resolves once every write committed so far is durable\n\t * on this device. Sync awaits it before an operation leaves the device.\n\t */\n\tasync ensureDurable(): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait this.adapter.ensureDurable?.()\n\t}\n\n\t/** Record operations the server refused for good (RT-36). Never cleared. */\n\tasync recordTerminalRejections(entries: TerminalRejection[]): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait recordTerminalRejections(this.adapter, entries)\n\t\t// The server never stored these operations: re-fold their records without them,\n\t\t// so this device converges to the server's state (W7 step 2).\n\t\tawait this.refoldRecordsOf(entries.map((entry) => entry.operationId))\n\t}\n\n\t/** Which of these operation ids the server refused for good (RT-36). */\n\tasync findTerminalRejections(operationIds: string[]): Promise<Set<string>> {\n\t\tthis.ensureOpen()\n\t\treturn findTerminalRejections(this.adapter, operationIds)\n\t}\n\n\t/** Every node id this database authored operations under (RT-38, RT-40). */\n\tasync listLocalNodes(): Promise<LocalNodeRecord[]> {\n\t\tthis.ensureOpen()\n\t\treturn listLocalNodes(this.adapter)\n\t}\n\n\t/** Forget a drained local node other than this store's own (RT-40). */\n\tasync forgetLocalNode(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return\n\t\tawait forgetLocalNode(this.adapter, nodeId)\n\t}\n\n\t/** The current refusal cycle: the count of accepted sync handshakes (RT-38). */\n\tasync loadAcceptedCycle(): Promise<number> {\n\t\tthis.ensureOpen()\n\t\treturn loadAcceptedCycle(this.adapter)\n\t}\n\n\t/** Record an accepted sync handshake as `nodeId` (RT-38). */\n\tasync markLocalNodeAccepted(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait markLocalNodeAccepted(this.adapter, nodeId)\n\t}\n\n\t/** Record that the sync server refused `nodeId`; `held` holds its writes (RT-38). */\n\tasync markLocalNodeRefused(nodeId: string, held: boolean): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait markLocalNodeRefused(this.adapter, nodeId, held)\n\t}\n\n\t/**\n\t * Take over another local node's unsynced writes (RT-40): resolves to a release\n\t * function when no live tab uses `nodeId` (its lock is free), or null when one does.\n\t * Without Web Locks (Node, old browsers) the node is assumed free.\n\t */\n\tasync claimLocalNode(nodeId: string): Promise<(() => void) | null> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return null\n\t\treturn tryAcquireNodeLock(nodeLockName(this.dbName, nodeId))\n\t}\n\n\t/** Whether a live tab holds `nodeId` (per-tab isolation, RT-40). */\n\tasync isLocalNodeLive(nodeId: string): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return true\n\t\treturn isNodeLockHeld(nodeLockName(this.dbName, nodeId))\n\t}\n\n\tasync rebaseUnsyncedOperations(\n\t\tunsyncedOpIds: string[],\n\t\tcorrectedNowMs: number,\n\t): Promise<ClockRebaseResult> {\n\t\tthis.ensureOpen()\n\t\tconst result = await rebaseUnsyncedOperationsInLog(\n\t\t\tthis.adapter,\n\t\t\tthis.schema,\n\t\t\tunsyncedOpIds,\n\t\t\tcorrectedNowMs,\n\t\t)\n\t\tif (result.newMaxTimestamp && this.clock) {\n\t\t\tthis.clock.advanceTo(result.newMaxTimestamp)\n\t\t}\n\t\t// Re-stamped operations order differently: re-fold their records.\n\t\tawait this.refoldRecordsOf(result.operations.map((op) => op.id))\n\t\treturn result\n\t}\n\n\t/**\n\t * Count of local operations ahead of the server version vector.\n\t */\n\tasync countUnsyncedOperations(serverVector: VersionVector): Promise<number> {\n\t\tconst ops = await this.getUnsyncedOperations(serverVector)\n\t\treturn ops.length\n\t}\n\n\t/**\n\t * Compact the local operation log. Only removes ops the server has acknowledged\n\t * (per {@link CompactionStrategy}). With the W7 fold (STORE-14), the effect of the\n\t * removed operations is first joined into each record's base fold state, so a\n\t * re-fold (rejection exclusion, a later re-materialization) and the merge of a\n\t * late operation stay exact; delete, atomic and custom-resolver operations are\n\t * kept, and a re-delivered compacted id is a duplicate by its node's compacted\n\t * prefix.\n\t */\n\tasync compact(strategy: CompactionStrategy): Promise<CompactionResult> {\n\t\tthis.ensureOpen()\n\t\tconst fold = this.activeFold()\n\t\tif (strategy.mode === 'never') {\n\t\t\treturn compactOperationLog(this.adapter, this.schema, strategy, createVersionVector())\n\t\t}\n\n\t\tconst serverVector = strategy.serverVector ?? (await loadLastAckedServerVector(this.adapter))\n\t\tif (fold) {\n\t\t\treturn compactFoldedLog(this.adapter, this.schema, fold, strategy, serverVector)\n\t\t}\n\t\treturn compactOperationLog(this.adapter, this.schema, strategy, serverVector)\n\t}\n\n\t/**\n\t * Merge session remote vector with persisted last-acked vector (max per node).\n\t */\n\tmergeServerVectors(sessionVector: VersionVector, persistedVector: VersionVector): VersionVector {\n\t\treturn mergeVersionVectors(persistedVector, sessionVector)\n\t}\n\n\tasync getLatestLocalOperationForRecord(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation | null> {\n\t\tthis.ensureOpen()\n\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,\n\t\t\t[this.nodeId, recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\t\treturn deserializeOperationWithCollection(row, collection)\n\t}\n\n\t/**\n\t * Latest operation for a record from any node (for 3-way merge when local op log is empty).\n\t */\n\tasync getLatestOperationForRecord(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation | null> {\n\t\tthis.ensureOpen()\n\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t[recordId],\n\t\t)\n\n\t\tlet latest: Operation | null = null\n\t\tfor (const row of rows) {\n\t\t\tconst op = deserializeOperationWithCollection(row, collection)\n\t\t\tif (!latest || HybridLogicalClock.compare(op.timestamp, latest.timestamp) > 0) {\n\t\t\t\tlatest = op\n\t\t\t}\n\t\t}\n\t\treturn latest\n\t}\n\n\t/**\n\t * All operations for a record, sorted in HLC total order (wallTime, logical,\n\t * nodeId). Used by the apply pipeline to materialize atomic-op fields by folding\n\t * the record's log, matching the server's materialization exactly.\n\t */\n\tasync getOperationsForRecord(collection: string, recordId: string): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst rows = [\n\t\t\t...(await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t// Other nodes' operations kept only in the sequence-conflicts table still\n\t\t\t// belong to the record's history.\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => this.adapter.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t)),\n\t\t]\n\t\tconst ops = rows.map((row) => deserializeOperationWithCollection(row, collection))\n\t\tops.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\t\treturn ops\n\t}\n\n\t/** Expose the subscription manager for direct access (e.g., by QueryBuilder) */\n\tgetSubscriptionManager(): SubscriptionManager {\n\t\treturn this.subscriptionManager\n\t}\n\n\t/**\n\t * Get the sequence manager for offline-safe sequence generation.\n\t * @throws {StoreNotOpenError} If the store is not open\n\t */\n\tgetSequenceManager(): SequenceManager {\n\t\tthis.ensureOpen()\n\t\tif (!this.sequenceManager) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\treturn this.sequenceManager\n\t}\n\n\t/**\n\t * Create a TransactionContext for atomic multi-collection operations.\n\t * The returned context buffers all mutations and commits them atomically.\n\t *\n\t * After commit, the caller is responsible for notifying subscriptions\n\t * and emitting events for each operation.\n\t */\n\tcreateTransaction(): TransactionContext {\n\t\tthis.ensureOpen()\n\t\tif (!this.clock) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\tconst beforeLocalDelete = this.localMutationHandler?.beforeLocalDelete\n\t\tconst fold = this.activeFold()\n\t\treturn new TransactionContext({\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: beforeLocalDelete.bind(this.localMutationHandler) }\n\t\t\t\t: {}),\n\t\t\tonStorageError: (error) => this.reportStorageError(error),\n\t\t})\n\t}\n\n\t/**\n\t * Execute a function within a transaction. All mutations performed on the\n\t * TransactionContext are committed atomically. Subscription notifications\n\t * are batched and fired after the commit.\n\t *\n\t * If the function throws, the transaction is rolled back and the error is re-thrown.\n\t *\n\t * @param fn - Function receiving a TransactionContext for buffered operations\n\t * @returns The operations that were committed\n\t */\n\tasync transaction(fn: (tx: TransactionContext) => Promise<void>): Promise<Operation[]> {\n\t\tconst tx = this.createTransaction()\n\t\ttry {\n\t\t\tawait fn(tx)\n\t\t} catch (error) {\n\t\t\ttx.rollback()\n\t\t\tthrow error\n\t\t}\n\t\tconst { operations } = await tx.commit()\n\n\t\t// Notify subscriptions and emit events after commit\n\t\tfor (const op of operations) {\n\t\t\tthis.publishLocalOperation(op.collection, op)\n\t\t}\n\n\t\treturn operations\n\t}\n\n\t/**\n\t * Export all data as a portable backup binary.\n\t * Includes operations, version vector, metadata, and optionally materialized records.\n\t *\n\t * @param options - Backup options (includeRecords, collections, onProgress)\n\t * @returns Backup as a Uint8Array\n\t */\n\tasync exportBackup(options?: BackupOptions): Promise<Uint8Array> {\n\t\tthis.ensureOpen()\n\t\tconst { exportBackup: doExport } = await import('../backup/backup')\n\t\treturn doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options)\n\t}\n\n\t/**\n\t * Restore data from a backup binary (format version 2, STORE-5).\n\t *\n\t * - `merge: true`: every backup operation is applied through the remote-apply path\n\t * (deduplicated by id, merged per field), the version vector advances by MAX, and\n\t * nothing of the exporting device's identity or sync state is imported.\n\t * - Replace (default): the data is replaced by the backup's while this device keeps\n\t * its node id, local nodes and principal bindings, its own sequence counters never\n\t * move backwards, and unsynced own writes are kept (see\n\t * `RestoreOptions.keepUnsyncedWrites`). Then {@link reloadFromDisk} runs.\n\t *\n\t * A version-1 file is refused (`errorCode: 'BACKUP_FORMAT_OUTDATED'`); convert it with\n\t * `convertBackupV1`.\n\t *\n\t * @param data - The backup data\n\t * @param options - Restore options (merge, collections, keepUnsyncedWrites, onProgress)\n\t * @param internal - `applyOperation`: the app's remote-apply path (defaults to\n\t * {@link applyRemoteOperation}); `createApp` passes the merge-aware pipeline sync uses\n\t * @returns Result of the restore operation\n\t */\n\tasync importBackup(\n\t\tdata: Uint8Array,\n\t\toptions?: RestoreOptions,\n\t\tinternal?: { applyOperation?: (operation: Operation) => Promise<ApplyResult> },\n\t): Promise<RestoreResult> {\n\t\tthis.ensureOpen()\n\t\tconst started = Date.now()\n\t\tconst onProgress = options?.onProgress ?? (() => {})\n\t\tconst { BackupFormatError, parseBackup } = await import('../backup/backup')\n\t\tconst { restoreMerge, restoreReplace } = await import('../backup/restore')\n\t\tonProgress({ phase: 'verifying', progress: 0, message: 'Verifying backup' })\n\t\tlet parsed: Awaited<ReturnType<typeof parseBackup>>\n\t\ttry {\n\t\t\tparsed = await parseBackup(\n\t\t\t\tdata,\n\t\t\t\toptions?.collections ? { collections: options.collections } : undefined,\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof BackupFormatError)) throw error\n\t\t\treturn {\n\t\t\t\toperationsRestored: 0,\n\t\t\t\trecordsRestored: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error.message,\n\t\t\t\terrorCode: error.code,\n\t\t\t\tduration: Date.now() - started,\n\t\t\t}\n\t\t}\n\t\tif (parsed.manifest.schemaVersion > this.schema.version) {\n\t\t\treturn {\n\t\t\t\toperationsRestored: 0,\n\t\t\t\trecordsRestored: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `The backup was written by schema version ${parsed.manifest.schemaVersion}; this app runs version ${this.schema.version}. Update the app before restoring it.`,\n\t\t\t\terrorCode: 'BACKUP_SCHEMA_NEWER',\n\t\t\t\tduration: Date.now() - started,\n\t\t\t}\n\t\t}\n\t\tonProgress({ phase: 'restoring', progress: 0.3, message: 'Restoring' })\n\t\tconst explicitAuthorities = new Set((await loadAuthoritativeNodeIds(this.adapter)) ?? [])\n\t\tconst host = {\n\t\t\tadapter: this.adapter,\n\t\t\tschema: this.schema,\n\t\t\tapplyOperation:\n\t\t\t\tinternal?.applyOperation ?? ((op: Operation) => this.applyRemoteOperation(op)),\n\t\t\tlistLocalNodes: () => listLocalNodes(this.adapter),\n\t\t\tisServerAuthority: (nodeId: string) =>\n\t\t\t\tisReservedNodeId(nodeId) || explicitAuthorities.has(nodeId),\n\t\t}\n\t\tif (options?.merge) await this.mergeBackupFoldState(parsed, options.collections !== undefined)\n\t\tconst counts = options?.merge\n\t\t\t? await restoreMerge(host, parsed, options.collections !== undefined)\n\t\t\t: await restoreReplace(host, parsed, {\n\t\t\t\t\tcollections: options?.collections ?? null,\n\t\t\t\t\tkeepUnsyncedWrites: options?.keepUnsyncedWrites ?? true,\n\t\t\t\t})\n\t\tif (!options?.merge && this.folder) {\n\t\t\t// Restored rows and log replace what the fold states described: rebuild them,\n\t\t\t// from the backup's base states and log (RT-66). A file from an earlier\n\t\t\t// release carries no base states, and its log may have been compacted: its\n\t\t\t// records are rebuilt on top of its rows instead (row snapshots).\n\t\t\tawait this.adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [\n\t\t\t\tFOLD_MATERIALIZATION_META_KEY,\n\t\t\t])\n\t\t\tthis.foldActive = false\n\t\t\tawait this.ensureMaterialization(parsed.manifest.includesFoldState !== true)\n\t\t}\n\t\tawait this.reloadFromDisk()\n\t\tonProgress({ phase: 'restoring', progress: 1, message: 'Done' })\n\t\treturn {\n\t\t\toperationsRestored: counts.operationsRestored,\n\t\t\trecordsRestored: counts.recordsRestored,\n\t\t\t...(options?.merge ? {} : { unsyncedWritesKept: counts.unsyncedWritesKept }),\n\t\t\t...(counts.serverOperationsSkipped\n\t\t\t\t? { serverOperationsSkipped: counts.serverOperationsSkipped }\n\t\t\t\t: {}),\n\t\t\tsuccess: true,\n\t\t\tduration: Date.now() - started,\n\t\t}\n\t}\n\n\t/**\n\t * Merge mode (RT-66): join the backup's compacted base states and row snapshots\n\t * into this database's, and re-fold those records, before the backup's operations\n\t * are applied. The join is the fold's state-based merge, so the result equals\n\t * folding both devices' histories together. Compacted prefixes advance by MAX\n\t * (unfiltered restores only: the prefix is per node, across collections).\n\t */\n\tprivate async mergeBackupFoldState(\n\t\tparsed: import('../backup/backup').ParsedBackup,\n\t\tfiltered: boolean,\n\t): Promise<void> {\n\t\tconst folder = this.activeFold()\n\t\tif (!folder) return\n\t\tconst touched = new Map<string, Set<string>>()\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const [rows, kind] of [\n\t\t\t\t[parsed.foldBases, 'base'],\n\t\t\t\t[parsed.foldSnapshots, 'snapshot'],\n\t\t\t] as const) {\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tif (!this.schema.collections[row.collection]) continue\n\t\t\t\t\tlet state: FoldState\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstate = deserializeFoldState(row.state)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (state.c !== row.collection || state.r !== row.recordId) continue\n\t\t\t\t\tif (kind === 'base') await folder.joinIntoBase(tx, state)\n\t\t\t\t\telse await folder.saveSnapshot(tx, state)\n\t\t\t\t\tconst ids = touched.get(row.collection) ?? new Set<string>()\n\t\t\t\t\tids.add(row.recordId)\n\t\t\t\t\ttouched.set(row.collection, ids)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!filtered) {\n\t\t\t\tfor (const [nodeId, sequence] of parsed.compactedThrough) {\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t\t[nodeId, sequence],\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [collection, ids] of touched) {\n\t\t\t\tfor (const recordId of ids) await folder.refoldInTx(tx, collection, recordId)\n\t\t\t}\n\t\t})\n\t\tfor (const [collection, ids] of touched)\n\t\t\tthis.subscriptionManager.invalidate(collection, [...ids])\n\t}\n\n\t/**\n\t * Re-read this store's state from the database after it changed underneath it (a\n\t * backup restore): the node id, version vector and own sequence counter, the clock\n\t * (advanced past every timestamp in the log), and a fresh causal tracker. Every live\n\t * query re-runs. The local node registry and terminal rejections are always read\n\t * from the database, so they need no reload.\n\t */\n\tasync reloadFromDisk(): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tlet nodeId = this.nodeId\n\t\tif (!this.configNodeId && this.isolation !== 'per-tab') {\n\t\t\tconst rows = await this.adapter.query<MetaRow>(\n\t\t\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t\t\t)\n\t\t\tnodeId = rows[0]?.value ?? this.nodeId\n\t\t}\n\t\tawait this.rebindToNode(nodeId)\n\t\tconst newest = await this.loadNewestLogTimestamp()\n\t\tif (newest && this.clock) {\n\t\t\tthis.clock.advanceTo({ ...newest, nodeId: this.nodeId })\n\t\t}\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t}\n\t}\n\n\t/** The greatest HLC timestamp in the operation log (canonical strings sort by HLC). */\n\tprivate async loadNewestLogTimestamp(): Promise<HLCTimestamp | null> {\n\t\tlet newest: string | null = null\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<{ t: string | null }>(\n\t\t\t\t`SELECT MAX(timestamp) AS t FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t\t)\n\t\t\tconst value = rows[0]?.t ?? null\n\t\t\tif (value !== null && (newest === null || value > newest)) newest = value\n\t\t}\n\t\treturn newest === null ? null : HybridLogicalClock.deserialize(newest)\n\t}\n\n\t/**\n\t * Read backup manifest without loading the entire backup.\n\t *\n\t * @param data - The raw backup data\n\t * @returns The backup manifest\n\t */\n\tstatic readBackupManifest(data: Uint8Array): BackupManifest {\n\t\treturn readManifest(data)\n\t}\n\n\tprivate recordOperationSequence(operation: Operation): void {\n\t\tconst prev = this.versionVector.get(operation.nodeId) ?? 0\n\t\tif (operation.sequenceNumber > prev) {\n\t\t\tthis.versionVector.set(operation.nodeId, operation.sequenceNumber)\n\t\t}\n\t\tif (operation.nodeId === this.nodeId) {\n\t\t\tthis.sequenceNumber = Math.max(this.sequenceNumber, operation.sequenceNumber)\n\t\t}\n\t}\n\n\t/** Post-commit publication of a committed local operation. */\n\tprivate publishLocalOperation(collection: string, operation: Operation): void {\n\t\tthis.recordOperationSequence(operation)\n\t\tthis.subscriptionManager.notify(collection, operation)\n\t\tthis.emitter?.emit({ type: 'operation:created', operation })\n\t}\n\n\t/**\n\t * Map an out-of-space storage failure to `store:quota-exceeded` (STORE-15).\n\t * The error itself still propagates to the caller; this only makes the\n\t * condition observable on every adapter, not just IndexedDB.\n\t */\n\tprivate reportStorageError(error: unknown): void {\n\t\tif (!isStorageFullError(error)) return\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'store:quota-exceeded',\n\t\t\tdbName: this.dbName,\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t})\n\t}\n\n\t/** Report a database a newer build migrated (`store:schema-ahead`) and build the error. */\n\tprivate schemaAhead(storedVersion: number): SchemaVersionAheadError {\n\t\tconst error = new SchemaVersionAheadError(this.dbName, storedVersion, this.schema.version)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'store:schema-ahead',\n\t\t\tdbName: this.dbName,\n\t\t\tstoredVersion,\n\t\t\tcodeVersion: this.schema.version,\n\t\t\tmessage: error.message,\n\t\t})\n\t\treturn error\n\t}\n\n\t/**\n\t * Run pending schema migrations (STORE-13, NEW-STORE-1): one transaction per version\n\t * (DDL, backfills, `schema_version`); backfills write operations through the local\n\t * write path so they sync, unless declared `localOnly`.\n\t */\n\tprivate async runMigrationsIfNeeded(): Promise<void> {\n\t\tconst clock = this.clock\n\t\tif (!clock) throw new StoreNotOpenError()\n\t\tconst fold = this.activeFold()\n\t\tawait runSchemaMigrations({\n\t\t\tadapter: this.adapter,\n\t\t\tschema: this.schema,\n\t\t\tenv: {\n\t\t\t\t...(fold ? { fold } : {}),\n\t\t\t\tschema: this.schema,\n\t\t\t\tclock,\n\t\t\t\tnodeId: this.nodeId,\n\t\t\t\trelationEnforcer: null,\n\t\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t},\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\tonOperation: (operation) => this.publishLocalOperation(operation.collection, operation),\n\t\t})\n\t}\n\n\tprivate async loadOrGenerateNodeId(): Promise<string> {\n\t\t// The `kora:` namespace is Kora's own (server nodes `kora:server:<id>` are\n\t\t// authoritative by prefix, RT-61): a device never authors under such an id.\n\t\tif (this.configNodeId && isReservedNodeId(this.configNodeId)) {\n\t\t\tthrow new ReservedNodeIdError(this.configNodeId, 'StoreConfig.nodeId')\n\t\t}\n\t\tif (this.configNodeId) {\n\t\t\tif (this.isolation !== 'per-tab') {\n\t\t\t\tawait this.adapter.execute(\n\t\t\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\",\n\t\t\t\t\t[this.configNodeId],\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn this.configNodeId\n\t\t}\n\n\t\tif (this.isolation === 'per-tab') {\n\t\t\treturn resolvePerTabNodeId(this.dbName)\n\t\t}\n\n\t\t// Try to load existing node ID\n\t\tconst rows = await this.adapter.query<MetaRow>(\n\t\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t\t)\n\t\tif (rows[0] && !isReservedNodeId(rows[0].value)) {\n\t\t\treturn rows[0].value\n\t\t}\n\n\t\t// Generate a new node id (a UUIDv7, never in the reserved `kora:` namespace). A\n\t\t// persisted reserved id (written by something other than this client) is never\n\t\t// adopted: the database gets a fresh identity instead.\n\t\tconst newNodeId = generateUUIDv7()\n\t\tawait this.adapter.execute(\n\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\",\n\t\t\t[newNodeId],\n\t\t)\n\t\treturn newNodeId\n\t}\n\n\tprivate async loadSequenceNumber(): Promise<number> {\n\t\tconst rows = await this.adapter.query<VersionVectorRow>(\n\t\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t\t[this.nodeId],\n\t\t)\n\t\treturn rows[0]?.sequence_number ?? 0\n\t}\n\n\tprivate async loadVersionVector(): Promise<VersionVector> {\n\t\tconst rows = await this.adapter.query<VersionVectorRow>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tconst vector = createVersionVector()\n\t\tfor (const row of rows) {\n\t\t\tvector.set(row.node_id, row.sequence_number)\n\t\t}\n\t\treturn vector\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (!this.opened) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t}\n}\n\n/**\n * Public-facing collection accessor. Provides CRUD + where.\n */\nexport interface CollectionAccessor {\n\tinsert(data: Record<string, unknown>): Promise<import('../types').CollectionRecord>\n\tfindById(id: string): Promise<import('../types').CollectionRecord | null>\n\tupdate(id: string, data: Record<string, unknown>): Promise<import('../types').CollectionRecord>\n\tdelete(id: string): Promise<void>\n\twhere(conditions: Record<string, unknown>): QueryBuilder\n}\n\n/**\n * The newest HLC an operation carries: its timestamp, or for a scope-entry insert\n * (RT-27) the greatest of its timestamp and every per-field version.\n */\nfunction newestFieldVersion(op: Operation): HLCTimestamp {\n\tlet newest = op.timestamp\n\tfor (const version of Object.values(op.fieldVersions ?? {})) {\n\t\tif (HybridLogicalClock.compare(version, newest) > 0) newest = version\n\t}\n\treturn newest\n}\n","// @korajs/store — public API\n// Every export here is a public API commitment. Be explicit.\n\n// === Types ===\nexport type {\n\tApplyRemoteOptions,\n\tApplyResult,\n\tLocalMutationHandler,\n\tMaterializedRowSnapshot,\n\tRowVersionState,\n\tCollectionRecord,\n\tReplaySnapshot,\n\tMigrationPlan,\n\tOrderByClause,\n\tOrderByDirection,\n\tQueryDescriptor,\n\tStoreConfig,\n\tStoreIsolation,\n\tStorageFallbackReason,\n\tStorageOpenState,\n\tStorageAdapter,\n\tSubscriptionCallback,\n\tTransaction,\n\tWhereClause,\n\tWhereOperators,\n} from './types'\n\n// === Errors ===\nexport {\n\tAdapterError,\n\tBridgeTerminatedError,\n\tLeaderUnresponsiveError,\n\tNoLeaderError,\n\tOptimisticLockError,\n\tPersistenceError,\n\tQueryError,\n\tRecordNotFoundError,\n\tRequestAbortedError,\n\tSchemaVersionAheadError,\n\tStorageBackendMismatchError,\n\tStorageDurabilityError,\n\tStorageInUseError,\n\tStoreNotOpenError,\n\tUnsyncedDataError,\n\tWorkerInitError,\n\tWorkerTimeoutError,\n} from './errors'\n\n// === Operation log compaction ===\nexport type { CompactionResult, CompactionStrategy } from './compaction/types'\nexport { COMPACTION_BASELINE_META_KEY } from './compaction/types'\nexport {\n\tcompactOperationLog,\n\tcomputeAckCompactionWatermark,\n} from './compaction/compact-operation-log'\n\n// === W7 record fold (client materialization) ===\nexport { mergeYjsUpdates } from './fold/record-folder'\nexport type { RematerializationMode } from './fold/rematerialize'\n\n// === Clock rebase (timestamp rebase of unsynced operations) ===\nexport type { ClockRebaseResult } from './sync/rebase-unsynced-operations'\nexport type { NodeRotationResult } from './sync/rotate-node-id'\nexport type { ResequenceResult } from './sync/rehash-operation'\nexport type { UnappliedOperation } from './sync/sync-durability'\nexport type {\n\tAdoptionSchedule,\n\tLocalNodeRecord,\n\tParkedAdoption,\n\tTerminalRejection,\n} from './sync/local-sync-records'\nexport type { PrincipalBinding } from './store/store'\n\n// === Sync state helpers ===\nexport {\n\tcollectOperationsAheadOfServer,\n\tdeserializeVersionVectorFromMeta,\n\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\tmergeVersionVectors,\n\tserializeVersionVectorToMeta,\n} from './sync/sync-state'\n\n// === Store ===\nexport { Store } from './store/store'\nexport type { CollectionAccessor } from './store/store'\n\n// === Query ===\nexport { QueryBuilder } from './query/query-builder'\nexport { normalizeWhere, queryKey } from './query/query-key'\nexport { VIRTUAL_TIMESTAMP_FIELDS, VIRTUAL_TIMESTAMP_FIELD_NAMES } from './query/sql-builder'\nexport type { VirtualTimestampField } from './query/sql-builder'\nexport type { QueryErrorPhase, QuerySubscriptionError, SubscribeOptions } from './types'\n\n// === Durable storage (navigator.storage.persist), never on the startup path ===\nexport { StoragePersistence } from './persistence/storage-persistence'\nexport type {\n\tPersistenceRequestReason,\n\tPersistenceStorageManager,\n\tStoragePersistenceOptions,\n\tStoragePersistenceState,\n\tStoragePersistenceStatus,\n} from './persistence/storage-persistence'\nexport { QueryStore } from './reactivity/query-store'\nexport { assertQueryReady } from './reactivity/assert-query-ready'\nexport {\n\tgetSharedQueryStoreCache,\n\tQueryStoreCache,\n} from './reactivity/query-store-cache'\n\n// === Subscription ===\nexport { SubscriptionManager } from './subscription/subscription-manager'\nexport type {\n\tRecordsChange,\n\tRecordsChangeListener,\n\tRegisterOptions,\n\tSubscriptionManagerOptions,\n\tSubscriptionStats,\n} from './subscription/subscription-manager'\nexport type { ResultsEqual } from './subscription/result-equality'\nexport { SubscriptionBloomFilter } from './subscription/bloom-filter'\n\n// === Collection ===\nexport { Collection } from './collection/collection'\n\n// === State Machine Validation ===\nexport {\n\tInvalidStateTransitionError,\n\tvalidateStateTransition,\n\tvalidateUpdateStateMachine,\n} from './state-machine/state-validator'\n\n// === Transaction ===\nexport { TransactionContext } from './transaction/transaction-context'\nexport type {\n\tTransactionCollectionAccessor,\n\tTransactionContextConfig,\n} from './transaction/transaction-context'\n\n// === Sequences ===\nexport { SequenceManager } from './sequences/sequence-manager'\n\n// === Richtext controller (framework bindings) ===\nexport { createRichTextController } from './richtext/create-richtext-controller'\nexport { asRichTextSyncEngine } from './richtext/as-rich-text-sync-engine'\nexport type {\n\tCreateRichTextControllerOptions,\n\tRichTextAwarenessUser,\n\tRichTextController,\n\tRichTextControllerSnapshot,\n\tRichTextCursorInfo,\n\tRichTextSyncEngine,\n} from './richtext/types'\n\n// === Richtext Serialization ===\nexport {\n\tdecodeRichtext,\n\tencodeRichtext,\n\trichtextToPlainText,\n\trichtextStatesEqual,\n} from './serialization/richtext-serializer'\n\n// === Query Utilities ===\nexport { pluralize, singularize } from './query/pluralize'\n\n// === Backup/Restore ===\nexport {\n\tBACKUP_VERSION,\n\tBackupFormatError,\n\tconvertBackupV1,\n\texportBackup,\n\treadBackupManifest,\n\trestoreBackup,\n\tverifyBackupChecksum,\n} from './backup'\nexport type {\n\tConvertBackupV1Options,\n\tBackupManifest,\n\tBackupOptions,\n\tBackupProgress,\n\tRestoreOptions,\n\tRestoreResult,\n} from './backup'\n\n// === Log integrity (W8 step 0) ===\nexport { LOG_QUARANTINE_TABLE } from './log-integrity/log-integrity'\nexport type {\n\tLogIntegrityReport,\n\tLogIntegrityRow,\n\tLogRowProblem,\n\tLogSequenceGap,\n} from './log-integrity/log-integrity'\n\n// === Audit export ===\nexport {\n\tdecodeAuditExport,\n\tpersistedAuditTraceFromEvent,\n\treadAuditExportManifest,\n\tverifyAuditExportChecksum,\n} from './audit'\nexport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditExportProgress,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './audit'\n\n// === Content-addressed blob store ===\nexport {\n\tBlobIntegrityError,\n\tMemoryBlobStore,\n\ttype ContentAddressedBlobStore,\n} from './blob/content-addressed-blob-store'\nexport {\n\tOpfsBlobStore,\n\tcreateOpfsBlobDirectory,\n\tcreateOpfsBlobStore,\n\ttype OpfsBlobDirectory,\n} from './blob/opfs-blob-store'\nexport {\n\tDEFAULT_CHUNK_SIZE,\n\tchunkBlob,\n\treassembleBlob,\n\ttype BlobManifest,\n\ttype BlobManifestMetadata,\n} from './blob/blob-chunking'\nexport {\n\tprepareBlobForSend,\n\treceiveBlob,\n\ttype ChunkProvider,\n\ttype ReceiveBlobResult,\n\ttype ReceiveBlobStores,\n} from './blob/blob-transfer'\nexport {\n\tfetchBlobManifest,\n\tparseBlobManifest,\n\tputBlobForTransfer,\n\tresolveBlobManifest,\n\tserializeBlobManifest,\n} from './blob/blob-manifest-transfer'\nexport {\n\tcreateMemoryServerBlobStore,\n\ttoServerBlobCallbacks,\n\ttype ServerBlobCallbacks,\n} from './blob/server-blob-callbacks'\nexport {\n\tcollectBlobGarbage,\n\textractBlobRefs,\n\ttype BlobGcOptions,\n\ttype BlobGcResult,\n} from './blob/blob-gc'\nexport {\n\tcreateChunkPortPair,\n\tcreateRemoteChunkProvider,\n\tserveBlobChunks,\n\ttype ChunkMessage,\n\ttype ChunkMessagePort,\n\ttype ChunkRequestMessage,\n\ttype ChunkResponseMessage,\n\ttype RemoteChunkProvider,\n\ttype RemoteChunkProviderOptions,\n} from './blob/blob-chunk-transport'\n","import type { KoraEventEmitter } from '@korajs/core'\n\n/**\n * Durable-storage state of this origin, as far as Kora knows (NEW-STORE-4).\n * - `unknown`: not checked yet (the boot check runs in the background).\n * - `persisted`: the browser granted persistent storage; it will not evict this\n * origin's data under storage pressure.\n * - `best-effort`: storage may be evicted under pressure (the browser default).\n * - `unsupported`: the runtime has no StorageManager persistence API (Node,\n * older browsers, some WebViews).\n * - `error`: the check or request threw; `lastError` says why.\n */\nexport type StoragePersistenceState =\n\t| 'unknown'\n\t| 'persisted'\n\t| 'best-effort'\n\t| 'unsupported'\n\t| 'error'\n\n/** Snapshot returned by `app.storage.persistence.status()`. */\nexport interface StoragePersistenceStatus {\n\tstate: StoragePersistenceState\n\t/** True only when the browser reported persistent storage. */\n\tpersisted: boolean\n\t/** True once `persist()` was asked for (explicitly or by an automatic trigger). */\n\trequested: boolean\n\t/** Message of the last failure, when `state` is `error`. */\n\tlastError?: string\n}\n\n/** Why an automatic (background) persistence request was made. */\nexport type PersistenceRequestReason = 'explicit' | 'sign-in' | 'first-write' | 'installed-app'\n\n/** The subset of `navigator.storage` used here. */\nexport interface PersistenceStorageManager {\n\tpersist?: () => Promise<boolean>\n\tpersisted?: () => Promise<boolean>\n}\n\n/** Options for {@link StoragePersistence}. */\nexport interface StoragePersistenceOptions {\n\t/** Receives `storage:persistence` events. */\n\temitter?: KoraEventEmitter | null\n\t/**\n\t * The StorageManager to use. Defaults to `globalThis.navigator.storage`,\n\t * resolved on each call so tests and late polyfills are honoured.\n\t */\n\tstorage?: PersistenceStorageManager | null\n}\n\nfunction defaultStorageManager(): PersistenceStorageManager | null {\n\tconst nav = (globalThis as { navigator?: { storage?: PersistenceStorageManager } }).navigator\n\treturn nav?.storage ?? null\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Tracks and requests durable storage (`navigator.storage.persist()`) without ever\n * putting it on the startup path (NEW-STORE-4).\n *\n * In Firefox `persist()` opens a permission prompt and its promise stays pending\n * until the user answers, so awaiting it inside startup could hang `app.ready`\n * forever. Kora therefore:\n * - checks `persisted()` at boot, which never prompts, in the background;\n * - requests persistence only on an explicit `request()` or, without awaiting,\n * after a meaningful moment (sign-in, the first local write, running as an\n * installed app);\n * - surfaces every result through `status()` and the `storage:persistence` event,\n * never by blocking.\n */\nexport class StoragePersistence {\n\tprivate current: StoragePersistenceStatus = {\n\t\tstate: 'unknown',\n\t\tpersisted: false,\n\t\trequested: false,\n\t}\n\tprivate inFlightRequest: Promise<StoragePersistenceStatus> | null = null\n\tprivate readonly emitter: KoraEventEmitter | null\n\tprivate readonly storageOverride: PersistenceStorageManager | null | undefined\n\n\tconstructor(options: StoragePersistenceOptions = {}) {\n\t\tthis.emitter = options.emitter ?? null\n\t\tthis.storageOverride = options.storage\n\t}\n\n\t/** Synchronous snapshot of the last known state. Never prompts. */\n\tstatus(): StoragePersistenceStatus {\n\t\treturn { ...this.current }\n\t}\n\n\t/**\n\t * Read whether storage is already persistent (`navigator.storage.persisted()`).\n\t * Never prompts and never throws: a failure becomes `state: 'error'`.\n\t */\n\tasync check(): Promise<StoragePersistenceStatus> {\n\t\tconst storage = this.storage()\n\t\tif (!storage || typeof storage.persisted !== 'function') {\n\t\t\tthis.update({ state: 'unsupported', persisted: false })\n\t\t\tif (storage) this.emit('unsupported', false)\n\t\t\treturn this.status()\n\t\t}\n\t\ttry {\n\t\t\tconst persisted = (await storage.persisted()) === true\n\t\t\t// A grant observed by a concurrent request() is never downgraded here.\n\t\t\tif (!this.current.persisted) {\n\t\t\t\tthis.update({ state: persisted ? 'persisted' : 'best-effort', persisted })\n\t\t\t}\n\t\t\tthis.emit('checked', this.current.persisted)\n\t\t} catch (error) {\n\t\t\tthis.update({ state: 'error', persisted: false, lastError: errorMessage(error) })\n\t\t\tthis.emit('error', false, errorMessage(error))\n\t\t}\n\t\treturn this.status()\n\t}\n\n\t/**\n\t * Ask the browser for persistent storage (`navigator.storage.persist()`).\n\t * May show a permission prompt (Firefox), so call it from a user gesture or a\n\t * meaningful moment, and do not block rendering on it. Concurrent calls share\n\t * one request. Never throws: a failure becomes `state: 'error'`.\n\t *\n\t * @returns The state after the browser answered\n\t */\n\trequest(): Promise<StoragePersistenceStatus> {\n\t\tif (this.inFlightRequest) return this.inFlightRequest\n\t\tconst storage = this.storage()\n\t\tif (!storage || typeof storage.persist !== 'function') {\n\t\t\tthis.update({ state: 'unsupported', persisted: false })\n\t\t\tif (storage) this.emit('unsupported', false)\n\t\t\treturn Promise.resolve(this.status())\n\t\t}\n\t\tif (this.current.persisted) return Promise.resolve(this.status())\n\t\tconst persist = storage.persist.bind(storage)\n\t\tthis.current = { ...this.current, requested: true }\n\t\tconst pending = (async (): Promise<StoragePersistenceStatus> => {\n\t\t\ttry {\n\t\t\t\tconst persisted = (await persist()) === true\n\t\t\t\tthis.update({ state: persisted ? 'persisted' : 'best-effort', persisted })\n\t\t\t\tthis.emit('requested', persisted)\n\t\t\t} catch (error) {\n\t\t\t\tthis.update({ state: 'error', persisted: false, lastError: errorMessage(error) })\n\t\t\t\tthis.emit('error', false, errorMessage(error))\n\t\t\t} finally {\n\t\t\t\tthis.inFlightRequest = null\n\t\t\t}\n\t\t\treturn this.status()\n\t\t})()\n\t\tthis.inFlightRequest = pending\n\t\treturn pending\n\t}\n\n\t/**\n\t * Fire-and-forget `request()` for an automatic trigger. Never awaited by Kora,\n\t * so a pending prompt cannot block anything; the outcome arrives as a\n\t * `storage:persistence` event. Skipped when storage is already persistent or a\n\t * request was already made this session.\n\t *\n\t * @param _reason - Which trigger fired (kept for tracing at call sites)\n\t */\n\trequestInBackground(_reason: PersistenceRequestReason): void {\n\t\tif (this.current.persisted || this.current.requested) return\n\t\tvoid this.request()\n\t}\n\n\tprivate storage(): PersistenceStorageManager | null {\n\t\treturn this.storageOverride === undefined ? defaultStorageManager() : this.storageOverride\n\t}\n\n\tprivate update(next: Omit<StoragePersistenceStatus, 'requested'>): void {\n\t\tthis.current = { ...next, requested: this.current.requested }\n\t}\n\n\tprivate emit(\n\t\tstate: 'checked' | 'requested' | 'unsupported' | 'error',\n\t\tpersisted: boolean,\n\t\tmessage?: string,\n\t): void {\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'storage:persistence',\n\t\t\tstate,\n\t\t\tpersisted,\n\t\t\t...(message !== undefined ? { message } : {}),\n\t\t})\n\t}\n}\n","import type { QueryBuilder } from '../query/query-builder'\nimport type { CollectionRecord } from '../types'\n\n/**\n * Frozen empty array returned as the initial snapshot before any data loads.\n * Same reference every time prevents infinite update loops in UI bindings.\n */\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\n/**\n * Bridges the async QueryBuilder.subscribe() API with synchronous snapshot reads\n * required by React useSyncExternalStore, Vue composables, and Svelte stores.\n *\n * Uses lazy subscription: the underlying query subscription starts when the first\n * listener attaches and stops when the last listener detaches.\n */\nexport class QueryStore<T = CollectionRecord> {\n\tprivate snapshot: readonly T[] = EMPTY_ARRAY as readonly T[]\n\tprivate listeners = new Set<() => void>()\n\tprivate unsubscribeQuery: (() => void) | null = null\n\tprivate active = false\n\tprivate hasEmittedSnapshot = false\n\tprivate error: Error | null = null\n\tprivate readonly queryBuilder: QueryBuilder<T>\n\n\tconstructor(queryBuilder: QueryBuilder<T>) {\n\t\tthis.queryBuilder = queryBuilder\n\t}\n\n\t/**\n\t * Subscribe to snapshot changes.\n\t *\n\t * @returns Unsubscribe function\n\t */\n\tsubscribe = (onStoreChange: () => void): (() => void) => {\n\t\tthis.listeners.add(onStoreChange)\n\n\t\tif (!this.active) {\n\t\t\tthis.startSubscription()\n\t\t}\n\n\t\treturn () => {\n\t\t\tthis.listeners.delete(onStoreChange)\n\t\t\tif (this.listeners.size === 0) {\n\t\t\t\tthis.stopSubscription()\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Synchronous read of the latest query results. */\n\tgetSnapshot = (): readonly T[] => {\n\t\treturn this.snapshot\n\t}\n\n\t/**\n\t * Whether the underlying query subscription has delivered at least one\n\t * authoritative result for the current subscription lifecycle.\n\t */\n\thasSnapshot = (): boolean => {\n\t\treturn this.hasEmittedSnapshot\n\t}\n\n\t/**\n\t * The latest query failure, or null. Set when the query (or a re-run after a\n\t * write) fails; cleared by the next successful delivery. Listeners are notified\n\t * on both transitions, so bindings read it next to `getSnapshot()`.\n\t */\n\tgetError = (): Error | null => {\n\t\treturn this.error\n\t}\n\n\t/** Tear down listeners and the underlying query subscription. */\n\tdestroy(): void {\n\t\tthis.stopSubscription()\n\t\tthis.listeners.clear()\n\t\tthis.snapshot = EMPTY_ARRAY as readonly T[]\n\t\tthis.hasEmittedSnapshot = false\n\t\tthis.error = null\n\t}\n\n\tprivate startSubscription(): void {\n\t\tthis.active = true\n\t\tthis.unsubscribeQuery = this.queryBuilder.subscribe(\n\t\t\t(results: readonly T[]) => {\n\t\t\t\tif (!this.active) return\n\t\t\t\tthis.hasEmittedSnapshot = true\n\t\t\t\tthis.error = null\n\t\t\t\tthis.snapshot = Object.freeze([...results])\n\t\t\t\tthis.notifyListeners()\n\t\t\t},\n\t\t\t{\n\t\t\t\t// STORE-12: the failure reaches bindings as error state; the last\n\t\t\t\t// snapshot stays readable and the next success clears the error.\n\t\t\t\tonError: (failure) => {\n\t\t\t\t\tif (!this.active) return\n\t\t\t\t\tthis.error = failure.error\n\t\t\t\t\tthis.notifyListeners()\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t}\n\n\tprivate stopSubscription(): void {\n\t\tthis.active = false\n\t\tif (this.unsubscribeQuery) {\n\t\t\tthis.unsubscribeQuery()\n\t\t\tthis.unsubscribeQuery = null\n\t\t}\n\t}\n\n\tprivate notifyListeners(): void {\n\t\tfor (const listener of this.listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n}\n","import { AppNotReadyError } from '@korajs/core'\nimport type { QueryBuilder } from '../query/query-builder'\n\nconst LEGACY_PENDING_COLLECTION = '__pending__'\n\n/**\n * Ensures a query builder is backed by an open store (not a legacy pending placeholder).\n */\nexport function assertQueryReady(query: QueryBuilder<unknown>): void {\n\tconst descriptor = query.getDescriptor()\n\tif (descriptor.collection === LEGACY_PENDING_COLLECTION) {\n\t\tthrow new AppNotReadyError(\n\t\t\t'Cannot use useQuery() before app.ready. Await app.ready or wrap your UI in <KoraProvider app={app}>.',\n\t\t)\n\t}\n}\n","import type { QueryBuilder } from '../query/query-builder'\nimport { queryKey } from '../query/query-key'\nimport type { CollectionRecord } from '../types'\nimport { QueryStore } from './query-store'\n\ninterface CacheEntry {\n\tqueryStore: QueryStore<CollectionRecord>\n\trefCount: number\n}\n\n/**\n * Reference-counted cache of {@link QueryStore} instances keyed by query descriptor.\n * Identical queries from different components share one underlying subscription.\n */\nexport class QueryStoreCache {\n\tprivate entries = new Map<string, CacheEntry>()\n\n\tconstructor(private readonly scopeKey = 'default') {}\n\n\tgetOrCreate<T>(queryBuilder: QueryBuilder<T>): QueryStore<T> {\n\t\tconst key = this.getKey(queryBuilder)\n\t\tconst existing = this.entries.get(key)\n\n\t\tif (existing) {\n\t\t\texisting.refCount++\n\t\t\treturn existing.queryStore as QueryStore<T>\n\t\t}\n\n\t\tconst queryStore = new QueryStore<T>(queryBuilder)\n\t\tthis.entries.set(key, {\n\t\t\tqueryStore: queryStore as QueryStore<CollectionRecord>,\n\t\t\trefCount: 1,\n\t\t})\n\t\treturn queryStore\n\t}\n\n\trelease(queryBuilder: QueryBuilder<unknown>): void {\n\t\tconst key = this.getKey(queryBuilder)\n\t\tconst entry = this.entries.get(key)\n\t\tif (!entry) {\n\t\t\treturn\n\t\t}\n\n\t\tentry.refCount--\n\t\tif (entry.refCount <= 0) {\n\t\t\tentry.queryStore.destroy()\n\t\t\tthis.entries.delete(key)\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tentry.queryStore.destroy()\n\t\t}\n\t\tthis.entries.clear()\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size\n\t}\n\n\tprivate getKey(queryBuilder: QueryBuilder<unknown>): string {\n\t\treturn `${this.scopeKey}:${queryKey(queryBuilder.getDescriptor())}`\n\t}\n}\n\nlet sharedCache: QueryStoreCache | null = null\n\n/**\n * Process-wide shared query store cache for framework bindings.\n *\n * @deprecated Prefer {@link KoraApp.getQueryStoreCache} via `KoraProvider` context\n * so each app instance owns an isolated cache.\n */\nexport function getSharedQueryStoreCache(): QueryStoreCache {\n\tif (!sharedCache) {\n\t\tsharedCache = new QueryStoreCache()\n\t}\n\treturn sharedCache\n}\n","import * as Y from 'yjs'\nimport { encodeRichtext } from '../serialization/richtext-serializer'\nimport type {\n\tCreateRichTextControllerOptions,\n\tRichTextAwarenessState,\n\tRichTextAwarenessUser,\n\tRichTextController,\n\tRichTextControllerSnapshot,\n\tRichTextCursorInfo,\n} from './types'\n\nconst LOAD_ORIGIN = 'kora-load'\nconst REMOTE_ORIGIN = 'kora-remote'\nconst DOC_CHANNEL_ORIGIN = 'kora-doc-channel'\nconst TEXT_KEY = 'content'\nconst COMPACT_AFTER_DELTAS = 20\nconst PERSIST_DEBOUNCE_MS = 400\n\n/**\n * Framework-agnostic richtext binding: Yjs document lifecycle, persistence,\n * incremental doc channel, and awareness cursors.\n */\nexport function createRichTextController(\n\toptions: CreateRichTextControllerOptions,\n): RichTextController {\n\tconst {\n\t\tcollection,\n\t\tcollectionName,\n\t\trecordId,\n\t\tfieldName,\n\t\tstore,\n\t\tsyncEngine = null,\n\t\tuseDocChannel,\n\t} = options\n\n\tconst doc = new Y.Doc()\n\tconst text = doc.getText(TEXT_KEY)\n\tconst undoManager = new Y.UndoManager(text)\n\n\tlet user = options.user\n\tlet disposed = false\n\tlet ready = false\n\tlet error: Error | null = null\n\tlet canUndo = false\n\tlet canRedo = false\n\tlet cursors: RichTextCursorInfo[] = []\n\n\tconst listeners = new Set<() => void>()\n\tlet snapshot: RichTextControllerSnapshot = {\n\t\tready: false,\n\t\terror: null,\n\t\tcanUndo: false,\n\t\tcanRedo: false,\n\t\tcursors: [],\n\t}\n\tconst baseUpdateRef = { current: null as Uint8Array | null }\n\tconst pendingDeltasRef = { current: [] as Uint8Array[] }\n\tconst docChannelActiveRef = { current: false }\n\tlet persistTimer: ReturnType<typeof setTimeout> | null = null\n\n\tlet recordUnsubscribe: (() => void) | null = null\n\tlet docChannelUnsubscribe: (() => void) | null = null\n\tlet awarenessUnsubscribe: (() => void) | null = null\n\n\tconst refreshSnapshot = (): void => {\n\t\tsnapshot = {\n\t\t\tready,\n\t\t\terror,\n\t\t\tcanUndo,\n\t\t\tcanRedo,\n\t\t\tcursors: [...cursors],\n\t\t}\n\t}\n\n\tconst notify = (): void => {\n\t\trefreshSnapshot()\n\t\tfor (const listener of listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n\n\tconst syncHistoryState = (): void => {\n\t\tcanUndo = undoManager.undoStack.length > 0\n\t\tcanRedo = undoManager.redoStack.length > 0\n\t\tnotify()\n\t}\n\n\tconst getSnapshot = (): RichTextControllerSnapshot => snapshot\n\n\tconst resolveAwarenessUser = (): RichTextAwarenessUser => {\n\t\tif (user) {\n\t\t\treturn user\n\t\t}\n\t\tif (syncEngine) {\n\t\t\tconst existing = syncEngine.getAwarenessManager().getLocalState()?.user\n\t\t\tif (existing) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tname: 'Anonymous',\n\t\t\tcolor: '#6366f1',\n\t\t}\n\t}\n\n\tconst setCursor = (anchor: number, head: number): void => {\n\t\tif (!syncEngine) {\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst state: RichTextAwarenessState = {\n\t\t\tuser: resolveAwarenessUser(),\n\t\t\tcursor: {\n\t\t\t\tcollection: collectionName,\n\t\t\t\trecordId,\n\t\t\t\tfield: fieldName,\n\t\t\t\tanchor,\n\t\t\t\thead,\n\t\t\t},\n\t\t}\n\t\tawareness.setLocalState(state)\n\t}\n\n\tconst clearCursor = (): void => {\n\t\tif (!syncEngine) {\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst current = awareness.getLocalState()\n\t\tif (!current?.cursor) {\n\t\t\treturn\n\t\t}\n\t\tif (\n\t\t\tcurrent.cursor.collection !== collectionName ||\n\t\t\tcurrent.cursor.recordId !== recordId ||\n\t\t\tcurrent.cursor.field !== fieldName\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tawareness.setLocalState({ user: current.user })\n\t}\n\n\tconst applyRemoteSnapshot = (value: unknown): void => {\n\t\tconst encoded = encodeRichtextInput(value)\n\t\tif (!encoded) {\n\t\t\treturn\n\t\t}\n\n\t\tconst currentSnapshot = Y.encodeStateAsUpdate(doc)\n\t\tif (updatesEqual(currentSnapshot, encoded)) {\n\t\t\treturn\n\t\t}\n\n\t\tY.applyUpdate(doc, encoded, REMOTE_ORIGIN)\n\t\tbaseUpdateRef.current = encoded\n\t\tpendingDeltasRef.current = []\n\t\tsyncHistoryState()\n\t}\n\n\tconst flushPersist = async (): Promise<void> => {\n\t\tconst snapshot = composeRichtextSnapshot(baseUpdateRef.current, pendingDeltasRef.current)\n\t\tif (pendingDeltasRef.current.length >= COMPACT_AFTER_DELTAS) {\n\t\t\tbaseUpdateRef.current = snapshot\n\t\t\tpendingDeltasRef.current = []\n\t\t}\n\n\t\ttry {\n\t\t\tawait collection.update(recordId, {\n\t\t\t\t[fieldName]: snapshot,\n\t\t\t})\n\t\t} catch (cause) {\n\t\t\tif (!disposed) {\n\t\t\t\terror = cause instanceof Error ? cause : new Error(String(cause))\n\t\t\t\tnotify()\n\t\t\t}\n\t\t}\n\t}\n\n\tconst schedulePersist = (): void => {\n\t\tif (persistTimer) {\n\t\t\tclearTimeout(persistTimer)\n\t\t}\n\t\tpersistTimer = setTimeout(() => {\n\t\t\tpersistTimer = null\n\t\t\tvoid flushPersist()\n\t\t}, PERSIST_DEBOUNCE_MS)\n\t}\n\n\tconst onDocUpdate = (update: Uint8Array, origin: unknown): void => {\n\t\tsyncHistoryState()\n\t\tif (origin === LOAD_ORIGIN || origin === REMOTE_ORIGIN || origin === DOC_CHANNEL_ORIGIN) {\n\t\t\treturn\n\t\t}\n\n\t\tpendingDeltasRef.current.push(update)\n\n\t\tif (docChannelActiveRef.current && syncEngine) {\n\t\t\tsyncEngine.getRichtextDocChannel?.().send(collectionName, recordId, fieldName, update)\n\t\t\tschedulePersist()\n\t\t\treturn\n\t\t}\n\n\t\tvoid flushPersist()\n\t}\n\n\tconst subscribeRecordChanges = (): void => {\n\t\trecordUnsubscribe?.()\n\t\trecordUnsubscribe = store\n\t\t\t.collection(collectionName)\n\t\t\t.where({ id: recordId })\n\t\t\t.subscribe((results) => {\n\t\t\t\tconst record = results[0]\n\t\t\t\tif (!record) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tapplyRemoteSnapshot(record[fieldName])\n\t\t\t})\n\t}\n\n\tconst subscribeDocChannel = (): void => {\n\t\tdocChannelUnsubscribe?.()\n\t\tif (!ready || !syncEngine || !docChannelActiveRef.current) {\n\t\t\treturn\n\t\t}\n\n\t\tconst channel = syncEngine.getRichtextDocChannel?.()\n\t\tif (!channel) {\n\t\t\treturn\n\t\t}\n\n\t\tdocChannelUnsubscribe = channel.subscribe(collectionName, recordId, fieldName, (update) => {\n\t\t\tY.applyUpdate(doc, update, DOC_CHANNEL_ORIGIN)\n\t\t\tsyncHistoryState()\n\t\t})\n\t}\n\n\tconst updateCursors = (): void => {\n\t\tif (!syncEngine) {\n\t\t\tcursors = []\n\t\t\tnotify()\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst localClientId = awareness.clientId\n\t\tconst states = awareness.getStates()\n\t\tconst fieldCursors: RichTextCursorInfo[] = []\n\n\t\tfor (const [clientId, state] of states) {\n\t\t\tif (clientId === localClientId) continue\n\t\t\tif (!state.cursor) continue\n\t\t\tif (\n\t\t\t\tstate.cursor.collection !== collectionName ||\n\t\t\t\tstate.cursor.recordId !== recordId ||\n\t\t\t\tstate.cursor.field !== fieldName\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfieldCursors.push({\n\t\t\t\tclientId,\n\t\t\t\tuserName: state.user.name,\n\t\t\t\tcolor: state.user.color,\n\t\t\t\tanchor: state.cursor.anchor,\n\t\t\t\thead: state.cursor.head,\n\t\t\t})\n\t\t}\n\n\t\tcursors = fieldCursors\n\t\tnotify()\n\t}\n\n\tconst subscribeAwareness = (): void => {\n\t\tawarenessUnsubscribe?.()\n\t\tif (!syncEngine) {\n\t\t\tcursors = []\n\t\t\tnotify()\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tawarenessUnsubscribe = awareness.on('change', () => {\n\t\t\tupdateCursors()\n\t\t})\n\t\tupdateCursors()\n\t}\n\n\tconst initialize = async (): Promise<void> => {\n\t\tready = false\n\t\terror = null\n\t\tnotify()\n\n\t\ttry {\n\t\t\tconst record = await collection.findById(recordId)\n\t\t\tif (disposed) return\n\n\t\t\tdoc.transact(() => {\n\t\t\t\tconst target = doc.getText(TEXT_KEY)\n\t\t\t\ttarget.delete(0, target.length)\n\t\t\t}, LOAD_ORIGIN)\n\n\t\t\tconst encoded = encodeRichtextInput(record?.[fieldName])\n\t\t\tbaseUpdateRef.current = encoded\n\t\t\tpendingDeltasRef.current = []\n\t\t\tif (encoded) {\n\t\t\t\tY.applyUpdate(doc, encoded, LOAD_ORIGIN)\n\t\t\t}\n\n\t\t\tconst channel = syncEngine?.getRichtextDocChannel?.()\n\t\t\tdocChannelActiveRef.current =\n\t\t\t\tchannel?.shouldUseChannel(encoded?.length ?? 0, useDocChannel) ?? false\n\n\t\t\tready = true\n\t\t\tsyncHistoryState()\n\t\t\tsubscribeRecordChanges()\n\t\t\tsubscribeDocChannel()\n\t\t\tsubscribeAwareness()\n\t\t\tnotify()\n\t\t} catch (cause) {\n\t\t\tif (disposed) return\n\t\t\terror = cause instanceof Error ? cause : new Error(String(cause))\n\t\t\tnotify()\n\t\t}\n\t}\n\n\tdoc.on('update', onDocUpdate)\n\tvoid initialize()\n\n\treturn {\n\t\tdoc,\n\t\ttext,\n\t\tgetSnapshot,\n\t\tsubscribe(listener) {\n\t\t\tlisteners.add(listener)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t}\n\t\t},\n\t\tundo() {\n\t\t\tundoManager.undo()\n\t\t\tsyncHistoryState()\n\t\t},\n\t\tredo() {\n\t\t\tundoManager.redo()\n\t\t\tsyncHistoryState()\n\t\t},\n\t\tsetCursor,\n\t\tclearCursor,\n\t\tsetUser(nextUser: RichTextAwarenessUser | undefined) {\n\t\t\tuser = nextUser\n\t\t},\n\t\tdestroy() {\n\t\t\tif (disposed) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdisposed = true\n\t\t\tif (persistTimer) {\n\t\t\t\tclearTimeout(persistTimer)\n\t\t\t\tpersistTimer = null\n\t\t\t}\n\t\t\tdoc.off('update', onDocUpdate)\n\t\t\trecordUnsubscribe?.()\n\t\t\tdocChannelUnsubscribe?.()\n\t\t\tawarenessUnsubscribe?.()\n\t\t\tclearCursor()\n\t\t\tundoManager.destroy()\n\t\t\tbaseUpdateRef.current = null\n\t\t\tpendingDeltasRef.current = []\n\t\t\tdocChannelActiveRef.current = false\n\t\t\tlisteners.clear()\n\t\t},\n\t}\n}\n\nfunction encodeRichtextInput(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\ttry {\n\t\treturn encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t} catch {\n\t\tif (typeof value === 'string') {\n\t\t\tconst fallbackDoc = new Y.Doc()\n\t\t\tfallbackDoc.getText(TEXT_KEY).insert(0, value)\n\t\t\treturn Y.encodeStateAsUpdate(fallbackDoc)\n\t\t}\n\t\tthrow new Error('Richtext record value must be a string, Uint8Array, ArrayBuffer, or null.')\n\t}\n}\n\nfunction composeRichtextSnapshot(base: Uint8Array | null, deltas: Uint8Array[]): Uint8Array {\n\tconst mergedDoc = new Y.Doc()\n\tif (base) {\n\t\tY.applyUpdate(mergedDoc, base)\n\t}\n\n\tfor (const delta of deltas) {\n\t\tY.applyUpdate(mergedDoc, delta)\n\t}\n\n\treturn Y.encodeStateAsUpdate(mergedDoc)\n}\n\nfunction updatesEqual(left: Uint8Array, right: Uint8Array): boolean {\n\tif (left.length !== right.length) {\n\t\treturn false\n\t}\n\tfor (let index = 0; index < left.length; index++) {\n\t\tif (left[index] !== right[index]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n","import type { RichTextSyncEngine } from './types'\n\n/**\n * Narrows a sync engine reference to the richtext controller surface.\n * SyncEngine satisfies this interface at runtime; types live in different packages.\n */\nexport function asRichTextSyncEngine(engine: unknown): RichTextSyncEngine | null {\n\tif (engine == null) {\n\t\treturn null\n\t}\n\treturn engine as RichTextSyncEngine\n}\n","export {\n\tBACKUP_VERSION,\n\tBackupFormatError,\n\tconvertBackupV1,\n\texportBackup,\n\tparseBackup,\n\treadBackupManifest,\n\trestoreBackup,\n\tverifyBackupChecksum,\n} from './backup'\nexport type { ConvertBackupV1Options, ParsedBackup } from './backup'\nexport type {\n\tBackupManifest,\n\tBackupOptions,\n\tBackupProgress,\n\tRestoreOptions,\n\tRestoreResult,\n} from './types'\n","export {\n\tappendAuditTrace,\n\tauditTraceIndexFields,\n\tcountAuditTraces,\n\tpersistedAuditTraceFromEvent,\n\treadAuditTraces,\n} from './audit-trace-store'\nexport {\n\tauditJsonReplacer,\n\tauditJsonReviver,\n\tdeserializeAuditJson,\n\tserializeAuditJson,\n} from './audit-json'\nexport {\n\tdecodeAuditExport,\n\texportAudit,\n\treadAuditExportManifest,\n\tverifyAuditExportChecksum,\n} from './export-audit'\nexport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditExportProgress,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './types'\n","import { type BlobRef, type BlobRefMetadata, createBlobRef, hashBlob } from '@korajs/core'\n\n/**\n * Thrown when a blob read fails its integrity check: the bytes stored under a\n * hash do not actually hash to that value (corruption or tampering).\n */\nexport class BlobIntegrityError extends Error {\n\tconstructor(\n\t\treadonly expectedHash: string,\n\t\treadonly actualHash: string,\n\t) {\n\t\tsuper(`Blob integrity check failed: content under hash ${expectedHash} hashes to ${actualHash}`)\n\t\tthis.name = 'BlobIntegrityError'\n\t}\n}\n\n/**\n * A content-addressed store for the bytes behind `blob` fields.\n *\n * Blobs are keyed by the SHA-256 hash of their content, so identical content is\n * stored exactly once (deduplication) and a peer never needs to transfer bytes\n * it already holds. Reads are integrity-checked: the returned bytes are verified\n * to hash to the requested key.\n */\nexport interface ContentAddressedBlobStore {\n\t/**\n\t * Store bytes and return their content-addressed reference. Storing content\n\t * that already exists is a no-op that returns the same reference (dedup).\n\t */\n\tput(bytes: Uint8Array, metadata?: BlobRefMetadata): Promise<BlobRef>\n\t/**\n\t * Retrieve the bytes for a hash, or null if absent. The returned bytes are\n\t * verified to hash to the requested value; a mismatch throws\n\t * {@link BlobIntegrityError} rather than returning corrupt data.\n\t */\n\tget(hash: string): Promise<Uint8Array | null>\n\t/** Whether the store holds content for the given hash. */\n\thas(hash: string): Promise<boolean>\n\t/** Remove the content for a hash. Returns whether anything was removed. */\n\tdelete(hash: string): Promise<boolean>\n\t/** Number of distinct blobs held. */\n\tsize(): Promise<number>\n\t/**\n\t * List the hashes of every blob currently held. Used by garbage collection to\n\t * find content no live reference points to. Order is unspecified.\n\t */\n\tlist(): Promise<string[]>\n}\n\n/**\n * In-memory {@link ContentAddressedBlobStore}. The reference backend used for\n * tests and for environments without a persistent blob backend yet. Persistent\n * backends (OPFS client-side, filesystem/S3 server-side) implement the same\n * interface.\n */\nexport class MemoryBlobStore implements ContentAddressedBlobStore {\n\tprivate readonly blobs = new Map<string, Uint8Array>()\n\n\tasync put(bytes: Uint8Array, metadata: BlobRefMetadata = {}): Promise<BlobRef> {\n\t\tconst ref = await createBlobRef(bytes, metadata)\n\t\tif (!this.blobs.has(ref.hash)) {\n\t\t\t// Copy so later mutation of the caller's buffer cannot corrupt the store.\n\t\t\tconst stored = new Uint8Array(bytes.byteLength)\n\t\t\tstored.set(bytes)\n\t\t\tthis.blobs.set(ref.hash, stored)\n\t\t}\n\t\treturn ref\n\t}\n\n\tasync get(hash: string): Promise<Uint8Array | null> {\n\t\tconst stored = this.blobs.get(hash)\n\t\tif (stored === undefined) {\n\t\t\treturn null\n\t\t}\n\t\tconst actualHash = await hashBlob(stored)\n\t\tif (actualHash !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actualHash)\n\t\t}\n\t\t// Return a copy so callers cannot mutate the stored bytes.\n\t\tconst out = new Uint8Array(stored.byteLength)\n\t\tout.set(stored)\n\t\treturn out\n\t}\n\n\tasync has(hash: string): Promise<boolean> {\n\t\treturn this.blobs.has(hash)\n\t}\n\n\tasync delete(hash: string): Promise<boolean> {\n\t\treturn this.blobs.delete(hash)\n\t}\n\n\tasync size(): Promise<number> {\n\t\treturn this.blobs.size\n\t}\n\n\tasync list(): Promise<string[]> {\n\t\treturn [...this.blobs.keys()]\n\t}\n}\n","import { type BlobRef, type BlobRefMetadata, createBlobRef, hashBlob } from '@korajs/core'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * The minimal directory abstraction an {@link OpfsBlobStore} needs. Blobs are\n * laid out as `<shard>/<name>` (shard = first two hex chars of the hash) so a\n * single directory never holds millions of entries.\n *\n * The real backend ({@link createOpfsBlobDirectory}) is the browser Origin\n * Private File System; tests supply an in-memory implementation. Keeping this\n * port small means the content-addressed logic (hashing, integrity, dedup,\n * sharding) is fully testable without a browser.\n */\nexport interface OpfsBlobDirectory {\n\t/** Read the bytes at `<shard>/<name>`, or null if absent. */\n\tread(shard: string, name: string): Promise<Uint8Array | null>\n\t/**\n\t * Write bytes at `<shard>/<name>`, creating the shard directory as needed.\n\t * Must be atomic: a crash mid-write may not leave a partially-written file\n\t * that a later read would trust.\n\t */\n\twrite(shard: string, name: string, bytes: Uint8Array): Promise<void>\n\t/** Remove `<shard>/<name>`. Returns whether anything was removed. */\n\tremove(shard: string, name: string): Promise<boolean>\n\t/** Whether `<shard>/<name>` exists. */\n\thas(shard: string, name: string): Promise<boolean>\n\t/** Count of stored blobs across all shards (temp files excluded). */\n\tcount(): Promise<number>\n\t/** Every stored blob name (hash) across all shards (temp files excluded). */\n\tkeys(): Promise<string[]>\n}\n\n/**\n * A persistent {@link ContentAddressedBlobStore} for the browser, backed by the\n * Origin Private File System (OPFS) — the same durable storage the SQLite WASM\n * adapter uses. Blobs survive reloads, are sharded by hash prefix, deduplicated,\n * and integrity-verified on read (the returned bytes are checked to hash to the\n * requested key). Writes commit atomically so a torn write cannot surface as\n * trusted data.\n *\n * The store itself is environment-neutral: it talks to an {@link OpfsBlobDirectory}.\n * Use {@link createOpfsBlobStore} in a browser to get one backed by real OPFS.\n */\nexport class OpfsBlobStore implements ContentAddressedBlobStore {\n\tconstructor(private readonly dir: OpfsBlobDirectory) {}\n\n\tprivate shardFor(hash: string): string {\n\t\t// Two hex chars → 256 shards. Hashes are hex, so this is always well-formed.\n\t\treturn hash.slice(0, 2)\n\t}\n\n\tasync put(bytes: Uint8Array, metadata: BlobRefMetadata = {}): Promise<BlobRef> {\n\t\tconst ref = await createBlobRef(bytes, metadata)\n\t\tconst shard = this.shardFor(ref.hash)\n\n\t\t// Dedup: identical content already stored is a no-op.\n\t\tif (await this.dir.has(shard, ref.hash)) {\n\t\t\treturn ref\n\t\t}\n\n\t\t// Copy into an exactly-sized buffer so a subarray view writes its own bytes.\n\t\tconst out = new Uint8Array(bytes.byteLength)\n\t\tout.set(bytes)\n\t\tawait this.dir.write(shard, ref.hash, out)\n\t\treturn ref\n\t}\n\n\tasync get(hash: string): Promise<Uint8Array | null> {\n\t\tconst bytes = await this.dir.read(this.shardFor(hash), hash)\n\t\tif (bytes === null) {\n\t\t\treturn null\n\t\t}\n\t\tconst actual = await hashBlob(bytes)\n\t\tif (actual !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actual)\n\t\t}\n\t\treturn bytes\n\t}\n\n\tasync has(hash: string): Promise<boolean> {\n\t\treturn this.dir.has(this.shardFor(hash), hash)\n\t}\n\n\tasync delete(hash: string): Promise<boolean> {\n\t\treturn this.dir.remove(this.shardFor(hash), hash)\n\t}\n\n\tasync size(): Promise<number> {\n\t\treturn this.dir.count()\n\t}\n\n\tasync list(): Promise<string[]> {\n\t\treturn this.dir.keys()\n\t}\n}\n\n// --- Real OPFS binding (browser only) ---\n\n/** Minimal structural views of the File System Access handles we use. */\ninterface OpfsWritableStream {\n\twrite(data: Uint8Array): Promise<void>\n\tclose(): Promise<void>\n}\ninterface OpfsFileHandle {\n\tcreateWritable(options?: { keepExistingData?: boolean }): Promise<OpfsWritableStream>\n\tgetFile(): Promise<{ arrayBuffer(): Promise<ArrayBuffer> }>\n}\ninterface OpfsDirectoryHandle {\n\tgetDirectoryHandle(name: string, options?: { create?: boolean }): Promise<OpfsDirectoryHandle>\n\tgetFileHandle(name: string, options?: { create?: boolean }): Promise<OpfsFileHandle>\n\tremoveEntry(name: string, options?: { recursive?: boolean }): Promise<void>\n\tkeys(): AsyncIterableIterator<string>\n}\n\ninterface StorageManagerLike {\n\tgetDirectory(): Promise<OpfsDirectoryHandle>\n}\n\nfunction getStorageManager(): StorageManagerLike {\n\tconst nav = (globalThis as unknown as { navigator?: { storage?: StorageManagerLike } }).navigator\n\tif (!nav?.storage || typeof nav.storage.getDirectory !== 'function') {\n\t\tthrow new Error(\n\t\t\t'OPFS is unavailable in this environment. The OPFS blob store requires a browser with Origin Private File System support; use MemoryBlobStore or a server-side store elsewhere.',\n\t\t)\n\t}\n\treturn nav.storage\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === 'object' &&\n\t\terror !== null &&\n\t\t(error as { name?: string }).name === 'NotFoundError'\n\t)\n}\n\n/**\n * Create an {@link OpfsBlobDirectory} backed by the browser's Origin Private\n * File System, rooted at a named subdirectory. It does not request persistent\n * storage: that is `app.storage.persistence`, kept off the startup path.\n *\n * @param rootDirName - The OPFS subdirectory to store blobs under (default `kora-blobs`)\n * @throws {Error} If OPFS is unavailable (e.g. called outside a browser)\n */\nexport async function createOpfsBlobDirectory(\n\trootDirName = 'kora-blobs',\n): Promise<OpfsBlobDirectory> {\n\tconst storage = getStorageManager()\n\t// NEW-STORE-4: no persist() here. In Firefox it opens a permission prompt that\n\t// stays pending until the user answers, and this runs inside app startup.\n\t// Durable storage is checked and requested by StoragePersistence\n\t// (app.storage.persistence), never on the startup path.\n\tconst opfsRoot = await storage.getDirectory()\n\tconst root = await opfsRoot.getDirectoryHandle(rootDirName, { create: true })\n\n\tasync function shardHandle(shard: string, create: boolean): Promise<OpfsDirectoryHandle | null> {\n\t\ttry {\n\t\t\treturn await root.getDirectoryHandle(shard, { create })\n\t\t} catch (error) {\n\t\t\tif (isNotFoundError(error)) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\treturn {\n\t\tasync read(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tlet handle: OpfsFileHandle\n\t\t\ttry {\n\t\t\t\thandle = await dir.getFileHandle(name, { create: false })\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tconst file = await handle.getFile()\n\t\t\treturn new Uint8Array(await file.arrayBuffer())\n\t\t},\n\t\tasync write(shard, name, bytes) {\n\t\t\tconst dir = await root.getDirectoryHandle(shard, { create: true })\n\t\t\tconst handle = await dir.getFileHandle(name, { create: true })\n\t\t\t// createWritable buffers to a swap file and only commits on close(), so\n\t\t\t// the target file is updated atomically. Combined with integrity-on-read,\n\t\t\t// a torn write is never trusted.\n\t\t\tconst writable = await handle.createWritable({ keepExistingData: false })\n\t\t\ttry {\n\t\t\t\tawait writable.write(bytes)\n\t\t\t} finally {\n\t\t\t\tawait writable.close()\n\t\t\t}\n\t\t},\n\t\tasync remove(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait dir.removeEntry(name)\n\t\t\t\treturn true\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\t\tasync has(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait dir.getFileHandle(name, { create: false })\n\t\t\t\treturn true\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\t\tasync count() {\n\t\t\tlet total = 0\n\t\t\tfor await (const shard of root.keys()) {\n\t\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\t\tif (!dir) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor await (const name of dir.keys()) {\n\t\t\t\t\tif (!name.endsWith('.tmp')) {\n\t\t\t\t\t\ttotal++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn total\n\t\t},\n\t\tasync keys() {\n\t\t\tconst names: string[] = []\n\t\t\tfor await (const shard of root.keys()) {\n\t\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\t\tif (!dir) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor await (const name of dir.keys()) {\n\t\t\t\t\tif (!name.endsWith('.tmp')) {\n\t\t\t\t\t\tnames.push(name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn names\n\t\t},\n\t}\n}\n\n/**\n * Create a persistent {@link OpfsBlobStore} backed by real browser OPFS.\n *\n * @param rootDirName - The OPFS subdirectory to store blobs under (default `kora-blobs`)\n * @throws {Error} If OPFS is unavailable (e.g. called outside a browser)\n */\nexport async function createOpfsBlobStore(rootDirName = 'kora-blobs'): Promise<OpfsBlobStore> {\n\treturn new OpfsBlobStore(await createOpfsBlobDirectory(rootDirName))\n}\n","import { hashBlob } from '@korajs/core'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/** Default chunk size for out-of-band blob transfer (256 KiB). */\nexport const DEFAULT_CHUNK_SIZE = 256 * 1024\n\n/**\n * A manifest describing how a blob is split into content-addressed chunks.\n *\n * The manifest is small and travels with the operation stream (or alongside it);\n * the chunk bytes travel out of band. Because every chunk is content-addressed,\n * identical chunks across blobs are stored and transferred once, and a peer only\n * ever requests chunk hashes it does not already hold.\n */\nexport interface BlobManifest {\n\t/** Hex SHA-256 hash of the full reassembled blob (its content address). */\n\tblobHash: string\n\t/** Total size of the full blob in bytes. */\n\tsize: number\n\t/** The chunk size used to split the blob. */\n\tchunkSize: number\n\t/** Ordered hashes of each chunk. Repeats when identical chunks recur. */\n\tchunkHashes: string[]\n\tmimeType?: string\n\tfilename?: string\n}\n\n/** Optional metadata carried on a manifest. */\nexport interface BlobManifestMetadata {\n\tmimeType?: string\n\tfilename?: string\n}\n\n/**\n * Split a blob into content-addressed chunks and produce its manifest.\n *\n * @param bytes - The full blob content\n * @param chunkSize - Bytes per chunk (defaults to {@link DEFAULT_CHUNK_SIZE})\n * @param metadata - Optional mime type / filename to record on the manifest\n * @returns The manifest and a map of chunk hash to chunk bytes (deduplicated)\n */\nexport async function chunkBlob(\n\tbytes: Uint8Array,\n\tchunkSize: number = DEFAULT_CHUNK_SIZE,\n\tmetadata: BlobManifestMetadata = {},\n): Promise<{ manifest: BlobManifest; chunks: Map<string, Uint8Array> }> {\n\tif (chunkSize <= 0) {\n\t\tthrow new Error(`chunkBlob requires a positive chunkSize, got ${chunkSize}`)\n\t}\n\n\tconst chunkHashes: string[] = []\n\tconst chunks = new Map<string, Uint8Array>()\n\n\tfor (let offset = 0; offset < bytes.byteLength; offset += chunkSize) {\n\t\tconst end = Math.min(offset + chunkSize, bytes.byteLength)\n\t\tconst chunk = new Uint8Array(end - offset)\n\t\tchunk.set(bytes.subarray(offset, end))\n\t\tconst hash = await hashBlob(chunk)\n\t\tchunkHashes.push(hash)\n\t\t// Identical chunks collapse to one stored entry; the ordered hash list\n\t\t// still records every position so reassembly reproduces the exact bytes.\n\t\tif (!chunks.has(hash)) {\n\t\t\tchunks.set(hash, chunk)\n\t\t}\n\t}\n\n\tconst blobHash = await hashBlob(bytes)\n\tconst manifest: BlobManifest = {\n\t\tblobHash,\n\t\tsize: bytes.byteLength,\n\t\tchunkSize,\n\t\tchunkHashes,\n\t}\n\tif (metadata.mimeType !== undefined) {\n\t\tmanifest.mimeType = metadata.mimeType\n\t}\n\tif (metadata.filename !== undefined) {\n\t\tmanifest.filename = metadata.filename\n\t}\n\n\treturn { manifest, chunks }\n}\n\n/**\n * Reassemble a blob from chunks held in a content-addressed store, verifying\n * integrity at both levels: each chunk is verified by the store on read, and the\n * reassembled whole is verified against the manifest's blob hash.\n *\n * @param manifest - The blob manifest\n * @param chunkStore - A store holding the chunk bytes keyed by chunk hash\n * @returns The full reassembled blob bytes\n * @throws {BlobIntegrityError} If the reassembled bytes do not match blobHash\n * @throws {Error} If a chunk named in the manifest is missing from the store\n */\nexport async function reassembleBlob(\n\tmanifest: BlobManifest,\n\tchunkStore: ContentAddressedBlobStore,\n): Promise<Uint8Array> {\n\tconst parts: Uint8Array[] = []\n\tlet total = 0\n\n\tfor (const hash of manifest.chunkHashes) {\n\t\tconst chunk = await chunkStore.get(hash)\n\t\tif (chunk === null) {\n\t\t\tthrow new Error(`Cannot reassemble blob ${manifest.blobHash}: missing chunk ${hash}`)\n\t\t}\n\t\tparts.push(chunk)\n\t\ttotal += chunk.byteLength\n\t}\n\n\tconst out = new Uint8Array(total)\n\tlet offset = 0\n\tfor (const part of parts) {\n\t\tout.set(part, offset)\n\t\toffset += part.byteLength\n\t}\n\n\tconst actual = await hashBlob(out)\n\tif (actual !== manifest.blobHash) {\n\t\tthrow new BlobIntegrityError(manifest.blobHash, actual)\n\t}\n\treturn out\n}\n","import { type BlobRef, hashBlob } from '@korajs/core'\nimport { type BlobManifest, chunkBlob, reassembleBlob } from './blob-chunking'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * A source of chunk bytes on the sending side of a transfer. In production this\n * is backed by the sync connection (the receiver requests a chunk hash, the peer\n * that holds the blob answers with the bytes); in tests it is backed by a map.\n */\nexport interface ChunkProvider {\n\t/** Fetch the bytes for a chunk hash, or null if the provider does not have it. */\n\tgetChunk(hash: string): Promise<Uint8Array | null>\n}\n\n/** Result of receiving a blob out of band. */\nexport interface ReceiveBlobResult {\n\t/** The content-addressed reference to the reassembled blob. */\n\tref: BlobRef\n\t/** Number of chunks actually fetched from the provider. */\n\tchunksFetched: number\n\t/** Number of chunks skipped because they were already held locally. */\n\tchunksSkipped: number\n}\n\n/** Stores used while receiving a blob. */\nexport interface ReceiveBlobStores {\n\t/**\n\t * Where fetched chunks are staged, keyed by chunk hash. A persistent chunk\n\t * store makes a transfer resumable: an interrupted transfer leaves its chunks\n\t * here, and a resumed transfer skips them.\n\t */\n\tchunkStore: ContentAddressedBlobStore\n\t/** Where the fully reassembled, verified blob is written. */\n\tblobStore: ContentAddressedBlobStore\n}\n\n/**\n * Receive a blob out of band, chunk by chunk, resumably and with integrity\n * verification at every step.\n *\n * For each chunk named in the manifest: if the chunk store already holds it (a\n * prior, possibly interrupted transfer), it is skipped; otherwise it is fetched\n * from the provider and verified to hash to the expected chunk hash before being\n * staged. Once every chunk is present, the blob is reassembled, verified against\n * the manifest's blob hash, and written to the blob store (which deduplicates).\n *\n * The transfer is idempotent: running it again after completion fetches nothing\n * and returns the same reference.\n *\n * @param manifest - The manifest of the blob to receive\n * @param provider - The source of chunk bytes\n * @param stores - The chunk staging store and the destination blob store\n * @returns The reference plus how many chunks were fetched versus skipped\n * @throws {BlobIntegrityError} If a fetched chunk or the whole blob fails verification\n * @throws {Error} If the provider cannot supply a required chunk\n */\nexport async function receiveBlob(\n\tmanifest: BlobManifest,\n\tprovider: ChunkProvider,\n\tstores: ReceiveBlobStores,\n): Promise<ReceiveBlobResult> {\n\tlet chunksFetched = 0\n\tlet chunksSkipped = 0\n\n\t// Distinct chunk hashes only: a manifest may repeat a hash, but we need each\n\t// unique chunk exactly once. Skipping duplicates also means a blob made of\n\t// identical chunks transfers that chunk a single time.\n\tconst seen = new Set<string>()\n\tfor (const hash of manifest.chunkHashes) {\n\t\tif (seen.has(hash)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(hash)\n\n\t\tif (await stores.chunkStore.has(hash)) {\n\t\t\tchunksSkipped++\n\t\t\tcontinue\n\t\t}\n\n\t\tconst bytes = await provider.getChunk(hash)\n\t\tif (bytes === null) {\n\t\t\tthrow new Error(`Blob transfer failed: provider could not supply chunk ${hash}`)\n\t\t}\n\t\tconst actual = await hashBlob(bytes)\n\t\tif (actual !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actual)\n\t\t}\n\t\tawait stores.chunkStore.put(bytes)\n\t\tchunksFetched++\n\t}\n\n\tconst full = await reassembleBlob(manifest, stores.chunkStore)\n\tconst ref = await stores.blobStore.put(full, {\n\t\tmimeType: manifest.mimeType,\n\t\tfilename: manifest.filename,\n\t})\n\n\treturn { ref, chunksFetched, chunksSkipped }\n}\n\n/**\n * Prepare a blob for out-of-band sending: split it into chunks, stage those\n * chunks in a content-addressed store, and return the manifest plus a\n * {@link ChunkProvider} that serves the chunks from that store.\n *\n * @param bytes - The full blob content\n * @param chunkStore - Where to stage the chunks (served to receivers)\n * @param options - Optional chunk size and metadata\n * @returns The manifest and a provider that serves the staged chunks\n */\nexport async function prepareBlobForSend(\n\tbytes: Uint8Array,\n\tchunkStore: ContentAddressedBlobStore,\n\toptions: { chunkSize?: number; mimeType?: string; filename?: string } = {},\n): Promise<{ manifest: BlobManifest; provider: ChunkProvider }> {\n\tconst { manifest, chunks } = await chunkBlob(bytes, options.chunkSize, {\n\t\tmimeType: options.mimeType,\n\t\tfilename: options.filename,\n\t})\n\tfor (const chunk of chunks.values()) {\n\t\tawait chunkStore.put(chunk)\n\t}\n\tconst provider: ChunkProvider = {\n\t\tgetChunk: (hash) => chunkStore.get(hash),\n\t}\n\treturn { manifest, provider }\n}\n","import { type BlobRef, type BlobRefMetadata, hashBlob } from '@korajs/core'\nimport { type BlobManifest, chunkBlob } from './blob-chunking'\nimport type { ChunkProvider } from './blob-transfer'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * Serialize a {@link BlobManifest} to canonical bytes for content addressing.\n *\n * Fields are emitted in a fixed order so the same manifest always produces the\n * same bytes, which is what lets the manifest be stored and fetched under its own\n * SHA-256 hash. Optional fields are omitted when absent.\n */\nexport function serializeBlobManifest(manifest: BlobManifest): Uint8Array {\n\tconst canonical: Record<string, unknown> = {\n\t\tblobHash: manifest.blobHash,\n\t\tsize: manifest.size,\n\t\tchunkSize: manifest.chunkSize,\n\t\tchunkHashes: manifest.chunkHashes,\n\t}\n\tif (manifest.mimeType !== undefined) {\n\t\tcanonical.mimeType = manifest.mimeType\n\t}\n\tif (manifest.filename !== undefined) {\n\t\tcanonical.filename = manifest.filename\n\t}\n\treturn new TextEncoder().encode(JSON.stringify(canonical))\n}\n\n/**\n * Parse canonical manifest bytes back into a {@link BlobManifest}, validating the\n * shape. Throws on malformed input rather than returning a partial manifest.\n */\nexport function parseBlobManifest(bytes: Uint8Array): BlobManifest {\n\tconst parsed: unknown = JSON.parse(new TextDecoder().decode(bytes))\n\tif (typeof parsed !== 'object' || parsed === null) {\n\t\tthrow new Error('Invalid blob manifest: not an object')\n\t}\n\tconst obj = parsed as Record<string, unknown>\n\tif (typeof obj.blobHash !== 'string') {\n\t\tthrow new Error('Invalid blob manifest: missing blobHash')\n\t}\n\tif (typeof obj.size !== 'number' || typeof obj.chunkSize !== 'number') {\n\t\tthrow new Error('Invalid blob manifest: missing size or chunkSize')\n\t}\n\tif (!Array.isArray(obj.chunkHashes) || obj.chunkHashes.some((h) => typeof h !== 'string')) {\n\t\tthrow new Error('Invalid blob manifest: chunkHashes must be an array of strings')\n\t}\n\tconst manifest: BlobManifest = {\n\t\tblobHash: obj.blobHash,\n\t\tsize: obj.size,\n\t\tchunkSize: obj.chunkSize,\n\t\tchunkHashes: obj.chunkHashes as string[],\n\t}\n\tif (typeof obj.mimeType === 'string') {\n\t\tmanifest.mimeType = obj.mimeType\n\t}\n\tif (typeof obj.filename === 'string') {\n\t\tmanifest.filename = obj.filename\n\t}\n\treturn manifest\n}\n\n/**\n * Store a blob for out-of-band transfer, addressed entirely by content.\n *\n * Stages the blob's chunks (so this device can serve them), stores the full blob\n * (so local reads by hash are O(1)), and stores the blob's manifest as its own\n * content-addressed object. The returned {@link BlobRef} carries `manifestHash`,\n * so a peer that receives the reference in a synced record can pull the bytes\n * knowing only the reference — no separate manifest hand-off.\n *\n * @param store - The content-addressed store to stage chunks, blob, and manifest in\n * @param bytes - The full blob content\n * @param options - Optional chunk size and metadata\n * @returns The reference (including `manifestHash`) and the manifest\n */\nexport async function putBlobForTransfer(\n\tstore: ContentAddressedBlobStore,\n\tbytes: Uint8Array,\n\toptions: { chunkSize?: number } & BlobRefMetadata = {},\n): Promise<{ ref: BlobRef; manifest: BlobManifest }> {\n\tconst { manifest, chunks } = await chunkBlob(bytes, options.chunkSize, {\n\t\t...(options.mimeType !== undefined ? { mimeType: options.mimeType } : {}),\n\t\t...(options.filename !== undefined ? { filename: options.filename } : {}),\n\t})\n\tfor (const chunk of chunks.values()) {\n\t\tawait store.put(chunk)\n\t}\n\t// Full blob for local O(1) reads by content hash.\n\tconst baseRef = await store.put(bytes, {\n\t\t...(options.mimeType !== undefined ? { mimeType: options.mimeType } : {}),\n\t\t...(options.filename !== undefined ? { filename: options.filename } : {}),\n\t})\n\t// Manifest as its own content-addressed object, served over the same channel.\n\tconst manifestRef = await store.put(serializeBlobManifest(manifest))\n\treturn { ref: { ...baseRef, manifestHash: manifestRef.hash }, manifest }\n}\n\n/**\n * Fetch and integrity-verify a blob's manifest from a {@link ChunkProvider}.\n *\n * The manifest is a content-addressed object like a chunk, so it is requested by\n * its hash, verified to hash to that value, and parsed. Used to resolve a\n * {@link BlobRef}'s manifest before pulling the blob's chunks.\n *\n * @param provider - The source to fetch the manifest bytes from\n * @param manifestHash - The manifest's content hash (from `BlobRef.manifestHash`)\n * @throws {BlobIntegrityError} If the fetched bytes do not hash to `manifestHash`\n * @throws {Error} If the provider cannot supply the manifest\n */\nexport async function fetchBlobManifest(\n\tprovider: ChunkProvider,\n\tmanifestHash: string,\n): Promise<BlobManifest> {\n\tconst bytes = await provider.getChunk(manifestHash)\n\tif (bytes === null) {\n\t\tthrow new Error(`Blob manifest ${manifestHash} could not be fetched from the provider`)\n\t}\n\tconst actual = await hashBlob(bytes)\n\tif (actual !== manifestHash) {\n\t\tthrow new BlobIntegrityError(manifestHash, actual)\n\t}\n\treturn parseBlobManifest(bytes)\n}\n\n/**\n * Resolve the manifest for a {@link BlobRef} that was stored via\n * {@link putBlobForTransfer}. Fetches and verifies the manifest by the ref's\n * `manifestHash`.\n *\n * @throws {Error} If the ref has no `manifestHash` (it was not stored for transfer)\n */\nexport async function resolveBlobManifest(\n\tprovider: ChunkProvider,\n\tref: BlobRef,\n): Promise<BlobManifest> {\n\tif (ref.manifestHash === undefined) {\n\t\tthrow new Error(\n\t\t\t`Blob ${ref.hash} has no manifest to resolve. Store it with putBlobForTransfer (or app.blobs.put) so its reference carries a manifestHash, or pull with an explicit manifest.`,\n\t\t)\n\t}\n\treturn fetchBlobManifest(provider, ref.manifestHash)\n}\n","import { hashBlob } from '@korajs/core'\nimport { type ContentAddressedBlobStore, MemoryBlobStore } from './content-addressed-blob-store'\n\n/**\n * The server-side blob callbacks a `KoraSyncServer` accepts: read a chunk by\n * hash (to serve it) and persist an uploaded chunk by hash (to store it).\n */\nexport interface ServerBlobCallbacks {\n\tresolveBlobChunk: (hash: string) => Promise<Uint8Array | null>\n\tpersistBlobChunk: (hash: string, bytes: Uint8Array) => Promise<void>\n}\n\n/**\n * Adapt a {@link ContentAddressedBlobStore} into the read/persist callbacks a\n * `KoraSyncServer` needs for central blob storage. The server package depends\n * only on these plain function signatures, so a self-hosted server can back its\n * blob storage with any store (for example a `FilesystemBlobStore`) without the\n * server package taking a dependency on `@korajs/store`.\n *\n * @example\n * ```typescript\n * const server = new KoraSyncServer({\n * store,\n * ...toServerBlobCallbacks(new FilesystemBlobStore('/var/kora/blobs')),\n * })\n * ```\n */\nexport function toServerBlobCallbacks(store: ContentAddressedBlobStore): ServerBlobCallbacks {\n\treturn {\n\t\tresolveBlobChunk: (hash) => store.get(hash),\n\t\tasync persistBlobChunk(hash, bytes) {\n\t\t\t// The store keys by the hash it computes from the bytes; verify it matches\n\t\t\t// the declared hash so a mismatched upload is rejected, not silently stored\n\t\t\t// under the wrong key.\n\t\t\tconst actual = await hashBlob(bytes)\n\t\t\tif (actual !== hash) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait store.put(bytes)\n\t\t},\n\t}\n}\n\n/**\n * Convenience: an in-memory central blob store plus its server callbacks. For\n * tests and single-process deployments. Persistent deployments should back\n * {@link toServerBlobCallbacks} with a durable store instead.\n */\nexport function createMemoryServerBlobStore(): {\n\tstore: MemoryBlobStore\n\tcallbacks: ServerBlobCallbacks\n} {\n\tconst store = new MemoryBlobStore()\n\treturn { store, callbacks: toServerBlobCallbacks(store) }\n}\n","import { type BlobRef, isBlobRef } from '@korajs/core'\nimport { parseBlobManifest } from './blob-manifest-transfer'\nimport type { ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/** Outcome of a blob garbage-collection sweep. */\nexport interface BlobGcResult {\n\t/** Total distinct blobs held before the sweep. */\n\tscanned: number\n\t/** Distinct hashes kept because a live reference points to them (blob, manifest, or chunk). */\n\tlive: number\n\t/** Number of blobs deleted (or, with `dryRun`, that would be deleted). */\n\tcollected: number\n\t/** The hashes deleted (or, with `dryRun`, that would be deleted). */\n\tcollectedHashes: string[]\n}\n\n/** Options for {@link collectBlobGarbage}. */\nexport interface BlobGcOptions {\n\t/** Compute what would be collected without deleting anything. */\n\tdryRun?: boolean\n}\n\n/**\n * Extract the {@link BlobRef}s referenced by a materialized record. Scans the\n * record's top-level field values, so it works without the schema; a `blob`\n * field simply holds a `BlobRef`.\n */\nexport function extractBlobRefs(record: Record<string, unknown>): BlobRef[] {\n\tconst refs: BlobRef[] = []\n\tfor (const value of Object.values(record)) {\n\t\tif (isBlobRef(value)) {\n\t\t\trefs.push(value)\n\t\t}\n\t}\n\treturn refs\n}\n\n/**\n * Garbage-collect a content-addressed blob store by mark-and-sweep: keep every\n * blob reachable from a live reference, delete the rest.\n *\n * The live set is closed over the reference graph — for each live {@link BlobRef}\n * it retains the blob hash, the manifest hash, and every chunk hash named in that\n * manifest. Because chunks (and blobs) are shared by content address, a chunk\n * referenced by any surviving blob is retained even if another blob that used it\n * was collected. This makes GC safe under deduplication.\n *\n * Mark-and-sweep (rather than reference counting) is deliberate: counts are\n * fragile under concurrent edits and CRDT merges, whereas a sweep against the\n * current live set is always correct for the state it observes. Run it\n * periodically or on demand.\n *\n * A manifest that cannot be read or parsed (corruption) contributes no chunk\n * hashes; its own hash still counts as live. The blob it describes is already\n * unusable, so its chunks becoming collectable is acceptable, and GC never\n * throws on a single bad manifest.\n *\n * @param store - The blob store to sweep\n * @param liveRefs - Every reference still reachable from live records\n * @param options - `dryRun` to report without deleting\n */\nexport async function collectBlobGarbage(\n\tstore: ContentAddressedBlobStore,\n\tliveRefs: Iterable<BlobRef>,\n\toptions: BlobGcOptions = {},\n): Promise<BlobGcResult> {\n\tconst live = new Set<string>()\n\tfor (const ref of liveRefs) {\n\t\tlive.add(ref.hash)\n\t\tif (ref.manifestHash === undefined) {\n\t\t\tcontinue\n\t\t}\n\t\tlive.add(ref.manifestHash)\n\t\ttry {\n\t\t\tconst manifestBytes = await store.get(ref.manifestHash)\n\t\t\tif (manifestBytes !== null) {\n\t\t\t\tconst manifest = parseBlobManifest(manifestBytes)\n\t\t\t\tfor (const chunkHash of manifest.chunkHashes) {\n\t\t\t\t\tlive.add(chunkHash)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// A corrupt/unreadable manifest contributes no chunk hashes; the blob is\n\t\t\t// already broken. Never abort the whole sweep for one bad manifest.\n\t\t}\n\t}\n\n\tconst all = await store.list()\n\tconst collectedHashes: string[] = []\n\tfor (const hash of all) {\n\t\tif (live.has(hash)) {\n\t\t\tcontinue\n\t\t}\n\t\tcollectedHashes.push(hash)\n\t\tif (!options.dryRun) {\n\t\t\tawait store.delete(hash)\n\t\t}\n\t}\n\n\treturn {\n\t\tscanned: all.length,\n\t\tlive: live.size,\n\t\tcollected: collectedHashes.length,\n\t\tcollectedHashes,\n\t}\n}\n","import { generateUUIDv7 } from '@korajs/core'\nimport type { ChunkProvider } from './blob-transfer'\nimport type { ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * Blob chunk exchange messages. These ride any message transport (the sync\n * WebSocket in production, an in-memory pair in tests). A receiver requests a\n * chunk by hash and correlates the answer by `requestId`.\n */\nexport interface ChunkRequestMessage {\n\ttype: 'blob-chunk-request'\n\trequestId: string\n\thash: string\n}\nexport interface ChunkResponseMessage {\n\ttype: 'blob-chunk-response'\n\trequestId: string\n\t/** The chunk bytes, or null when the responder does not hold that hash. */\n\tbytes: Uint8Array | null\n\t/**\n\t * The server refused the request for rate, not because the chunk is missing\n\t * (RT-24). The requester retries after `retryAfterMs` instead of failing.\n\t */\n\tthrottled?: boolean\n\t/** With `throttled`: how long to wait before retrying, in ms. */\n\tretryAfterMs?: number\n}\nexport type ChunkMessage = ChunkRequestMessage | ChunkResponseMessage\n\n/**\n * A bidirectional message port carrying {@link ChunkMessage}s. Implemented over\n * the sync connection in production; `createChunkPortPair` provides an in-memory\n * duplex pair for tests.\n */\nexport interface ChunkMessagePort {\n\tsend(message: ChunkMessage): void\n\t/** Register a handler for incoming messages. Multiple handlers are allowed. */\n\tonMessage(handler: (message: ChunkMessage) => void): void\n}\n\n/** A {@link ChunkProvider} that fetches chunks over a message port. */\nexport interface RemoteChunkProvider extends ChunkProvider {\n\t/** Number of requests still awaiting a response (for diagnostics/tests). */\n\tpendingCount(): number\n}\n\n/** Options for {@link createRemoteChunkProvider}. */\nexport interface RemoteChunkProviderOptions {\n\t/** Per-attempt timeout in ms (default 30s). */\n\ttimeoutMs?: number\n\t/**\n\t * Longest total time one chunk may spend waiting on \"throttled\" answers before\n\t * the request fails (default 10 minutes). The transfer is resumable, so a failed\n\t * request can simply be retried later.\n\t */\n\tmaxThrottleWaitMs?: number\n\t/** Smallest back-off after a throttled answer, in ms (default 250). */\n\tminThrottleDelayMs?: number\n\t/** Largest single back-off after a throttled answer, in ms (default 30s). */\n\tmaxThrottleDelayMs?: number\n}\n\n/**\n * Create a {@link ChunkProvider} that requests chunks over a message port,\n * correlating each answer to its request and timing out a stalled request so a\n * dropped response cannot hang a transfer forever (the transfer is resumable, so\n * a timed-out request can simply be retried).\n *\n * A \"throttled\" answer (the server's blob request budget is spent, RT-24) is not a\n * failure: the request is re-sent after the server's `retryAfterMs` (bounded, with\n * exponential back-off when absent), until `maxThrottleWaitMs` has elapsed.\n *\n * @param port - The message port to the peer that holds the blob\n * @param options - Timeouts and throttle back-off bounds\n */\nexport function createRemoteChunkProvider(\n\tport: ChunkMessagePort,\n\toptions: RemoteChunkProviderOptions = {},\n): RemoteChunkProvider {\n\tconst timeoutMs = options.timeoutMs ?? 30_000\n\tconst maxThrottleWaitMs = options.maxThrottleWaitMs ?? 10 * 60_000\n\tconst minDelayMs = options.minThrottleDelayMs ?? 250\n\tconst maxDelayMs = options.maxThrottleDelayMs ?? 30_000\n\tconst pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\thash: string\n\t\t\tresolve: (bytes: Uint8Array | null) => void\n\t\t\treject: (error: Error) => void\n\t\t\ttimer: ReturnType<typeof setTimeout>\n\t\t\tstartedAtMs: number\n\t\t\tthrottledCount: number\n\t\t}\n\t>()\n\n\tconst armTimeout = (requestId: string, hash: string): ReturnType<typeof setTimeout> =>\n\t\tsetTimeout(() => {\n\t\t\tconst entry = pending.get(requestId)\n\t\t\tif (!entry) return\n\t\t\tpending.delete(requestId)\n\t\t\tentry.reject(new Error(`Blob chunk request for ${hash} timed out after ${timeoutMs}ms`))\n\t\t}, timeoutMs)\n\n\tport.onMessage((message) => {\n\t\tif (message.type !== 'blob-chunk-response') {\n\t\t\treturn\n\t\t}\n\t\tconst entry = pending.get(message.requestId)\n\t\tif (!entry) {\n\t\t\treturn\n\t\t}\n\t\tclearTimeout(entry.timer)\n\t\tif (message.throttled === true) {\n\t\t\t// Over the server's blob budget: back off and ask again, same request id.\n\t\t\tentry.throttledCount += 1\n\t\t\tconst backoff = Math.min(maxDelayMs, minDelayMs * 2 ** (entry.throttledCount - 1))\n\t\t\tconst delay = Math.min(maxDelayMs, Math.max(minDelayMs, message.retryAfterMs ?? backoff))\n\t\t\tif (Date.now() + delay - entry.startedAtMs > maxThrottleWaitMs) {\n\t\t\t\tpending.delete(message.requestId)\n\t\t\t\tentry.reject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Blob chunk request for ${entry.hash} was throttled for longer than ${maxThrottleWaitMs}ms`,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tentry.timer = setTimeout(() => {\n\t\t\t\tif (pending.get(message.requestId) !== entry) return\n\t\t\t\tentry.timer = armTimeout(message.requestId, entry.hash)\n\t\t\t\tport.send({ type: 'blob-chunk-request', requestId: message.requestId, hash: entry.hash })\n\t\t\t}, delay)\n\t\t\treturn\n\t\t}\n\t\tpending.delete(message.requestId)\n\t\tentry.resolve(message.bytes)\n\t})\n\n\treturn {\n\t\tpendingCount: () => pending.size,\n\t\tgetChunk(hash: string): Promise<Uint8Array | null> {\n\t\t\tconst requestId = generateUUIDv7()\n\t\t\treturn new Promise<Uint8Array | null>((resolve, reject) => {\n\t\t\t\tpending.set(requestId, {\n\t\t\t\t\thash,\n\t\t\t\t\tresolve,\n\t\t\t\t\treject,\n\t\t\t\t\ttimer: armTimeout(requestId, hash),\n\t\t\t\t\tstartedAtMs: Date.now(),\n\t\t\t\t\tthrottledCount: 0,\n\t\t\t\t})\n\t\t\t\tport.send({ type: 'blob-chunk-request', requestId, hash })\n\t\t\t})\n\t\t},\n\t}\n}\n\n/**\n * Serve blob chunk requests arriving on a message port from a blob store. Answers\n * each `blob-chunk-request` with the bytes for that hash, or null when the store\n * does not hold it. Returns nothing; attach it once per connection.\n *\n * @param port - The message port from the peer requesting chunks\n * @param blobStore - The store to serve chunks from (keyed by chunk hash)\n */\nexport function serveBlobChunks(\n\tport: ChunkMessagePort,\n\tblobStore: ContentAddressedBlobStore,\n): void {\n\tport.onMessage((message) => {\n\t\tif (message.type !== 'blob-chunk-request') {\n\t\t\treturn\n\t\t}\n\t\tvoid blobStore.get(message.hash).then(\n\t\t\t(bytes) => {\n\t\t\t\tport.send({ type: 'blob-chunk-response', requestId: message.requestId, bytes })\n\t\t\t},\n\t\t\t() => {\n\t\t\t\t// Integrity failure or read error: report as not-held rather than\n\t\t\t\t// crashing the connection. The requester treats null as unavailable.\n\t\t\t\tport.send({ type: 'blob-chunk-response', requestId: message.requestId, bytes: null })\n\t\t\t},\n\t\t)\n\t})\n}\n\n/**\n * Create a connected in-memory pair of {@link ChunkMessagePort}s. Messages sent\n * on one arrive on the other, asynchronously (next microtask) so the pair models\n * a real transport rather than re-entrant synchronous delivery. For tests.\n */\nexport function createChunkPortPair(): { a: ChunkMessagePort; b: ChunkMessagePort } {\n\tconst handlersA: Array<(m: ChunkMessage) => void> = []\n\tconst handlersB: Array<(m: ChunkMessage) => void> = []\n\n\tconst a: ChunkMessagePort = {\n\t\tsend(message) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tfor (const handler of handlersB) {\n\t\t\t\t\thandler(message)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tonMessage(handler) {\n\t\t\thandlersA.push(handler)\n\t\t},\n\t}\n\tconst b: ChunkMessagePort = {\n\t\tsend(message) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tfor (const handler of handlersA) {\n\t\t\t\t\thandler(message)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tonMessage(handler) {\n\t\t\thandlersB.push(handler)\n\t\t},\n\t}\n\treturn { a, b }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAKa,YAUA,qBAmBA,qBAcA,cAiBA,wBAoBA,yBAkBA,mBAUA,iBAUA,oBAiBA,eAkBA,yBAiBA,uBAYA,qBAeA,mBAeA,mBAgBA,6BAcA;AAvPb;AAAA;AAAA;AAAA,kBAA0B;AAKnB,IAAM,aAAN,cAAyB,sBAAU;AAAA,MACzC,YAAY,SAAiB,SAAmC;AAC/D,cAAM,SAAS,eAAe,OAAO;AACrC,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAKO,IAAM,sBAAN,cAAkC,sBAAU;AAAA,MAClD,YAAY,YAAoB,UAAkB;AACjD,cAAM,WAAW,QAAQ,8BAA8B,UAAU,KAAK,oBAAoB;AAAA,UACzF;AAAA,UACA;AAAA,QACD,CAAC;AACD,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAWO,IAAM,sBAAN,cAAkC,sBAAU;AAAA,MAClD,YAAY,YAAoB,UAAkB;AACjD;AAAA,UACC,6CAA6C,QAAQ,SAAS,UAAU;AAAA,UACxE;AAAA,UACA,EAAE,YAAY,SAAS;AAAA,QACxB;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAKO,IAAM,eAAN,cAA2B,sBAAU;AAAA,MAC3C,YAAY,SAAiB,SAAmC;AAC/D,cAAM,SAAS,iBAAiB,OAAO;AACvC,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAYO,IAAM,yBAAN,cAAqC,sBAAU;AAAA,MACrD,YAAY,QAAgB,OAA6B,QAAgB;AACxE;AAAA,UACC,aAAa,MAAM,6BAA6B,MAAM,WAAW,KAAK;AAAA,UACtE;AAAA,UACA,EAAE,QAAQ,OAAO,OAAO;AAAA,QACzB;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAWO,IAAM,0BAAN,cAAsC,sBAAU;AAAA,MACtD,YACiB,QACA,eACA,aACf;AACD;AAAA,UACC,aAAa,MAAM,0BAA0B,aAAa,4CAA4C,WAAW;AAAA,UACjH;AAAA,UACA,EAAE,QAAQ,eAAe,YAAY;AAAA,QACtC;AARgB;AACA;AACA;AAOhB,aAAK,OAAO;AAAA,MACb;AAAA,MAViB;AAAA,MACA;AAAA,MACA;AAAA,IASlB;AAKO,IAAM,oBAAN,cAAgC,sBAAU;AAAA,MAChD,cAAc;AACb,cAAM,sEAAsE,gBAAgB;AAC5F,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAKO,IAAM,kBAAN,cAA8B,sBAAU;AAAA,MAC9C,YAAY,SAAiB,SAAmC;AAC/D,cAAM,iCAAiC,OAAO,IAAI,qBAAqB,OAAO;AAC9E,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAKO,IAAM,qBAAN,cAAiC,sBAAU;AAAA,MACjD,YAAY,WAAmB,WAAmB;AACjD;AAAA,UACC,iCAAiC,SAAS,qBAAqB,SAAS;AAAA,UACxE;AAAA,UACA,EAAE,WAAW,UAAU;AAAA,QACxB;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAQO,IAAM,gBAAN,cAA4B,sBAAU;AAAA,MAC5C,YACC,WACA,UAAU,wEAAwE,SAAS,KAC3F,OAAO,aACP,UAAmC,CAAC,GACnC;AACD,cAAM,SAAS,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;AAC9C,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAQO,IAAM,0BAAN,cAAsC,cAAc;AAAA,MAC1D,YAAY,WAAmB,UAAkB,WAAmB;AACnE;AAAA,UACC;AAAA,UACA,uDAAuD,QAAQ,eAAe,SAAS;AAAA,UACvF;AAAA,UACA,EAAE,UAAU,WAAW,WAAW,KAAK;AAAA,QACxC;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAOO,IAAM,wBAAN,cAAoC,sBAAU;AAAA,MACpD,YAAY,WAAmB,QAAgB;AAC9C;AAAA,UACC,oBAAoB,SAAS,sBAAsB,MAAM;AAAA,UACzD;AAAA,UACA,EAAE,WAAW,QAAQ,WAAW,KAAK;AAAA,QACtC;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAGO,IAAM,sBAAN,cAAkC,sBAAU;AAAA,MAClD,YAAY,WAAmB,WAAmB;AACjD;AAAA,UACC,oBAAoB,SAAS;AAAA,UAC7B;AAAA,UACA,EAAE,WAAW,UAAU;AAAA,QACxB;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAMO,IAAM,oBAAN,cAAgC,sBAAU;AAAA,MAChD,YAAY,QAAgB;AAC3B;AAAA,UACC,aAAa,MAAM;AAAA,UACnB;AAAA,UACA,EAAE,OAAO;AAAA,QACV;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAMO,IAAM,oBAAN,cAAgC,sBAAU;AAAA,MAChD,YAAY,QAAgB;AAC3B;AAAA,UACC,aAAa,MAAM;AAAA,UACnB;AAAA,UACA,EAAE,OAAO;AAAA,QACV;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAOO,IAAM,8BAAN,cAA0C,sBAAU;AAAA,MAC1D,YAAY,QAAgB,UAAkB,WAAmB,QAAgB;AAChF;AAAA,UACC,aAAa,MAAM,kBAAkB,QAAQ,mCAAmC,SAAS,KAAK,MAAM,mFAAmF,QAAQ;AAAA,UAC/L;AAAA,UACA,EAAE,QAAQ,UAAU,WAAW,OAAO;AAAA,QACvC;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAKO,IAAM,mBAAN,cAA+B,sBAAU;AAAA,MAC/C,YAAY,SAAiB,SAAmC;AAC/D,cAAM,sBAAsB,OAAO,IAAI,qBAAqB,OAAO;AACnE,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAAA;AAAA;;;AC5PA,IA8Ba;AA9Bb;AAAA;AAAA;AA8BO,IAAM,+BAA+B;AAAA;AAAA;;;ACrBrC,SAAS,8BAA8B,cAA4C;AACzF,QAAM,gBAAY,kCAAoB;AACtC,aAAW,CAAC,QAAQ,GAAG,KAAK,cAAc;AACzC,QAAI,MAAM,GAAG;AACZ,gBAAU,IAAI,QAAQ,GAAG;AAAA,IAC1B;AAAA,EACD;AACA,SAAO;AACR;AAMA,eAAsB,oBACrB,SACA,QACA,UACA,cAC4B;AAC5B,MAAI,SAAS,SAAS,SAAS;AAC9B,WAAO,EAAE,cAAc,GAAG,eAAW,kCAAoB,EAAE;AAAA,EAC5D;AAEA,QAAM,YAAY,8BAA8B,YAAY;AAC5D,MAAI,UAAU,SAAS,GAAG;AACzB,WAAO,EAAE,cAAc,GAAG,UAAU;AAAA,EACrC;AAEA,QAAM,gBACL,SAAS,SAAS,eAAe,KAAK,IAAI,IAAI,SAAS,OAAO,KAAK,KAAK,KAAK,MAAO;AACrF,QAAM,sBACL,kBAAkB,OACf,gCAAmB,UAAU;AAAA,IAC7B,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,EACT,CAAC,EAAE,MAAM,GAAG,EAAE,IACb;AAEJ,MAAI,eAAe;AACnB,QAAM,kBAAkB,OAAO,KAAK,OAAO,WAAW;AAEtD,QAAM,QAAQ,YAAY,OAAO,OAAoB;AACpD,eAAW,kBAAkB,iBAAiB;AAG7C,YAAM,YAAQ,yBAAW,aAAa,cAAc,EAAE;AACtD,iBAAW,CAAC,QAAQ,MAAM,KAAK,WAAW;AACzC,YAAI,UAAU,EAAG;AAEjB,cAAM,WAAW,cAAc,OAAO,wBAAwB,IAAI;AAClE,cAAM,cACL,wBAAwB,OAAO,CAAC,QAAQ,QAAQ,mBAAmB,IAAI,CAAC,QAAQ,MAAM;AACvF,cAAM,YAAY,MAAM,GAAG,MAAyB,UAAU,WAAW;AACzE,wBAAgB,UAAU,CAAC,GAAG,SAAS;AAEvC,cAAM,YAAY,eAAe,OAAO,wBAAwB,IAAI;AACpE,cAAM,GAAG,QAAQ,WAAW,WAAW;AAAA,MACxC;AAAA,IACD;AAEA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA,OAAO,KAAK,IAAI,CAAC;AAAA,IAClB,CAAC;AAAA,EACF,CAAC;AAED,SAAO,EAAE,cAAc,UAAU;AAClC;AAEA,SAAS,cAAc,OAAe,SAA0B;AAC/D,MAAI,SAAS;AACZ,WAAO,iCAAiC,KAAK;AAAA,EAC9C;AACA,SAAO,iCAAiC,KAAK;AAC9C;AAEA,SAAS,eAAe,OAAe,SAA0B;AAChE,MAAI,SAAS;AACZ,WAAO,eAAe,KAAK;AAAA,EAC5B;AACA,SAAO,eAAe,KAAK;AAC5B;AA5FA,IACAA;AADA;AAAA;AAAA;AACA,IAAAA,eAAoE;AAGpE;AAAA;AAAA;;;ACMO,SAAS,oBAAoB,WAAiC;AACpE,SAAO,gCAAmB,UAAU,SAAS;AAC9C;AAMO,SAAS,qBACf,KACe;AACf,QAAM,UAAU,IAAI;AACpB,MAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,GAAG;AACtD,WAAO,gCAAmB,YAAY,OAAO;AAAA,EAC9C;AACA,SAAO,EAAE,UAAU,IAAI,aAAa,SAAS,GAAG,QAAQ,GAAG;AAC5D;AAKO,SAAS,uBACf,UACA,KACU;AACV,SAAO,gCAAmB,QAAQ,UAAU,qBAAqB,GAAG,CAAC,IAAI;AAC1E;AAMO,SAAS,sBAAsB,eAA0D;AAC/F,SAAO;AAAA,IACN,KAAK;AAAA,IACL,QAAQ,CAAC,mBAAmB,aAAa;AAAA,EAC1C;AACD;AA/CA,IAAAC,cAIa;AAJb;AAAA;AAAA;AAAA,IAAAA,eAAsD;AAI/C,IAAM,oBAAoB;AAAA;AAAA;;;AC4B1B,SAAS,8BACf,MACA,QAC0B;AAC1B,QAAM,SAAkC,EAAE,GAAG,KAAK;AAClD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,QAAI,OAAO,GAAG,GAAG,SAAS,YAAY;AACrC;AAAA,IACD;AACA,QAAI,OAAO,UAAU,YAAY,iBAAiB,cAAc,iBAAiB,aAAa;AAC7F,aAAO,GAAG,QAAI,mCAAqB,KAAK;AAAA,IACzC;AAAA,EACD;AACA,SAAO;AACR;AAQO,SAAS,+BACf,MACA,QAC0B;AAC1B,QAAM,SAAkC,EAAE,GAAG,KAAK;AAClD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,QAAI,OAAO,GAAG,GAAG,SAAS,cAAc,UAAU,QAAQ,UAAU,QAAW;AAC9E;AAAA,IACD;AACA,WAAO,GAAG,QAAI,oCAAsB,KAAK;AAAA,EAC1C;AACA,SAAO;AACR;AAlEA,IAAAC,cAuBa;AAvBb;AAAA;AAAA;AAAA,IAAAA,eAQO;AAeA,IAAM,4BAA4B;AAAA;AAAA;;;ACFlC,SAAS,eAAe,OAA0D;AACxF,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,MAAM,IAAM,MAAI;AAKtB,QAAI,WAAW;AACf,QAAI,QAAQ,QAAQ,EAAE,OAAO,GAAG,KAAK;AACrC,WAAS,sBAAoB,GAAG;AAAA,EACjC;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,aAAa;AACjC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,UAAI,+BAAiB,KAAK,SAAK,wCAA0B,KAAK,GAAG;AAChE,UAAM,UAAU,0BAA0B,KAAK;AAE/C,WAAO,mBAAmB,aAAa,UAAU;AAAA,EAClD;AAEA,QAAM,IAAI,MAAM,+EAA+E;AAChG;AAKO,SAAS,eAAe,OAAmC;AACjE,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,MAAI,OAAO,WAAW,eAAe,OAAO,SAAS,KAAK,GAAG;AAC5D,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,aAAa;AACjC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,QAAM,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAKO,SAAS,oBAAoB,OAA8B;AACjE,QAAM,UAAU,eAAe,KAAK;AACpC,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,MAAM,IAAM,MAAI;AACtB,EAAE,cAAY,KAAK,OAAO;AAC1B,SAAO,IAAI,QAAQ,QAAQ,EAAE,SAAS;AACvC;AAMO,SAAS,oBAAoB,GAAY,GAAqB;AACpE,MAAI;AACH,WAAO,oBAAoB,CAAkB,MAAM,oBAAoB,CAAkB;AAAA,EAC1F,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AArGA,OAQM;AARN;AAAA;AAAA;AAAA,QAAmB;AACnB;AAOA,IAAM,WAAW;AAAA;AAAA;;;ACKV,SAAS,gBACf,MACA,QAC0B;AAC1B,QAAM,SAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,UAAM,aAAa,OAAO,GAAG;AAC7B,QAAI,CAAC,YAAY;AAChB,aAAO,GAAG,IAAI;AACd;AAAA,IACD;AACA,WAAO,GAAG,IAAI,eAAe,OAAO,UAAU;AAAA,EAC/C;AACA,SAAO;AACR;AAUO,SAAS,kBACf,KACA,QACmB;AACnB,QAAM,SAA2B;AAAA,IAChC,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EAChB;AAEA,aAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACvD,UAAM,WAAW,IAAI,GAAG;AACxB,QAAI,aAAa,UAAa,aAAa,MAAM;AAChD,aAAO,GAAG,IAAI,YAAY;AAC1B;AAAA,IACD;AACA,WAAO,GAAG,IAAI,iBAAiB,UAAU,UAAU;AAAA,EACpD;AAEA,SAAO;AACR;AAqCO,SAAS,mBAAmB,IAA6B;AAC/D,QAAM,cACL,GAAG,kBAAkB,UAAa,GAAG,iBAAiB,UAAa,GAAG,gBAAgB;AACvF,MAAI,cAA8C;AAClD,MAAI,GAAG,MAAM;AAEZ,kBAAc,EAAE,GAAG,GAAG,KAAK;AAC3B,QAAI,GAAG,cAAc,UAAa,OAAO,KAAK,GAAG,SAAS,EAAE,SAAS,GAAG;AACvE,kBAAY,cAAc,IAAI,GAAG;AAAA,IAClC;AACA,QAAI,GAAG,kBAAkB,QAAW;AACnC,kBAAY,SAAS,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,GAAG,iBAAiB,QAAW;AAClC,kBAAY,iBAAiB,IAAI,GAAG;AAAA,IACrC;AACA,QAAI,GAAG,kBAAkB,QAAW;AACnC,kBAAY,kBAAkB,IAAI,GAAG;AAAA,IACtC;AACA,QAAI,GAAG,gBAAgB,QAAW;AACjC,kBAAY,gBAAgB,IAAI,GAAG;AAAA,IACpC;AAAA,EACD,WAAW,aAAa;AAEvB,kBAAc,CAAC;AACf,QAAI,GAAG,kBAAkB,QAAW;AACnC,kBAAY,SAAS,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,GAAG,iBAAiB,QAAW;AAClC,kBAAY,iBAAiB,IAAI,GAAG;AAAA,IACrC;AACA,QAAI,GAAG,gBAAgB,QAAW;AACjC,kBAAY,gBAAgB,IAAI,GAAG;AAAA,IACpC;AAAA,EACD;AAEA,SAAO;AAAA,IACN,IAAI,GAAG;AAAA,IACP,SAAS,GAAG;AAAA,IACZ,MAAM,GAAG;AAAA,IACT,WAAW,GAAG;AAAA,IACd,MAAM,cAAc,KAAK,UAAU,WAAW,IAAI;AAAA,IAClD,eAAe,GAAG,eAAe,KAAK,UAAU,GAAG,YAAY,IAAI;AAAA,IACnE,WAAW,gCAAmB,UAAU,GAAG,SAAS;AAAA,IACpD,iBAAiB,GAAG;AAAA,IACpB,aAAa,KAAK,UAAU,GAAG,UAAU;AAAA,IACzC,gBAAgB,GAAG;AAAA,EACpB;AACD;AAQO,SAAS,qBAAqB,KAA8B;AAClE,MAAI,OAAuC;AAC3C,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,IAAI,MAAM;AACb,UAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAElC,QAAI,kBAAkB,QAAQ;AAC7B,kBAAY,OAAO,cAAc;AAAA,IAClC;AACA,QAAI,aAAa,QAAQ;AACxB,sBAAgB,OAAO,SAAS;AAAA,IACjC;AACA,QAAI,qBAAqB,QAAQ;AAChC,qBAAe,OAAO,iBAAiB;AAAA,IACxC;AACA,QAAI,sBAAsB,QAAQ;AACjC,sBAAgB,OAAO,kBAAkB;AAAA,IAC1C;AACA,QAAI,oBAAoB,QAAQ;AAC/B,oBAAc,OAAO,gBAAgB;AAAA,IACtC;AAEA,UAAM;AAAA,MACL,CAAC,cAAc,GAAG;AAAA,MAClB,CAAC,SAAS,GAAG;AAAA,MACb,CAAC,iBAAiB,GAAG;AAAA,MACrB,CAAC,kBAAkB,GAAG;AAAA,MACtB,CAAC,gBAAgB,GAAG;AAAA,MACpB,GAAG;AAAA,IACJ,IAAI;AAIJ,WAAO,IAAI,SAAS,YAAY,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAAA,EACvE;AAEA,SAAO;AAAA,IACN,IAAI,IAAI;AAAA,IACR,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,YAAY;AAAA;AAAA,IACZ,UAAU,IAAI;AAAA,IACd;AAAA,IACA,cAAc,IAAI,gBACd,KAAK,MAAM,IAAI,aAAa,IAC7B;AAAA,IACH,WAAW,gCAAmB,YAAY,IAAI,SAAS;AAAA,IACvD,gBAAgB,IAAI;AAAA,IACpB,YAAY,KAAK,MAAM,IAAI,WAAW;AAAA,IACtC,eAAe,IAAI;AAAA,IACnB,GAAI,cAAc,SAAY,EAAE,UAA+C,IAAI,CAAC;AAAA,IACpF,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IACrD,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,EACpD;AACD;AAKO,SAAS,mCACf,KACA,YACY;AACZ,QAAM,KAAK,qBAAqB,GAAG;AACnC,SAAO,EAAE,GAAG,IAAI,WAAW;AAC5B;AAYO,SAAS,oBACf,MACA,QAC0B;AAC1B,MAAI,MAAM;AACV,aAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,QAAI,WAAW,SAAS,cAAc,EAAE,QAAQ,MAAO;AACvD,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI,UAAU,QAAQ,UAAU,UAAa,iBAAiB,WAAY;AAC1E,QAAI,QAAQ,KAAM,OAAM,EAAE,GAAG,KAAK;AAClC,QAAI,IAAI,IAAI,eAAe,KAA6C;AAAA,EACzE;AACA,SAAO;AACR;AAEA,SAAS,eAAe,OAAgB,YAAsC;AAC7E,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,UAAQ,WAAW,MAAM;AAAA,IACxB,KAAK;AACJ,aAAO,QAAQ,IAAI;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO,KAAK,UAAU,KAAK;AAAA,IAC5B,KAAK;AAGJ,aAAO,eAAe,KAA6C;AAAA,IACpE;AAKC,aAAO,OAAO,UAAU,YAAY,cAAc,WAAW,IAAI,QAC9D,+BAAiB,KAAK,IACtB;AAAA,EACL;AACD;AAWO,SAAS,cAAc,MAAuB;AACpD,SAAO,eAAe,IAAI,IAAI;AAC/B;AASO,SAAS,wBACf,OACA,YACU;AACV,SAAO,OAAO,UAAU,YAAY,eAAe,UAAa,cAAc,WAAW,IAAI,QAC1F,+BAAiB,KAAK,IACtB;AACJ;AAEA,SAAS,iBAAiB,OAAgB,YAAsC;AAC/E,UAAQ,WAAW,MAAM;AAAA,IACxB,KAAK;AACJ,aAAO,UAAU,KAAK,UAAU;AAAA,IACjC,KAAK;AACJ,UAAI,OAAO,UAAU,UAAU;AAC9B,eAAO,KAAK,MAAM,KAAK;AAAA,MACxB;AACA,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,UAAI,OAAO,UAAU,UAAU;AAC9B,eAAO,KAAK,MAAM,KAAK;AAAA,MACxB;AACA,aAAO;AAAA,IACR,KAAK;AACJ,aAAO,eAAe,KAAK;AAAA,IAC5B;AACC,aAAO,OAAO,UAAU,YAAY,cAAc,WAAW,IAAI,QAC9D,+BAAiB,KAAK,IACtB;AAAA,EACL;AACD;AAzUA,IAAAC,cA+DM,gBAKA,WAKA,mBAMA,oBAOA,kBAqMA;AA3RN;AAAA;AAAA;AAAA,IAAAA,eAAuE;AAGvE;AA4DA,IAAM,iBAAiB;AAKvB,IAAM,YAAY;AAKlB,IAAM,oBAAoB;AAM1B,IAAM,qBAAqB;AAO3B,IAAM,mBAAmB;AAqMzB,IAAM,iBAAsC,oBAAI,IAAI,CAAC,UAAU,QAAQ,CAAC;AAAA;AAAA;;;ACpQjE,SAAS,iBACf,YACA,QACW;AACX,QAAM,SAAoB,CAAC;AAC3B,QAAM,QAAQ,CAAC,qBAAiB,yBAAW,WAAW,UAAU,CAAC,EAAE;AAEnE,QAAM,cAAc,sBAAsB,WAAW,OAAO,QAAQ,MAAM;AAE1E,QAAM,gBAAgB;AACtB,MAAI,aAAa;AAChB,UAAM,KAAK,SAAS,aAAa,QAAQ,WAAW,EAAE;AAAA,EACvD,OAAO;AACN,UAAM,KAAK,SAAS,aAAa,EAAE;AAAA,EACpC;AAEA,MAAI,WAAW,QAAQ,SAAS,GAAG;AAClC,UAAM,aAAa,WAAW,QAAQ,IAAI,CAAC,MAAM;AAChD,wBAAkB,EAAE,OAAO,MAAM;AAGjC,aAAO,OAAG,yBAAW,kBAAkB,EAAE,OAAO,MAAM,CAAC,CAAC,IAAI,iBAAiB,EAAE,WAAW,EAAE,KAAK,CAAC;AAAA,IACnG,CAAC;AACD,UAAM,KAAK,YAAY,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,EAC/C;AAIA,QAAM,QAAQ,WAAW,UAAU,SAAY,iBAAiB,WAAW,OAAO,OAAO,IAAI;AAC7F,QAAM,SACL,WAAW,WAAW,SAAY,iBAAiB,WAAW,QAAQ,QAAQ,IAAI;AACnF,MAAI,UAAU,MAAM;AACnB,UAAM,KAAK,SAAS;AACpB,WAAO,KAAK,KAAK;AAAA,EAClB;AACA,MAAI,WAAW,MAAM;AAEpB,QAAI,UAAU,KAAM,OAAM,KAAK,UAAU;AACzC,UAAM,KAAK,UAAU;AACrB,WAAO,KAAK,MAAM;AAAA,EACnB;AAEA,SAAO,EAAE,KAAK,MAAM,KAAK,GAAG,GAAG,OAAO;AACvC;AAUO,SAAS,gBACf,YACA,QACW;AACX,QAAM,SAAoB,CAAC;AAC3B,QAAM,QAAQ,CAAC,qCAAiC,yBAAW,WAAW,UAAU,CAAC,EAAE;AAEnF,QAAM,cAAc,sBAAsB,WAAW,OAAO,QAAQ,MAAM;AAC1E,QAAM,gBAAgB;AACtB,MAAI,aAAa;AAChB,UAAM,KAAK,SAAS,aAAa,QAAQ,WAAW,EAAE;AAAA,EACvD,OAAO;AACN,UAAM,KAAK,SAAS,aAAa,EAAE;AAAA,EACpC;AAEA,SAAO,EAAE,KAAK,MAAM,KAAK,GAAG,GAAG,OAAO;AACvC;AASO,SAAS,iBAAiB,YAAoB,QAA2C;AAC/F,QAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAM,eAAe,QAAQ,IAAI,MAAM,GAAG;AAC1C,QAAM,SAAS,OAAO,OAAO,MAAM;AAEnC,QAAM,gBAAgB,QAAQ,IAAI,CAAC,YAAQ,yBAAW,GAAG,CAAC;AAC1D,QAAM,MAAM,mBAAe,yBAAW,UAAU,CAAC,KAAK,cAAc,KAAK,IAAI,CAAC,aAAa,aAAa,KAAK,IAAI,CAAC;AAClH,SAAO,EAAE,KAAK,OAAO;AACtB;AAUO,SAAS,iBACf,YACA,IACA,SACW;AACX,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,IAAI,CAAC,QAAQ,OAAG,yBAAW,GAAG,CAAC,MAAM;AAC7E,QAAM,SAAS,CAAC,GAAG,OAAO,OAAO,OAAO,GAAG,EAAE;AAE7C,QAAM,MAAM,cAAU,yBAAW,UAAU,CAAC,QAAQ,WAAW,KAAK,IAAI,CAAC;AACzE,SAAO,EAAE,KAAK,OAAO;AACtB;AAyBO,SAAS,iCACf,YACA,IACA,cACA,eACA,UACA,SACW;AACX,QAAM,eAAe,OAAO,KAAK,YAAY,EAAE,IAAI,CAAC,QAAQ,OAAG,yBAAW,GAAG,CAAC,MAAM;AAGpF,QAAM,aAAa;AAAA,IAClB,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACD;AACA,QAAM,SAAoB;AAAA,IACzB,GAAG,OAAO,OAAO,YAAY;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,MAAI,SAAS,iBAAiB,QAAW;AACxC,eAAW,KAAK,sEAAsE;AACtF,WAAO,KAAK,QAAQ,cAAc,QAAQ,YAAY;AAAA,EACvD;AACA,SAAO,KAAK,EAAE;AACd,QAAM,MAAM,cAAU,yBAAW,UAAU,CAAC,QAAQ,WAAW,KAAK,IAAI,CAAC;AACzE,SAAO,EAAE,KAAK,OAAO;AACtB;AAUO,SAAS,qBACf,YACA,IACA,WACA,SACW;AACX,MAAI,YAAY,QAAW;AAC1B,WAAO;AAAA,MACN,KAAK,cAAU,yBAAW,UAAU,CAAC;AAAA,MACrC,QAAQ,CAAC,WAAW,SAAS,EAAE;AAAA,IAChC;AAAA,EACD;AACA,SAAO;AAAA,IACN,KAAK,cAAU,yBAAW,UAAU,CAAC;AAAA,IACrC,QAAQ,CAAC,WAAW,EAAE;AAAA,EACvB;AACD;AAsBO,SAAS,wBACf,YACA,IACA,WACA,SACW;AACX,QAAM,MAAM,sBAAsB,OAAO;AACzC,SAAO;AAAA,IACN,KAAK,cAAU,yBAAW,UAAU,CAAC,qEAAqE,IAAI,GAAG;AAAA,IACjH,QAAQ,CAAC,WAAW,SAAS,IAAI,GAAG,IAAI,MAAM;AAAA,EAC/C;AACD;AAuBA,SAAS,sBACR,OACA,QACA,QACgB;AAChB,QAAM,aAAuB,CAAC;AAE9B,aAAW,CAAC,WAAW,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACvD,sBAAkB,WAAW,MAAM;AACnC,UAAM,aAAa,OAAO,SAAS;AACnC,UAAM,SAAS,kBAAkB,WAAW,MAAM;AAElD,QAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAEzE,YAAM,MAAM;AACZ,iBAAW,CAAC,IAAI,OAAO,KAAK,OAAO,QAAQ,GAAG,GAAG;AAChD,YAAI,CAAC,gBAAgB,IAAI,EAAE,GAAG;AAC7B,gBAAM,IAAI,WAAW,qBAAqB,EAAE,eAAe,SAAS,KAAK;AAAA,YACxE,OAAO;AAAA,YACP,UAAU;AAAA,YACV,gBAAgB,CAAC,GAAG,eAAe;AAAA,UACpC,CAAC;AAAA,QACF;AACA,mBAAW,KAAK,uBAAuB,WAAW,QAAQ,IAAI,SAAS,YAAY,MAAM,CAAC;AAAA,MAC3F;AAAA,IACD,OAAO;AAEN,iBAAW,KAAK,uBAAuB,WAAW,QAAQ,OAAO,OAAO,YAAY,MAAM,CAAC;AAAA,IAC5F;AAAA,EACD;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,SAAO,WAAW,KAAK,OAAO;AAC/B;AAEA,SAAS,uBACR,WACA,YACA,UACA,OACA,YACA,QACS;AAET,QAAM,WAAW,iBAAiB,OAAO,UAAU;AAEnD,QAAM,aAAS,yBAAW,UAAU;AAEpC,UAAQ,UAAU;AAAA,IACjB,KAAK;AACJ,UAAI,aAAa,MAAM;AACtB,eAAO,GAAG,MAAM;AAAA,MACjB;AACA,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK;AACJ,UAAI,aAAa,MAAM;AACtB,eAAO,GAAG,MAAM;AAAA,MACjB;AACA,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK;AACJ,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK;AACJ,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK;AACJ,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK;AACJ,aAAO,KAAK,QAAQ;AACpB,aAAO,GAAG,MAAM;AAAA,IACjB,KAAK,OAAO;AACX,UAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG;AAC7B,cAAM,IAAI,WAAW,mDAAmD,SAAS,KAAK;AAAA,UACrF,OAAO;AAAA,UACP,UAAU,OAAO;AAAA,QAClB,CAAC;AAAA,MACF;AACA,YAAM,eAAe,SAAS,IAAI,MAAM,GAAG;AAC3C,iBAAW,QAAQ,UAAU;AAC5B,eAAO,KAAK,iBAAiB,MAAM,UAAU,CAAC;AAAA,MAC/C;AACA,aAAO,GAAG,MAAM,QAAQ,aAAa,KAAK,IAAI,CAAC;AAAA,IAChD;AAAA,IACA;AACC,YAAM,IAAI,WAAW,qBAAqB,QAAQ,KAAK,EAAE,SAAS,CAAC;AAAA,EACrE;AACD;AAEA,SAAS,iBAAiB,OAAgB,YAAkD;AAC3F,MAAI,YAAY,SAAS,aAAa,OAAO,UAAU,UAAW,QAAO,QAAQ,IAAI;AACrF,SAAO,wBAAwB,OAAO,UAAU;AACjD;AA4BA,SAAS,kBAAkB,WAAmB,QAAiD;AAC9F,MAAI,OAAO,OAAO,QAAQ,SAAS,EAAG,QAAO;AAC7C,MAAI,cAAc,eAAe,cAAc,aAAa;AAC3D,WAAO,yBAAyB,SAAS;AAAA,EAC1C;AACA,SAAO;AACR;AAEA,SAAS,iBAAiB,WAAoB,OAA+B;AAC5E,QAAM,MAAM,OAAO,cAAc,WAAW,UAAU,YAAY,IAAI;AACtE,QAAM,UAAU,OAAO,OAAO,iBAAiB,GAAG,IAAI,gBAAgB,GAAG,IAAI;AAC7E,MAAI,YAAY,QAAW;AAC1B,UAAM,IAAI,WAAW,qCAAqC,KAAK,2BAA2B;AAAA,MACzF;AAAA,MACA,WAAW,OAAO,cAAc,WAAW,UAAU,MAAM,GAAG,EAAE,IAAI,OAAO;AAAA,IAC5E,CAAC;AAAA,EACF;AACA,SAAO;AACR;AAEA,SAAS,iBAAiB,OAAgB,QAAoC;AAC7E,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG;AAC3E,UAAM,IAAI;AAAA,MACT,WAAW,MAAM,6EAA6E,MAAM;AAAA,MACpG,EAAE,QAAQ,UAAU,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAAA,IACtE;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,kBAAkB,WAAmB,QAA+C;AAE5F,QAAM,gBAAgB,oBAAI,IAAI;AAAA,IAC7B,GAAG,OAAO,KAAK,MAAM;AAAA,IACrB;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACD,CAAC;AACD,MAAI,CAAC,cAAc,IAAI,SAAS,GAAG;AAClC,UAAM,IAAI;AAAA,MACT,kBAAkB,SAAS,iCAAiC,CAAC,GAAG,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,MACzF,EAAE,OAAO,UAAU;AAAA,IACpB;AAAA,EACD;AACD;AAjbA,IACAC,cAuQM,iBAwGO,0BASA,+BAKP;AA9XN;AAAA;AAAA;AACA,IAAAA,eAA2B;AAC3B;AACA;AACA;AAoQA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK,CAAC;AAwG5E,IAAM,2BAA2B,OAAO,OAAO;AAAA,MACrD,WAAW;AAAA,MACX,WAAW;AAAA,IACZ,CAAU;AAMH,IAAM,gCAAkE,OAAO,OAAO;AAAA,MAC5F;AAAA,MACA;AAAA,IACD,CAAU;AAEV,IAAM,kBAA4D,OAAO,OAAO;AAAA,MAC/E,KAAK;AAAA,MACL,MAAM;AAAA,IACP,CAAC;AAAA;AAAA;;;ACrWD,eAAsB,gBAAgB,IAAgC;AACrE,aAAO;AAAA,IACN;AAAA,MACC,QAAQ,GAAG;AAAA,MACX,MAAM,GAAG;AAAA,MACT,YAAY,GAAG;AAAA,MACf,UAAU,GAAG;AAAA,MACb,MAAM,GAAG;AAAA,MACT,cAAc,GAAG;AAAA,MACjB,WAAW,GAAG;AAAA,MACd,gBAAgB,GAAG;AAAA,MACnB,YAAY,GAAG;AAAA,MACf,eAAe,GAAG;AAAA,MAClB,GAAI,GAAG,cAAc,SAAY,EAAE,WAAW,GAAG,UAAU,IAAI,CAAC;AAAA,IACjE;AAAA,IACA,GAAG,gBAAgB,IAAI,IAAI;AAAA,EAC5B;AACD;AAWA,eAAsB,qBACrB,IACA,YACA,KACA,gBACqB;AACrB,QAAM,YAAQ,yBAAW,aAAa,UAAU,EAAE;AAClD,QAAM,UAAU,mCAAmC,KAAK,UAAU;AAClE,QAAM,aAAwB,EAAE,GAAG,SAAS,eAAe;AAC3D,MAAI,QAAQ,gBAAgB,GAAG;AAC9B,UAAM,GAAG,QAAQ,UAAU,KAAK,yCAAyC;AAAA,MACxE;AAAA,MACA,IAAI;AAAA,IACL,CAAC;AACD,WAAO;AAAA,EACR;AACA,QAAM,KAAK,MAAM,gBAAgB,UAAU;AAC3C,QAAM,QAAmB,EAAE,GAAG,YAAY,GAAG;AAC7C,QAAM,oBAAoB,IAAI,YAAY,IAAI,IAAI,KAAK;AACvD,SAAO;AACR;AAEA,eAAe,oBACd,IACA,YACA,OACA,MACgB;AAChB,QAAM,GAAG,QAAQ,mBAAe,yBAAW,aAAa,UAAU,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC7F,QAAM,SAAS;AAAA,IACd,aAAa,UAAU;AAAA,IACvB,mBAAmB,IAAI;AAAA,EACxB;AACA,QAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAC3C;AAkBA,eAAsB,sBACrB,IACA,aACA,QACA,WACA,YACuB;AACvB,MAAI,WAAW,SAAS,EAAG,QAAO,CAAC;AACnC,QAAM,aAA8E,CAAC;AACrF,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,qBAAiB,yBAAW,aAAa,UAAU,EAAE,CAAC;AAAA,MACtD,CAAC,MAAM;AAAA,IACR;AACA,eAAW,OAAO,MAAM;AACvB,UAAI,CAAC,WAAW,IAAI,IAAI,EAAE,EAAG;AAC7B,iBAAW,KAAK,EAAE,YAAY,KAAK,IAAI,mCAAmC,KAAK,UAAU,EAAE,CAAC;AAAA,IAC7F;AAAA,EACD;AACA,aAAW,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,iBAAiB,EAAE,GAAG,cAAc;AACnE,QAAM,YAAyB,CAAC;AAChC,aAAW,EAAE,YAAY,KAAK,GAAG,KAAK,YAAY;AACjD,QAAI,CAAC,GAAG,WAAW,KAAK,CAAC,QAAQ,UAAU,GAAG,MAAM,MAAS,EAAG;AAChE,UAAM,aAAa,GAAG,WAAW,IAAI,CAAC,QAAQ,UAAU,GAAG,KAAK,GAAG;AACnE,UAAM,UAAqB,EAAE,GAAG,IAAI,WAAW;AAC/C,UAAM,KAAK,GAAG,gBAAgB,IAAI,MAAM,gBAAgB,OAAO,IAAI,GAAG;AACtE,UAAM,OAAkB,EAAE,GAAG,SAAS,GAAG;AACzC,UAAM,oBAAoB,IAAI,YAAY,IAAI,IAAI,IAAI;AACtD,QAAI,OAAO,GAAG,GAAI,WAAU,GAAG,EAAE,IAAI;AACrC,cAAU,KAAK,IAAI;AAAA,EACpB;AACA,SAAO;AACR;AA5IA,IAAAC,cAEA;AAFA;AAAA;AAAA;AAAA,IAAAA,eAA2B;AAE3B,sBAAmC;AACnC;AACA;AAAA;AAAA;;;ACWA,eAAsB,kCACrB,IACA,QACkB;AAClB,QAAM,OAAO,MAAM,GAAG;AAAA,IACrB;AAAA;AAAA;AAAA,IAGA,CAAC,MAAM;AAAA,EACR;AACA,QAAM,MAAM,KAAK,CAAC,GAAG;AACrB,MAAI,QAAQ,QAAW;AACtB,UAAM,IAAI,MAAM,gDAAgD,MAAM,kBAAkB;AAAA,EACzF;AACA,SAAO;AACR;AA9BA;AAAA;AAAA;AAAA;AAAA;;;AC0CO,SAAS,wBAAwB,YAA4B;AACnE,SAAO,iBAAiB,WAAW,MAAM,IAAI,UAAU;AACxD;AA8CA,eAAsB,yBACrB,SACA,QACA,QACgC;AAChC,QAAM,QAAQ,QAAQ,wBAAwB;AAC9C,QAAM,cAAc,OAAO,KAAK,OAAO,WAAW;AAClD,QAAM,SAA+B,EAAE,aAAa,GAAG,UAAU,EAAE;AAEnE,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA,CAAC,oBAAoB;AAAA,EACtB;AACA,MAAI,KAAK,WAAW,KAAK,YAAY,SAAS,GAAG;AAChD,UAAM,UAAU,SAAS,aAAa,QAAQ,MAAM;AAAA,EACrD;AAEA,aAAW,cAAc,aAAa;AACrC,UAAM,cAAc,yCAAqC,yBAAW,wBAAwB,UAAU,CAAC,CAAC,WAAO,yBAAW,aAAa,UAAU,EAAE,CAAC;AACpJ,QAAI;AACH,YAAM,QAAQ,QAAQ,WAAW;AAAA,IAClC,SAAS,OAAO;AAIf,UAAI,CAAC,UAAU,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAG,OAAM;AACnF,YAAM,UAAU,SAAS,aAAa,QAAQ,MAAM;AACpD,YAAM,QAAQ,QAAQ,WAAW;AAAA,IAClC;AAAA,EACD;AACA,SAAO;AACR;AAEA,eAAe,UACd,SACA,aACA,QACA,QACgB;AAChB,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,qBAAqB,IAAI,aAAa,MAAM;AAClD,UAAM,WAAW,MAAM,iBAAiB,IAAI,aAAa,MAAM;AAC/D,kBAAc,SAAS;AACvB,eAAW,SAAS;AACpB,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA,OAAO,KAAK,IAAI,CAAC;AAAA,IAClB,CAAC;AAAA,EACF,CAAC;AACD,SAAO,eAAe;AACtB,SAAO,YAAY;AACnB,MAAI,cAAc,KAAK,WAAW,GAAG;AACpC,YAAQ;AAAA,MACP,mBAAmB,cAAc,QAAQ,qFAAqF,WAAW,uCAAuC,QAAQ,oCAAoC,mBAAmB;AAAA,IAChP;AAAA,EACD;AACD;AAEA,eAAe,qBACd,IACA,aACA,QACgB;AAChB,MAAI,SAAS;AACb,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,mDAA+C,yBAAW,aAAa,UAAU,EAAE,CAAC;AAAA,MACpF,CAAC,MAAM;AAAA,IACR;AACA,aAAS,KAAK,IAAI,QAAQ,KAAK,CAAC,GAAG,WAAW,CAAC;AAAA,EAChD;AACA,MAAI,SAAS,GAAG;AACf,UAAM,GAAG;AAAA,MACR;AAAA;AAAA,MAEA,CAAC,QAAQ,MAAM;AAAA,IAChB;AAAA,EACD;AACD;AASA,eAAe,iBACd,IACA,aACA,QACgC;AAGhC,QAAM,MAAwB,CAAC;AAC/B,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,gDAA4C,yBAAW,aAAa,UAAU,EAAE,CAAC;AAAA,IAClF;AACA,eAAW,OAAO,KAAM,KAAI,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;AAAA,EACxD;AACA,QAAM,SAAS,oBAAI,IAA8B;AACjD,aAAW,OAAO,KAAK;AACtB,UAAM,MAAM,GAAG,IAAI,OAAO,KAAS,IAAI,eAAe;AACtD,UAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,QAAI,MAAO,OAAM,KAAK,GAAG;AAAA,QACpB,QAAO,IAAI,KAAK,CAAC,GAAG,CAAC;AAAA,EAC3B;AAEA,QAAM,SAA2B,CAAC;AAClC,aAAW,SAAS,OAAO,OAAO,GAAG;AACpC,QAAI,MAAM,SAAS,EAAG;AAKtB,UAAM,WAAW,oBAAI,IAAY;AACjC,eAAW,UAAU,OAAO;AAC3B,UAAI,MAAM,cAAc,IAAI,MAAM,EAAG,UAAS,IAAI,OAAO,EAAE;AAAA,IAC5D;AACA,UAAM,KAAK,CAAC,GAAG,MAAM;AACpB,YAAM,KAAK,SAAS,IAAI,EAAE,EAAE,IAAI,IAAI;AACpC,YAAM,KAAK,SAAS,IAAI,EAAE,EAAE,IAAI,IAAI;AACpC,UAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,aAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI;AAAA,IAC7C,CAAC;AACD,WAAO,KAAK,GAAG,MAAM,MAAM,CAAC,CAAC;AAAA,EAC9B;AAEA,SAAO;AAAA,IAAK,CAAC,GAAG,MACf,EAAE,oBAAoB,EAAE,kBACrB,EAAE,kBAAkB,EAAE,kBACtB,EAAE,KAAK,EAAE,KACR,KACA,EAAE,KAAK,EAAE,KACR,IACA;AAAA,EACN;AAEA,QAAM,SAA+B,EAAE,aAAa,GAAG,UAAU,EAAE;AACnE,QAAM,MAAM,KAAK,IAAI;AACrB,aAAW,SAAS,QAAQ;AAC3B,UAAM,YAAQ,yBAAW,aAAa,MAAM,UAAU,EAAE;AACxD,UAAM,OAAO,MAAM,GAAG,MAAoB,iBAAiB,KAAK,iBAAiB,CAAC,MAAM,EAAE,CAAC;AAC3F,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,CAAC,IAAK;AACV,QAAI,MAAM,YAAY,QAAQ;AAC7B,YAAM,SAAS,MAAM,kCAAkC,IAAI,MAAM;AACjE,YAAM,QAAQ,MAAM,qBAAqB,IAAI,MAAM,YAAY,KAAK,MAAM;AAC1E,YAAM;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACD;AACA,aAAO;AAAA,IACR,OAAO;AACN,YAAM,kBAAkB,IAAI,MAAM,YAAY,KAAK,sBAAsB,MAAM,MAAM,GAAG;AACxF,YAAM,GAAG,QAAQ,eAAe,KAAK,iBAAiB,CAAC,MAAM,EAAE,CAAC;AAChE,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAGA,eAAe,cAAc,IAAiB,UAA4C;AACzF,QAAM,OAAO,MAAM,GAAG;AAAA,IACrB,qBAAiB,yBAAW,aAAa,SAAS,UAAU,EAAE,CAAC;AAAA,IAC/D,CAAC,SAAS,EAAE;AAAA,EACb;AACA,QAAM,MAAM,KAAK,CAAC;AAClB,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,mCAAmC,KAAK,SAAS,UAAU,EAAE,gBAAgB;AACrF;AASA,eAAsB,kBACrB,IACA,YACA,KACA,QACA,aACA,mBACA,YACgB;AAChB,QAAM,GAAG;AAAA,IACR,yBAAyB,mBAAmB;AAAA;AAAA,IAE5C;AAAA,MACC,IAAI;AAAA,MACJ;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;AAMA,eAAsB,yBACrB,OACA,YACA,UACA,OAC0B;AAC1B,QAAM,aACL,SAAS,MAAM,SAAS,IAAI,iBAAiB,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC,MAAM;AACnF,SAAO;AAAA,IACN,0HAA0H,mBAAmB,mEAAmE,UAAU;AAAA,IAC1N,CAAC,YAAY,UAAU,GAAI,SAAS,CAAC,CAAE;AAAA,EACxC;AACD;AAGA,eAAsB,kBACrB,IACA,YACA,MACmB;AACnB,QAAM,QAAQ,MAAM,GAAG;AAAA,IACtB,sBAAkB,yBAAW,aAAa,UAAU,EAAE,CAAC;AAAA,IACvD,CAAC,IAAI;AAAA,EACN;AACA,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,WAAW,MAAM,GAAG;AAAA,IACzB,kBAAkB,mBAAmB;AAAA,IACrC,CAAC,IAAI;AAAA,EACN;AACA,SAAO,SAAS,SAAS;AAC1B;AAxVA,IAAAC,cAkBa,qBAEP,sBAGA;AAvBN;AAAA;AAAA;AAAA,IAAAA,eAA2B;AAE3B;AACA;AAEA;AAaO,IAAM,sBAAsB;AAEnC,IAAM,uBAAuB;AAG7B,IAAM,2BAA2B,8BAA8B,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACV3E,SAAS,6BAA6B,QAA+B;AAC3E,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,QAAQ,GAAG,KAAK,QAAQ;AACnC,WAAO,MAAM,IAAI;AAAA,EAClB;AACA,SAAO,KAAK,UAAU,MAAM;AAC7B;AAKO,SAAS,iCAAiC,OAA8B;AAC9E,QAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAM,aAAS,kCAAoB;AACnC,aAAW,CAAC,QAAQ,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AACnD,QAAI,OAAO,QAAQ,YAAY,OAAO,GAAG;AACxC,aAAO,IAAI,QAAQ,GAAG;AAAA,IACvB;AAAA,EACD;AACA,SAAO;AACR;AAKO,SAAS,oBAAoB,GAAkB,GAAiC;AACtF,QAAM,SAAS,IAAI,IAAI,CAAC;AACxB,aAAW,CAAC,QAAQ,GAAG,KAAK,GAAG;AAC9B,WAAO,IAAI,QAAQ,KAAK,IAAI,OAAO,IAAI,MAAM,KAAK,GAAG,GAAG,CAAC;AAAA,EAC1D;AACA,SAAO;AACR;AAKA,eAAsB,+BACrB,aACA,cACA,YACuB;AACvB,QAAM,UAAuB,CAAC;AAC9B,aAAW,CAAC,QAAQ,QAAQ,KAAK,aAAa;AAC7C,UAAM,YAAY,aAAa,IAAI,MAAM,KAAK;AAC9C,QAAI,WAAW,WAAW;AACzB,YAAM,MAAM,MAAM,WAAW,QAAQ,YAAY,GAAG,QAAQ;AAC5D,cAAQ,KAAK,GAAG,GAAG;AAAA,IACpB;AAAA,EACD;AACA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc;AAC1D,SAAO;AACR;AAKA,eAAsB,0BAA0B,SAAiD;AAChG,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,MAAM,KAAK,CAAC;AAClB,MAAI,CAAC,KAAK,OAAO;AAChB,eAAO,kCAAoB;AAAA,EAC5B;AACA,MAAI;AACH,WAAO,iCAAiC,IAAI,KAAK;AAAA,EAClD,QAAQ;AACP,eAAO,kCAAoB;AAAA,EAC5B;AACD;AAKA,eAAsB,0BACrB,SACA,QACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA,6BAA6B,MAAM;AAAA,EACpC,CAAC;AACF;AAKA,eAAsB,cACrB,SACA,QACyB;AACzB,MAAI,WAAW,QAAW;AACzB,UAAM,MAAM,MAAM,QAAQ,MAAe,8CAA8C;AAAA,MACtF,aAAa,MAAM;AAAA,IACpB,CAAC;AACD,QAAI,IAAI,CAAC,EAAG,QAAO,IAAI,CAAC,EAAE;AAE1B,UAAM,OAAO,MAAM,QAAQ,MAAe,oDAAoD;AAC9F,QAAI,KAAK,CAAC,GAAG,UAAU,OAAQ,QAAO;AAAA,EACvC;AACA,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,SAAO,KAAK,CAAC,GAAG,SAAS;AAC1B;AAGO,SAAS,aAAa,QAAwB;AACpD,SAAO,GAAG,mBAAmB,IAAI,MAAM;AACxC;AAOA,eAAsB,cACrB,SACA,OACA,QACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF,WAAW,SAAY,sBAAsB,aAAa,MAAM;AAAA,IAChE;AAAA,EACD,CAAC;AACF;AAKA,eAAsB,gBAAgB,SAAiD;AACtF,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,SAAO,KAAK,CAAC,GAAG,SAAS;AAC1B;AAKA,eAAsB,gBACrB,SACA,QACgB;AAChB,MAAI,WAAW,MAAM;AACpB,UAAM,QAAQ,QAAQ,wCAAwC,CAAC,qBAAqB,CAAC;AACrF;AAAA,EACD;AAEA,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA;AAAA,EACD,CAAC;AACF;AAMO,SAAS,qBAAqB,WAA2B;AAC/D,SAAO,cAAc,KAClB,8BACA,GAAG,2BAA2B,IAAI,SAAS;AAC/C;AAKA,eAAsB,sBACrB,SACA,WACkB;AAClB,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF,qBAAqB,SAAS;AAAA,EAC/B,CAAC;AACD,QAAM,QAAQ,KAAK,CAAC,GAAG;AACvB,MAAI,UAAU,UAAa,UAAU,MAAM;AAC1C,WAAO;AAAA,EACR;AACA,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO,OAAO,SAAS,MAAM,KAAK,UAAU,IAAI,SAAS;AAC1D;AAKA,eAAsB,sBACrB,SACA,WACA,WACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF,qBAAqB,SAAS;AAAA,IAC9B,OAAO,SAAS;AAAA,EACjB,CAAC;AACF;AAOA,eAAsB,wBACrB,SACA,WACgB;AAChB,QAAM,QAAQ,QAAQ,wCAAwC,CAAC,qBAAqB,SAAS,CAAC,CAAC;AAChG;AAKA,eAAsB,0BACrB,SACkC;AAClC,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA,CAAC,6BAA6B,GAAG,2BAA2B,IAAI;AAAA,EACjE;AACA,QAAM,SAAiC,CAAC;AACxC,QAAM,SAAS,GAAG,2BAA2B;AAC7C,aAAW,OAAO,MAAM;AACvB,UAAM,YAAY,IAAI,QAAQ,8BAA8B,KAAK,IAAI,IAAI,MAAM,OAAO,MAAM;AAC5F,UAAM,SAAS,OAAO,IAAI,KAAK;AAC/B,QAAI,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG;AAC3C,aAAO,SAAS,IAAI;AAAA,IACrB;AAAA,EACD;AACA,SAAO;AACR;AAMA,eAAsB,yBACrB,SACA,SACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA,KAAK,UAAU,OAAO;AAAA,EACvB,CAAC;AACF;AASA,eAAsB,gCACrB,SACA,SACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA,KAAK,UAAU,OAAO;AAAA,EACvB,CAAC;AACF;AAGA,eAAsB,gCAAgC,SAA4C;AACjG,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,MAAM,KAAK,CAAC,GAAG;AACrB,MAAI,QAAQ,OAAW,QAAO,CAAC;AAC/B,MAAI;AACH,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,MAAM,QAAQ,MAAM,EAAG,QAAO,OAAO,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AAAA,EAC7F,QAAQ;AAAA,EAER;AACA,SAAO,CAAC;AACT;AAMA,eAAsB,yBAAyB,SAAmD;AACjG,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,MAAM,KAAK,CAAC,GAAG;AACrB,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACH,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,CAAC,OAAO,OAAO,OAAO,QAAQ,GAAG;AAC1E,aAAO;AAAA,IACR;AAAA,EACD,QAAQ;AAAA,EAER;AACA,SAAO;AACR;AAtTA,IACAC,cAGa,mCACA,uBACA,6BACA,qBACA,iCA2PP;AAnQN;AAAA;AAAA;AACA,IAAAA,eAAoC;AAG7B,IAAM,oCAAoC;AAC1C,IAAM,wBAAwB;AAC9B,IAAM,8BAA8B;AACpC,IAAM,sBAAsB;AAC5B,IAAM,kCAAkC;AA2P/C,IAAM,0CAA0C;AAAA;AAAA;;;ACjNhD,eAAe,qBAAqB,SAAwC;AAC3E,MAAI,gBAAgB,IAAI,OAAO,EAAG;AAClC,QAAM,QAAQ,QAAQ,iBAAiB;AACvC,kBAAgB,IAAI,OAAO;AAC5B;AAOA,eAAsB,wBACrB,SACA,SACA,WACgB;AAChB,QAAM,qBAAqB,OAAO;AAClC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,eAAW,SAAS,SAAS;AAC5B,YAAM,GAAG;AAAA,QACR;AAAA,QACA;AAAA,UACC,MAAM,UAAU;AAAA,UAChB,MAAM,UAAU;AAAA,UAChB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,KAAK,UAAU,MAAM,SAAS;AAAA,UAC9B,MAAM;AAAA,QACP;AAAA,MACD;AAAA,IACD;AACA,QAAI,WAAW;AACd,YAAM,GAAG,QAAQ,gEAAgE;AAAA,QAChF,qBAAqB,UAAU,SAAS;AAAA,QACxC,OAAO,UAAU,SAAS;AAAA,MAC3B,CAAC;AAAA,IACF;AAAA,EACD,CAAC;AACF;AAGA,eAAsB,wBACrB,SACgC;AAChC,QAAM,qBAAqB,OAAO;AAClC,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,EACD;AACA,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACzB,WAAW,KAAK,MAAM,IAAI,OAAO;AAAA,IACjC,kBAAkB,IAAI,iBAAiB,OAAO,OAAO,OAAO,IAAI,YAAY;AAAA,IAC5E,MAAM,IAAI;AAAA,IACV,SAAS,IAAI;AAAA,IACb,eAAe,OAAO,IAAI,cAAc;AAAA,EACzC,EAAE;AACH;AAGA,eAAsB,0BACrB,SACA,cACgB;AAChB,MAAI,aAAa,WAAW,EAAG;AAC/B,QAAM,qBAAqB,OAAO;AAClC,QAAM,eAAe,aAAa,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAC1D,QAAM,QAAQ;AAAA,IACb,mDAAmD,YAAY;AAAA,IAC/D;AAAA,EACD;AACD;AAGO,SAAS,mBAAmB,QAAwB;AAC1D,SAAO,GAAG,0BAA0B,IAAI,MAAM;AAC/C;AAEA,SAAS,kBAAkB,OAAwE;AAClG,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI;AACH,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,OAAO,OAAO,WAAW,SAAU,QAAO;AAC9C,UAAM,WACL,OAAO,OAAO,aAAa,YAAY,OAAO,YAAY,IAAI,OAAO,WAAW;AACjF,WAAO,aAAa,OAAO,OAAO,EAAE,QAAQ,OAAO,QAAQ,SAAS;AAAA,EACrE,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAWA,eAAsB,oBACrB,SACA,QACyB;AACzB,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,SAAS,kBAAkB,KAAK,CAAC,GAAG,KAAK;AAC/C,MAAI,UAAU,OAAO,WAAW,OAAQ,QAAO,OAAO;AACtD,QAAM,MAAM,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACtF,mBAAmB,MAAM;AAAA,EAC1B,CAAC;AACD,QAAM,QAAQ,IAAI,CAAC,GAAG;AACtB,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,QAAM,WAAW,OAAO,KAAK;AAC7B,SAAO,OAAO,UAAU,QAAQ,KAAK,YAAY,IAAI,WAAW;AACjE;AAGA,eAAsB,oBACrB,SACA,QACA,UACgB;AAChB,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,OAAO,MAAM,GAAG,MAAe,8CAA8C;AAAA,MAClF;AAAA,IACD,CAAC;AACD,UAAM,SAAS,kBAAkB,KAAK,CAAC,GAAG,KAAK;AAC/C,QAAI,WAAW,QAAQ,OAAO,WAAW,QAAQ;AAChD,YAAM,GAAG,QAAQ,gEAAgE;AAAA,QAChF;AAAA,QACA,KAAK,UAAU,EAAE,QAAQ,SAAS,CAAC;AAAA,MACpC,CAAC;AACD;AAAA,IACD;AACA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF,mBAAmB,MAAM;AAAA,MACzB,OAAO,QAAQ;AAAA,IAChB,CAAC;AAAA,EACF,CAAC;AACF;AAGA,eAAsB,0BACrB,SAC0D;AAC1D,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,QAAQ,KAAK,CAAC,GAAG;AACvB,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI;AACH,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,WAAO,WAAW,QAAQ,OAAO,WAAW,WACxC,SACD;AAAA,EACJ,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAGA,eAAsB,0BACrB,SACA,OACgB;AAChB,MAAI,UAAU,MAAM;AACnB,UAAM,QAAQ,QAAQ,wCAAwC;AAAA,MAC7D;AAAA,IACD,CAAC;AACD;AAAA,EACD;AACA,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA,KAAK,UAAU,KAAK;AAAA,EACrB,CAAC;AACF;AAlOA,IAKa,4BAEA,kCAOP,mBAkCA;AAhDN;AAAA;AAAA;AAEA;AAGO,IAAM,6BAA6B;AAEnC,IAAM,mCAAmC;AAOhD,IAAM,oBACL;AAiCD,IAAM,kBAAkB,oBAAI,QAAwB;AAAA;AAAA;;;AC4HpD,eAAsB,4BAA4B,SAAwC;AACzF,QAAM,QAAQ,QAAQ,uBAAuB;AAC7C,QAAM,QAAQ,QAAQ,eAAe;AACrC,MAAI,iBAAiB,IAAI,OAAO,EAAG;AAGnC,QAAM,UAAU,MAAM,QAAQ,MAAwB,qBAAqB,iBAAiB,GAAG;AAC/F,aAAW,UAAU,CAAC,aAAa,WAAW,oBAAoB,GAAG;AACpE,QAAI,CAAC,QAAQ,KAAK,CAAC,aAAa,SAAS,SAAS,MAAM,GAAG;AAC1D,YAAM,QAAQ,QAAQ,eAAe,iBAAiB,eAAe,MAAM,OAAO;AAAA,IACnF;AAAA,EACD;AACA,mBAAiB,IAAI,OAAO;AAC7B;AAGA,eAAsB,yBACrB,SACA,SACgB;AAChB,QAAM,aAAa,QAAQ,OAAO,CAAC,UAAU,CAAC,6BAA6B,IAAI,MAAM,IAAI,CAAC;AAC1F,MAAI,WAAW,WAAW,EAAG;AAC7B,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,eAAW,SAAS,YAAY;AAC/B,YAAM,GAAG;AAAA,QACR,yBAAyB,yBAAyB;AAAA,QAClD,CAAC,MAAM,aAAa,MAAM,QAAQ,MAAM,gBAAgB,MAAM,MAAM,MAAM,UAAU;AAAA,MACrF;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAGA,eAAsB,uBACrB,SACA,cACuB;AACvB,QAAM,QAAQ,oBAAI,IAAY;AAC9B,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,QAAM,QAAQ;AACd,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK,OAAO;AACpD,UAAM,QAAQ,aAAa,MAAM,GAAG,IAAI,KAAK;AAC7C,UAAM,OAAO,MAAM,QAAQ;AAAA,MAC1B,4BAA4B,yBAAyB,2BAA2B,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/G;AAAA,IACD;AACA,eAAW,OAAO,KAAM,OAAM,IAAI,IAAI,YAAY;AAAA,EACnD;AACA,SAAO;AACR;AAQA,eAAsB,2BAA2B,SAAwC;AACxF,QAAM,4BAA4B,OAAO;AACzC,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,MAAI,KAAK,SAAS,EAAG;AACrB,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC5B;AAAA,EACD;AACA,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,QAAI,OAAO,SAAS,GAAG;AACtB,YAAM,eAAe,CAAC,GAAG,4BAA4B,EAAE,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAC/E,YAAM,GAAG;AAAA,QACR,yBAAyB,yBAAyB;AAAA;AAAA,gDAEN,YAAY;AAAA,QACxD,CAAC,GAAG,4BAA4B;AAAA,MACjC;AAAA,IACD;AACA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA,OAAO,KAAK,IAAI,CAAC;AAAA,IAClB,CAAC;AAAA,EACF,CAAC;AACF;AAEA,SAAS,YAAY,KAAoC;AACxD,SAAO;AAAA,IACN,QAAQ,IAAI;AAAA,IACZ,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,UAAU,OAAO,IAAI,QAAQ,MAAM;AAAA,IACnC,MAAM,OAAO,IAAI,IAAI,MAAM;AAAA,IAC3B,cAAc,IAAI,kBAAkB,OAAO,OAAO,OAAO,IAAI,aAAa;AAAA,IAC1E,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;AAAA,IAC/D,SACC,OAAO,IAAI,cAAc,YACzB,oBAAoB,SAAS,IAAI,OAA2B,IACxD,IAAI,UACL;AAAA,IACJ,mBAAmB,mBAAmB,IAAI,kBAAkB;AAAA,EAC7D;AACD;AAEA,SAAS,mBAAmB,OAAgC;AAC3D,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG,QAAO,CAAC;AAC7D,MAAI;AACH,UAAM,SAAkB,KAAK,MAAM,KAAK;AACxC,WAAO,MAAM,QAAQ,MAAM,IACxB,OAAO,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IACnE,CAAC;AAAA,EACL,QAAQ;AACP,WAAO,CAAC;AAAA,EACT;AACD;AAaA,eAAsB,kBAAkB,SAAyB,QAA+B;AAC/F,QAAM,4BAA4B,OAAO;AACzC,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,uBAAuB,iBAAiB;AAAA,IACxC,CAAC,MAAM;AAAA,EACR;AACA,MAAI,SAAS,SAAS,EAAG;AACzB,QAAM,WAAW,MAAM,eAAe,SAAS,MAAM;AACrD,QAAM,QAAQ;AAAA,IACb,yBAAyB,iBAAiB;AAAA,IAC1C,CAAC,QAAQ,KAAK,IAAI,GAAG,WAAW,IAAI,CAAC;AAAA,EACtC;AACD;AAQA,eAAe,eAAe,SAAyB,QAAkC;AACxF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA,CAAC,qBAAqB,aAAa,MAAM,GAAG,0BAA0B;AAAA,EACvE;AACA,QAAM,aAAa,MAAM,QAAQ;AAAA,IAChC;AAAA,EACD;AACA,QAAM,aAAa,WAAW,CAAC,GAAG,UAAU;AAC5C,aAAW,OAAO,MAAM;AACvB,QAAI,IAAI,QAAQ,aAAa,MAAM,EAAG,QAAO;AAC7C,QAAI,IAAI,QAAQ,qBAAqB;AACpC,UAAI,WAAY,QAAO;AACvB;AAAA,IACD;AACA,QAAI;AACH,YAAM,SAAS,KAAK,MAAM,IAAI,KAAK;AACnC,UAAI,IAAI,QAAQ,4BAA4B;AAC3C,YAAI,OAAO,WAAW,UAAU,OAAO,OAAO,aAAa,YAAY,OAAO,WAAW;AACxF,iBAAO;AAAA,MACT;AAAA,IACD,QAAQ;AAAA,IAER;AAAA,EACD;AACA,SAAO;AACR;AAGA,eAAsB,eAAe,SAAqD;AACzF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B,0GAA0G,iBAAiB;AAAA,EAC5H;AACA,SAAO,KAAK,IAAI,WAAW;AAC5B;AAEA,eAAe,kBAAkB,IAAkC;AAClE,QAAM,OAAO,MAAM,GAAG,MAAe,8CAA8C;AAAA,IAClF;AAAA,EACD,CAAC;AACD,QAAM,QAAQ,OAAO,KAAK,CAAC,GAAG,SAAS,CAAC;AACxC,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACzC;AAMA,eAAsB,sBACrB,SACA,QACgB;AAChB,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,QAAQ,MAAM,kBAAkB,EAAE;AACxC,UAAM,GAAG;AAAA,MACR,eAAe,iBAAiB;AAAA;AAAA,MAEhC,CAAC,QAAQ,KAAK,IAAI,CAAC;AAAA,IACpB;AACA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA,OAAO,QAAQ,CAAC;AAAA,IACjB,CAAC;AAAA,EACF,CAAC;AACF;AAMA,eAAsB,qBACrB,SACA,QACA,MACgB;AAChB,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,QAAQ,MAAM,kBAAkB,EAAE;AACxC,UAAM,GAAG;AAAA,MACR,eAAe,iBAAiB;AAAA;AAAA,MAEhC,CAAC,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,GAAG,KAAK;AAAA,IACzC;AAAA,EACD,CAAC;AACF;AAOA,eAAsB,gBAAgB,SAAyB,QAA+B;AAC7F,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ;AAAA,IACb,eAAe,iBAAiB;AAAA,IAChC,CAAC,MAAM;AAAA,EACR;AACD;AAMA,eAAsB,sBACrB,SACA,QACA,WACA,SACgB;AAChB,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ;AAAA,IACb,eAAe,iBAAiB;AAAA;AAAA,IAEhC,CAAC,QAAQ,KAAK,IAAI,GAAG,WAAW,OAAO;AAAA,EACxC;AACD;AAGA,SAAS,iBAAiB,MAAgC;AACzD,SAAO,KAAK,cAAc,SAAS,KAAK,YAAY,QAAQ,KAAK,YAAY;AAC9E;AAEA,eAAe,cACd,SACA,QACkC;AAClC,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B,0GAA0G,iBAAiB;AAAA,IAC3H,CAAC,MAAM;AAAA,EACR;AACA,QAAM,MAAM,KAAK,CAAC;AAClB,SAAO,MAAM,YAAY,GAAG,IAAI;AACjC;AAQA,eAAsB,0BACrB,SACA,QACA,WACgB;AAChB,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,OAAO,MAAM,cAAc,IAAI,MAAM;AAC3C,QAAI,QAAQ,KAAK,cAAc,QAAQ,KAAK,cAAc,aAAa,CAAC,iBAAiB,IAAI;AAC5F;AACD,UAAM,GAAG;AAAA,MACR,eAAe,iBAAiB;AAAA;AAAA,MAEhC,CAAC,QAAQ,KAAK,IAAI,GAAG,SAAS;AAAA,IAC/B;AAAA,EACD,CAAC;AACF;AAOA,eAAsB,0BACrB,SACA,QACA,WACgB;AAChB,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,OAAO,MAAM,cAAc,IAAI,MAAM;AAC3C,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,cAAc,QAAQ,CAAC,iBAAiB,IAAI,EAAG;AACxD,UAAM,UAAU,KAAK,kBAAkB,OAAO,CAAC,UAAU,UAAU,SAAS;AAC5E,YAAQ,KAAK,SAAS;AACtB,UAAM,GAAG;AAAA,MACR,UAAU,iBAAiB;AAAA,MAC3B,CAAC,KAAK,UAAU,QAAQ,MAAM,CAAC,sBAAsB,CAAC,GAAG,MAAM;AAAA,IAChE;AAAA,EACD,CAAC;AACF;AASA,eAAsB,yBACrB,SACA,QACA,WACmB;AACnB,QAAM,4BAA4B,OAAO;AACzC,MAAI,WAAW;AACf,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,OAAO,MAAM,cAAc,IAAI,MAAM;AAC3C,QAAI,CAAC,QAAQ,KAAK,cAAc,QAAQ,KAAK,kBAAkB,SAAS,SAAS,EAAG;AACpF,UAAM,GAAG;AAAA,MACR,UAAU,iBAAiB;AAAA,MAC3B,CAAC,WAAW,MAAM;AAAA,IACnB;AACA,eAAW;AAAA,EACZ,CAAC;AACD,SAAO;AACR;AAGA,eAAsB,cAAc,SAAyB,QAA+B;AAC3F,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ;AAAA,IACb,eAAe,iBAAiB;AAAA,IAChC,CAAC,MAAM;AAAA,EACR;AACD;AAGA,eAAsB,qBAAqB,SAAoD;AAC9F,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,QAA0B,EAAE,UAAU,GAAG,QAAQ,CAAC,EAAE;AAC1D,QAAM,MAAM,KAAK,CAAC,GAAG;AACrB,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACH,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO;AAAA,MACN,UAAU,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW;AAAA,MAClE,QAAQ,OAAO,UAAU,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,CAAC;AAAA,IAC/E;AAAA,EACD,QAAQ;AAEP,WAAO;AAAA,EACR;AACD;AAGA,eAAsB,qBACrB,SACA,UACgB;AAChB,QAAM,QAAQ,QAAQ,gEAAgE;AAAA,IACrF;AAAA,IACA,KAAK,UAAU,QAAQ;AAAA,EACxB,CAAC;AACF;AAGA,eAAsB,kBAAkB,SAA0C;AACjF,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,QAAQ,OAAO,KAAK,CAAC,GAAG,SAAS,CAAC;AACxC,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACzC;AA5jBA,IAkBa,2BAMA,mBAGA,yBAGP,wBAYO,8BAMP,yBAQA,iBAuBA,qBAGA,wBAGO,4BAGP;AAxFN;AAAA;AAAA;AACA;AACA;AAgBO,IAAM,4BAA4B;AAMlC,IAAM,oBAAoB;AAG1B,IAAM,0BAA0B;AAGvC,IAAM,yBAAyB;AAYxB,IAAM,+BAAoD,oBAAI,IAAI;AAAA,MACxE;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,IAAM,0BAA0B,8BAA8B,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvF,IAAM,kBAAkB,8BAA8B,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBvE,IAAM,sBAAmD,CAAC,SAAS,UAAU,KAAK;AAGlF,IAAM,yBAAyB;AAGxB,IAAM,6BAA6B;AAG1C,IAAM,mBAAmB,oBAAI,QAAwB;AAAA;AAAA;;;ACA9C,SAAS,gBAAgB,SAAmC;AAClE,QAAM,MAAM,IAAM,OAAI;AACtB,aAAW,UAAU,QAAS,CAAE,eAAY,KAAK,MAAM;AACvD,SAAS,uBAAoB,GAAG;AACjC;AAEA,SAAS,UAAU,GAAe,GAAwB;AACzD,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,KAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAC7D,SAAO;AACR;AAMO,SAAS,YAAY,GAAe,GAAwB;AAClE,SAAO,UAAU,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D;AAMA,eAAsB,YAAY,IAAiB,IAAiC;AACnF,QAAM,OAAO,MAAM,GAAG;AAAA,IACrB,+BAA+B,uBAAuB;AAAA,IACtD,CAAC,GAAG,MAAM;AAAA,EACX;AACA,QAAM,UAAU,KAAK,CAAC,GAAG;AACzB,SAAO,YAAY,UAAa,GAAG,kBAAkB;AACtD;AAmpBA,SAAS,cAAc,OAA0B;AAChD,SAAO,KAAK,UAAU,KAAK;AAC5B;AAEA,SAAS,YAAY,OAA2B;AAC/C,SAAO,KAAC,+BAAgB,KAAK;AAC9B;AAhxBA,IAAAC,eAyBAC,IAQa,kBAMA,iBAEA,yBASA,qBASA,uBAKP,sBAEO,+BAEA,8BAEA,6BAGA,iBAkEA;AA3Ib;AAAA;AAAA;AAAA,IAAAD,gBAwBO;AACP,IAAAC,KAAmB;AACnB;AACA;AACA;AACA;AAIO,IAAM,mBAAmB;AAMzB,IAAM,kBAAkB;AAExB,IAAM,0BAA0B;AAShC,IAAM,sBAAsB;AAS5B,IAAM,wBAAwB;AAKrC,IAAM,uBAA0C,CAAC,gBAAgB;AAE1D,IAAM,gCAAgC;AAEtC,IAAM,+BAA+B,SAAS,gCAAkB;AAEhE,IAAM,8BAA8B;AAGpC,IAAM,kBAAqC;AAAA,MACjD,8BAA8B,gBAAgB;AAAA,MAC9C,8BAA8B,eAAe;AAAA,MAC7C,8BAA8B,uBAAuB;AAAA,MACrD,8BAA8B,mBAAmB;AAAA,MACjD,8BAA8B,qBAAqB;AAAA,MACnD,8BAA8B,qBAAqB,cAAc,qBAAqB;AAAA,IACvF;AA2DO,IAAM,eAAN,MAAmB;AAAA,MAGzB,YACkB,QACA,aAA4C,CAAC,GAC7D;AAFgB;AACA;AAAA,MACf;AAAA,MAFe;AAAA,MACA;AAAA,MAJV,gBAAqC,oBAAI,IAAI;AAAA;AAAA,MAQrD,yBAAwD;AACvD,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,cAAc,IAAkC;AACvD,YAAI,KAAK,WAAW,SAAS,KAAK,GAAG,kBAAkB,KAAK,OAAO,QAAS,QAAO;AACnF,eAAO,IAAI,IAAI,OAAO,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC;AAAA,MAC1C;AAAA;AAAA,MAGA,0BAA+C;AAC9C,eAAO,KAAK;AAAA,MACb;AAAA;AAAA,MAGA,wBAAwB,KAA6B;AACpD,aAAK,gBAAgB,IAAI,IAAI,GAAG;AAAA,MACjC;AAAA;AAAA,MAGA,QAAQ,SAAgC,QAAqB;AAC5D,eAAO;AAAA,UACN,UAAU;AAAA,UACV,kBAAkB;AAAA,UAClB;AAAA,UACA,GAAI,KAAK,cAAc,OAAO,IAAI,EAAE,sBAAsB,KAAK,cAAc,IAAI,CAAC;AAAA,UAClF,GAAI,KAAK,WAAW,SAAS,IAAI,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,QACrE;AAAA,MACD;AAAA;AAAA,MAGA,uBAAuB,YAA6B;AACnD,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU;AACrD,YAAI,CAAC,WAAY,QAAO;AACxB,eAAO,OAAO,OAAO,WAAW,MAAM,EAAE;AAAA,UACvC,CAAC,UAAU,MAAM,kBAAkB;AAAA,QACpC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,MAAM,UACL,IACA,IACA,MAC4B;AAC5B,cAAM,aAAa,GAAG,SAAS;AAC/B,YAAI,SAAS,UAAU;AAKtB,gBAAM,UAAU,MAAM,KAAK,kBAAkB,IAAI,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU;AAC1F,gBAAM,WAAW,MAAM,KAAK,4BAA4B,IAAI,EAAE;AAC9D,cAAI,UAAU,KAAK,UAAU;AAC5B,kBAAM,KAAK,WAAW,IAAI,GAAG,YAAY,GAAG,UAAU,EAAE,iBAAiB,WAAW,CAAC;AACrF,mBAAO,EAAE,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,UACpC;AAAA,QACD;AAEA,cAAM,QAAQ,SAAS,WAAW,GAAG,SAAS;AAC9C,cAAM,QAAQ,QACX,EAAE,WAAO,+BAAgB,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,MAAM,IACrE,MAAM,KAAK,cAAc,IAAI,GAAG,YAAY,GAAG,UAAU,GAAG,EAAE;AACjE,YAAI;AACJ,YAAI;AACH,uBAAS;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA,KAAK;AAAA,YACL,KAAK,QAAQ,SAAS,WAAW,cAAc,MAAM;AAAA,UACtD;AAAA,QACD,SAAS,OAAO;AACf,cAAI,EAAE,iBAAiB,8BAAiB,OAAM;AAK9C,gBAAM,KAAK,WAAW,IAAI,GAAG,YAAY,GAAG,UAAU,EAAE,iBAAiB,WAAW,CAAC;AACrF,iBAAO,EAAE,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,QACpC;AACA,YAAI,CAAC,OAAO,WAAW,CAAC,MAAM,WAAW,CAAC,YAAY;AACrD,iBAAO,EAAE,SAAS,OAAO,QAAQ,MAAM,KAAK,cAAc,IAAI,OAAO,MAAM,EAAE;AAAA,QAC9E;AACA,cAAM,KAAK,UAAU,IAAI,OAAO,KAAK;AACrC,cAAM,UAAU,YAAY,MAAM,KAAK,KAAK,CAAC,YAAY,OAAO,KAAK;AACrE,cAAM,SACL,MAAM,WAAW,WAAW,GAAG,cAAc,SAAY,QAAQ,KAAK,cAAc,EAAE;AACvF,cAAM,KAAK,eAAe,IAAI,OAAO,OAAO,QAAQ;AAAA,UACnD,iBAAiB;AAAA,UACjB,GAAI,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,QACjC,CAAC;AACD,eAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,MAAM,KAAK,cAAc,IAAI,OAAO,MAAM,EAAE;AAAA,MACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,WACL,IACA,YACA,UACA,UAAyC,CAAC,GACd;AAC5B,cAAM,QAAQ,MAAM,KAAK,YAAY,IAAI,YAAY,QAAQ;AAC7D,YAAI,UAAU,MAAM;AACnB,gBAAM,GAAG,QAAQ,eAAe,gBAAgB,2CAA2C;AAAA,YAC1F;AAAA,YACA;AAAA,UACD,CAAC;AAED,gBAAM,GAAG,QAAQ,cAAU,0BAAW,UAAU,CAAC,kCAAkC,CAAC,QAAQ,CAAC;AAC7F,iBAAO;AAAA,QACR;AACA,cAAM,KAAK,UAAU,IAAI,KAAK;AAC9B,cAAM,KAAK,eAAe,IAAI,OAAO,OAAO;AAAA,UAC3C,iBAAiB,QAAQ,mBAAmB;AAAA,QAC7C,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,YACL,IACA,YACA,UAC4B;AAC5B,cAAM,MAAM;AAAA,UACX,GAAI,MAAM,KAAK,qBAAqB,IAAI,YAAY,QAAQ;AAAA,UAC5D,GAAI,MAAM,KAAK,gBAAgB,IAAI,YAAY,QAAQ;AAAA,QACxD;AACA,cAAM,WAAW,MAAM,KAAK;AAAA,UAC3B;AAAA,UACA,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE;AAAA,QACtB;AACA,cAAM,OAAO,MAAM,KAAK,SAAS,IAAI,YAAY,QAAQ;AACzD,cAAM,WAAW,MAAM,KAAK,aAAa,IAAI,YAAY,QAAQ;AACjE,YAAI,QACH,SAAS,QAAQ,aAAa,WAC3B,0BAAW,MAAM,UAAU,KAAK,MAAM,IACrC,QAAQ;AACb,mBAAW,MAAM,KAAK;AACrB,cAAI,SAAS,IAAI,GAAG,EAAE,EAAG;AACzB,sBAAQ;AAAA,YACP,aAAS,+BAAgB,YAAY,QAAQ;AAAA,YAC7C;AAAA,YACA,KAAK;AAAA,YACL,KAAK,QAAQ;AAAA,UACd,EAAE;AAAA,QACH;AACA,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,MAAM,qBACL,IACA,YACA,UACuB;AACvB,cAAM,OAAO;AAAA,UACZ,GAAI,MAAM,GAAG;AAAA,YACZ,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,YACtD,CAAC,QAAQ;AAAA,UACV;AAAA,UACA,GAAI,MAAM;AAAA,YACT,CAAC,KAAK,WAAW,GAAG,MAAM,KAAK,MAAM;AAAA,YACrC;AAAA,YACA;AAAA,UACD;AAAA,QACD;AACA,eAAO,KAAK,IAAI,CAAC,QAAQ,mCAAmC,KAAK,UAAU,CAAC;AAAA,MAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,uBAAuB,IAAiB,KAA8C;AAC3F,cAAM,QAAQ,oBAAI,IAAY;AAC9B,cAAM,QAAQ;AACd,iBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,OAAO;AAC3C,gBAAM,QAAQ,IAAI,MAAM,GAAG,IAAI,KAAK;AACpC,gBAAM,OAAO,MAAM,GAAG;AAAA,YACrB,4BAA4B,yBAAyB,uBAAuB,qBAAqB,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC,0BAA0B,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,YACnL,CAAC,GAAG,sBAAsB,GAAG,KAAK;AAAA,UACnC;AACA,qBAAW,OAAO,KAAM,OAAM,IAAI,IAAI,YAAY;AAAA,QACnD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,UACL,IACA,YACA,UAC4B;AAC5B,cAAM,QAAQ,MAAM,KAAK,aAAa,IAAI,kBAAkB,YAAY,QAAQ;AAChF,YAAI,UAAU,YAAQ,oCAAqB,OAAO,KAAK,MAAM,EAAE,SAAS,EAAG,QAAO;AAClF,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,MAAM,gBACL,IACA,YACA,UAC4B;AAC5B,eAAO,KAAK,aAAa,IAAI,kBAAkB,YAAY,QAAQ;AAAA,MACpE;AAAA;AAAA,MAGA,MAAM,SAAS,IAAiB,YAAoB,UAA6C;AAChG,cAAM,OAAO,MAAM,KAAK,aAAa,IAAI,iBAAiB,YAAY,QAAQ;AAC9E,eAAO,SAAS,OAAO,WAAO,8BAAe,MAAM,KAAK,QAAQ,KAAK,QAAQ,CAAC,EAAE;AAAA,MACjF;AAAA;AAAA,MAGA,MAAM,aACL,IACA,YACA,UAC4B;AAC5B,cAAM,WAAW,MAAM,KAAK,aAAa,IAAI,qBAAqB,YAAY,QAAQ;AACtF,eAAO,aAAa,OAAO,WAAO,8BAAe,UAAU,KAAK,QAAQ,KAAK,QAAQ,CAAC,EAAE;AAAA,MACzF;AAAA;AAAA,MAGA,MAAM,aAAa,IAAiB,UAAoC;AACvE,cAAM,WAAW,MAAM,KAAK,aAAa,IAAI,SAAS,GAAG,SAAS,CAAC;AACnE,cAAM,QAAQ,aAAa,OAAO,eAAW,0BAAW,UAAU,UAAU,KAAK,MAAM;AACvF,cAAM,GAAG;AAAA,UACR,0BAA0B,mBAAmB;AAAA,UAC7C,CAAC,MAAM,GAAG,MAAM,GAAG,cAAc,KAAK,CAAC;AAAA,QACxC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,MAAc,4BAA4B,IAAiB,IAAiC;AAC3F,YAAI,GAAG,SAAS,YAAY,GAAG,cAAc,OAAW,QAAO;AAC/D,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,6BAA6B,mBAAmB;AAAA,UAChD,CAAC,GAAG,YAAY,GAAG,QAAQ;AAAA,QAC5B;AACA,aAAK,KAAK,CAAC,GAAG,KAAK,OAAO,EAAG,QAAO;AACpC,YAAI;AACJ,YAAI;AACH,wBAAU,oCAAqB,GAAG,SAAS;AAAA,QAC5C,SAAS,OAAO;AACf,cAAI,iBAAiB,6BAAgB,QAAO;AAC5C,gBAAM;AAAA,QACP;AACA,YAAI,QAAQ,MAAM,GAAG,cAAc,QAAQ,MAAM,GAAG,SAAU,QAAO;AACrE,gBAAI,oCAAqB,SAAS,KAAK,MAAM,EAAE,SAAS,EAAG,QAAO;AAClE,cAAM,GAAG,QAAQ,eAAe,mBAAmB,2CAA2C;AAAA,UAC7F,GAAG;AAAA,UACH,GAAG;AAAA,QACJ,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,MAAM,oBACL,IAC2D;AAC3D,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,qCAAqC,mBAAmB;AAAA,QACzD;AACA,eAAO,KAAK,IAAI,CAAC,SAAS,EAAE,YAAY,IAAI,YAAY,UAAU,IAAI,UAAU,EAAE;AAAA,MACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,mBACL,IACA,YACA,UACmB;AACnB,cAAM,MAAM,MAAM,KAAK,qBAAqB,IAAI,YAAY,QAAQ;AACpE,cAAM,WAAW,MAAM,KAAK;AAAA,UAC3B;AAAA,UACA,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE;AAAA,QACtB;AACA,cAAM,YAAY,IAAI,KAAK,CAAC,OAAO,GAAG,SAAS,YAAY,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;AAC/E,cAAM,OAAO,MAAM,KAAK,SAAS,IAAI,YAAY,QAAQ;AACzD,YAAI,CAAC,cAAc,MAAM,MAAM,UAAU,KAAM,QAAO;AACtD,cAAM,GAAG,QAAQ,eAAe,mBAAmB,2CAA2C;AAAA,UAC7F;AAAA,UACA;AAAA,QACD,CAAC;AACD,cAAM,KAAK,WAAW,IAAI,YAAY,QAAQ;AAC9C,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,qBAAqB,IAAiB,IAAe,UAAiC;AAC3F,cAAM,WAAW,MAAM,GAAG;AAAA,UACzB,kBAAkB,qBAAqB;AAAA,UACvC,CAAC,GAAG,EAAE;AAAA,QACP;AACA,YAAI,SAAS,SAAS,EAAG;AACzB,cAAM,GAAG;AAAA,UACR,eAAe,qBAAqB;AAAA,UACpC,CAAC,GAAG,IAAI,GAAG,YAAY,GAAG,UAAU,UAAU,KAAK,UAAU,EAAE,CAAC;AAAA,QACjE;AACA,cAAM,QAAQ,MAAM,KAAK,cAAc,IAAI,GAAG,YAAY,GAAG,UAAU,GAAG,EAAE;AAC5E,cAAM,aAAS,uBAAQ,MAAM,OAAO,IAAI,KAAK,QAAQ,KAAK,QAAQ,CAAC;AACnE,YAAI,CAAC,OAAO,WAAW,CAAC,MAAM,QAAS;AACvC,cAAM,KAAK,UAAU,IAAI,OAAO,KAAK;AACrC,cAAM,KAAK,eAAe,IAAI,OAAO,OAAO,MAAM,UAAU,QAAQ,KAAK,cAAc,EAAE,GAAG;AAAA,UAC3F,iBAAiB;AAAA,QAClB,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,kBACL,IACA,YACA,UACA,WACkB;AAClB,YAAI,cAAc,QAAQ,UAAU,WAAW,EAAG,QAAO;AACzD,cAAM,SACL,cAAc,OAAO,KAAK,sBAAsB,UAAU,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AACpF,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,kBAAkB,qBAAqB,0CAA0C,MAAM;AAAA,UACvF,CAAC,YAAY,UAAU,GAAI,aAAa,CAAC,CAAE;AAAA,QAC5C;AACA,YAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,cAAM,GAAG;AAAA,UACR,eAAe,qBAAqB,iBAAiB,KAAK,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,UACnF,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE;AAAA,QACzB;AACA,eAAO,KAAK;AAAA,MACb;AAAA;AAAA,MAGA,MAAM,uBACL,IAC2D;AAC3D,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,8CAA8C,qBAAqB;AAAA,QACpE;AACA,eAAO,KAAK,IAAI,CAAC,SAAS,EAAE,YAAY,IAAI,YAAY,UAAU,IAAI,UAAU,EAAE;AAAA,MACnF;AAAA,MAEA,MAAc,gBACb,IACA,YACA,UACuB;AACvB,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,yBAAyB,qBAAqB;AAAA,UAC9C,CAAC,YAAY,QAAQ;AAAA,QACtB;AACA,eAAO,KAAK,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,SAAS,CAAc;AAAA,MAChE;AAAA,MAEA,MAAM,UAAU,IAAiB,OAAiC;AACjE,cAAM,GAAG;AAAA,UACR,0BAA0B,gBAAgB;AAAA,UAC1C,CAAC,MAAM,GAAG,MAAM,GAAG,cAAc,KAAK,CAAC;AAAA,QACxC;AAAA,MACD;AAAA,MAEA,MAAM,SAAS,IAAiB,OAAiC;AAChE,cAAM,GAAG;AAAA,UACR,0BAA0B,eAAe;AAAA,UACzC,CAAC,MAAM,GAAG,MAAM,GAAG,cAAc,KAAK,CAAC;AAAA,QACxC;AAAA,MACD;AAAA;AAAA,MAGA,MAAM,aAAa,IAAiB,UAAoC;AACvE,cAAM,OAAO,MAAM,KAAK,SAAS,IAAI,SAAS,GAAG,SAAS,CAAC;AAC3D,cAAM,KAAK,SAAS,IAAI,SAAS,OAAO,eAAW,0BAAW,MAAM,UAAU,KAAK,MAAM,CAAC;AAAA,MAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,MAAM,eACL,IACA,OACA,QACA,SACgB;AAChB,cAAM,aAAa,MAAM;AACzB,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU;AACrD,YAAI,CAAC,WAAY;AACjB,cAAM,YAAQ,0BAAW,UAAU;AACnC,cAAM,OAAO,QAAQ,SAClB,CAAC,IACD,MAAM,GAAG,MAAwB,4BAA4B,KAAK,iBAAiB;AAAA,UACnF,MAAM;AAAA,QACP,CAAC;AACH,cAAM,WAAW,KAAK,CAAC;AACvB,YAAI,MAAM,OAAO,QAAQ,MAAM,MAAM,MAAM;AAC1C,cAAI,YAAY,SAAS,aAAa,GAAG;AACxC,kBAAM,GAAG,QAAQ,UAAU,KAAK,kCAAkC,CAAC,MAAM,CAAC,CAAC;AAAA,UAC5E;AACA;AAAA,QACD;AACA,cAAM,SAAoB,EAAE,GAAG,OAAO,GAAG,KAAK;AAC9C,cAAM,aAAS,2BAAY,QAAQ,EAAE,UAAU,gBAAgB,CAAC,KAAK,CAAC;AACtE,cAAM,SAAS,iCAAmB,YAAY,MAAM,EAAE,CAAC;AACvD,cAAM,UAAU,iCAAmB,YAAY,MAAM,GAAG,CAAC;AAEzD,cAAM,oBAAgB,0CAA2B,KAAK;AACtD,YAAI,UAAU,YAAY,KAAK,IAAI,IAAI;AACvC,YAAI,YAAY,YAAY,GAAG;AAC9B,gBAAM,YAAY,MAAM,GAAG;AAAA,YAC1B;AAAA,YACA,CAAC,YAAY,MAAM,CAAC;AAAA,UACrB;AACA,cAAI,UAAU,SAAS,GAAG;AACzB,gBAAI,QAAQ,iBAAiB;AAC5B,oBAAM,GAAG;AAAA,gBACR;AAAA,gBACA,CAAC,YAAY,MAAM,CAAC;AAAA,cACrB;AAAA,YACD,OAAO;AACN,wBAAU;AAAA,YACX;AAAA,UACD;AAAA,QACD;AACA,cAAM,QAAQ,OAAO,KAAK,WAAW,MAAM;AAG3C,cAAM,WACL,YAAY,YAAY,IACrB,CAAC,IACD,MAAM,OAAO,CAAC,UAAU,SAAS,MAAM,MAAM,WAAW,SAAS,OAAO,IAAI,KAAK,EAAE;AACvF,cAAM,cAAuC,CAAC;AAC9C,mBAAW,SAAS,UAAU;AAC7B,gBAAM,QAAQ,OAAO,KAAK,KAAK;AAI/B,sBAAY,KAAK,IAChB,WAAW,OAAO,KAAK,GAAG,SAAS,cACnC,UAAU,QACV,OAAO,UAAU,YACjB,gBAAgB,QACb,gBAAgB,KAAC,6BAAc,OAAQ,MAAiC,UAAU,CAAC,CAAC,CAAC,IACrF;AAAA,QACL;AACA,cAAM,aAAa,gBAAgB,aAAa,WAAW,MAAM;AACjE,cAAM,OAAgC;AAAA,UACrC,aAAa,OAAO;AAAA,UACpB,UAAU,MAAM,EAAE;AAAA,UAClB,iBAAiB,KAAK,UAAU,aAAa;AAAA,UAC7C,UAAU;AAAA,QACX;AACA,YAAI,CAAC,UAAU;AACd,gBAAM,SAAS,iBAAiB,YAAY;AAAA,YAC3C,IAAI,MAAM;AAAA,YACV,GAAG;AAAA,YACH,GAAG;AAAA,YACH,aAAa,QAAQ;AAAA,UACtB,CAAC;AACD,gBAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAC1C;AAAA,QACD;AACA,cAAM,UAAmC;AAAA,UACxC,GAAG;AAAA,UACH,GAAG;AAAA,UACH,aAAa,QAAQ;AAAA,QACtB;AACA,cAAM,UAAU,OAAO,KAAK,OAAO;AACnC,cAAM,GAAG;AAAA,UACR,UAAU,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM,OAAG,0BAAW,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,UAC5E,CAAC,GAAG,QAAQ,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC;AAAA,QAC5C;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAc,cACb,IACA,YACA,UACA,YACkD;AAClD,cAAM,SAAS,MAAM,KAAK,UAAU,IAAI,YAAY,QAAQ;AAC5D,YAAI,WAAW,KAAM,QAAO,EAAE,OAAO,QAAQ,SAAS,MAAM;AAC5D,cAAM,SAAS,MAAM,KAAK,YAAY,IAAI,YAAY,QAAQ;AAC9D,cAAM,SAAS,MAAM,GAAG;AAAA,UACvB,iCAA6B,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,UAClE,CAAC,UAAU,UAAU;AAAA,QACtB;AACA,cAAM,WAAW,MAAM;AAAA,UACtB,CAAC,KAAK,WAAW,GAAG,MAAM,KAAK,MAAM;AAAA,UACrC;AAAA,UACA;AAAA,QACD;AACA,cAAM,UACJ,MAAM,KAAK,SAAS,IAAI,YAAY,QAAQ,MAAO,QACnD,MAAM,KAAK,aAAa,IAAI,YAAY,QAAQ,MAAO,SACvD,MAAM,KAAK,gBAAgB,IAAI,YAAY,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AACvF,YACC,CAAC,UACD,CAAC,YACA,OAAO,CAAC,GAAG,KAAK,OAAO,KACxB,SAAS,MAAM,CAAC,QAAQ,IAAI,OAAO,UAAU,GAC5C;AAED,iBAAO,EAAE,WAAO,+BAAgB,YAAY,QAAQ,GAAG,SAAS,MAAM;AAAA,QACvE;AACA,cAAM,UAAU,MAAM,KAAK,YAAY,IAAI,YAAY,QAAQ;AAC/D,eAAO,EAAE,OAAO,eAAW,+BAAgB,YAAY,QAAQ,GAAG,SAAS,KAAK;AAAA,MACjF;AAAA,MAEA,MAAc,YACb,IACA,YACA,UACmB;AACnB,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,6BAA6B,gBAAgB;AAAA,UAC7C,CAAC,YAAY,QAAQ;AAAA,QACtB;AACA,gBAAQ,KAAK,CAAC,GAAG,KAAK,KAAK;AAAA,MAC5B;AAAA,MAEA,MAAc,aACb,IACA,OACA,YACA,UAC4B;AAC5B,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,qBAAqB,KAAK;AAAA,UAC1B,CAAC,YAAY,QAAQ;AAAA,QACtB;AACA,cAAM,MAAM,KAAK,CAAC,GAAG;AACrB,YAAI,QAAQ,OAAW,QAAO;AAC9B,YAAI;AACH,qBAAO,oCAAqB,GAAG;AAAA,QAChC,SAAS,OAAO;AAEf,cAAI,iBAAiB,6BAAgB,QAAO;AAC5C,gBAAM;AAAA,QACP;AAAA,MACD;AAAA,MAEA,MAAc,cAAc,IAAiB,QAA4C;AACxF,cAAM,MAAoB,CAAC;AAC3B,mBAAW,SAAS,QAAQ;AAC3B,cAAI,QAA0B;AAC9B,cAAI,MAAM,qBAAqB,MAAM;AACpC,kBAAM,OAAO,MAAM,GAAG;AAAA,cACrB,qBAAiB,0BAAW,aAAa,MAAM,UAAU,UAAU,EAAE,CAAC;AAAA,cACtE,CAAC,MAAM,gBAAgB;AAAA,YACxB;AACA,kBAAM,MAAM,KAAK,CAAC;AAClB,gBAAI,IAAK,SAAQ,mCAAmC,KAAK,MAAM,UAAU,UAAU;AAAA,UACpF;AACA,cAAI,SAAK,4BAAa,OAAO,KAAK,CAAC;AAAA,QACpC;AACA,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;ACxmBA,eAAsB,iBACrB,SACA,QACA,SAC8B;AAC9B,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,OAAO,QAAQ,QAAQ;AAC3B,QAAM,QAAQ,QAAQ,cAAc;AAEpC,QAAM,UAAoF,CAAC;AAC3F,MAAI,cAAc;AAClB,aAAW,cAAc,OAAO,KAAK,OAAO,WAAW,GAAG;AACzD,UAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,QAAI,OAA8B;AAClC,QAAI,SAAS,SAAS;AACrB,UAAI;AACH,eAAO,MAAM,QAAQ;AAAA,UACpB,mCAAmC,KAAK,UAAU,aAAa;AAAA,QAChE;AAAA,MACD,QAAQ;AAEP,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,SAAS,MAAM;AAClB,iBAAW,OAAO,MAAM;AACvB;AACA,cAAM,UAAU,kBAAkB,GAAG;AACrC,YAAI,QAAQ,SAAS,KAAM,SAAQ,KAAK,EAAE,YAAY,KAAK,QAAQ,CAAC;AAAA,MACrE;AACA;AAAA,IACD;AACA,QAAI,QAAQ;AACZ,eAAS;AACR,YAAM,OAAO,MAAM,QAAQ;AAAA,QAC1B,mCAAmC,KAAK,yCAAyC,SAAS;AAAA,QAC1F,CAAC,KAAK;AAAA,MACP;AACA,iBAAW,OAAO,MAAM;AACvB;AACA,cAAM,UAAU,kBAAkB,GAAG;AACrC,YAAI,QAAQ,SAAS,KAAM,SAAQ,KAAK,EAAE,YAAY,KAAK,QAAQ,CAAC;AAAA,MACrE;AACA,UAAI,KAAK,SAAS,UAAW;AAC7B,cAAQ,KAAK,KAAK,SAAS,CAAC,GAAG,WAAW;AAAA,IAC3C;AAAA,EACD;AAEA,QAAM,WAA8B,CAAC;AACrC,QAAM,mBAAsC,CAAC;AAC7C,aAAW,EAAE,YAAY,KAAK,QAAQ,KAAK,SAAS;AACnD,QAAI,QAAQ,SAAS,KAAM;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,QAAQ,SAAS,QAAQ,MAAM;AAC1E,QAAI,QAAQ,SAAS,SAAU,UAAS,KAAK,KAAK;AAAA,QAC7C,kBAAiB,KAAK,KAAK;AAAA,EACjC;AAEA,MAAI,UAAU,QAAQ,SAAS,GAAG;AACjC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,iBAAW,EAAE,YAAY,KAAK,QAAQ,KAAK,SAAS;AACnD,cAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,YAAI,QAAQ,SAAS,UAAU;AAC9B,gBAAM,GAAG,QAAQ,UAAU,KAAK,sCAAsC;AAAA,YACrE,QAAQ;AAAA,YACR,IAAI;AAAA,UACL,CAAC;AAAA,QACF,WAAW,QAAQ,SAAS,cAAc;AACzC,gBAAM,cAAc,IAAI,YAAY,KAAK,QAAQ,SAAS,QAAQ,QAAQ,GAAG;AAC7E,gBAAM,GAAG,QAAQ,eAAe,KAAK,oBAAoB,CAAC,IAAI,OAAO,CAAC;AAAA,QACvE;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,eAAe,OAAO;AAChD,QAAM,OAAO,MAAM,oBAAoB,SAAS,QAAQ,QAAQ,YAAY;AAC5E,QAAM,cAAc,MAAM,gBAAgB,OAAO;AACjD,QAAM,oBAAoB,SAAS,IAAI,iBAAiB;AACxD,SAAO;AAAA,IACN,OAAO,YAAY,WAAW,KAAK,sBAAsB,KAAK,KAAK,WAAW;AAAA,IAC9E;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EAChB;AACD;AAMO,SAAS,kBAAkB,KAAkC;AACnE,MACC,CAAC,iBAAiB,IAAI,EAAE,KACxB,CAAC,iBAAiB,IAAI,OAAO,KAC7B,CAAC,iBAAiB,IAAI,SAAS,GAC9B;AACD,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,IACT;AAAA,EACD;AACA,MAAI,CAAC,gBAAgB,IAAI,IAAI,IAAI,GAAG;AACnC,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,QAAQ,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IACzC;AAAA,EACD;AACA,MAAI,CAAC,OAAO,UAAU,IAAI,eAAe,KAAK,IAAI,kBAAkB,GAAG;AACtE,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,mBAAmB,KAAK,UAAU,IAAI,eAAe,CAAC;AAAA,IAC/D;AAAA,EACD;AACA,MAAI,CAAC,mBAAmB,IAAI,IAAI,KAAK,CAAC,mBAAmB,IAAI,aAAa,GAAG;AAC5E,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,IACT;AAAA,EACD;AACA,MAAI,CAAC,kBAAkB,IAAI,WAAW,GAAG;AACxC,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,eAAe,SAAS,OAAO,IAAI,WAAW,CAAC,CAAC;AAAA,IACzD;AAAA,EACD;AAEA,MAAI,YAAY,IAAI;AACpB,MAAI,eAA8B;AAClC,MAAI,CAAC,qBAAqB,SAAS,GAAG;AACrC,UAAM,YAAY,iBAAiB,SAAS;AAC5C,QAAI,cAAc,MAAM;AACvB,aAAO;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,QAAQ,aAAa,SAAS,OAAO,SAAS,CAAC,CAAC;AAAA,MACjD;AAAA,IACD;AACA,mBAAe,OAAO,SAAS;AAC/B,gBAAY;AAAA,EACb;AAEA,MAAI;AACH,UAAM,KAAK,qBAAqB,EAAE,GAAG,KAAK,UAAU,CAAC;AACrD,UAAM,QAAQ,mBAAmB,EAAE,GAAG,IAAI,YAAY,GAAG,CAAC;AAC1D,QAAI,MAAM,cAAc,WAAW;AAClC,YAAM,IAAI,MAAM,aAAa,MAAM,SAAS,OAAO,SAAS,EAAE;AAAA,IAC/D;AAAA,EACD,SAAS,OAAO;AACf,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D;AAAA,EACD;AAEA,MAAI,iBAAiB,MAAM;AAC1B,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,aAAa,SAAS,YAAY,CAAC,OAAO,SAAS;AAAA,MAC3D;AAAA,IACD;AAAA,EACD;AACA,SAAO,EAAE,MAAM,KAAK;AACrB;AAGA,SAAS,qBAAqB,OAAiC;AAC9D,MAAI,OAAO,UAAU,YAAY,CAAC,oBAAoB,KAAK,KAAK,EAAG,QAAO;AAC1E,MAAI;AACH,WAAO,iCAAmB,UAAU,iCAAmB,YAAY,KAAK,CAAC,MAAM;AAAA,EAChF,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAeO,SAAS,iBAAiB,OAA+B;AAC/D,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO;AAChE,MAAI;AACJ,MAAI;AACH,aAAS,KAAK,MAAM,KAAK;AAAA,EAC1B,QAAQ;AACP,WAAO;AAAA,EACR;AACA,MAAI,YAAY;AAChB,WAAS,QAAQ,GAAG,QAAQ,GAAG,SAAS;AACvC,QAAI,cAAc,QAAQ,OAAO,cAAc,SAAU,QAAO;AAChE,UAAM,EAAE,UAAU,SAAS,OAAO,IAAI;AACtC,QAAI,OAAO,UAAU,QAAQ,KAAK,OAAO,UAAU,OAAO,KAAK,iBAAiB,MAAM,GAAG;AACxF,UAAI;AACH,eAAO,iCAAmB,UAAU;AAAA,UACnC;AAAA,UACA;AAAA,UACA;AAAA,QACD,CAAC;AAAA,MACF,QAAQ;AACP,eAAO;AAAA,MACR;AAAA,IACD;AAGA,QAAI,aAAa,QAAQ,CAAC,OAAO,UAAU,OAAO,KAAK,OAAO,WAAW,SAAU,QAAO;AAC1F,UAAM,QAAQ,4BAA4B,KAAK,MAAM;AACrD,QAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAG,QAAO;AACrC,QAAI;AACJ,QAAI;AACH,kBAAY,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAChC,QAAQ;AACP,aAAO;AAAA,IACR;AACA,gBAAY,EAAE,UAAU,SAAS,SAAS,OAAO,MAAM,CAAC,CAAC,GAAG,QAAQ,UAAU;AAAA,EAC/E;AACA,SAAO;AACR;AAEA,eAAe,cACd,IACA,YACA,KACA,SACA,QACA,KACgB;AAChB,QAAM,EAAE,SAAS,QAAQ,GAAG,SAAS,IAAI;AACzC,QAAM,GAAG;AAAA,IACR,0BAA0B,oBAAoB;AAAA,IAC9C;AAAA,MACC;AAAA,MACA,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK,SAAS,IAAI,OAAO;AAAA,MAC1D,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAAA,MAChD,OAAO,UAAU,IAAI,eAAe,IAAI,IAAI,kBAAkB;AAAA,MAC9D;AAAA,MACA;AAAA,MACA,KAAK,UAAU,UAAU,aAAa;AAAA,MACtC;AAAA,IACD;AAAA,EACD;AACD;AAWA,eAAe,eAAe,SAAqD;AAClF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B,mFAAmF,oBAAoB;AAAA,EACxG;AACA,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACzB,YAAY,IAAI;AAAA,IAChB,aAAa,IAAI;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZ,gBAAgB,IAAI;AAAA,IACpB,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,EACb,EAAE;AACH;AAOA,eAAe,oBACd,SACA,QACA,SAC4B;AAC5B,QAAM,cAAc,OAAO,KAAK,OAAO,WAAW;AAClD,MAAI,YAAY,WAAW,EAAG,QAAO,CAAC;AACtC,QAAM,OAAyB,CAAC;AAChC,QAAM,QAAQ,YACZ,IAAI,CAAC,MAAM,mCAA+B,0BAAW,aAAa,CAAC,EAAE,CAAC,oBAAoB,EAC1F,KAAK,aAAa;AACpB,aAAW,UAAU,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG;AAC3C,UAAM,SAAS,YAAY,IAAI,MAAM,MAAM;AAC3C,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC7B,gFAAgF,KAAK;AAAA,MACrF;AAAA,IACD;AACA,UAAM,QAAQ,QAAQ,CAAC,GAAG,KAAK;AAC/B,UAAM,MAAM,QAAQ,CAAC,GAAG,KAAK;AAC7B,QAAI,QAAQ,QAAQ,QAAQ,KAAK,UAAU,IAAK;AAChD,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC7B,yCAAyC,KAAK;AAAA,MAC9C;AAAA,IACD;AACA,QAAI,WAAW;AACf,eAAW,EAAE,iBAAiB,IAAI,KAAK,SAAS;AAC/C,UAAI,MAAM,SAAU,MAAK,KAAK,EAAE,QAAQ,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;AACrE,iBAAW,KAAK,IAAI,UAAU,MAAM,CAAC;AAAA,IACtC;AAAA,EACD;AACA,SAAO;AACR;AAEA,eAAe,gBAAgB,SAAiD;AAC/E,QAAM,OAAO,MAAM,QAAQ,MAAe,8CAA8C;AAAA,IACvF;AAAA,EACD,CAAC;AACD,QAAM,QAAQ,OAAO,KAAK,CAAC,GAAG,KAAK;AACnC,SAAO,KAAK,CAAC,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ;AACpD;AAEA,SAAS,YACR,YACA,KACA,SACA,QACkB;AAClB,SAAO;AAAA,IACN;AAAA,IACA,aAAa,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK;AAAA,IACnD,QAAQ,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAAA,IACxD,gBAAgB,OAAO,UAAU,IAAI,eAAe,IAAI,IAAI,kBAAkB;AAAA,IAC9E;AAAA,IACA;AAAA,EACD;AACD;AAEA,SAAS,iBAAiB,OAAiC;AAC1D,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS;AACpD;AAEA,SAAS,mBAAmB,OAAyB;AACpD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACH,UAAM,SAAkB,KAAK,MAAM,KAAK;AACxC,WAAO,WAAW,QAAQ,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM;AAAA,EAC9E,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,kBAAkB,OAAyB;AACnD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACH,UAAM,SAAkB,KAAK,MAAM,KAAK;AACxC,WAAO,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,CAAC,OAAO,OAAO,OAAO,QAAQ;AAAA,EAC5E,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,SAAS,OAAuB;AACxC,SAAO,MAAM,SAAS,MAAM,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ;AAC3D;AAEA,SAAS,cAAc,MAAc,OAAyB;AAC7D,MAAI,iBAAiB,WAAY,QAAO,EAAE,QAAQ,MAAM,KAAK,KAAK,EAAE;AACpE,SAAO;AACR;AArhBA,IAAAC,eA2Ba,sBAEP,gBAyFA,iBACA,qBACA,WAMA;AA9HN;AAAA;AAAA;AAAA,IAAAA,gBAA+C;AAE/C;AACA;AAwBO,IAAM,uBAAuB;AAEpC,IAAM,iBAAiB,8BAA8B,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyFzE,IAAM,kBAAkB,oBAAI,IAAI,CAAC,UAAU,UAAU,QAAQ,CAAC;AAC9D,IAAM,sBAAsB;AAC5B,IAAM,YAAY;AAMlB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC9HtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkDA,SAAS,cAAc,MAAc,SAAiC;AACrE,QAAM,YAAY,IAAI,YAAY,EAAE,OAAO,IAAI;AAC/C,QAAM,SAAS,IAAI,WAAW,IAAI,UAAU,SAAS,QAAQ,MAAM;AACnE,QAAM,KAAK,IAAI,SAAS,OAAO,MAAM;AACrC,KAAG,UAAU,GAAG,UAAU,QAAQ,IAAI;AACtC,KAAG,UAAU,GAAG,QAAQ,QAAQ,IAAI;AACpC,SAAO,IAAI,WAAW,CAAC;AACvB,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM;AACxC,SAAO;AACR;AAEA,SAAS,kBAAkB,MAAc,MAA2B;AACnE,SAAO,cAAc,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,MAAMC,cAAa,CAAC,CAAC;AACzF;AAEA,SAAS,oBAAoB,MAAc,OAA8B;AACxE,QAAM,QAAQ,MAAM,IAAI,CAAC,SAAS,KAAK,UAAU,MAAMA,cAAa,CAAC,EAAE,KAAK,IAAI;AAChF,SAAO,cAAc,MAAM,IAAI,YAAY,EAAE,OAAO,MAAM,SAAS,IAAI,GAAG,KAAK;AAAA,IAAO,EAAE,CAAC;AAC1F;AAOA,SAAS,cAAc,MAA6B;AACnD,QAAM,WAAsB,CAAC;AAC7B,QAAM,KAAK,IAAI,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AACrE,MAAI,SAAS;AACb,SAAO,SAAS,KAAK,KAAK,YAAY;AACrC,UAAM,UAAU,GAAG,UAAU,QAAQ,IAAI;AACzC,UAAM,aAAa,GAAG,UAAU,SAAS,GAAG,IAAI;AAChD,cAAU;AACV,QAAI,SAAS,UAAU,aAAa,KAAK,WAAY;AACrD,UAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,MAAM,QAAQ,SAAS,OAAO,CAAC;AAC1E,cAAU;AACV,aAAS,KAAK,EAAE,MAAM,SAAS,KAAK,MAAM,QAAQ,SAAS,UAAU,EAAE,CAAC;AACxE,cAAU;AAAA,EACX;AACA,SAAO;AACR;AAEA,SAAS,YAAY,UAAqB,MAAiC;AAC1E,SAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,IAAI,GAAG,WAAW;AACtE;AAEA,SAAS,iBAAoB,UAAqB,MAAwB;AACzE,QAAM,UAAU,YAAY,UAAU,IAAI;AAC1C,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO,GAAG,YAAY;AAClE;AAEA,SAAS,YAAe,SAAiC;AACxD,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,SAAO,IAAI,YAAY,EACrB,OAAO,OAAO,EACd,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC,EACvC,IAAI,CAAC,SAAS,KAAK,MAAM,MAAM,YAAY,CAAM;AACpD;AAEA,SAAS,OAAO,OAAiC;AAChD,QAAM,QAAQ,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,QAAQ,CAAC;AAC9D,QAAM,SAAS,IAAI,WAAW,KAAK;AACnC,MAAI,MAAM;AACV,aAAW,QAAQ,OAAO;AACzB,WAAO,IAAI,MAAM,GAAG;AACpB,WAAO,KAAK;AAAA,EACb;AACA,SAAO;AACR;AAkBA,eAAsB,aACrB,SACA,QACA,QACA,eACA,SACsB;AACtB,QAAM,aAAa,SAAS,eAAe,MAAM;AAAA,EAAC;AAClD,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,SAAS,SAAS;AACxB,QAAM,cAAc,OAAO,KAAK,OAAO,WAAW,EAAE;AAAA,IACnD,CAAC,SAAS,CAAC,UAAU,OAAO,SAAS,IAAI;AAAA,EAC1C;AAEA,QAAM,WASF;AAAA,IACH,QAAQ,CAAC;AAAA,IACT,YAAY,CAAC;AAAA,IACb,UAAU,CAAC;AAAA,IACX,SAAS,oBAAI,IAAI;AAAA,IACjB,OAAO,CAAC;AAAA,IACR,WAAW,CAAC;AAAA,IACZ,kBAAkB,CAAC;AAAA,IACnB,WAAW;AAAA,EACZ;AAEA,aAAW,EAAE,OAAO,WAAW,UAAU,GAAG,SAAS,6BAA6B,CAAC;AACnF,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,SAAS,MAAM,GAAG;AAAA,MACvB;AAAA,IACD;AACA,eAAW,OAAO,OAAQ,UAAS,OAAO,IAAI,OAAO,IAAI,IAAI;AAC7D,aAAS,aAAa,MAAM,eAAe,IAAI,WAAW;AAC1D,aAAS,WAAW,MAAM,uBAAuB,EAAE;AAGnD,aAAS,QAAQ,MAAM,kBAAkB,IAAI,iBAAiB,WAAW;AACzE,aAAS,YAAY,MAAM,kBAAkB,IAAI,qBAAqB,WAAW;AACjF,QAAI,MAAM,SAAS,IAAI,uBAAuB,GAAG;AAChD,iBAAW,OAAO,MAAM,GAAG;AAAA,QAC1B,wCAAwC,uBAAuB;AAAA,MAChE,GAAG;AACF,iBAAS,iBAAiB,IAAI,OAAO,IAAI,IAAI;AAAA,MAC9C;AAAA,IACD;AACA,aAAS,YACR,SAAS,MAAM,SAAS,KACxB,OAAO,KAAK,SAAS,gBAAgB,EAAE,SAAS,MAE/C,MAAM,GAAG,MAAyB,8CAA8C;AAAA,MAC/E;AAAA,IACD,CAAC,GACA,SAAS;AACZ,QAAI,gBAAgB;AACnB,iBAAW,cAAc,aAAa;AACrC,iBAAS,QAAQ;AAAA,UAChB;AAAA,UACA,MAAM,GAAG,MAA+B,qBAAiB,0BAAW,UAAU,CAAC,EAAE;AAAA,QAClF;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACD,aAAW,EAAE,OAAO,WAAW,UAAU,KAAK,SAAS,WAAW,CAAC;AAEnE,QAAM,UAAwB;AAAA,IAC7B,kBAAkB,kBAAkB,SAAS,MAAM;AAAA,IACnD,oBAAoB,cAAc,SAAS,UAAU;AAAA,IACrD,kBAAkB,uBAAuB,SAAS,QAAQ;AAAA,IAC1D,oBAAoB,aAAa,SAAS,KAAK;AAAA,IAC/C,oBAAoB,iBAAiB,SAAS,SAAS;AAAA,IACvD,kBAAkB,qBAAqB,SAAS,gBAAgB;AAAA,EACjE;AACA,aAAW,CAAC,YAAY,IAAI,KAAK,SAAS,SAAS;AAClD,QAAI,KAAK,SAAS,EAAG,SAAQ,KAAK,oBAAoB,WAAW,UAAU,IAAI,IAAI,CAAC;AAAA,EACrF;AACA,QAAM,OAAO,OAAO,OAAO;AAC3B,QAAM,WAAW,MAAM,cAAc,IAAI;AACzC,aAAW,EAAE,OAAO,WAAW,UAAU,GAAG,SAAS,aAAa,CAAC;AAEnE,QAAM,WAA2B;AAAA,IAChC,SAAS;AAAA,IACT,WAAW,KAAK,IAAI;AAAA,IACpB;AAAA,IACA;AAAA,IACA,gBAAgB,SAAS,WAAW;AAAA,IACpC;AAAA,IACA,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,WAAW,SAAS;AAAA,IACpB;AAAA,EACD;AACA,SAAO,OAAO;AAAA,IACb,kBAAkB,YAAY,QAAQ;AAAA,IACtC;AAAA,IACA,cAAc,YAAY,IAAI,YAAY,EAAE,OAAO,QAAQ,CAAC;AAAA,EAC7D,CAAC;AACF;AAGA,eAAe,eAAe,IAAiB,aAA6C;AAC3F,QAAM,aAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,WAAW,MAAM,SAAS,IAAI,mBAAmB;AACvD,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,IACvD;AAGA,QAAI,UAAU;AACb,WAAK;AAAA,QACJ,GAAI,MAAM,GAAG;AAAA,UACZ,0HAA0H,mBAAmB;AAAA,UAC7I,CAAC,UAAU;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AACA,eAAW,OAAO,MAAM;AACvB,UAAI,KAAK,IAAI,IAAI,EAAE,EAAG;AACtB,WAAK,IAAI,IAAI,EAAE;AACf,iBAAW,KAAK,mCAAmC,KAAK,UAAU,CAAC;AAAA,IACpE;AAAA,EACD;AACA,aAAW,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAC9E,SAAO;AACR;AAUA,eAAe,kBACd,IACA,OACA,aAC0B;AAC1B,MAAI,CAAE,MAAM,SAAS,IAAI,KAAK,EAAI,QAAO,CAAC;AAC1C,QAAM,MAAsB,CAAC;AAC7B,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,gCAAgC,KAAK;AAAA,MACrC,CAAC,UAAU;AAAA,IACZ;AACA,eAAW,OAAO,KAAM,KAAI,KAAK,EAAE,YAAY,UAAU,IAAI,WAAW,OAAO,IAAI,MAAM,CAAC;AAAA,EAC3F;AACA,SAAO;AACR;AAEA,eAAe,uBAAuB,IAA+C;AACpF,MAAI,CAAE,MAAM,SAAS,IAAI,yBAAyB,EAAI,QAAO,CAAC;AAC9D,QAAM,OAAO,MAAM,GAAG;AAAA,IAOrB,yEAAyE,yBAAyB;AAAA,EACnG;AACA,SAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACzB,aAAa,IAAI;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZ,gBAAgB,IAAI;AAAA,IACpB,MAAM,IAAI;AAAA,IACV,YAAY,IAAI;AAAA,EACjB,EAAE;AACH;AAEA,eAAe,SAAS,IAAiB,MAAgC;AACxE,QAAM,OAAO,MAAM,GAAG;AAAA,IACrB;AAAA,IACA,CAAC,IAAI;AAAA,EACN;AACA,SAAO,KAAK,SAAS;AACtB;AA4BO,SAAS,mBAAmB,MAAkC;AACpE,QAAM,WAAW,iBAAiC,cAAc,IAAI,GAAG,UAAU;AACjF,MAAI,CAAC,UAAU;AACd,UAAM,IAAI,kBAAkB,8CAA8C,gBAAgB;AAAA,EAC3F;AACA,SAAO;AACR;AAQA,eAAsB,qBAAqB,MAAoC;AAC9E,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,WAAW,iBAAiC,UAAU,UAAU;AACtE,MAAI,CAAC,UAAU,SAAU,QAAO;AAChC,QAAM,OAAO;AAAA,IACZ,SACE,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,SAAS,UAAU,EAC5D,IAAI,CAAC,MAAM,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EAC9C;AACA,SAAQ,MAAM,cAAc,IAAI,MAAO,SAAS;AACjD;AAUA,eAAsB,YACrB,MACA,SACwB;AACxB,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,WAAW,iBAAiC,UAAU,UAAU;AACtE,MAAI,CAAC,UAAU;AACd,UAAM,IAAI,kBAAkB,8CAA8C,gBAAgB;AAAA,EAC3F;AACA,MAAI,SAAS,YAAY,GAAG;AAC3B,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA,EAAE,SAAS,GAAG,KAAK,oDAAoD;AAAA,IACxE;AAAA,EACD;AACA,MAAI,SAAS,YAAY,gBAAgB;AACxC,UAAM,IAAI;AAAA,MACT,+BAA+B,OAAO,SAAS,OAAO,CAAC,gCAAgC,cAAc;AAAA,MACrG;AAAA,MACA,EAAE,SAAS,SAAS,QAAQ;AAAA,IAC7B;AAAA,EACD;AACA,MAAI,CAAE,MAAM,qBAAqB,IAAI,GAAI;AACxC,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,OAAO,CAAC,eACb,CAAC,SAAS,eAAe,QAAQ,YAAY,SAAS,UAAU;AACjE,QAAM,aAA0B,CAAC;AACjC,aAAW,OAAO,YAAuB,YAAY,UAAU,YAAY,CAAC,GAAG;AAC9E,QAAI,CAAC,KAAK,IAAI,UAAU,EAAG;AAC3B,eAAW,KAAK,mBAAmB,GAAG,CAAC;AAAA,EACxC;AACA,aAAW,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAE9E,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,CAAC,QAAQ,GAAG,KAAK,OAAO;AAAA,IAClC,iBAAyC,UAAU,gBAAgB,KAAK,CAAC;AAAA,EAC1E,GAAG;AACF,QAAI,OAAO,UAAU,GAAG,KAAK,MAAM,EAAG,QAAO,IAAI,QAAQ,GAAG;AAAA,EAC7D;AAEA,QAAM,UAAU,oBAAI,IAA4C;AAChE,MAAI,SAAS,iBAAiB;AAC7B,eAAW,cAAc,SAAS,aAAa;AAC9C,UAAI,CAAC,KAAK,UAAU,EAAG;AACvB,cAAQ;AAAA,QACP;AAAA,QACA,YAAqC,YAAY,UAAU,WAAW,UAAU,EAAE,CAAC;AAAA,MACpF;AAAA,IACD;AAAA,EACD;AAEA,QAAM,WAAW,CAAC,SACjB,YAA0B,YAAY,UAAU,IAAI,CAAC,EAAE;AAAA,IACtD,CAAC,QACA,OAAO,KAAK,eAAe,YAC3B,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,UAAU,YACrB,KAAK,IAAI,UAAU;AAAA,EACrB;AACD,QAAM,mBAAmB,oBAAI,IAAoB;AACjD,aAAW,CAAC,QAAQ,GAAG,KAAK,OAAO;AAAA,IAClC,iBAAyC,UAAU,mBAAmB,KAAK,CAAC;AAAA,EAC7E,GAAG;AACF,QAAI,OAAO,UAAU,GAAG,KAAK,MAAM,EAAG,kBAAiB,IAAI,QAAQ,GAAG;AAAA,EACvE;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,oBACC,iBAAsC,UAAU,qBAAqB,KAAK,CAAC;AAAA,IAC5E;AAAA,IACA,WAAW,SAAS,WAAW;AAAA,IAC/B,eAAe,SAAS,eAAe;AAAA,IACvC;AAAA,EACD;AACD;AAGA,SAAS,mBAAmB,KAA2B;AACtD,MAAI;AACJ,MAAI;AACH,UAAM,mBAAmB,GAAG;AAAA,EAC7B,SAAS,OAAO;AACf,UAAM,IAAI;AAAA,MACT,oBAAoB,OAAO,KAAK,EAAE,CAAC,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACvH;AAAA,MACA,EAAE,aAAa,KAAK,GAAG;AAAA,IACxB;AAAA,EACD;AACA,QAAM,UAAU,kBAAkB,GAAG;AACrC,MAAI,QAAQ,SAAS,QAAQ,OAAO,IAAI,eAAe,YAAY,IAAI,eAAe,IAAI;AACzF,UAAM,IAAI;AAAA,MACT,oBAAoB,OAAO,IAAI,EAAE,CAAC,sBAAsB,QAAQ,SAAS,OAAO,kBAAkB,QAAQ,OAAO;AAAA,MACjH;AAAA,MACA,EAAE,aAAa,IAAI,GAAG;AAAA,IACvB;AAAA,EACD;AACA,SAAO,mCAAmC,KAAK,IAAI,UAAU;AAC9D;AA4BA,eAAsB,gBACrB,MACA,SACsB;AACtB,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,WAAW,iBAAiC,UAAU,UAAU;AACtE,MAAI,CAAC,YAAY,SAAS,YAAY,GAAG;AACxC,UAAM,IAAI,kBAAkB,+CAA+C,kBAAkB;AAAA,MAC5F,SAAS,UAAU;AAAA,IACpB,CAAC;AAAA,EACF;AACA,MAAI,CAAE,MAAM,qBAAqB,IAAI,GAAI;AACxC,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACA,QAAM,aAA0B,CAAC;AACjC,QAAM,UAAoB,CAAC;AAC3B,aAAW,OAAO,YAAuB,YAAY,UAAU,YAAY,CAAC,GAAG;AAC9E,UAAM,QAAQ,mBAAmB,GAAG;AACpC,QAAI,MAAO,YAAW,KAAK,KAAK;AAAA,QAC3B,SAAQ,KAAK,OAAO,KAAK,EAAE,CAAC;AAAA,EAClC;AACA,MAAI,QAAQ,SAAS,KAAK,CAAC,SAAS,mBAAmB;AACtD,UAAM,IAAI;AAAA,MACT,GAAG,QAAQ,MAAM,gFAAgF,QAAQ,CAAC,CAAC;AAAA,MAC3G;AAAA,MACA,EAAE,cAAc,QAAQ,MAAM,GAAG,EAAE,EAAE;AAAA,IACtC;AAAA,EACD;AACA,aAAW,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAE9E,QAAM,UAAwB;AAAA,IAC7B;AAAA,MACC;AAAA,MACA,iBAAyC,UAAU,gBAAgB,KAAK,CAAC;AAAA,IAC1E;AAAA,IACA,oBAAoB,cAAc,UAAU;AAAA,IAC5C,kBAAkB,uBAAuB,CAAC,CAAC;AAAA,EAC5C;AACA,aAAW,WAAW,UAAU;AAC/B,QAAI,QAAQ,KAAK,WAAW,UAAU,GAAG;AACxC,YAAM,OAAO,YAAqC,QAAQ,OAAO,EAAE,IAAI,aAAa;AACpF,cAAQ,KAAK,oBAAoB,QAAQ,MAAM,IAAI,CAAC;AAAA,IACrD;AAAA,EACD;AACA,QAAM,OAAO,OAAO,OAAO;AAC3B,QAAM,WAAW,MAAM,cAAc,IAAI;AACzC,QAAM,YAA4B;AAAA,IACjC,SAAS;AAAA,IACT,WAAW,SAAS;AAAA,IACpB,QAAQ,SAAS;AAAA,IACjB,eAAe,SAAS;AAAA,IACxB,gBAAgB,WAAW;AAAA,IAC3B,aAAa,SAAS;AAAA,IACtB,iBAAiB,SAAS;AAAA,IAC1B,oBAAoB;AAAA,IACpB;AAAA,IACA,eAAe;AAAA,EAChB;AACA,SAAO,OAAO;AAAA,IACb,kBAAkB,YAAY,SAAS;AAAA,IACvC;AAAA,IACA,cAAc,YAAY,IAAI,YAAY,EAAE,OAAO,QAAQ,CAAC;AAAA,EAC7D,CAAC;AACF;AAEA,SAAS,mBAAmB,KAAkC;AAC7D,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,OAAO,SAAU,QAAO;AAC1E,QAAM,KAAK,IAAI;AACf,MAAI,YAAY;AAChB,QAAM,QACL,OAAO,QACP,OAAO,OAAO,YACd,OAAO,UAAW,GAA6B,QAAQ,KACvD,OAAO,UAAW,GAA4B,OAAO;AACtD,MAAI,CAAC,OAAO;AACX,UAAM,YAAY,iBAAiB,KAAK,UAAU,EAAE,CAAC;AACrD,QAAI,CAAC,UAAW,QAAO;AACvB,gBAAY,iCAAmB,YAAY,SAAS;AAAA,EACrD;AACA,MAAI;AACH,WAAO,mBAAmB,EAAE,GAAG,KAAK,UAAU,CAAC;AAAA,EAChD,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAGA,SAAS,cAAc,KAAuD;AAC7E,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,GAAG,IAAI,yBAAyB,KAAK,IAAI,QAAQ,KAA+B,IAAI;AAAA,EACzF;AACA,SAAO;AACR;AAEA,SAAS,yBAAyB,OAAyB;AAC1D,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AAChF,QAAM,UAAU,OAAO,QAAQ,KAAgC;AAC/D,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,QAAQ;AAAA,IACd,CAAC,CAAC,KAAK,IAAI,GAAG,UACb,QAAQ,OAAO,KAAK,KACpB,OAAO,UAAU,IAAI,KACpB,QAAmB,KACnB,OAAkB;AAAA,EACrB;AACD;AAEA,SAAS,QAAQ,OAA2C;AAC3D,QAAM,SAAS,OAAO,KAAK,KAAK,EAAE;AAClC,QAAM,QAAQ,IAAI,WAAW,MAAM;AACnC,WAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,OAAM,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,KAAK;AAChE,SAAO;AACR;AAgBA,eAAsB,cACrB,SACA,QACA,MACA,SACyB;AACzB,QAAM,EAAE,OAAAC,OAAM,IAAI,MAAM;AACxB,QAAM,QAAQ,IAAIA,OAAM,EAAE,QAAQ,QAAQ,CAAC;AAC3C,QAAM,MAAM,KAAK;AACjB,MAAI;AACH,WAAO,MAAM,MAAM,aAAa,MAAM,OAAO;AAAA,EAC9C,UAAE;AACD,UAAM,MAAM,MAAM;AAAA,EACnB;AACD;AAIA,SAASD,eAAc,MAAc,OAAyB;AAC7D,MAAI,iBAAiB,WAAY,QAAO,EAAE,QAAQ,SAAS,KAAK,EAAE;AAClE,SAAO;AACR;AAEA,SAAS,aAAa,MAAc,OAAyB;AAC5D,MACC,UAAU,QACV,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,KAAK,KAAK,EAAE,WAAW,KAC9B,OAAQ,MAA+B,WAAW,UACjD;AACD,WAAO,WAAY,MAA6B,MAAM;AAAA,EACvD;AACA,SAAO;AACR;AAEA,SAAS,SAAS,OAA2B;AAC5C,MAAI,SAAS;AACb,QAAM,QAAQ;AACd,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,OAAO;AAC7C,cAAU,OAAO,aAAa,GAAG,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC;AAAA,EAC9D;AACA,SAAO,KAAK,MAAM;AACnB;AAEA,SAAS,WAAW,MAA0B;AAC7C,QAAM,SAAS,KAAK,IAAI;AACxB,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AACtE,SAAO;AACR;AAEA,eAAe,cAAc,MAAmC;AAC/D,QAAM,aAAa,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI,WAAW,IAAI,CAAC;AAC7E,SAAO,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC,EAC1C,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACV;AAtsBA,IAAAE,eAwCa,gBAGA;AA3Cb;AAAA;AAAA;AAAA,IAAAA,gBAA0D;AAE1D;AACA;AAKA;AACA;AACA;AACA;AA6BO,IAAM,iBAAiB;AAGvB,IAAM,oBAAN,cAAgC,wBAAU;AAAA,MAChD,YAAY,SAAiB,MAAc,SAAmC;AAC7E,cAAM,SAAS,MAAM,OAAO;AAC5B,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAAA;AAAA;;;ACqIA,eAAsB,eACrB,IACA,QACA,QACA,OACa;AACb,QAAM,QAAoB,EAAE,IAAI,UAAU,IAAI,cAAc,IAAI,MAAM,GAAG,OAAO;AAChF,QAAM,SAAS,MAAM,MAAM,KAAK;AAChC,QAAM,MAAM,SAAS,MAAM;AAC3B,SAAO;AACR;AAOO,SAAS,mBAAmB,OAAyB;AAC3D,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAM,YAAY;AAClB,MAAI,UAAU,SAAS,qBAAsB,QAAO;AACpD,MAAI,UAAU,SAAS,iBAAiB,UAAU,SAAS,iBAAkB,QAAO;AACpF,QAAM,UAAU,OAAO,UAAU,YAAY,WAAW,UAAU,UAAU;AAC5E,MAAI,wDAAwD,KAAK,OAAO,EAAG,QAAO;AAClF,SAAO,UAAU,UAAU,UAAa,UAAU,UAAU,QACzD,mBAAmB,UAAU,KAAK,IAClC;AACJ;AAhNA,IAOAC,eAuDa,aA2DA;AAzHb;AAAA;AAAA;AAOA,IAAAA,gBAA0B;AAuDnB,IAAM,cAAN,MAAkB;AAAA,MAKxB,YACkB,SAEA,iBAChB;AAHgB;AAEA;AAAA,MACf;AAAA,MAHe;AAAA,MAEA;AAAA,MAPD,mBAAmB,oBAAI,IAAoB;AAAA,MACpD,cAA6B;AAAA,MACpB,WAAsD,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAcxE,QAAQ,YAAoB,QAA2B,CAAC,GAAa;AACpE,cAAM,OAAiB,CAAC;AACxB,cAAM,MAAM,CAAC,OAAwC;AACpD,cAAI,MAAM,CAAC,KAAK,SAAS,EAAE,EAAG,MAAK,KAAK,EAAE;AAAA,QAC3C;AACA,mBAAW,MAAM,MAAO,KAAI,EAAE;AAC9B,cAAM,QAAQ,KAAK,iBAAiB,IAAI,UAAU;AAClD,YAAI,UAAU,QAAW;AACxB,cAAI,KAAK;AAAA,QACV,OAAO;AACN,qBAAW,MAAM,KAAK,SAAS,eAAe,YAAY,KAAK,KAAK,CAAC,EAAG,KAAI,EAAE;AAAA,QAC/E;AACA,YAAI,KAAK,gBAAiB,KAAI,KAAK,WAAW;AAC9C,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,OAAO,YAAoB,aAA2B;AACrD,aAAK,iBAAiB,IAAI,YAAY,WAAW;AACjD,aAAK,cAAc;AACnB,aAAK,SAAS,KAAK,EAAE,YAAY,IAAI,YAAY,CAAC;AAAA,MACnD;AAAA;AAAA,MAGA,UAAgB;AACf,mBAAW,EAAE,YAAY,GAAG,KAAK,KAAK,UAAU;AAC/C,eAAK,SAAS,eAAe,YAAY,IAAI,KAAK;AAAA,QACnD;AAAA,MACD;AAAA,IACD;AAaO,IAAM,gBAAN,MAAoB;AAAA,MAI1B,YACkB,IACA,QAChB;AAFgB;AACA;AAAA,MACf;AAAA,MAFe;AAAA,MACA;AAAA,MALV,OAAsB;AAAA,MACtB,YAAY;AAAA;AAAA,MAQpB,MAAM,OAAwB;AAC7B,YAAI,KAAK,SAAS,MAAM;AACvB,gBAAM,OAAO,MAAM,KAAK,GAAG;AAAA,YAC1B;AAAA;AAAA;AAAA,YAGA,CAAC,KAAK,MAAM;AAAA,UACb;AACA,gBAAM,QAAQ,KAAK,CAAC,GAAG;AACvB,cAAI,UAAU,QAAW;AACxB,kBAAM,IAAI;AAAA,cACT,iDAAiD,KAAK,MAAM;AAAA,cAC5D;AAAA,cACA,EAAE,QAAQ,KAAK,OAAO;AAAA,YACvB;AAAA,UACD;AACA,eAAK,OAAO;AACZ,eAAK,YAAY;AACjB,iBAAO;AAAA,QACR;AACA,aAAK,QAAQ;AACb,eAAO,KAAK;AAAA,MACb;AAAA;AAAA,MAGA,MAAM,QAAuB;AAC5B,YAAI,KAAK,SAAS,QAAQ,KAAK,SAAS,KAAK,UAAW;AACxD,cAAM,KAAK,GAAG;AAAA,UACb;AAAA,UACA,CAAC,KAAK,MAAM,KAAK,MAAM;AAAA,QACxB;AACA,aAAK,YAAY,KAAK;AAAA,MACvB;AAAA,IACD;AAAA;AAAA;;;ACvJA,eAAsB,cACrB,KACA,OACuB;AACvB,QAAM,SAAS,IAAI,YAAY,IAAI,eAAe,KAAK;AACvD,MAAI;AACJ,MAAI;AACH,UAAM,IAAI,QAAQ,YAAY,OAAO,OAAO;AAC3C,eAAS,MAAM,eAAe,IAAI,IAAI,QAAQ,QAAQ,KAAK;AAAA,IAC5D,CAAC;AAAA,EACF,SAAS,OAAO;AACf,QAAI,iBAAiB,KAAK;AAC1B,UAAM;AAAA,EACP;AACA,MAAI,CAAC,QAAQ;AACZ,UAAM,IAAI,wBAAU,sDAAsD,oBAAoB;AAAA,MAC7F,YAAY,IAAI;AAAA,IACjB,CAAC;AAAA,EACF;AACA,SAAO,QAAQ;AACf,oBAAkB,KAAK,MAAM;AAC7B,SAAO;AACR;AAGA,SAAS,kBAAkB,KAA2B,QAA2B;AAChF,QAAM,MAAmB,CAAC;AAC1B,MAAI,OAAO,UAAW,KAAI,KAAK,OAAO,SAAS;AAC/C,MAAI,KAAK,GAAG,OAAO,WAAW;AAC9B,aAAW,MAAM,KAAK;AACrB,QAAI,WAAW,GAAG,YAAY,EAAE;AAAA,EACjC;AACD;AA7CA,IACAC;AADA;AAAA;AAAA;AACA,IAAAA,gBAA0B;AAE1B;AAAA;AAAA;;;ACgBO,SAAS,mBAAmB,KAA6B;AAC/D,MAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,GAAG;AAChD,WAAO,CAAC;AAAA,EACT;AACA,MAAI;AACH,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAC3E,aAAO,CAAC;AAAA,IACT;AACA,UAAM,SAAwB,CAAC;AAC/B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC7E,UAAI,OAAO,UAAU,UAAU;AAC9B,eAAO,GAAG,IAAI;AAAA,MACf;AAAA,IACD;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO,CAAC;AAAA,EACT;AACD;AAKO,SAAS,uBAAuB,UAAiC;AACvE,SAAO,KAAK,UAAU,QAAQ;AAC/B;AAMO,SAAS,uBACf,YACA,SACgB;AAChB,QAAM,WAA0B,CAAC;AACjC,aAAW,SAAS,YAAY;AAC/B,aAAS,KAAK,IAAI;AAAA,EACnB;AACA,SAAO;AACR;AAOO,SAAS,sBACf,SACA,OACAC,aACS;AACT,QAAM,MAAM,QAAQ,KAAK;AACzB,MAAI,QAAQ,QAAW;AACtB,WAAO;AAAA,EACR;AACA,SAAOA,eAAc;AACtB;AA2BO,SAAS,mBACf,SACA,gBACA,iBACAA,aACoB;AACpB,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAwB,EAAE,GAAG,QAAQ;AAC3C,aAAW,SAAS,gBAAgB;AACnC,UAAM,SAAS,sBAAsB,SAAS,OAAOA,WAAU;AAC/D,QAAI,kBAAkB,QAAQ;AAC7B,cAAQ,KAAK,KAAK;AAClB,aAAO,KAAK,IAAI;AAAA,IACjB;AAAA,EAGD;AACA,SAAO,EAAE,SAAS,OAAO;AAC1B;AAgBO,SAAS,mBACf,YACA,QACA,SACS;AACT,QAAM,WAAW,mBAAmB,UAAU;AAC9C,aAAW,SAAS,QAAQ;AAC3B,UAAM,WAAW,SAAS,KAAK;AAC/B,QAAI,aAAa,UAAa,WAAW,SAAS;AACjD,eAAS,KAAK,IAAI;AAAA,IACnB;AAAA,EACD;AACA,SAAO,uBAAuB,QAAQ;AACvC;AAvJA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACmDO,SAAS,wBACf,gBACA,UACA,cACA,cACA,UAC8C;AAG9C,MAAI,iBAAiB,MAAM;AAC1B,WAAO,EAAE,OAAO,MAAM,eAAe,CAAC,EAAE;AAAA,EACzC;AAGA,MAAI,iBAAiB,UAAU;AAC9B,WAAO,EAAE,OAAO,MAAM,eAAe,aAAa,YAAY,YAAY,KAAK,CAAC,EAAE;AAAA,EACnF;AAEA,QAAM,aAAqC;AAAA,IAC1C,OAAO,aAAa;AAAA,IACpB,YAAY;AAAA,IACZ,aAAa,aAAa;AAAA,EAC3B;AACA,QAAM,uBAAmB,kCAAmB,YAAY,cAAc,QAAQ;AAC9E,MAAI,iBAAiB,OAAO;AAC3B,WAAO,EAAE,OAAO,MAAM,eAAe,iBAAiB,eAAe;AAAA,EACtE;AAEA,QAAM,gBAAgB,iBAAiB;AAEvC,MAAI,aAAa,wBAAwB,UAAU;AAClD,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAGA,SAAO,EAAE,OAAO,OAAO,cAAc;AACtC;AAiBO,SAAS,2BACf,gBACA,UACA,eACA,eACA,YAC0B;AAC1B,MAAI,SAAS;AACb,QAAM,eAAe,cAAc;AACnC,MAAI,iBAAiB,QAAW;AAC/B,aAAS,kBAAkB,gBAAgB,UAAU,cAAc,eAAe,MAAM;AAAA,EACzF;AAIA,aAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,cAAc,MAAM,GAAG;AACvE,QAAI,WAAW,SAAS,UAAU,CAAC,WAAW,YAAa;AAC3D,QAAI,cAAc,UAAU,MAAO;AACnC,aAAS;AAAA,MACR;AAAA,MACA;AAAA,MACA,EAAE,OAAO,aAAa,WAAW,aAAa,qBAAqB,SAAS;AAAA,MAC5E;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,kBACR,gBACA,UACA,cACA,eACA,YAC0B;AAC1B,QAAM,aAAa,aAAa;AAChC,MAAI,EAAE,cAAc,aAAa;AAEhC,WAAO;AAAA,EACR;AAEA,QAAM,eAAe,cAAc,UAAU;AAC7C,QAAM,WAAW,WAAW,UAAU;AAGtC,MAAI,OAAO,iBAAiB,YAAY,OAAO,aAAa,UAAU;AACrE,WAAO;AAAA,EACR;AAEA,QAAM,SAAS;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,MAAI,OAAO,OAAO;AACjB,WAAO;AAAA,EACR;AAGA,QAAM,WAAW,EAAE,GAAG,WAAW;AACjC,SAAO,SAAS,UAAU;AAI1B,SAAO;AACR;AApLA,IAAAC,eAaa;AAbb;AAAA;AAAA;AAAA,IAAAA,gBAA8C;AAavC,IAAM,8BAAN,cAA0C,wBAAU;AAAA,MAC1D,YACiB,YACA,UACA,OACA,WACA,SACA,eACf;AACD;AAAA,UACC,2CAA2C,UAAU,+BACxB,KAAK,WAAW,SAAS,SAAS,OAAO,gCACxC,SAAS,MAAM,cAAc,SAAS,IAAI,cAAc,KAAK,IAAI,IAAI,0BAA0B;AAAA,UAC7H;AAAA,UACA,EAAE,YAAY,UAAU,OAAO,WAAW,SAAS,cAAc;AAAA,QAClE;AAbgB;AACA;AACA;AACA;AACA;AACA;AAShB,aAAK,OAAO;AAAA,MACb;AAAA,MAfiB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAWlB;AAAA;AAAA;;;ACbO,SAAS,kBACf,MACA,YACA,mBACmC;AACnC,aAAO,6CAA8B,MAAM,YAAY,iBAAiB;AACzE;AAxBA,IACAC;AADA;AAAA;AAAA;AACA,IAAAA,gBAA8C;AAAA;AAAA;;;AC6D9C,eAAsB,cACrB,KACA,YACA,MAC0B;AAC1B,QAAM,aAAa,kBAAkB,KAAK,UAAU;AACpD,QAAM,gBAAY,8BAAe,YAAY,YAAY,MAAM,QAAQ;AACvE,QAAM,MAAM,KAAK,IAAI;AACrB,aAAW,CAAC,WAAW,UAAU,KAAK,OAAO,QAAQ,WAAW,MAAM,GAAG;AACxE,QAAI,WAAW,QAAQ,WAAW,SAAS,aAAa;AACvD,gBAAU,SAAS,IAAI;AAAA,IACxB;AAAA,EACD;AAGA,QAAM,YAAY,MAAM,kBAAkB,WAAW,YAAY,IAAI,iBAAiB;AACtF,SAAO,EAAE,YAAY,cAAU,8BAAe,GAAG,MAAM,UAAU;AAClE;AAeA,eAAsB,gBACrB,KACA,OACA,QACA,kBAAqC,CAAC,GACf;AACvB,QAAM,aAAa,kBAAkB,KAAK,OAAO,UAAU;AAC3D,QAAM,YAAY,MAAM,oBAAoB,KAAK,OAAO;AAAA,IACvD,MAAM;AAAA,IACN,YAAY,OAAO;AAAA,IACnB,UAAU,OAAO;AAAA;AAAA;AAAA,IAGjB,MAAM,8BAA8B,OAAO,MAAM,WAAW,MAAM;AAAA,IAClE,cAAc;AAAA,IACd;AAAA,EACD,CAAC;AAED,MAAI,IAAI,MAAM;AAEb,UAAM,mBAAmB,OAAO,SAAS;AACzC,UAAM,IAAI,KAAK,UAAU,MAAM,IAAI,WAAW,OAAO;AAAA,EACtD,OAAO;AACN,UAAM,aAAa,gBAAgB,OAAO,MAAM,WAAW,MAAM;AACjE,UAAM,UAAU,oBAAoB,UAAU,SAAS;AACvD,UAAM,MAA+B;AAAA,MACpC,IAAI,OAAO;AAAA,MACX,GAAG;AAAA,MACH,aAAa,UAAU,UAAU;AAAA,MACjC,aAAa,UAAU,UAAU;AAAA,MACjC,UAAU;AAAA;AAAA;AAAA,MAGV,iBAAiB,mBAAmB,MAAM,OAAO,KAAK,UAAU,GAAG,OAAO;AAAA,IAC3E;AACA,UAAM,YAAY,iBAAiB,OAAO,YAAY,GAAG;AACzD,UAAM,MAAM,GAAG,QAAQ,UAAU,KAAK,UAAU,MAAM;AACtD,UAAM,mBAAmB,OAAO,SAAS;AAAA,EAC1C;AAEA,SAAO;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,MACP,IAAI,OAAO;AAAA;AAAA,MAEX,GAAG,oBAAoB,OAAO,MAAM,WAAW,MAAM;AAAA,MACrD,WAAW,UAAU,UAAU;AAAA,MAC/B,WAAW,UAAU,UAAU;AAAA,IAChC;AAAA,IACA,aAAa,CAAC;AAAA,EACf;AACD;AAUA,eAAsB,gBACrB,KACA,OACA,YACA,IACA,MACA,kBAAqC,CAAC,GACf;AACvB,QAAM,aAAa,kBAAkB,KAAK,UAAU;AACpD,QAAM,aAAa,MAAM,YAAY,OAAO,YAAY,EAAE;AAC1D,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,oBAAoB,YAAY,EAAE;AAAA,EAC7C;AACA,QAAM,gBAAgB,kBAAkB,YAAY,WAAW,MAAM;AACrE,QAAM,UAAU,2BAA2B,YAAY,IAAI,YAAY,eAAe,IAAI;AAC1F,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACtC,WAAO,EAAE,WAAW,MAAM,QAAQ,eAAe,aAAa,CAAC,EAAE;AAAA,EAClE;AAEA,QAAM,eAAwC,CAAC;AAC/C,QAAM,WAAoC,CAAC;AAC3C,QAAM,YAAsC,CAAC;AAC7C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AACnD,iBAAa,GAAG,IAAI,cAAc,GAAG;AACrC,YAAI,0BAAW,KAAK,GAAG;AACtB,eAAS,GAAG,QAAI,+BAAgB,cAAc,GAAG,GAAG,KAAK;AAIzD,YAAM,aAAa,WAAW,OAAO,GAAG;AACxC,UAAI,WAAY,6CAAyB,YAAY,KAAK,YAAY,SAAS,GAAG,CAAC;AACnF,gBAAU,GAAG,QAAI,0BAAW,KAAK;AAAA,IAClC,OAAO;AACN,eAAS,GAAG,IAAI;AAAA,IACjB;AAAA,EACD;AAGA,QAAM,YAAY,MAAM,kBAAkB,UAAU,YAAY,IAAI,iBAAiB;AAErF,QAAM,YAAY,MAAM,oBAAoB,KAAK,OAAO;AAAA,IACvD,MAAM;AAAA,IACN;AAAA,IACA,UAAU;AAAA,IACV,MAAM,8BAA8B,WAAW,WAAW,MAAM;AAAA,IAChE,cAAc,8BAA8B,cAAc,WAAW,MAAM;AAAA,IAC3E;AAAA,IACA,GAAI,OAAO,KAAK,SAAS,EAAE,SAAS,IAAI,EAAE,UAAU,IAAI,CAAC;AAAA,EAC1D,CAAC;AAED,MAAI,IAAI,MAAM;AACb,UAAM,mBAAmB,OAAO,SAAS;AACzC,UAAM,IAAI,KAAK,UAAU,MAAM,IAAI,WAAW,OAAO;AAAA,EACtD,OAAO;AACN,UAAM,oBAAoB,gBAAgB,WAAW,WAAW,MAAM;AACtE,UAAM,UAAU,oBAAoB,UAAU,SAAS;AAGvD,UAAM,YAAY,iBAAiB,YAAY,IAAI;AAAA,MAClD,GAAG;AAAA,MACH,aAAa,UAAU,UAAU;AAAA,MACjC,UAAU;AAAA,MACV,iBAAiB;AAAA,QAChB,WAAW;AAAA,QACX,OAAO,KAAK,iBAAiB;AAAA,QAC7B;AAAA,MACD;AAAA,IACD,CAAC;AACD,UAAM,MAAM,GAAG,QAAQ,UAAU,KAAK,UAAU,MAAM;AACtD,UAAM,mBAAmB,OAAO,SAAS;AAAA,EAC1C;AAEA,QAAM,aAAa,MAAM,YAAY,OAAO,YAAY,EAAE;AAC1D,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,oBAAoB,YAAY,EAAE;AAAA,EAC7C;AACA,SAAO;AAAA,IACN;AAAA,IACA,QAAQ,kBAAkB,YAAY,WAAW,MAAM;AAAA,IACvD,aAAa,CAAC;AAAA,EACf;AACD;AAgBA,eAAsB,gBACrB,KACA,OACA,YACA,IACA,UAA8B,CAAC,GACR;AACvB,QAAM,aAAa,kBAAkB,KAAK,UAAU;AACpD,QAAM,aAAa,MAAM,YAAY,OAAO,YAAY,EAAE;AAC1D,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,oBAAoB,YAAY,EAAE;AAAA,EAC7C;AACA,QAAM,YAAY,MAAM,oBAAoB,KAAK,OAAO;AAAA,IACvD,MAAM;AAAA,IACN;AAAA,IACA,UAAU;AAAA,IACV,MAAM;AAAA,IACN,cAAc;AAAA,IACd,iBAAiB,QAAQ,mBAAmB,CAAC;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,QAAQ,8BAA8B,IAAI,mBAAmB;AACjE,UAAM,IAAI,kBAAkB,WAAW,MAAM,EAAE;AAAA,EAChD;AAKA,MAAI,IAAI,MAAM;AACb,UAAM,mBAAmB,OAAO,SAAS;AACzC,UAAM,IAAI,KAAK,UAAU,MAAM,IAAI,WAAW,OAAO;AAAA,EACtD,OAAO;AACN,UAAM,UAAU,oBAAoB,UAAU,SAAS;AACvD,UAAM,aAAa,qBAAqB,YAAY,IAAI,UAAU,UAAU,UAAU,OAAO;AAC7F,UAAM,MAAM,GAAG,QAAQ,WAAW,KAAK,WAAW,MAAM;AACxD,UAAM,mBAAmB,OAAO,SAAS;AAAA,EAC1C;AAEA,QAAM,cAA2B,CAAC;AAClC,MAAI,CAAC,QAAQ,8BAA8B,IAAI,kBAAkB;AAChE,UAAM,SAAS,MAAM,IAAI,iBAAiB;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IACX;AACA,gBAAY,KAAK,GAAG,OAAO,UAAU;AAAA,EACtC;AAEA,SAAO;AAAA,IACN;AAAA,IACA,QAAQ,kBAAkB,YAAY,WAAW,MAAM;AAAA,IACvD;AAAA,EACD;AACD;AAgBA,eAAe,oBACd,KACA,OACA,OACqB;AACrB,QAAM,iBAAiB,MAAM,MAAM,SAAS,KAAK;AACjD,QAAM,aAAa,MAAM,OAAO,QAAQ,MAAM,YAAY,MAAM,eAAe;AAC/E,QAAM,YAAY,UAAM;AAAA,IACvB;AAAA,MACC,QAAQ,IAAI;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,YAAY,MAAM;AAAA,MAClB,UAAU,MAAM;AAAA,MAChB,MAAM,MAAM;AAAA,MACZ,cAAc,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA,eAAe,IAAI,OAAO;AAAA,MAC1B,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MACtE,GAAI,IAAI,kBAAkB,SAAY,EAAE,eAAe,IAAI,cAAc,IAAI,CAAC;AAAA,MAC9E,GAAI,IAAI,iBAAiB,SAAY,EAAE,cAAc,IAAI,aAAa,IAAI,CAAC;AAAA,IAC5E;AAAA,IACA,IAAI;AAAA,EACL;AAIA,QAAM,WAAW,IAAI,qBAAqB;AAC1C,QAAM,YAAQ,qCAAsB,SAAS;AAC7C,MAAI,QAAQ,UAAU;AACrB,UAAM,IAAI,qCAAuB,MAAM,YAAY,MAAM,UAAU,OAAO,QAAQ;AAAA,EACnF;AACA,QAAM,OAAO,OAAO,MAAM,YAAY,UAAU,EAAE;AAClD,SAAO;AACR;AAEA,eAAe,mBAAmB,OAAmB,WAAqC;AACzF,QAAM,WAAW;AAAA,IAChB,aAAa,UAAU,UAAU;AAAA,IACjC,mBAAmB,SAAS;AAAA,EAC7B;AACA,QAAM,MAAM,GAAG,QAAQ,SAAS,KAAK,SAAS,MAAM;AACrD;AAEA,eAAe,YACd,OACA,YACA,IACwC;AACxC,QAAM,OAAO,MAAM,MAAM,GAAG;AAAA,IAC3B,qBAAiB,0BAAW,UAAU,CAAC;AAAA,IACvC,CAAC,EAAE;AAAA,EACJ;AACA,SAAO,KAAK,CAAC;AACd;AAEA,SAAS,kBAAkB,KAAe,YAA0C;AACnF,QAAM,aAAa,IAAI,OAAO,YAAY,UAAU;AACpD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI;AAAA,MACT,uBAAuB,UAAU,iBAAiB,OAAO,KAAK,IAAI,OAAO,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,MAChG;AAAA,MACA,EAAE,WAAW;AAAA,IACd;AAAA,EACD;AACA,SAAO;AACR;AArYA,IACAC;AADA;AAAA;AAAA;AACA,IAAAA,gBAaO;AACP;AACA;AACA;AACA;AACA;AACA;AAMA;AAEA;AAAA;AAAA;;;ACbA,eAAsB,cACrB,KACA,IACA,SACuB;AACvB,QAAM,SAAS,MAAM;AAAA,IAAc;AAAA,IAAK,CAAC,UACxC,gBAAgB,KAAK,OAAO,IAAI,YAAY,IAAI;AAAA,MAC/C,4BAA4B,SAAS,8BAA8B;AAAA,MACnE,iBAAiB,IAAI,mBAAmB,CAAC;AAAA,IAC1C,CAAC;AAAA,EACF;AACA,SAAO,OAAO,YAAY,CAAC,OAAO,WAAW,GAAG,OAAO,WAAW,IAAI,OAAO;AAC9E;AA3BA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;;ACOA,eAAsB,cACrB,KACA,MAC4B;AAC5B,QAAM,WAAW,MAAM,cAAc,KAAK,IAAI,YAAY,IAAI;AAC9D,QAAM,SAAS,MAAM;AAAA,IAAc;AAAA,IAAK,CAAC,UACxC,gBAAgB,KAAK,OAAO,UAAU,IAAI,mBAAmB,CAAC,CAAC;AAAA,EAChE;AACA,SAAO,OAAO;AACf;AAnBA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;;ACQA,eAAsB,cACrB,KACA,IACA,MAC4B;AAC5B,QAAM,gBAAY,8BAAe,IAAI,YAAY,IAAI,YAAY,MAAM,QAAQ;AAC/E,QAAM,SAAS,MAAM;AAAA,IAAc;AAAA,IAAK,CAAC,UACxC,gBAAgB,KAAK,OAAO,IAAI,YAAY,IAAI,WAAW,IAAI,mBAAmB,CAAC,CAAC;AAAA,EACrF;AACA,SAAO,OAAO;AACf;AArBA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA+B;AAE/B;AAEA;AAAA;AAAA;;;ACJA,IAQAC,eAyBa;AAjCb;AAAA;AAAA;AAQA,IAAAA,gBAA2B;AAE3B;AACA;AACA;AAGA;AAkBO,IAAM,aAAN,MAAiB;AAAA,MACvB,YACkB,MACA,YACA,QACA,SACT,OACA,QACS,YACT,kBACA,iBACA,eACS,mBACA,gBACA,MACA,mBAChB;AAdgB;AACA;AACA;AACA;AACT;AACA;AACS;AACT;AACA;AACA;AACS;AACA;AACA;AACA;AAAA,MACf;AAAA,MAde;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACT;AAAA,MACA;AAAA,MACS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACS;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASlB,WACC,OACA,QACA,kBACA,eACO;AACP,aAAK,QAAQ;AACb,aAAK,SAAS;AACd,aAAK,mBAAmB;AACxB,aAAK,gBAAgB;AAAA,MACtB;AAAA,MAEQ,kBAAwC;AAC/C,cAAM,OAAO,KAAK,OAAO;AACzB,eAAO;AAAA,UACN,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACvB,YAAY,KAAK;AAAA,UACjB,YAAY,KAAK;AAAA,UACjB,QAAQ,KAAK;AAAA,UACb,SAAS,KAAK;AAAA,UACd,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,YAAY,KAAK;AAAA,UACjB,kBAAkB,KAAK;AAAA,UACvB,eAAe,KAAK;AAAA,UACpB,GAAI,KAAK,oBAAoB,EAAE,mBAAmB,KAAK,kBAAkB,IAAI,CAAC;AAAA,UAC9E,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,UACrE,GAAI,KAAK,sBAAsB,SAC5B,EAAE,mBAAmB,KAAK,kBAAkB,IAC5C,CAAC;AAAA,QACL;AAAA,MACD;AAAA,MAEA,MAAM,OAAO,MAA0D;AACtE,YAAI,KAAK,iBAAiB;AACzB,iBAAO,KAAK,gBAAgB,OAAO,KAAK,MAAM,IAAI;AAAA,QACnD;AACA,eAAO,cAAc,KAAK,gBAAgB,GAAG,IAAI;AAAA,MAClD;AAAA,MAEA,MAAM,SAAS,IAA8C;AAC5D,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B,qBAAiB,0BAAW,KAAK,IAAI,CAAC;AAAA,UACtC,CAAC,EAAE;AAAA,QACJ;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,CAAC,IAAK,QAAO;AACjB,eAAO,kBAAkB,KAAK,KAAK,WAAW,MAAM;AAAA,MACrD;AAAA,MAEA,MAAM,OAAO,IAAY,MAA0D;AAClF,YAAI,KAAK,iBAAiB;AACzB,iBAAO,KAAK,gBAAgB,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,QACvD;AACA,eAAO,cAAc,KAAK,gBAAgB,GAAG,IAAI,IAAI;AAAA,MACtD;AAAA,MAEA,MAAM,OAAO,IAA2B;AACvC,YAAI,KAAK,iBAAiB;AACzB,gBAAM,KAAK,gBAAgB,OAAO,KAAK,MAAM,EAAE;AAC/C;AAAA,QACD;AACA,cAAM,cAAc,KAAK,gBAAgB,GAAG,EAAE;AAAA,MAC/C;AAAA,MAEA,UAAkB;AACjB,eAAO,KAAK;AAAA,MACb;AAAA,MAEA,gBAAsC;AACrC,eAAO,KAAK;AAAA,MACb;AAAA;AAAA,MAGA,mBAAmB,SAA4C;AAC9D,aAAK,kBAAkB;AAAA,MACxB;AAAA,IACD;AAAA;AAAA;;;AC5GA,SAAS,SAAS,IAAe,QAAmC;AACnE,MAAI,GAAG,SAAS,SAAU,QAAO;AACjC,MAAI,GAAG,cAAc,UAAa,OAAO,KAAK,GAAG,SAAS,EAAE,SAAS,EAAG,QAAO;AAC/E,QAAM,YAAY,OAAO,YAAY,GAAG,UAAU,GAAG,aAAa,CAAC;AACnE,SAAO,OAAO,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,UAAU,KAAK,MAAM,MAAS;AACjF;AAQA,eAAe,mBACd,IACA,QACA,OACyB;AACzB,QAAM,UAAM,mCAAoB;AAChC,aAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO;AACvC,QAAI,YAAY,EAAG;AACnB,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,cAAc,OAAO,KAAK,OAAO,WAAW,GAAG;AACzD,YAAM,OAAO,MAAM,GAAG;AAAA,QACrB,mCAA+B,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,QACpE,CAAC,QAAQ,QAAQ;AAAA,MAClB;AACA,iBAAW,OAAO,KAAM,MAAK,IAAI,IAAI,eAAe;AAAA,IACrD;AACA,UAAM,YAAY,MAAM,GAAG;AAAA,MAC1B,+BAA+B,mBAAmB;AAAA,MAClD,CAAC,QAAQ,QAAQ;AAAA,IAClB;AACA,eAAW,OAAO,UAAW,MAAK,IAAI,IAAI,eAAe;AACzD,UAAM,UAAU,MAAM,GAAG;AAAA,MACxB,+BAA+B,uBAAuB;AAAA,MACtD,CAAC,MAAM;AAAA,IACR;AACA,QAAI,IAAI,QAAQ,CAAC,GAAG,mBAAmB;AACvC,WAAO,IAAI,YAAY,KAAK,IAAI,IAAI,CAAC,EAAG,MAAK;AAC7C,QAAI,IAAI,EAAG,KAAI,IAAI,QAAQ,CAAC;AAAA,EAC7B;AACA,SAAO;AACR;AAWA,eAAsB,iBACrB,SACA,QACA,QACA,UACA,cAC4B;AAC5B,QAAM,QAAQ,8BAA8B,YAAY;AACxD,MAAI,MAAM,SAAS,EAAG,QAAO,EAAE,cAAc,GAAG,WAAW,MAAM;AACjE,QAAM,SACL,SAAS,SAAS,eACf,iCAAmB,UAAU;AAAA,IAC7B,UAAU,KAAK,IAAI,IAAI,SAAS,OAAO,KAAK,KAAK,KAAK;AAAA,IACtD,SAAS;AAAA,IACT,QAAQ;AAAA,EACT,CAAC,EAAE,MAAM,GAAG,EAAE,IACb;AAEJ,MAAI,eAAe;AACnB,MAAI,gBAAY,mCAAoB;AACpC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,gBAAY,MAAM,mBAAmB,IAAI,QAAQ,KAAK;AACtD,eAAW,cAAc,OAAO,KAAK,OAAO,WAAW,GAAG;AACzD,YAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,YAAM,WAAW,oBAAI,IAAyB;AAC9C,iBAAW,CAAC,QAAQ,MAAM,KAAK,WAAW;AACzC,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,iBAAiB,KAAK,8CAA8C,WAAW,OAAO,sCAAsC,EAAE;AAAA,UAC9H,WAAW,OAAO,CAAC,QAAQ,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM;AAAA,QAC7D;AACA,mBAAW,OAAO,MAAM;AACvB,gBAAM,KAAK,mCAAmC,KAAK,UAAU;AAC7D,cAAI,SAAS,IAAI,MAAM,EAAG;AAC1B,gBAAM,OAAO,SAAS,IAAI,GAAG,QAAQ,KAAK,CAAC;AAC3C,eAAK,KAAK,EAAE;AACZ,mBAAS,IAAI,GAAG,UAAU,IAAI;AAAA,QAC/B;AAAA,MACD;AACA,iBAAW,CAAC,UAAU,GAAG,KAAK,UAAU;AACvC,cAAM,WAAW,MAAM,OAAO;AAAA,UAC7B;AAAA,UACA,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE;AAAA,QACtB;AACA,YAAI,eAAsB,+BAAgB,YAAY,QAAQ;AAC9D,YAAI,MAAM;AACV,mBAAW,MAAM,KAAK;AACrB,cAAI,SAAS,IAAI,GAAG,EAAE,EAAG;AACzB,yBAAW,uBAAQ,UAAU,IAAI,QAAQ,OAAO,QAAQ,CAAC,EAAE;AAC3D,gBAAM;AAAA,QACP;AACA,YAAI,IAAK,OAAM,OAAO,aAAa,IAAI,QAAQ;AAC/C,iBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,KAAK;AACzC,gBAAM,QAAQ,IAAI,MAAM,GAAG,IAAI,GAAG;AAClC,gBAAM,GAAG;AAAA,YACR,eAAe,KAAK,iBAAiB,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,YACpE,MAAM,IAAI,CAAC,OAAO,GAAG,EAAE;AAAA,UACxB;AAAA,QACD;AACA,wBAAgB,IAAI;AAAA,MACrB;AAAA,IACD;AACA,eAAW,CAAC,QAAQ,GAAG,KAAK,WAAW;AACtC,YAAM,GAAG;AAAA,QACR,eAAe,uBAAuB;AAAA;AAAA,QAEtC,CAAC,QAAQ,GAAG;AAAA,MACb;AAAA,IACD;AACA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA,OAAO,KAAK,IAAI,CAAC;AAAA,IAClB,CAAC;AAAA,EACF,CAAC;AACD,SAAO,EAAE,cAAc,UAAU;AAClC;AA1JA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAUO;AACP;AAEA;AACA;AACA;AAEA;AAAA;AAAA;;;ACsBA,eAAsB,4BACrB,SACA,QACA,WACqC;AACrC,QAAM,YAAuC,CAAC;AAC9C,aAAW,cAAc,OAAO,KAAK,OAAO,WAAW,GAAG;AACzD,UAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,UAAM,OAAO,MAAM,QAAQ;AAAA,MAC1B,iBAAiB,KAAK;AAAA,IACvB;AACA,UAAM,UAAsD,CAAC;AAC7D,eAAW,OAAO,MAAM;AACvB,UAAI;AACJ,UAAI;AACH,aAAK,mCAAmC,KAAK,UAAU;AAAA,MACxD,QAAQ;AAEP;AAAA,MACD;AACA,UAAI,GAAG,gBAAgB,SAAK,2CAA4B,EAAE,MAAM,GAAI;AACpE,YAAMC,aACL,GAAG,WAAW,gBACX,2CAA4B,EAAE,IAC9B,UAAM,6CAA8B,EAAE;AAC1C,UAAIA,eAAc,GAAI;AACtB,cAAQ,KAAK,EAAE,IAAI,GAAG,IAAI,MAAM,mBAAmBA,UAAS,EAAE,KAAK,CAAC;AACpE,gBAAU,KAAK,EAAE,YAAY,UAAU,GAAG,SAAS,CAAC;AAAA,IACrD;AACA,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,iBAAW,UAAU,SAAS;AAC7B,cAAM,GAAG,QAAQ,UAAU,KAAK,8BAA8B,CAAC,OAAO,MAAM,OAAO,EAAE,CAAC;AAAA,MACvF;AAAA,IACD,CAAC;AAAA,EACF;AACA,SAAO;AACR;AA5EA,IAAAC,eAUa;AAVb;AAAA;AAAA;AAAA,IAAAA,gBAIO;AAEP;AAIO,IAAM,yBAAyB;AAAA;AAAA;;;AC8DtC,eAAsB,sBACrB,SACA,QACA,QACA,MACA,OAAoB,EAAE,SAAS,oBAAI,IAAI,GAAG,aAAa,oBAAI,IAAI,EAAE,GACjE,aACmC;AACnC,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,QAAM,gBAAgB,OAAO,wBAAwB;AACrD,aAAW,CAAC,YAAY,UAAU,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AAC1E,QAAI,eAAe,CAAC,YAAY,SAAS,UAAU,EAAG;AACtD,UAAM,MAAM,oBAAI,IAAY;AAC5B,eAAW,OAAO,MAAM,QAAQ;AAAA,MAC/B,sBAAkB,0BAAW,UAAU,CAAC;AAAA,IACzC,GAAG;AACF,UAAI,IAAI,IAAI,EAAE;AAAA,IACf;AACA,eAAW,OAAO,MAAM,QAAQ;AAAA,MAC/B,sCAAkC,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,IACxE,GAAG;AACF,UAAI,IAAI,IAAI,SAAS;AAAA,IACtB;AACA,UAAM,UAAU,KAAK,QAAQ,IAAI,UAAU;AAC3C,UAAM,UAAU,KAAK,YAAY,IAAI,UAAU;AAC/C,UAAM,MAAM,CAAC,GAAG,GAAG,EAAE,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,OAAO;AAC3C,YAAM,QAAQ,IAAI,MAAM,GAAG,IAAI,KAAK;AACpC,YAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,mBAAW,YAAY,OAAO;AAC7B,qBAAW;AACX,gBAAM,OAAO,MAAM,GAAG;AAAA,YACrB,qBAAiB,0BAAW,UAAU,CAAC;AAAA,YACvC,CAAC,QAAQ;AAAA,UACV;AACA,gBAAM,MAAM,KAAK,CAAC;AAClB,gBAAM,SAAS,MAAM,KAAK,UAAU,kBAAkB,KAAK,WAAW,MAAM,CAAC,IAAI;AACjF,gBAAM,OAAO,MAAM,OAAO,gBAAgB,IAAI,YAAY,QAAQ;AAClE,gBAAM,GAAG;AAAA,YACR,eAAe,gBAAgB;AAAA,YAC/B,CAAC,YAAY,QAAQ;AAAA,UACtB;AACA,gBAAM,aAAa,CAAC,SACnB,gBAAgB,MAAM,YAAY,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClE,cAAI,WAAW,SAAS,IAAI,QAAQ,GAAG;AACtC,gBAAI,KAAK;AAGR,oBAAM,WAAW,WAAW,GAAG;AAC/B,oBAAM,OAAO,aAAa,IAAI,QAAQ;AACtC,2BAAa;AACb,oBAAM,OAAO,MAAM,OAAO,SAAS,IAAI,YAAY,QAAQ;AAC3D,oBAAM,OAAO,UAAU,IAAI,WAAO,0BAAW,MAAM,UAAU,MAAM,IAAI,QAAQ;AAAA,YAChF;AACA;AAAA,UACD;AACA,cAAI,SAAS,kBAAkB,KAAK;AACnC,kBAAM,OAAO,aAAa,IAAI,WAAW,GAAG,CAAC;AAC7C,yBAAa;AAAA,UACd;AACA,gBAAM,QAAQ,MAAM,OAAO,YAAY,IAAI,YAAY,QAAQ;AAC/D,cAAI,UAAU,MAAM;AAGnB,gBAAI,KAAK;AACR,oBAAM,WAAW,WAAW,GAAG;AAC/B,oBAAM,OAAO,aAAa,IAAI,QAAQ;AACtC,oBAAM,OAAO,UAAU,IAAI,QAAQ;AACnC,2BAAa;AAAA,YACd;AACA;AAAA,UACD;AACA,gBAAM,OAAO,UAAU,IAAI,KAAK;AAChC,gBAAM,OAAO,eAAe,IAAI,OAAO,OAAO,EAAE,iBAAiB,MAAM,CAAC;AACxE,gBAAM,YAAY,MAAM,GAAG;AAAA,YAC1B,qBAAiB,0BAAW,UAAU,CAAC;AAAA,YACvC,CAAC,QAAQ;AAAA,UACV;AACA,gBAAM,QAAQ,UAAU,CAAC,IACtB,KAAK,UAAU,kBAAkB,UAAU,CAAC,GAAG,WAAW,MAAM,CAAC,IACjE;AACH,cAAI,WAAW,MAAO,gBAAe;AAAA,QACtC;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD;AACA,QAAM,UAAU,KAAK,YAAY,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;AAC9F,SAAO,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,aAAa,UAAU;AACzE;AAQO,SAAS,gBACf,KACA,YACA,QACA,UAA4E,CAAC,GACjE;AACZ,QAAM,aAAa,OAAO,YAAY,UAAU;AAChD,QAAM,SAAS,aAAa,kBAAkB,KAAK,WAAW,MAAM,IAAI,EAAE,IAAI,IAAI,GAAG;AACrF,QAAM,EAAE,IAAI,KAAK,WAAW,IAAI,WAAW,IAAI,GAAG,OAAO,IAAI;AAC7D,QAAM,SAAS,WAAW,GAAG;AAC7B,QAAM,gBAA8C,CAAC;AACrD,QAAM,MAAM,OAAO,IAAI,oBAAoB,WAAW,IAAI,kBAAkB;AAC5E,MAAI;AACH,eAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG,CAA4B,GAAG;AAC1F,UAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,GAAG;AACtD,sBAAc,KAAK,IAAI,iCAAmB,YAAY,OAAO;AAAA,MAC9D;AAAA,IACD;AAAA,EACD,QAAQ;AAAA,EAER;AACA,QAAM,YAAY,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc,OAAO;AACjF,aAAO;AAAA,IACN;AAAA,MACC;AAAA,MACA,UAAU,IAAI;AAAA,MACd;AAAA,MACA;AAAA,MACA,SAAS,EAAE,UAAU,WAAW,SAAS,GAAG,QAAQ,GAAG;AAAA,MACvD;AAAA,MACA,SAAS,IAAI,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,MACC,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,MAC7C,GAAI,QAAQ,gBAAgB,EAAE,sBAAsB,QAAQ,cAAc,IAAI,CAAC;AAAA,IAChF;AAAA,EACD;AACD;AAEA,SAAS,WAAW,KAAqC;AACxD,MAAI,OAAO,IAAI,aAAa,YAAY,IAAI,SAAS,SAAS,GAAG;AAChE,QAAI;AACH,aAAO,iCAAmB,YAAY,IAAI,QAAQ;AAAA,IACnD,QAAQ;AAAA,IAER;AAAA,EACD;AACA,QAAM,OAAO,OAAO,IAAI,gBAAgB,WAAW,IAAI,cAAc;AACrE,SAAO,EAAE,UAAU,MAAM,SAAS,GAAG,QAAQ,GAAG;AACjD;AA5NA,IAAAC,eA2DM;AA3DN;AAAA;AAAA;AAAA,IAAAA,gBAQO;AACP;AAEA;AAgDA,IAAM,QAAQ;AAAA;AAAA;;;ACfd,eAAsB,oBAAoB,KAAgD;AACzF,QAAM,SAAS,MAAM,wBAAwB,IAAI,OAAO;AACxD,QAAM,SAAS,IAAI,OAAO;AAC1B,MAAI,UAAU,QAAQ;AACrB,QAAI,WAAW,EAAG,OAAM,mBAAmB,IAAI,SAAS,MAAM;AAC9D,WAAO,CAAC;AAAA,EACT;AAEA,QAAM,UAAuB,CAAC;AAC9B,QAAM,aAAa,IAAI,OAAO,cAAc,CAAC;AAC7C,WAAS,UAAU,SAAS,GAAG,WAAW,QAAQ,WAAW;AAC5D,UAAM,YAAY,WAAW,OAAO;AACpC,UAAM,QAAQ,WAAW,SAAS,CAAC;AACnC,UAAM,YAAyB,CAAC;AAChC,UAAM,SAAS,IAAI,YAAY,IAAI,eAAe,KAAK;AACvD,UAAM,IAAI,QAAQ,YAAY,OAAO,OAAO;AAC3C,iBAAW,QAAQ,OAAO;AACzB,YAAI,KAAK,SAAS,eAAe;AAChC,gBAAM,aAAa,IAAI,KAAK,YAAY,KAAK,MAAM,KAAK,EAAE;AAC1D;AAAA,QACD;AACA,mBAAW,WAAO,mCAAoB,CAAC,IAAI,CAAC,GAAG;AAC9C,gBAAM,kBAAkB,IAAI,GAAG;AAAA,QAChC;AAAA,MACD;AACA,YAAM,YAAY,MAAM,OAAO,CAAC,SAA+B,KAAK,SAAS,UAAU;AACvF,UAAI,UAAU,SAAS,GAAG;AACzB,cAAM,MAAgB,EAAE,GAAG,IAAI,KAAK,cAAc,cAAc,OAAO,GAAG;AAC1E,cAAM,eAAe,IAAI,IAAI,IAAI,QAAQ,QAAQ,OAAO,UAAU;AACjE,qBAAW,QAAQ,WAAW;AAC7B,sBAAU,KAAK,GAAI,MAAM,YAAY,IAAI,QAAQ,KAAK,OAAO,SAAS,IAAI,CAAE;AAAA,UAC7E;AAAA,QACD,CAAC;AAAA,MACF;AACA,YAAM,GAAG;AAAA,QACR;AAAA,QACA,CAAC,OAAO,OAAO,CAAC;AAAA,MACjB;AAAA,IACD,CAAC;AACD,WAAO,QAAQ;AACf,eAAW,aAAa,UAAW,KAAI,YAAY,SAAS;AAC5D,YAAQ,KAAK,GAAG,SAAS;AAAA,EAC1B;AACA,SAAO;AACR;AAOA,eAAe,kBAAkB,IAAiB,KAA4B;AAC7E,MAAI;AACH,UAAM,GAAG,QAAQ,GAAG;AAAA,EACrB,SAAS,OAAO;AACf,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,QAAI,CAAC,QAAQ,SAAS,uBAAuB,EAAG,OAAM;AAAA,EACvD;AACD;AAUA,eAAe,aACd,IACA,YACA,MACA,IACgB;AAChB,QAAM,YAAQ,0BAAW,UAAU;AACnC,QAAM,UAAU,MAAM,GAAG;AAAA,IACxB,sCAAsC,QAAQ,UAAU,CAAC;AAAA,EAC1D;AACA,QAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI,CAAC;AAI1D,MAAI,CAAC,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,EAAE,EAAG;AACvC,MAAI,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,EAAE,GAAG;AACrC,UAAM,UAAU,MAAM,GAAG;AAAA,MACxB,oGAAoG,QAAQ,UAAU,CAAC,+FAA+F,QAAQ,EAAE,CAAC;AAAA,IAClO;AACA,eAAW,SAAS,QAAS,OAAM,GAAG,QAAQ,kBAAc,0BAAW,MAAM,IAAI,CAAC,EAAE;AACpF,UAAM,GAAG,QAAQ,eAAe,KAAK,oBAAgB,0BAAW,EAAE,CAAC,EAAE;AACrE,UAAM,GAAG,QAAQ,eAAe,KAAK,sBAAkB,0BAAW,IAAI,CAAC,WAAO,0BAAW,EAAE,CAAC,EAAE;AAC9F,eAAW,SAAS,SAAS;AAC5B,YAAM,GAAG,QAAQ,MAAM,IAAI,QAAQ,mBAAmB,6BAA6B,CAAC;AAAA,IACrF;AACA;AAAA,EACD;AACA,QAAM;AAAA,IACL;AAAA,IACA,eAAe,KAAK,sBAAkB,0BAAW,IAAI,CAAC,WAAO,0BAAW,EAAE,CAAC;AAAA,EAC5E;AACD;AAEA,SAAS,QAAQ,OAAuB;AACvC,SAAO,IAAI,MAAM,WAAW,KAAK,IAAI,CAAC;AACvC;AAEA,eAAe,YACd,QACA,KACA,OACA,SACA,MACuB;AACvB,QAAM,aAAa,OAAO,YAAY,KAAK,UAAU;AACrD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI;AAAA,MACT,cAAc,OAAO,kCAAkC,KAAK,UAAU;AAAA,MACtE;AAAA,MACA,EAAE,SAAS,YAAY,KAAK,WAAW;AAAA,IACxC;AAAA,EACD;AACA,QAAM,OAAO,MAAM,MAAM,GAAG;AAAA,IAC3B,qBAAiB,0BAAW,KAAK,UAAU,CAAC;AAAA,EAC7C;AACA,QAAM,aAA0B,CAAC;AACjC,aAAW,OAAO,MAAM;AACvB,UAAM,SAAS,kBAAkB,KAAK,WAAW,MAAM;AACvD,UAAM,UAAU,KAAK,UAAU,EAAE,GAAG,OAAO,CAAC;AAC5C,QAAI,YAAY,QAAQ,OAAO,YAAY,SAAU;AACrD,UAAM,UAAmC,CAAC;AAC1C,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAErD,UAAI,YAAY,IAAI,KAAK,KAAK,UAAU,OAAO,KAAK,GAAG,KAAK,EAAG;AAC/D,UAAI,EAAE,SAAS,WAAW,SAAS;AAClC,cAAM,IAAI;AAAA,UACT,cAAc,OAAO,iBAAiB,KAAK,UAAU,6BAA6B,KAAK;AAAA,UACvF;AAAA,UACA,EAAE,SAAS,YAAY,KAAK,YAAY,OAAO,KAAK,6BAA6B;AAAA,QAClF;AAAA,MACD;AACA,UAAI,CAAC,UAAU,OAAO,KAAK,GAAG,KAAK,EAAG,SAAQ,KAAK,IAAI;AAAA,IACxD;AACA,QAAI,OAAO,KAAK,OAAO,EAAE,WAAW,EAAG;AAEvC,QAAI,KAAK,WAAW;AACnB,YAAM,aAAa,gBAAgB,SAAS,WAAW,MAAM;AAC7D,YAAM,UAAU,OAAO,KAAK,UAAU;AACtC,YAAM,MAAM,GAAG;AAAA,QACd,cAAU,0BAAW,KAAK,UAAU,CAAC,QAAQ,QAAQ,IAAI,CAAC,MAAM,OAAG,0BAAW,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,QAClG,CAAC,GAAG,QAAQ,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,GAAG,IAAI,EAAE;AAAA,MAC9C;AACA;AAAA,IACD;AACA,UAAM,gBAAY,8BAAe,KAAK,YAAY,YAAY,SAAS,QAAQ;AAC/E,UAAM,SAAS,MAAM,gBAAgB,KAAK,OAAO,KAAK,YAAY,IAAI,IAAI,SAAS;AACnF,QAAI,OAAO,UAAW,YAAW,KAAK,OAAO,SAAS;AAAA,EACvD;AACA,SAAO;AACR;AAGA,SAAS,UAAU,GAAY,GAAqB;AACnD,MAAI,OAAO,GAAG,GAAG,CAAC,EAAG,QAAO;AAC5B,MAAI,aAAa,cAAc,aAAa,YAAY;AACvD,QAAI,EAAE,aAAa,eAAe,EAAE,aAAa,eAAe,EAAE,WAAW,EAAE,QAAQ;AACtF,aAAO;AAAA,IACR;AACA,WAAO,EAAE,MAAM,CAAC,MAAM,UAAU,SAAS,EAAE,KAAK,CAAC;AAAA,EAClD;AACA,MAAI,MAAM,QAAQ,MAAM,QAAQ,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAE/E,YAAQ,KAAK,WAAW,KAAK;AAAA,EAC9B;AACA,MAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,EAAG,QAAO;AAClD,QAAM,QAAQ,OAAO,KAAK,CAAC;AAC3B,QAAM,QAAQ,OAAO,KAAK,CAAC;AAC3B,MAAI,MAAM,WAAW,MAAM,OAAQ,QAAO;AAC1C,SAAO,MAAM;AAAA,IAAM,CAAC,QACnB,UAAW,EAA8B,GAAG,GAAI,EAA8B,GAAG,CAAC;AAAA,EACnF;AACD;AAEA,eAAe,wBAAwB,SAA0C;AAChF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,EACD;AACA,SAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;AAC1C;AAEA,eAAe,mBAAmB,SAAyB,SAAgC;AAC1F,QAAM,QAAQ;AAAA,IACb;AAAA,IACA,CAAC,OAAO,OAAO,CAAC;AAAA,EACjB;AACD;AA7OA,IAAAC,eAeM;AAfN;AAAA;AAAA;AAAA,IAAAA,gBAA2E;AAE3E;AAMA;AACA;AAMA,IAAM,cAAmC,oBAAI,IAAI,CAAC,MAAM,aAAa,WAAW,CAAC;AAAA;AAAA;;;ACS1E,SAAS,oBAAoB,MAAiD;AACpF,QAAM,QAAQ,OAAO,KAAK,CAAC,GAAG,SAAS,CAAC;AACxC,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACzC;AAQO,SAAS,iBAAiB,OAAyD;AACzF,QAAM,OAAO,oBAAI,IAAa;AAC9B,MAAI,UAAmB;AACvB,SAAO,YAAY,QAAQ,YAAY,UAAa,CAAC,KAAK,IAAI,OAAO,GAAG;AACvE,SAAK,IAAI,OAAO;AAChB,UAAM,OACL,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,YAAY,WAAW,UAAU;AACtF,UAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,QAAI,MAAO,QAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC,GAAG,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE;AACrE,cAAU,mBAAmB,QAAS,QAAgC,QAAQ;AAAA,EAC/E;AACA,SAAO;AACR;AA/CA,IAeM,OAmCO;AAlDb;AAAA;AAAA;AAeA,IAAM,QAAQ;AAmCP,IAAM,4BAA4B;AAAA;AAAA;;;AC9BlC,SAAS,kBAAkB,GAAY,GAAqB;AAClE,MAAI,OAAO,GAAG,GAAG,CAAC,EAAG,QAAO;AAC5B,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAM,QAAO;AAEvF,MAAI,YAAY,OAAO,CAAC,KAAK,YAAY,OAAO,CAAC,GAAG;AACnD,QAAI,CAAC,YAAY,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,EAAG,QAAO;AAC7D,WAAO,WAAW,GAAG,CAAC;AAAA,EACvB;AACA,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACzC,QAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAQ,QAAO;AAC5E,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAClC,UAAI,CAAC,kBAAkB,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAG,QAAO;AAAA,IAC5C;AACA,WAAO;AAAA,EACR;AACA,MAAI,aAAa,QAAQ,aAAa,MAAM;AAC3C,WAAO,aAAa,QAAQ,aAAa,QAAQ,OAAO,GAAG,EAAE,QAAQ,GAAG,EAAE,QAAQ,CAAC;AAAA,EACpF;AAEA,QAAM,OAAO;AACb,QAAM,OAAO;AACb,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,OAAQ,QAAO;AACtD,aAAW,OAAO,OAAO;AACxB,QAAI,CAAC,OAAO,OAAO,MAAM,GAAG,EAAG,QAAO;AACtC,QAAI,CAAC,kBAAkB,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC,EAAG,QAAO;AAAA,EACtD;AACA,SAAO;AACR;AAEA,SAAS,WAAW,GAAoB,GAA6B;AACpE,MAAI,EAAE,eAAe,EAAE,WAAY,QAAO;AAC1C,QAAM,IAAI,IAAI,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU;AAC7D,QAAM,IAAI,IAAI,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU;AAC7D,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAClC,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAAA,EAC3B;AACA,SAAO;AACR;AAEA,SAAS,YAAY,GAAY,GAAqB;AACrD,SAAO,OAAO,GAAG,GAAG,CAAC;AACtB;AAOA,SAAS,gBAAgB,MAA6B;AACrD,UAAQ,MAAM;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;AAWO,SAAS,mBAAmB,QAAuD;AACzF,QAAM,WAAW,oBAAI,IAAwB;AAC7C,aAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,aAAS,IAAI,MAAM,gBAAgB,WAAW,IAAI,CAAC;AAAA,EACpD;AAEA,QAAM,cAAc,CAAC,GAAqB,MAAiC;AAC1E,UAAM,OAAO;AACb,UAAM,OAAO;AACb,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,OAAQ,QAAO;AACtD,eAAW,OAAO,OAAO;AACxB,UAAI,CAAC,OAAO,OAAO,MAAM,GAAG,EAAG,QAAO;AACtC,YAAM,KAAK,SAAS,IAAI,GAAG,KAAK;AAChC,UAAI,CAAC,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC,EAAG,QAAO;AAAA,IACvC;AACA,WAAO;AAAA,EACR;AAEA,SAAO,CAAC,MAAM,SAAS;AACtB,QAAI,SAAS,KAAM,QAAO;AAC1B,QAAI,KAAK,WAAW,KAAK,OAAQ,QAAO;AAExC,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACrC,UAAI,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,GAAI,QAAO;AAAA,IACzC;AACA,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACrC,YAAM,IAAI,KAAK,CAAC;AAChB,YAAM,IAAI,KAAK,CAAC;AAChB,UAAI,MAAM,UAAa,MAAM,OAAW,QAAO,MAAM;AACrD,UAAI,CAAC,YAAY,GAAG,CAAC,EAAG,QAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACR;AACD;AApIA,IA0Ia;AA1Ib;AAAA;AAAA;AA0IO,IAAM,sBAAoC,mBAAmB,CAAC,CAAC;AAAA;AAAA;;;ACrItE,SAAS,QAAQ,MAAmC;AACnD,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,aAAa,SAAS,IAAI;AAClC;AAYO,SAAS,UAAU,MAAsB;AAC/C,MAAI,KAAK,SAAS,GAAG,EAAG,QAAO;AAC/B,MAAI,KAAK,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,SAAS,CAAC,CAAC,GAAG;AAC1D,WAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,EAC5B;AACA,MAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;AAC3F,WAAO,GAAG,IAAI;AAAA,EACf;AACA,SAAO,GAAG,IAAI;AACf;AAYO,SAAS,YAAY,MAAsB;AACjD,MAAI,KAAK,SAAS,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,SAAS,CAAC,CAAC,GAAG;AAC5D,WAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,EAC5B;AACA,MACC,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,KAAK,KACnB,KAAK,SAAS,KAAK,GAClB;AACD,WAAO,KAAK,MAAM,GAAG,EAAE;AAAA,EACxB;AACA,MAAI,KAAK,SAAS,KAAK,GAAG;AACzB,WAAO,KAAK,MAAM,GAAG,EAAE;AAAA,EACxB;AACA,MAAI,KAAK,SAAS,GAAG,KAAK,CAAC,KAAK,SAAS,IAAI,GAAG;AAC/C,WAAO,KAAK,MAAM,GAAG,EAAE;AAAA,EACxB;AACA,SAAO;AACR;AA5DA;AAAA;AAAA;AAAA;AAAA;;;ACsBO,SAAS,eAAe,OAAiC;AAC/D,QAAM,MAAmB,CAAC;AAC1B,aAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACnD,QAAI,UAAU,OAAW;AACzB,QAAI,iBAAiB,KAAK,GAAG;AAC5B,YAAM,YAAqC,CAAC;AAC5C,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACxD,YAAI,YAAY,OAAW;AAC3B,kBAAU,QAAQ,IAAI,iBAAiB,OAAO,UAAU,OAAO;AAAA,MAChE;AACA,UAAI,OAAO,KAAK,SAAS,EAAE,WAAW,EAAG;AACzC,UAAI,KAAK,IAAI;AACb;AAAA,IACD;AACA,QAAI,KAAK,IAAI,iBAAiB,OAAO,OAAO,KAAK;AAAA,EAClD;AACA,SAAO;AACR;AAEA,SAAS,iBAAiB,OAAe,UAAkB,SAA2B;AACrF,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC3B,WAAO,QAAQ,IAAI,CAAC,SAAS;AAC5B,UAAI,SAAS,QAAW;AACvB,cAAM,IAAI;AAAA,UACT,WAAW,QAAQ,oBAAoB,KAAK;AAAA,UAC5C,EAAE,OAAO,SAAS;AAAA,QACnB;AAAA,MACD;AACA,aAAO,aAAa,OAAO,UAAU,IAAI;AAAA,IAC1C,CAAC;AAAA,EACF;AACA,SAAO,aAAa,OAAO,UAAU,OAAO;AAC7C;AAEA,SAAS,aAAa,OAAe,UAAkB,OAAyB;AAC/E,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACzD,UAAM,IAAI;AAAA,MACT,4BAA4B,KAAK,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC;AAAA,MAClE,EAAE,OAAO,UAAU,OAAO,OAAO,KAAK,EAAE;AAAA,IACzC;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,iBAAiB,OAAkD;AAC3E,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AAChF,MAAI,iBAAiB,QAAQ,YAAY,OAAO,KAAK,EAAG,QAAO;AAC/D,SAAO;AACR;AAeO,SAAS,SAAS,YAAqC;AAC7D,SAAO,UAAU;AAAA,IAChB,YAAY,WAAW;AAAA,IACvB,OAAO,eAAe,WAAW,KAAK;AAAA,IACtC,SAAS,WAAW,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,OAAO,OAAO,SAAS,CAAC;AAAA,IAC5E,OAAO,WAAW;AAAA,IAClB,QAAQ,WAAW;AAAA,IACnB,SAAS,WAAW;AAAA,EACrB,CAAC;AACF;AAEA,SAAS,UAAU,OAAwB;AAC1C,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU,KAAM,QAAO;AAC3B,UAAQ,OAAO,OAAO;AAAA,IACrB,KAAK;AACJ,aAAO,KAAK,UAAU,KAAK;AAAA,IAC5B,KAAK;AAEJ,aAAO,OAAO,GAAG,OAAO,EAAE,IAAI,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,IAC9D,KAAK;AACJ,aAAO,QAAQ,SAAS;AAAA,IACzB,KAAK;AACJ,aAAO,OAAO,MAAM,SAAS,CAAC;AAAA,IAC/B;AACC;AAAA,EACF;AACA,MAAI,iBAAiB,KAAM,QAAO,QAAQ,MAAM,QAAQ,CAAC;AACzD,MAAI,YAAY,OAAO,KAAK,GAAG;AAC9B,UAAM,QAAQ,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU;AAC7E,WAAO,SAAS,MAAM,KAAK,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EAC5C;AACA,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,GAAG,CAAC;AACnE,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,UAAU,OAAO,QAAQ,KAAgC,EAC7D,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,SAAS,MAAS,EACvC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AACjD,WAAO,IAAI,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,EAC/F;AACA,SAAO,KAAK,OAAO,KAAK;AACzB;AA7HA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IACAC,eAmBM,qBAkBO;AAtCb;AAAA;AAAA;AACA,IAAAA,gBAA6C;AAC7C;AACA;AACA;AAYA;AACA;AACA;AAEA,IAAM,sBAAsB,oBAAI,QAA4C;AAkBrE,IAAM,eAAN,MAAM,cAAmC;AAAA,MAG/C,YACkB,gBACA,YACA,SACA,qBACjB,eAA4B,CAAC,GACZ,QAChB;AANgB;AACA;AACA;AACA;AAEA;AAEjB,aAAK,aAAa;AAAA,UACjB,YAAY;AAAA,UACZ,OAAO,eAAe,YAAY;AAAA,UAClC,SAAS,CAAC;AAAA,QACX;AAAA,MACD;AAAA,MAZkB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,MARV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAwBR,MAAM,YAA0C;AAC/C,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,aAAa;AAAA,UAClB,GAAG,MAAM;AAAA,UACT,OAAO,EAAE,GAAG,MAAM,WAAW,OAAO,GAAG,eAAe,UAAU,EAAE;AAAA,QACnE;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,OAAe,YAA8B,OAAwB;AAC5E,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,aAAa;AAAA,UAClB,GAAG,MAAM;AAAA,UACT,SAAS,CAAC,GAAG,MAAM,WAAW,SAAS,EAAE,OAAO,UAAU,CAAC;AAAA,QAC5D;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,GAA4B;AACjC,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,aAAa,EAAE,GAAG,MAAM,YAAY,OAAO,EAAE;AACnD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,GAA4B;AAClC,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,aAAa,EAAE,GAAG,MAAM,YAAY,QAAQ,EAAE;AACpD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiBA,WAAW,SAAoC;AAC9C,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,WAAW,MAAM,WAAW,WAAW,CAAC;AAC9C,cAAM,aAAa;AAAA,UAClB,GAAG,MAAM;AAAA,UACT,SAAS,CAAC,GAAG,UAAU,GAAG,OAAO;AAAA,QAClC;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,OAAqB;AAC1B,cAAM,EAAE,KAAK,OAAO,IAAI,iBAAiB,KAAK,YAAY,KAAK,WAAW,MAAM;AAChF,cAAM,OAAO,MAAM,KAAK,QAAQ,MAAwB,KAAK,MAAM;AACnE,cAAM,UAAU,KAAK,IAAI,CAAC,QAAQ,kBAAkB,KAAK,KAAK,WAAW,MAAM,CAAC;AAGhF,YAAI,KAAK,WAAW,WAAW,KAAK,WAAW,QAAQ,SAAS,KAAK,KAAK,QAAQ;AACjF,gBAAM,KAAK,gBAAgB,OAAO;AAAA,QACnC;AAEA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAyB;AAC9B,cAAM,EAAE,KAAK,OAAO,IAAI,gBAAgB,KAAK,YAAY,KAAK,WAAW,MAAM;AAC/E,cAAM,OAAO,MAAM,KAAK,QAAQ,MAAyB,KAAK,MAAM;AACpE,eAAO,KAAK,CAAC,GAAG,SAAS;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,UAAU,UAAmC,SAAwC;AACpF,cAAM,YAAY,MAAM,KAAK,KAAK;AAGlC,cAAM,iBAAiB,EAAE,GAAG,KAAK,WAAW;AAC5C,YAAI,eAAe,WAAW,eAAe,QAAQ,SAAS,KAAK,KAAK,QAAQ;AAC/E,yBAAe,qBAAqB,KAAK,0BAA0B,eAAe,OAAO;AAAA,QAC1F;AAIA,eAAO,KAAK,oBAAoB;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,SAAS,SAAS,SAAS,cAAc,KAAK,gBAAgB,EAAE;AAAA,QACnE;AAAA,MACD;AAAA;AAAA,MAGQ,kBAAgC;AACvC,YAAI,SAAS,oBAAoB,IAAI,KAAK,UAAU;AACpD,YAAI,CAAC,QAAQ;AACZ,mBAAS,mBAAmB,KAAK,WAAW,MAAM;AAClD,8BAAoB,IAAI,KAAK,YAAY,MAAM;AAAA,QAChD;AACA,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,gBAAiC;AAChC,eAAO,EAAE,GAAG,KAAK,WAAW;AAAA,MAC7B;AAAA,MAEQ,QAAyB;AAChC,cAAM,KAAK,IAAI;AAAA,UACd,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,CAAC;AAAA,UACD,KAAK;AAAA,QACN;AACA,WAAG,aAAa;AAAA,UACf,GAAG,KAAK;AAAA,UACR,OAAO,EAAE,GAAG,KAAK,WAAW,MAAM;AAAA,UAClC,SAAS,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,UACpC,SAAS,KAAK,WAAW,UAAU,CAAC,GAAG,KAAK,WAAW,OAAO,IAAI;AAAA,UAClE,oBAAoB,KAAK,WAAW,qBACjC,CAAC,GAAG,KAAK,WAAW,kBAAkB,IACtC;AAAA,QACJ;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKQ,0BAA0B,SAA6B;AAC9D,YAAI,CAAC,KAAK,OAAQ,QAAO,CAAC;AAC1B,cAAM,cAAwB,CAAC;AAE/B,mBAAW,UAAU,SAAS;AAC7B,gBAAM,WAAW,KAAK,aAAa,MAAM;AACzC,cAAI,UAAU;AAGb,gBAAI,SAAS,SAAS,KAAK,gBAAgB;AAC1C,0BAAY,KAAK,SAAS,EAAE;AAAA,YAC7B,OAAO;AACN,0BAAY,KAAK,SAAS,IAAI;AAAA,YAC/B;AAAA,UACD;AAAA,QACD;AAEA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,gBAAgB,SAA4C;AACzE,YAAI,CAAC,KAAK,UAAU,CAAC,KAAK,WAAW,WAAW,QAAQ,WAAW,EAAG;AAEtE,mBAAW,UAAU,KAAK,WAAW,SAAS;AAC7C,gBAAM,WAAW,KAAK,aAAa,MAAM;AACzC,cAAI,CAAC,UAAU;AACd,kBAAM,IAAI;AAAA,cACT,yCAAyC,MAAM,oBAAoB,KAAK,cAAc,qEACnB,KAAK,cAAc,SAAS,MAAM;AAAA,YACtG;AAAA,UACD;AAEA,cAAI,SAAS,SAAS,KAAK,gBAAgB;AAE1C,kBAAM,KAAK,wBAAwB,SAAS,UAAU,MAAM;AAAA,UAC7D,OAAO;AAEN,kBAAM,KAAK,wBAAwB,SAAS,UAAU,MAAM;AAAA,UAC7D;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,wBACb,SACA,UACA,QACgB;AAChB,cAAM,UAAU,SAAS;AACzB,cAAM,WAAW,QACf,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EACrB,OAAO,CAAC,MAAmB,MAAM,QAAQ,MAAM,UAAa,OAAO,MAAM,QAAQ;AAEnF,YAAI,SAAS,WAAW,GAAG;AAE1B,gBAAMC,YAAW,YAAY,MAAM;AACnC,qBAAW,UAAU,SAAS;AAC7B;AAAC,YAAC,OAAmCA,SAAQ,IAAI;AAAA,UAClD;AACA;AAAA,QACD;AAEA,cAAM,YAAY,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC;AACvC,cAAM,oBAAoB,SAAS;AACnC,cAAM,aAAa,KAAK,QAAQ,YAAY,iBAAiB;AAC7D,YAAI,CAAC,WAAY;AAGjB,cAAM,eAAe,UAAU,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AACvD,cAAM,MAAM,qBAAiB,0BAAW,iBAAiB,CAAC,iBAAiB,YAAY;AACvF,cAAM,OAAO,MAAM,KAAK,QAAQ,MAAwB,KAAK,SAAS;AACtE,cAAM,iBAAiB,KAAK,IAAI,CAAC,QAAQ,kBAAkB,KAAK,WAAW,MAAM,CAAC;AAGlF,cAAM,SAAS,oBAAI,IAA8B;AACjD,mBAAW,KAAK,gBAAgB;AAC/B,iBAAO,IAAI,EAAE,IAAI,CAAC;AAAA,QACnB;AAGA,cAAM,WAAW,YAAY,MAAM;AACnC,mBAAW,UAAU,SAAS;AAC7B,gBAAM,KAAK,OAAO,OAAO;AACxB,UAAC,OAAmC,QAAQ,IAAI,KAAM,OAAO,IAAI,EAAE,KAAK,OAAQ;AAAA,QAClF;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,wBACb,SACA,UACA,QACgB;AAChB,cAAM,aAAa,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE;AAC1C,cAAM,oBAAoB,SAAS;AACnC,cAAM,aAAa,KAAK,QAAQ,YAAY,iBAAiB;AAC7D,YAAI,CAAC,WAAY;AAEjB,cAAM,UAAU,SAAS;AACzB,cAAM,eAAe,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AACxD,cAAM,MAAM,qBAAiB,0BAAW,iBAAiB,CAAC,cAAU,0BAAW,OAAO,CAAC,QAAQ,YAAY;AAC3G,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B;AAAA,UACA,WAAW,IAAI,CAAC,WAAO,gCAAiB,EAAE,CAAC;AAAA,QAC5C;AACA,cAAM,iBAAiB,KAAK,IAAI,CAAC,QAAQ,kBAAkB,KAAK,WAAW,MAAM,CAAC;AAGlF,cAAM,UAAU,oBAAI,IAAgC;AACpD,mBAAW,KAAK,gBAAgB;AAC/B,gBAAM,KAAK,EAAE,OAAO;AACpB,cAAI,CAAC,QAAQ,IAAI,EAAE,GAAG;AACrB,oBAAQ,IAAI,IAAI,CAAC,CAAC;AAAA,UACnB;AACA,kBAAQ,IAAI,EAAE,GAAG,KAAK,CAAC;AAAA,QACxB;AAGA,cAAM,WAAW,UAAU,MAAM;AACjC,mBAAW,UAAU,SAAS;AAC7B;AAAC,UAAC,OAAmC,QAAQ,IAAI,QAAQ,IAAI,OAAO,EAAE,KAAK,CAAC;AAAA,QAC7E;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,aACP,QACmE;AACnE,YAAI,CAAC,KAAK,OAAQ,QAAO;AAEzB,mBAAW,CAAC,OAAO,GAAG,KAAK,OAAO,QAAQ,KAAK,OAAO,SAAS,GAAG;AAEjE,cAAI,IAAI,SAAS,KAAK,kBAAkB,IAAI,OAAO,OAAQ,QAAO;AAClE,cAAI,IAAI,OAAO,KAAK,kBAAkB,IAAI,SAAS,OAAQ,QAAO;AAGlE,cAAI,IAAI,SAAS,KAAK,kBAAkB,IAAI,OAAO,UAAU,MAAM,EAAG,QAAO;AAC7E,cAAI,IAAI,OAAO,KAAK,kBAAkB,IAAI,SAAS,UAAU,MAAM,EAAG,QAAO;AAG7E,cAAI,IAAI,SAAS,KAAK,kBAAkB,IAAI,OAAO,YAAY,MAAM,EAAG,QAAO;AAC/E,cAAI,IAAI,OAAO,KAAK,kBAAkB,IAAI,SAAS,YAAY,MAAM,EAAG,QAAO;AAAA,QAChF;AAEA,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;AC9UO,SAAS,oBAAoB,QAA2D;AAC9F,QAAM,SAAS,oBAAI,IAAgC;AAEnD,aAAW,CAAC,cAAc,QAAQ,KAAK,OAAO,QAAQ,OAAO,SAAS,GAAG;AACxE,UAAM,mBAAmB,SAAS;AAClC,UAAM,WAAW,OAAO,IAAI,gBAAgB,KAAK,CAAC;AAClD,aAAS,KAAK;AAAA,MACb;AAAA,MACA,kBAAkB,SAAS;AAAA,MAC3B,iBAAiB,SAAS;AAAA,MAC1B,UAAU,SAAS;AAAA,MACnB;AAAA,IACD,CAAC;AACD,WAAO,IAAI,kBAAkB,QAAQ;AAAA,EACtC;AAEA,SAAO;AACR;AAUO,SAAS,qBACf,QACA,YACqB;AACrB,SAAO,OAAO,IAAI,UAAU,KAAK,CAAC;AACnC;AAtEA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IACAC,eAYa,2BAkEA;AA/Eb;AAAA;AAAA;AACA,IAAAA,gBAAwD;AAExD;AAGA;AAOO,IAAM,4BAAN,cAAwC,wBAAU;AAAA,MACxD,YACC,YACA,UACA,uBACA,cACA,kBACC;AACD;AAAA,UACC,yBAAyB,QAAQ,WAAW,UAAU,MAAM,gBAAgB,kBAAkB,qBAAqB,gCAAgC,YAAY;AAAA,UAC/J;AAAA,UACA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD;AAAA,QACD;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AA6CO,IAAM,mBAAN,MAAuB;AAAA,MACZ;AAAA,MAEjB,YAAY,QAAgC;AAC3C,aAAK,SAAS,oBAAoB,OAAO,MAAM;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaA,MAAM,cACL,YACA,UACA,OACA,KACA,YAC6B;AAC7B,cAAM,oBAAoB,qBAAqB,KAAK,QAAQ,UAAU;AACtE,YAAI,kBAAkB,WAAW,GAAG;AACnC,iBAAO,EAAE,YAAY,CAAC,EAAE;AAAA,QACzB;AAEA,cAAM,gBAA6B,CAAC;AAIpC,cAAM,kBAAkB,CAAC,GAAG,iBAAiB,EAAE;AAAA,UAAK,CAAC,GAAG,MACvD,EAAE,aAAa,cAAc,EAAE,YAAY;AAAA,QAC5C;AAEA,mBAAW,YAAY,iBAAiB;AACvC,gBAAM,MAAM,MAAM,KAAK,gBAAgB,UAAU,UAAU,OAAO,KAAK,UAAU;AACjF,wBAAc,KAAK,GAAG,GAAG;AAAA,QAC1B;AAEA,eAAO,EAAE,YAAY,cAAc;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,gBACb,UACA,iBACA,OACA,KACA,YACuB;AACvB,gBAAQ,SAAS,UAAU;AAAA,UAC1B,KAAK;AACJ,mBAAO,KAAK,eAAe,UAAU,iBAAiB,OAAO,KAAK,UAAU;AAAA,UAC7E,KAAK;AACJ,mBAAO,KAAK,eAAe,UAAU,iBAAiB,OAAO,KAAK,UAAU;AAAA,UAC7E,KAAK;AACJ,mBAAO,KAAK,gBAAgB,UAAU,iBAAiB,MAAM,EAAE;AAAA,UAChE,KAAK;AACJ,mBAAO,CAAC;AAAA,QACV;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,eACb,UACA,iBACA,OACA,KACA,YACuB;AACvB,cAAM,iBAAiB,MAAM,KAAK,gBAAgB,UAAU,iBAAiB,MAAM,EAAE;AACrF,cAAM,aAA0B,CAAC;AACjC,mBAAW,MAAM,gBAAgB;AAChC,gBAAM,SAAS,MAAM,gBAAgB,KAAK,OAAO,SAAS,kBAAkB,IAAI;AAAA,YAC/E,iBAAiB,CAAC,UAAU;AAAA,UAC7B,CAAC;AACD,cAAI,OAAO,UAAW,YAAW,KAAK,OAAO,SAAS;AACtD,qBAAW,KAAK,GAAG,OAAO,WAAW;AAAA,QACtC;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,eACb,UACA,iBACA,OACA,KACA,YACuB;AACvB,cAAM,iBAAiB,MAAM,KAAK,gBAAgB,UAAU,iBAAiB,MAAM,EAAE;AACrF,cAAM,aAA0B,CAAC;AACjC,mBAAW,MAAM,gBAAgB;AAChC,gBAAM,SAAS,MAAM;AAAA,YACpB;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,YACA,EAAE,CAAC,SAAS,eAAe,GAAG,KAAK;AAAA,YACnC,CAAC,UAAU;AAAA,UACZ;AACA,cAAI,OAAO,UAAW,YAAW,KAAK,OAAO,SAAS;AAAA,QACvD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,gBACb,UACA,iBACA,IACuB;AACvB,cAAM,EAAE,kBAAkB,iBAAiB,aAAa,IAAI;AAE5D,cAAM,YAAY,MAAM,GAAG;AAAA,UAC1B,mCAA+B,0BAAW,gBAAgB,CAAC,cAAU,0BAAW,eAAe,CAAC;AAAA;AAAA,UAEhG,KAAC,gCAAiB,eAAe,CAAC;AAAA,QACnC;AACA,cAAM,QAAQ,UAAU,CAAC,GAAG,OAAO;AAEnC,YAAI,QAAQ,GAAG;AACd,gBAAM,IAAI;AAAA,YACT,SAAS,SAAS;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD;AAAA,QACD;AAEA,eAAO,CAAC;AAAA,MACT;AAAA;AAAA,MAGA,MAAc,gBACb,UACA,iBACA,IACoB;AACpB,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,sBAAkB,0BAAW,SAAS,gBAAgB,CAAC,cAAU,0BAAW,SAAS,eAAe,CAAC;AAAA;AAAA,UAErG,KAAC,gCAAiB,eAAe,CAAC;AAAA,QACnC;AACA,eAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA,MAKA,oBAAqD;AACpD,eAAO,KAAK;AAAA,MACb;AAAA,IACD;AAAA;AAAA;;;ACrMO,SAAS,qBACf,QACA,mBACA,UAAuC,oBAAI,IAAI,GACjC;AACd,QAAM,QAAQ,oBAAI,IAAuB;AACzC,aAAW,MAAM,QAAQ;AACxB,UAAM,IAAI,GAAG,IAAI,EAAE;AAAA,EACpB;AAEA,QAAM,SAAS,MAAM,IAAI,iBAAiB;AAC1C,MAAI,CAAC,QAAQ;AACZ,UAAM,IAAI;AAAA,MACT,cAAc,iBAAiB;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,MACd;AAAA,IACD;AAAA,EACD;AAEA,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,QAAkB,CAAC,iBAAiB;AAE1C,SAAO,MAAM,SAAS,GAAG;AACxB,UAAM,KAAK,MAAM,IAAI;AACrB,QAAI,OAAO,UAAa,SAAS,IAAI,EAAE,GAAG;AACzC;AAAA,IACD;AACA,aAAS,IAAI,EAAE;AACf,UAAM,KAAK,MAAM,IAAI,EAAE;AACvB,QAAI,CAAC,IAAI;AACR;AAAA,IACD;AACA,eAAW,OAAO,GAAG,YAAY;AAChC,UAAI,QAAQ;AAEZ,eAAS,OAAO,GAAG,CAAC,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,GAAG,QAAQ;AAC/E,gBAAQ,QAAQ,IAAI,KAAK,KAAK;AAAA,MAC/B;AACA,UAAI,MAAM,IAAI,KAAK,GAAG;AACrB,cAAM,KAAK,KAAK;AAAA,MACjB;AAAA,IACD;AAAA,EACD;AAEA,QAAM,SAAS,OAAO,OAAO,CAAC,OAAO,SAAS,IAAI,GAAG,EAAE,CAAC;AACxD,aAAO,kCAAgB,MAAM;AAC9B;AAMO,SAAS,oBACf,QACA,QACA,mBACA,UAAuC,oBAAI,IAAI,GAC/C,aAA4C,CAAC,GAC5B;AACjB,QAAM,oBAAoB,qBAAqB,QAAQ,mBAAmB,OAAO;AACjF,QAAM,kBAAkB,kBAAkB,KAAK,CAAC,OAAO,GAAG,OAAO,iBAAiB;AAClF,MAAI,CAAC,iBAAiB;AACrB,UAAM,IAAI,6BAAe,cAAc,iBAAiB,iCAAiC;AAAA,MACxF,aAAa;AAAA,IACd,CAAC;AAAA,EACF;AAEA,QAAM,SAAS,eAAe,mBAAmB,QAAQ,UAAU;AAEnE,QAAM,cAAc,uBAAuB,QAAQ,MAAM;AAEzD,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,YAAoB,UAA2C;AACzE,YAAM,SAAS,OAAO,IAAI,UAAU;AACpC,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,UAAI,CAAC,UAAU,OAAO,SAAS;AAC9B,eAAO;AAAA,MACR;AACA,YAAM,aAAa,OAAO,YAAY,UAAU;AAChD,UAAI,CAAC,YAAY;AAChB,eAAO;AAAA,MACR;AACA,aAAO,mBAAmB,QAAQ,UAAU;AAAA,IAC7C;AAAA,EACD;AACD;AAOA,SAAS,eACR,KACA,QACA,YACoB;AACpB,QAAM,WAAW,oBAAI,IAAyB;AAC9C,aAAW,MAAM,KAAK;AACrB,QAAI,CAAC,OAAO,YAAY,GAAG,UAAU,EAAG;AACxC,UAAM,MAAM,GAAG,GAAG,UAAU,KAAS,GAAG,QAAQ;AAChD,UAAM,OAAO,SAAS,IAAI,GAAG,KAAK,CAAC;AACnC,SAAK,KAAK,EAAE;AACZ,aAAS,IAAI,KAAK,IAAI;AAAA,EACvB;AACA,QAAM,QAA2B,oBAAI,IAAI;AACzC,aAAW,aAAa,SAAS,OAAO,GAAG;AAC1C,UAAM,QAAQ,UAAU,CAAC;AACzB,UAAM,aAAa,OAAO,YAAY,MAAM,UAAU;AAEtD,UAAM,aAAS,0BAAW,WAAW,QAAQ;AAAA,MAC5C,UAAU;AAAA,MACV,GAAI,WAAW,SAAS,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA,IAC/C,CAAC,EAAE;AACH,QAAI,WAAW,QAAQ,OAAO,OAAO,QAAQ,OAAO,MAAM,KAAM;AAChE,UAAM,aAAS,2BAAY,EAAE,GAAG,QAAQ,GAAG,KAAK,GAAG,EAAE,UAAU,gBAAgB,CAAC,KAAK,CAAC;AACtF,QAAI,SAAS,MAAM,IAAI,MAAM,UAAU;AACvC,QAAI,CAAC,QAAQ;AACZ,eAAS,oBAAI,IAAI;AACjB,YAAM,IAAI,MAAM,YAAY,MAAM;AAAA,IACnC;AACA,WAAO,IAAI,MAAM,UAAU;AAAA,MAC1B,IAAI,MAAM;AAAA;AAAA;AAAA,MAGV,QAAQ,+BAA+B,QAAQ,WAAW,MAAM;AAAA,MAChE,SAAS,KAAC,+BAAgB,MAAM;AAAA,MAChC,WAAW,iCAAmB,YAAY,OAAO,GAAG,CAAC,EAAE;AAAA,MACvD,WAAW,iCAAmB,YAAY,OAAO,EAAE,CAAC,EAAE;AAAA,IACvD,CAAC;AAAA,EACF;AACA,SAAO;AACR;AAEA,SAAS,uBACR,QACA,QACqC;AACrC,QAAM,cAAkD,CAAC;AAEzD,aAAW,CAAC,gBAAgB,UAAU,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AAC9E,UAAM,SAAS,OAAO,IAAI,cAAc;AACxC,UAAM,UAA8B,CAAC;AACrC,QAAI,QAAQ;AACX,iBAAW,UAAU,OAAO,OAAO,GAAG;AACrC,YAAI,CAAC,OAAO,SAAS;AACpB,kBAAQ,KAAK,mBAAmB,QAAQ,UAAU,CAAC;AAAA,QACpD;AAAA,MACD;AAAA,IACD;AACA,gBAAY,cAAc,IAAI;AAAA,EAC/B;AAEA,SAAO;AACR;AAEA,SAAS,mBACR,QACA,YACmB;AACnB,QAAM,SAA2B;AAAA,IAChC,IAAI,OAAO;AAAA,IACX,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,EACnB;AACA,aAAW,CAAC,SAAS,KAAK,OAAO,QAAQ,WAAW,MAAM,GAAG;AAC5D,QAAI,aAAa,OAAO,QAAQ;AAC/B,aAAO,SAAS,IAAI,OAAO,OAAO,SAAS;AAAA,IAC5C;AAAA,EACD;AACA,SAAO;AACR;AAjOA,IAAAC,eAaAC;AAbA;AAAA;AAAA;AAAA,IAAAD,gBAMO;AAOP,IAAAC,mBAAgC;AAChC;AACA;AAAA;AAAA;;;ACfA,IACAC,eAyBa;AA1Bb;AAAA;AAAA;AACA,IAAAA,gBAA2D;AAyBpD,IAAM,kBAAN,MAAsB;AAAA,MACX;AAAA,MACA;AAAA,MAEjB,YAAY,SAAyB,QAAgB;AACpD,aAAK,UAAU;AACf,aAAK,SAAS;AAAA,MACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,KAAK,MAAc,QAA0C;AAClE,cAAM,QAAQ,QAAQ,SAAS;AAC/B,cAAM,UAAU,QAAQ,WAAW;AACnC,cAAM,SAAS,QAAQ,cAAU,qCAAsB,IAAI;AAE3D,YAAI,UAAU;AAEd,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAE5C,gBAAM,OAAO,MAAM,GAAG;AAAA,YACrB;AAAA,YACA,CAAC,MAAM,OAAO,KAAK,MAAM;AAAA,UAC1B;AAEA,cAAI,KAAK,SAAS,GAAG;AACpB,kBAAM,MAAM,KAAK,CAAC;AAClB,sBAAU,IAAI,UAAU;AACxB,kBAAM,GAAG;AAAA,cACR;AAAA,cACA,CAAC,SAAS,MAAM,OAAO,KAAK,MAAM;AAAA,YACnC;AAAA,UACD,OAAO;AAEN,sBAAU;AACV,kBAAM,GAAG;AAAA,cACR;AAAA,cACA,CAAC,MAAM,OAAO,KAAK,QAAQ,OAAO;AAAA,YACnC;AAAA,UACD;AAAA,QACD,CAAC;AAED,mBAAO,mCAAoB,QAAQ,SAAS,KAAK,MAAM;AAAA,MACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,QAAQ,MAAc,QAA8C;AACzE,cAAM,QAAQ,QAAQ,SAAS;AAE/B,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B;AAAA,UACA,CAAC,MAAM,OAAO,KAAK,MAAM;AAAA,QAC1B;AAEA,YAAI,KAAK,SAAS,GAAG;AACpB,iBAAQ,KAAK,CAAC,EAAkB;AAAA,QACjC;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,MAAM,MAAc,QAAyD;AAClF,cAAM,QAAQ,QAAQ,SAAS;AAC/B,cAAM,KAAK,QAAQ,MAAM;AAEzB,cAAM,KAAK,QAAQ;AAAA,UAClB;AAAA,UACA,CAAC,MAAM,OAAO,KAAK,MAAM;AAAA,QAC1B;AAEA,YAAI,KAAK,GAAG;AACX,gBAAM,KAAK,QAAQ;AAAA,YAClB;AAAA,YACA,CAAC,MAAM,OAAO,KAAK,QAAQ,EAAE;AAAA,UAC9B;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;AC9FA,eAAsB,sBACrB,SACA,QACgB;AAChB,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA,CAAC,0BAA0B;AAAA,EAC5B;AACA,MAAI,KAAK,CAAC,GAAG,UAAU,0BAA2B;AAClD,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,eAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AACpE,YAAM,UAAU,IAAI;AAAA,SAClB,MAAM,GAAG,MAAwB,yBAAqB,0BAAW,IAAI,CAAC,GAAG,GAAG;AAAA,UAC5E,CAAC,WAAW,OAAO;AAAA,QACpB;AAAA,MACD;AACA,UAAI,QAAQ,SAAS,EAAG;AACxB,iBAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,WAAW,MAAM,GAAG;AACpE,YAAI,CAAC,cAAc,WAAW,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAG;AAC5D,cAAM,aAAS,0BAAW,KAAK;AAC/B,cAAM,GAAG;AAAA,UACR,cAAU,0BAAW,IAAI,CAAC,QAAQ,MAAM,cAAc,MAAM,kDAAkD,MAAM;AAAA,QACrH;AAAA,MACD;AAAA,IACD;AACA,UAAM,GAAG,QAAQ,gEAAgE;AAAA,MAChF;AAAA,MACA;AAAA,IACD,CAAC;AAAA,EACF,CAAC;AACF;AAvDA,IAAAC,eAMa,4BAGP;AATN;AAAA;AAAA;AAAA,IAAAA,gBAA2B;AAG3B;AAGO,IAAM,6BAA6B;AAG1C,IAAM,4BAA4B;AAAA;AAAA;;;ACkB3B,SAAS,QAAQ,OAAuB;AAC9C,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,YAAQ,MAAM,WAAW,CAAC;AAE1B,WAAO,KAAK,KAAK,MAAM,SAAS;AAAA,EACjC;AAEA,SAAO,SAAS;AACjB;AAYO,SAAS,gBAAgB,eAAuB,mBAAmC;AACzF,MAAI,iBAAiB,EAAG,QAAO;AAC/B,MAAI,qBAAqB,KAAK,qBAAqB,EAAG,QAAO;AAE7D,QAAM,aAAa,KAAK,MAAM,KAAK;AACnC,QAAM,UAAU,EAAE,gBAAgB,KAAK,IAAI,iBAAiB,KAAK;AAGjE,QAAM,UAAU,KAAK,KAAK,UAAU,EAAE,IAAI;AAC1C,SAAO,KAAK,IAAI,IAAI,OAAO;AAC5B;AAYO,SAAS,iBAAiB,UAAkB,eAA+B;AACjF,MAAI,iBAAiB,EAAG,QAAO;AAC/B,QAAM,MAAO,WAAW,gBAAiB,KAAK;AAC9C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC;AACjD;AA1EA,IAcM,kBACA,WAgFO;AA/Fb;AAAA;AAAA;AAcA,IAAM,mBAAmB;AACzB,IAAM,YAAY;AAgFX,IAAM,0BAAN,MAA8B;AAAA,MAC5B;AAAA,MACS;AAAA,MACA;AAAA,MACT,YAAY;AAAA,MAEpB,YAAY,eAAuB,oBAAoB,MAAM;AAC5D,aAAK,WAAW,gBAAgB,eAAe,iBAAiB;AAChE,aAAK,YAAY,iBAAiB,KAAK,UAAU,aAAa;AAC9D,aAAK,OAAO,IAAI,YAAY,KAAK,WAAW,EAAE;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,IAAI,YAAoB,OAAsB;AAC7C,cAAM,MAAM,UAAU,SAAY,GAAG,UAAU,IAAI,KAAK,KAAK;AAC7D,cAAM,YAAY,KAAK,aAAa,GAAG;AACvC,mBAAW,OAAO,WAAW;AAC5B,gBAAM,YAAY,QAAQ;AAC1B,gBAAM,WAAW,MAAM;AACvB,gBAAM,UAAU,KAAK,KAAK,SAAS,KAAK;AACxC,eAAK,KAAK,SAAS,IAAI,UAAW,KAAK;AAAA,QACxC;AACA,aAAK;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYA,aAAa,YAAoB,OAAyB;AACzD,cAAM,MAAM,UAAU,SAAY,GAAG,UAAU,IAAI,KAAK,KAAK;AAC7D,cAAM,YAAY,KAAK,aAAa,GAAG;AACvC,mBAAW,OAAO,WAAW;AAC5B,gBAAM,YAAY,QAAQ;AAC1B,gBAAM,WAAW,MAAM;AACvB,gBAAM,KAAK,KAAK,SAAS,KAAK,KAAM,KAAK,cAAe,GAAG;AAC1D,mBAAO;AAAA,UACR;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,QAAc;AACb,aAAK,KAAK,KAAK,CAAC;AAChB,aAAK,YAAY;AAAA,MAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,6BAAqC;AACpC,YAAI,KAAK,cAAc,EAAG,QAAO;AACjC,cAAM,WAAW,EAAE,KAAK,YAAY,KAAK,aAAa,KAAK;AAC3D,gBAAQ,IAAI,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,eAAuB;AACtB,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA,MAKA,cAAsB;AACrB,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA,MAKA,eAAuB;AACtB,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,iBAAyB;AACxB,YAAI,QAAQ;AACZ,iBAAS,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;AAC1C,cAAI,OAAO,KAAK,KAAK,CAAC,KAAK;AAC3B,iBAAO,SAAS,GAAG;AAElB,oBAAQ,OAAO;AACf;AAAA,UACD;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaQ,aAAa,KAAuB;AAC3C,cAAM,KAAK,QAAQ,GAAG;AAEtB,cAAM,KAAK,QAAQ,GAAG,GAAG,SAAS;AAElC,cAAM,YAAY,IAAI,MAAc,KAAK,SAAS;AAClD,iBAAS,IAAI,GAAG,IAAI,KAAK,WAAW,KAAK;AAExC,oBAAU,CAAC,KAAM,KAAK,KAAK,KAAK,GAAG,EAAE,MAAO,KAAK,KAAK;AAAA,QACvD;AACA,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;AC1OA,IAsBI,WAME,yBAMA,8BAMA,mCA2FO;AAnIb;AAAA;AAAA;AACA;AAUA;AACA;AAUA,IAAI,YAAY;AAMhB,IAAM,0BAA0B;AAMhC,IAAM,+BAA+B;AAMrC,IAAM,oCAAoC;AA2FnC,IAAM,sBAAN,MAA0B;AAAA,MACxB,gBAAgB,oBAAI,IAA0B;AAAA,MAC9C,qBAAqB,oBAAI,IAAY;AAAA,MACrC,iBAAiB;AAAA,MACR;AAAA,MACA;AAAA,MACA,kBAAkB,oBAAI,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM1D,qBAAyC,oBAAI,IAAI;AAAA;AAAA,MAGjD,cAA8C;AAAA,MAC9C,aAAa;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGT,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,MAE3B,YAAY,SAAsC;AACjD,aAAK,iBAAiB,SAAS,kBAAkB;AACjD,aAAK,qBAAqB,SAAS,sBAAsB;AACzD,aAAK,yBACJ,SAAS,0BAA0B;AACpC,aAAK,oBAAoB,SAAS;AAClC,aAAK,eAAe,SAAS;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,SACC,YACA,UACA,WACA,SACa;AAGb,cAAM,eAAe,KAAK,mBAAmB,YAAY,UAAU,WAAW,OAAO;AACrF,qBAAa,YAAY;AACzB,eAAO,KAAK,MAAM,YAAY;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,iBACC,YACA,UACA,WACA,SACa;AACb,cAAM,eAAe,KAAK,mBAAmB,YAAY,UAAU,WAAW,OAAO;AACrF,cAAM,cAAc,KAAK,MAAM,YAAY;AAC3C,aAAK,KAAK,IAAI,YAAY;AAC1B,eAAO;AAAA,MACR;AAAA,MAEQ,mBACP,YACA,UACA,WACA,SACe;AACf,eAAO;AAAA,UACN,IAAI,OAAO,EAAE,SAAS;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa,CAAC;AAAA,UACd,cAAc,SAAS,gBAAgB;AAAA,UACvC,SAAS,SAAS;AAAA,UAClB,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,SAAS;AAAA,UACT,WAAW;AAAA,QACZ;AAAA,MACD;AAAA,MAEQ,MAAM,cAAwC;AACrD,cAAM,KAAK,aAAa;AACxB,aAAK,cAAc,IAAI,IAAI,YAAY;AAGvC,aAAK,aAAa;AAElB,cAAM,kBAAkB,KAAK,oBAAoB,aAAa,UAAU;AAExE,eAAO,MAAM;AACZ,cAAI,CAAC,KAAK,cAAc,OAAO,EAAE,EAAG;AACpC,eAAK,aAAa;AAClB,4BAAkB;AAAA,QACnB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,IAAI,KAAkC;AACnD,cAAM,aAAa,IAAI,eAAe,KAAK;AAC3C,YAAI,cAAc;AAClB,YAAI;AACJ,YAAI;AACH,oBAAU,MAAM,IAAI,UAAU;AAAA,QAC/B,SAAS,OAAO;AACf,cAAI,CAAC,KAAK,UAAU,KAAK,SAAS,EAAG;AACrC,cAAI,iBAAiB;AACrB,cAAI,UAAU;AACd,eAAK,YAAY,KAAK,OAAO,IAAI,YAAY,YAAY,SAAS;AAClE;AAAA,QACD;AACA,YAAI,CAAC,KAAK,UAAU,KAAK,SAAS,EAAG;AACrC,YAAI,iBAAiB;AAIrB,cAAM,QAAQ,IAAI,gBAAgB;AAClC,YAAI,IAAI,aAAa,CAAC,IAAI,WAAW,MAAM,IAAI,aAAa,OAAO,EAAG;AAEtE,YAAI,cAAc;AAClB,YAAI,YAAY;AAChB,YAAI,UAAU;AACd,YAAI;AACH,cAAI,SAAS,OAAO;AAAA,QACrB,SAAS,OAAO;AACf,eAAK,YAAY,KAAK,OAAO,UAAU;AAAA,QACxC;AAAA,MACD;AAAA,MAEQ,UAAU,KAAmB,WAA4B;AAChE,eAAO,KAAK,cAAc,IAAI,IAAI,EAAE,MAAM,OAAO,aAAa,IAAI,kBAAkB;AAAA,MACrF;AAAA,MAEQ,YAAY,KAAmB,QAAiB,OAA8B;AACrF,cAAM,QACL,kBAAkB,QACf,SACA,IAAI,WAAW,8BAA8B,OAAO,MAAM,CAAC,IAAI;AAAA,UAC/D,YAAY,IAAI,WAAW;AAAA,QAC5B,CAAC;AACJ,cAAM,UAAkC;AAAA,UACvC;AAAA,UACA;AAAA,UACA,YAAY,IAAI,WAAW;AAAA,UAC3B,SAAS,IAAI;AAAA,QACd;AACA,YAAI;AACH,eAAK,eAAe,OAAO;AAAA,QAC5B,SAAS,WAAW;AACnB,kBAAQ,MAAM,qCAAqC,SAAS;AAAA,QAC7D;AACA,YAAI,IAAI,SAAS;AAChB,cAAI;AACH,gBAAI,QAAQ,OAAO;AAAA,UACpB,SAAS,cAAc;AACtB,oBAAQ,MAAM,6CAA6C,YAAY;AAAA,UACxE;AACA;AAAA,QACD;AAEA,gBAAQ;AAAA,UACP,6BAA6B,IAAI,EAAE,QAAQ,IAAI,WAAW,UAAU,aAAa,KAAK;AAAA,UACtF;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO,YAAoB,WAA4B;AACtD,aAAK,eAAe,EAAE,YAAY,KAAK,CAAC,UAAU,QAAQ,GAAG,UAAU,CAAC;AAAA,MACzE;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,WAAW,YAAoB,MAAgC,MAAY;AAC1E,aAAK,eAAe,EAAE,YAAY,IAAI,CAAC;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,eAAe,QAA6B;AAC3C,aAAK,mBAAmB,IAAI,OAAO,UAAU;AAC7C,aAAK,cAAc;AACnB,YAAI,KAAK,mBAAoB,MAAK,mBAAmB,IAAI,OAAO,UAAU;AAC1E,mBAAW,YAAY,KAAK,iBAAiB;AAC5C,cAAI;AACH,qBAAS,MAAM;AAAA,UAChB,SAAS,OAAO;AAEf,oBAAQ,MAAM,yCAAyC,KAAK;AAAA,UAC7D;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,mBAAmB,YAA0B;AAC5C,aAAK,mBAAmB,IAAI,UAAU;AACtC,aAAK,cAAc;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,iBAAiB,UAA6C;AAC7D,aAAK,gBAAgB,IAAI,QAAQ;AACjC,cAAM,UAAU,KAAK;AACrB,aAAK,qBAAqB;AAC1B,mBAAW,cAAc,WAAW,CAAC,GAAG;AACvC,cAAI;AACH,qBAAS,EAAE,YAAY,KAAK,KAAK,CAAC;AAAA,UACnC,SAAS,OAAO;AACf,oBAAQ,MAAM,yCAAyC,KAAK;AAAA,UAC7D;AAAA,QACD;AACA,eAAO,MAAM;AACZ,eAAK,gBAAgB,OAAO,QAAQ;AAAA,QACrC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,QAAuB;AAC5B,YAAI,KAAK,mBAAmB,SAAS,EAAG;AAExC,cAAM,cAAc,IAAI,IAAI,KAAK,kBAAkB;AACnD,aAAK,mBAAmB,MAAM;AAC9B,aAAK,iBAAiB;AAEtB,cAAM,WAAW,KAAK,0BAA0B,WAAW;AAG3D,mBAAW,OAAO,UAAU;AAC3B,gBAAM,KAAK,IAAI,GAAG;AAAA,QACnB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,QAAc;AACb,aAAK,cAAc,MAAM;AACzB,aAAK,mBAAmB,MAAM;AAC9B,aAAK,iBAAiB;AACtB,aAAK,cAAc;AACnB,aAAK,aAAa;AAClB,aAAK,cAAc;AACnB,aAAK,kBAAkB;AACvB,aAAK,oBAAoB;AACzB,aAAK,iBAAiB;AACtB,aAAK,mBAAmB;AAAA,MACzB;AAAA;AAAA,MAGA,IAAI,OAAe;AAClB,eAAO,KAAK,cAAc;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,WAA8B;AAC7B,eAAO;AAAA,UACN,aAAa,KAAK;AAAA,UAClB,iBAAiB,KAAK;AAAA,UACtB,mBAAmB,KAAK;AAAA,UACxB,gBAAgB,KAAK;AAAA,UACrB,oBAAoB,KAAK,cAAc,IAAI,KAAK,mBAAmB,KAAK,cAAc;AAAA,UACtF,mBAAmB,KAAK,cAAc;AAAA,UACtC,mBAAmB,KAAK,cAAc;AAAA,QACvC;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,gBAAyB;AACxB,eAAO,KAAK,cAAc,QAAQ,KAAK;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYQ,0BAA0B,aAA0C;AAC3E,cAAM,YAAY,YAAY,IAAI;AAClC,aAAK;AAEL,cAAM,WAAW,KAAK,cAAc;AAEpC,YAAI,UAAU;AAEb,cAAI,KAAK,cAAc,KAAK,gBAAgB,MAAM;AACjD,iBAAK,mBAAmB;AAAA,UACzB;AAEA,gBAAM,SAAS,KAAK;AACpB,cAAI,WAAW,MAAM;AAEpB,gBAAI,mBAAmB;AACvB,uBAAW,OAAO,aAAa;AAC9B,kBAAI,OAAO,aAAa,GAAG,GAAG;AAC7B,mCAAmB;AACnB;AAAA,cACD;AAAA,YACD;AAEA,gBAAI,CAAC,kBAAkB;AAEtB,mBAAK;AACL,mBAAK,oBAAoB,YAAY,IAAI,IAAI;AAC7C,qBAAO,CAAC;AAAA,YACT;AAEA,iBAAK;AAAA,UACN;AAAA,QACD;AAGA,cAAM,WAA2B,CAAC;AAClC,YAAI,kBAAkB;AAEtB,mBAAW,OAAO,KAAK,cAAc,OAAO,GAAG;AAC9C,cAAI,YAAY,IAAI,IAAI,WAAW,UAAU,GAAG;AAC/C,qBAAS,KAAK,GAAG;AACjB,8BAAkB;AAAA,UACnB,WAAW,IAAI,WAAW,oBAAoB;AAE7C,uBAAW,UAAU,IAAI,WAAW,oBAAoB;AACvD,kBAAI,YAAY,IAAI,MAAM,GAAG;AAC5B,yBAAS,KAAK,GAAG;AACjB,kCAAkB;AAClB;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAGA,YAAI,YAAY,CAAC,iBAAiB;AACjC,eAAK;AAAA,QACN;AAEA,aAAK,oBAAoB,YAAY,IAAI,IAAI;AAC7C,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOQ,qBAA2B;AAClC,cAAM,SAAS,IAAI,wBAAwB,KAAK,oBAAoB,KAAK,sBAAsB;AAE/F,mBAAW,OAAO,KAAK,cAAc,OAAO,GAAG;AAE9C,iBAAO,IAAI,IAAI,WAAW,UAAU;AAGpC,cAAI,IAAI,WAAW,oBAAoB;AACtC,uBAAW,UAAU,IAAI,WAAW,oBAAoB;AACvD,qBAAO,IAAI,MAAM;AAAA,YAClB;AAAA,UACD;AAAA,QACD;AAEA,aAAK,cAAc;AACnB,aAAK,aAAa;AAAA,MACnB;AAAA,MAEQ,gBAAsB;AAC7B,YAAI,KAAK,eAAgB;AACzB,aAAK,iBAAiB;AACtB,uBAAe,MAAM;AAEpB,eAAK,KAAK,MAAM;AAAA,QACjB,CAAC;AAAA,MACF;AAAA,IACD;AAAA;AAAA;;;AC5gBA,SAAS,cAAiC;AACzC,SAAO,EAAE,YAAY,CAAC,GAAG,WAAW,CAAC,GAAG,cAAc,GAAG,iBAAiB,KAAK;AAChF;AAiBA,eAAsB,8BACrB,SACA,QACA,eACA,gBAC6B;AAC7B,MAAI,cAAc,WAAW,GAAG;AAC/B,WAAO,YAAY;AAAA,EACpB;AACA,QAAM,YAAY,IAAI,IAAI,aAAa;AAMvC,QAAM,UAAuB,CAAC;AAG9B,MAAI,uBAAsC;AAE1C,aAAW,kBAAkB,OAAO,KAAK,OAAO,WAAW,GAAG;AAC7D,UAAM,OAAO,MAAM,QAAQ;AAAA,MAC1B,qBAAiB,0BAAW,aAAa,cAAc,EAAE,CAAC;AAAA,IAC3D;AACA,eAAW,OAAO,MAAM;AACvB,UAAI,UAAU,IAAI,IAAI,EAAE,GAAG;AAC1B,gBAAQ,KAAK,mCAAmC,KAAK,cAAc,CAAC;AAAA,MACrE,WAAW,yBAAyB,QAAQ,IAAI,YAAY,sBAAsB;AACjF,+BAAuB,IAAI;AAAA,MAC5B;AAAA,IACD;AAAA,EACD;AAEA,MAAI,QAAQ,WAAW,GAAG;AACzB,WAAO,YAAY;AAAA,EACpB;AAKA,QAAM,mBACL,yBAAyB,OACtB,OAAO,oBACP,iCAAmB,YAAY,oBAAoB,EAAE;AACzD,QAAM,eAAe,KAAK,IAAI,gBAAgB,mBAAmB,CAAC;AAIlE,UAAQ,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAE3E,QAAM,gBAAgC,QAAQ,IAAI,CAAC,IAAI,OAAO;AAAA;AAAA;AAAA,IAG7D,UAAU,eAAe,KAAK,MAAM,IAAI,qBAAqB;AAAA,IAC7D,SAAS,IAAI;AAAA,IACb,QAAQ,GAAG;AAAA,EACZ,EAAE;AASF,QAAM,YAAoC,CAAC;AAC3C,QAAM,gBAA6B,CAAC;AACpC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,UAAM,KAAK,QAAQ,CAAC;AACpB,UAAM,KAAK,cAAc,CAAC;AAC1B,QAAI,CAAC,MAAM,CAAC,IAAI;AACf;AAAA,IACD;AACA,UAAM,aAAa,GAAG,WAAW,IAAI,CAAC,QAAQ,UAAU,GAAG,KAAK,GAAG;AACnE,UAAM,QAAQ,MAAM,gBAAgB,EAAE,GAAG,IAAI,WAAW,IAAI,WAAW,CAAC;AACxE,cAAU,GAAG,EAAE,IAAI;AACnB,kBAAc,KAAK,EAAE,GAAG,IAAI,IAAI,OAAO,WAAW,IAAI,WAAW,CAAC;AAAA,EACnE;AAIA,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,YAAM,QAAQ,QAAQ,CAAC;AACvB,YAAM,QAAQ,cAAc,CAAC;AAC7B,UAAI,CAAC,SAAS,CAAC,OAAO;AACrB;AAAA,MACD;AACA,YAAM,WAAW,aAAa,MAAM,UAAU;AAC9C,YAAM,GAAG,QAAQ,mBAAe,0BAAW,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;AAC/E,YAAM,WAAW;AAAA,QAChB;AAAA,QACA,mBAAmB,KAAK;AAAA,MACzB;AACA,YAAM,GAAG,QAAQ,SAAS,KAAK,SAAS,MAAM;AAK9C,YAAM,aAAa,oBAAoB,MAAM,SAAS;AACtD,YAAM,aAAa,oBAAoB,MAAM,SAAS;AACtD,YAAM,GAAG;AAAA,QACR,cAAU,0BAAW,MAAM,UAAU,CAAC;AAAA,QACtC,CAAC,YAAY,MAAM,UAAU,UAAU,MAAM,UAAU,UAAU;AAAA,MAClE;AAKA,YAAM,OAAO,MAAM,GAAG;AAAA,QACrB,mCAA+B,0BAAW,MAAM,UAAU,CAAC;AAAA,QAC3D,CAAC,MAAM,QAAQ;AAAA,MAChB;AACA,YAAM,gBAAgB,mBAAmB,KAAK,CAAC,GAAG,eAAe;AACjE,UAAI,UAAU;AACd,iBAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC7D,YAAI,YAAY,YAAY;AAC3B,wBAAc,KAAK,IAAI;AACvB,oBAAU;AAAA,QACX;AAAA,MACD;AACA,UAAI,SAAS;AACZ,cAAM,GAAG;AAAA,UACR,cAAU,0BAAW,MAAM,UAAU,CAAC;AAAA,UACtC,CAAC,uBAAuB,aAAa,GAAG,MAAM,QAAQ;AAAA,QACvD;AAAA,MACD;AAOA,UAAI,MAAM,SAAS,UAAU;AAC5B,cAAM,GAAG;AAAA,UACR,cAAU,0BAAW,MAAM,UAAU,CAAC;AAAA,UACtC,CAAC,MAAM,UAAU,UAAU,MAAM,UAAU,MAAM,UAAU,QAAQ;AAAA,QACpE;AAAA,MACD;AAAA,IACD;AAAA,EAGD,CAAC;AAED,QAAM,kBAAkB,cAAc,cAAc,SAAS,CAAC,KAAK;AAEnE,SAAO;AAAA,IACN,YAAY;AAAA,IACZ;AAAA,IACA,cAAc,cAAc;AAAA,IAC5B;AAAA,EACD;AACD;AA1MA,IAAAC,eA6BM;AA7BN;AAAA;AAAA;AAAA,IAAAA,gBAA4D;AAE5D;AACA;AACA;AACA;AAEA;AAsBA,IAAM,wBAAwB,4BAAc;AAAA;AAAA;;;ACc5C,eAAsB,8BACrB,SACA,QACA,eACA,WACA,WAC8B;AAC9B,QAAM,YAAY,IAAI,IAAI,aAAa;AACvC,QAAM,YAAoC,CAAC;AAC3C,QAAM,YAAyB,CAAC;AAIhC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,UAAM,UAAuB,CAAC;AAC9B,eAAW,kBAAkB,OAAO,KAAK,OAAO,WAAW,GAAG;AAC7D,YAAM,OAAO,MAAM,GAAG;AAAA,QACrB,qBAAiB,0BAAW,aAAa,cAAc,EAAE,CAAC;AAAA,QAC1D,CAAC,SAAS;AAAA,MACX;AACA,iBAAW,OAAO,MAAM;AACvB,YAAI,UAAU,IAAI,IAAI,EAAE,GAAG;AAC1B,kBAAQ,KAAK,mCAAmC,KAAK,cAAc,CAAC;AAAA,QACrE;AAAA,MACD;AAAA,IACD;AAEA,YAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc;AAE1D,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,YAAM,KAAK,QAAQ,CAAC;AACpB,UAAI,CAAC,GAAI;AACT,YAAM,YAAY,EAAE,GAAG,GAAG,WAAW,QAAQ,UAAU;AAIvD,YAAM,aAAa,GAAG,WAAW,IAAI,CAAC,QAAQ,UAAU,GAAG,KAAK,GAAG;AACnE,YAAM,QAAmB;AAAA,QACxB,GAAG;AAAA,QACH,QAAQ;AAAA,QACR;AAAA,QACA,gBAAgB,IAAI;AAAA,QACpB;AAAA,MACD;AACA,YAAM,KAAK,MAAM,gBAAgB,KAAK;AACtC,gBAAU,GAAG,EAAE,IAAI;AACnB,gBAAU,KAAK,EAAE,GAAG,OAAO,GAAG,CAAC;AAAA,IAChC;AAEA,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACxC,YAAM,QAAQ,QAAQ,CAAC;AACvB,YAAM,QAAQ,UAAU,CAAC;AACzB,UAAI,CAAC,SAAS,CAAC,MAAO;AACtB,YAAM,WAAW,aAAa,MAAM,UAAU;AAC9C,YAAM,GAAG,QAAQ,mBAAe,0BAAW,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;AAC/E,YAAM,SAAS;AAAA,QACd;AAAA,QACA,mBAAmB,KAAK;AAAA,MACzB;AACA,YAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAI1C,YAAM,aAAa,oBAAoB,MAAM,SAAS;AACtD,YAAM,aAAa,oBAAoB,MAAM,SAAS;AACtD,YAAM,GAAG;AAAA,QACR,cAAU,0BAAW,MAAM,UAAU,CAAC;AAAA,QACtC,CAAC,YAAY,MAAM,UAAU,UAAU;AAAA,MACxC;AACA,YAAM,OAAO,MAAM,GAAG;AAAA,QACrB,mCAA+B,0BAAW,MAAM,UAAU,CAAC;AAAA,QAC3D,CAAC,MAAM,QAAQ;AAAA,MAChB;AACA,YAAM,gBAAgB,mBAAmB,KAAK,CAAC,GAAG,eAAe;AACjE,UAAI,UAAU;AACd,iBAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC7D,YAAI,YAAY,YAAY;AAC3B,wBAAc,KAAK,IAAI;AACvB,oBAAU;AAAA,QACX;AAAA,MACD;AACA,UAAI,SAAS;AACZ,cAAM,GAAG;AAAA,UACR,cAAU,0BAAW,MAAM,UAAU,CAAC;AAAA,UACtC,CAAC,uBAAuB,aAAa,GAAG,MAAM,QAAQ;AAAA,QACvD;AAAA,MACD;AAAA,IACD;AACA,UAAM,GAAG,QAAQ,wEAAwE;AAAA,MACxF;AAAA,IACD,CAAC;AAED,UAAM,GAAG,QAAQ,wCAAwC,CAAC,mBAAmB,CAAC;AAG9E,QAAI,UAAU,SAAS,GAAG;AACzB,YAAM,GAAG;AAAA,QACR;AAAA;AAAA,QAEA,CAAC,WAAW,UAAU,MAAM;AAAA,MAC7B;AAAA,IACD;AAAA,EAMD,CAAC;AAED,SAAO,EAAE,QAAQ,WAAW,YAAY,WAAW,UAAU;AAC9D;AAzJA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA2B;AAE3B;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;;;ACRA,IAQAC,eAuGa;AA/Gb;AAAA;AAAA;AAQA,IAAAA,gBAOO;AACP;AAEA;AACA;AAMA;AASA;AACA;AA4EO,IAAM,qBAAN,MAAyB;AAAA,MACd;AAAA,MACT;AAAA,MACS,SAA0B,CAAC;AAAA,MACpC,YAAY;AAAA,MACZ,aAAa;AAAA,MACJ;AAAA,MAEjB,YAAY,QAAkC;AAC7C,aAAK,SAAS;AACd,aAAK,oBAAgB,8BAAe;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,gBAAgB,MAAoB;AACnC,aAAK,eAAe;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,kBAAsC;AACrC,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA,MAKA,WAAW,MAA6C;AACvD,cAAM,aAAa,KAAK,OAAO,OAAO,YAAY,IAAI;AACtD,YAAI,CAAC,YAAY;AAChB,gBAAM,IAAI;AAAA,YACT,uBAAuB,IAAI,iBAAiB,OAAO,KAAK,KAAK,OAAO,OAAO,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,YAClG;AAAA,YACA,EAAE,YAAY,KAAK;AAAA,UACpB;AAAA,QACD;AAEA,eAAO;AAAA,UACN,QAAQ,CAAC,SAAkC,KAAK,OAAO,MAAM,IAAI;AAAA,UACjE,QAAQ,CAAC,IAAY,SACpB,KAAK,OAAO,MAAM,YAAY,IAAI,IAAI;AAAA,UACvC,QAAQ,CAAC,OAAe,KAAK,aAAa,MAAM,YAAY,EAAE;AAAA,UAC9D,UAAU,CAAC,OAAe,KAAK,mBAAmB,MAAM,YAAY,EAAE;AAAA,QACvE;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYA,MAAM,SAAiF;AACtF,YAAI,KAAK,WAAW;AACnB,gBAAM,IAAI,wBAAU,kCAAkC,yBAAyB;AAAA,YAC9E,eAAe,KAAK;AAAA,UACrB,CAAC;AAAA,QACF;AACA,YAAI,KAAK,YAAY;AACpB,gBAAM,IAAI;AAAA,YACT;AAAA,YACA;AAAA,YACA,EAAE,eAAe,KAAK,cAAc;AAAA,UACrC;AAAA,QACD;AAEA,aAAK,YAAY;AAEjB,YAAI,KAAK,OAAO,WAAW,GAAG;AAC7B,iBAAO,EAAE,YAAY,CAAC,GAAG,qBAAqB,oBAAI,IAAI,EAAE;AAAA,QACzD;AAEA,cAAM,MAAM,KAAK,SAAS;AAC1B,cAAM,SAAS,IAAI,YAAY,KAAK,OAAO,eAAe,IAAI;AAC9D,cAAM,aAA0B,CAAC;AAEjC,YAAI;AACH,gBAAM,KAAK,OAAO,QAAQ,YAAY,OAAO,OAAO;AACnD,kBAAM,eAAe,IAAI,IAAI,QAAQ,QAAQ,OAAO,UAAU;AAC7D,yBAAW,SAAS,KAAK,QAAQ;AAChC,oBAAI;AACJ,wBAAQ,MAAM,MAAM;AAAA,kBACnB,KAAK;AACJ,6BAAS,MAAM,gBAAgB,KAAK,OAAO,MAAM,MAAM;AACvD;AAAA,kBACD,KAAK;AACJ,6BAAS,MAAM,gBAAgB,KAAK,OAAO,MAAM,YAAY,MAAM,IAAI,MAAM,IAAI;AACjF;AAAA,kBACD,KAAK;AACJ,6BAAS,MAAM,gBAAgB,KAAK,OAAO,MAAM,YAAY,MAAM,EAAE;AACrE;AAAA,gBACF;AACA,oBAAI,OAAO,UAAW,YAAW,KAAK,OAAO,SAAS;AACtD,2BAAW,KAAK,GAAG,OAAO,WAAW;AAAA,cACtC;AAAA,YACD,CAAC;AAAA,UACF,CAAC;AAAA,QACF,SAAS,OAAO;AACf,eAAK,OAAO,iBAAiB,KAAK;AAClC,gBAAM;AAAA,QACP;AAEA,eAAO,QAAQ;AACf,cAAM,sBAAsB,IAAI,IAAI,WAAW,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;AACzE,eAAO,EAAE,YAAY,oBAAoB;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA,MAKA,WAAiB;AAChB,aAAK,aAAa;AAClB,aAAK,OAAO,SAAS;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAKA,mBAA2B;AAC1B,eAAO,KAAK;AAAA,MACb;AAAA,MAEQ,WAAqB;AAC5B,eAAO;AAAA,UACN,QAAQ,KAAK,OAAO;AAAA,UACpB,OAAO,KAAK,OAAO;AAAA,UACnB,QAAQ,KAAK,OAAO;AAAA,UACpB,kBAAkB,KAAK,OAAO;AAAA,UAC9B,eAAe,KAAK;AAAA,UACpB,GAAI,KAAK,OAAO,oBACb,EAAE,mBAAmB,KAAK,OAAO,kBAAkB,IACnD,CAAC;AAAA,UACJ,GAAI,KAAK,iBAAiB,SAAY,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;AAAA,UAC7E,GAAI,KAAK,OAAO,oBACb,EAAE,mBAAmB,KAAK,OAAO,kBAAkB,IACnD,CAAC;AAAA,UACJ,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,QACtD;AAAA,MACD;AAAA,MAEQ,eAAqB;AAC5B,YAAI,KAAK,WAAW;AACnB,gBAAM,IAAI;AAAA,YACT;AAAA,YACA;AAAA,YACA,EAAE,eAAe,KAAK,cAAc;AAAA,UACrC;AAAA,QACD;AACA,YAAI,KAAK,YAAY;AACpB,gBAAM,IAAI;AAAA,YACT;AAAA,YACA;AAAA,YACA,EAAE,eAAe,KAAK,cAAc;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAAA,MAEA,MAAc,OACb,gBACA,MAC4B;AAC5B,aAAK,aAAa;AAClB,cAAM,SAAS,MAAM,cAAc,KAAK,SAAS,GAAG,gBAAgB,IAAI;AACxE,aAAK,OAAO,KAAK,EAAE,MAAM,UAAU,YAAY,gBAAgB,OAAO,CAAC;AACvE,cAAM,MAAM,KAAK,IAAI;AAGrB,cAAM,SAAS,KAAK,OAAO,OAAO,YAAY,cAAc,GAAG,UAAU,CAAC;AAC1E,eAAO;AAAA,UACN,IAAI,OAAO;AAAA,UACX,GAAG,oBAAoB,OAAO,MAAM,MAAM;AAAA,UAC1C,WAAW;AAAA,UACX,WAAW;AAAA,QACZ;AAAA,MACD;AAAA,MAEA,MAAc,OACb,gBACA,YACA,IACA,MAC4B;AAC5B,aAAK,aAAa;AAElB,cAAM,gBAAgB,MAAM,KAAK,mBAAmB,gBAAgB,YAAY,EAAE;AAClF,YAAI,CAAC,eAAe;AACnB,gBAAM,IAAI,oBAAoB,gBAAgB,EAAE;AAAA,QACjD;AAEA,cAAM,gBAAY,8BAAe,gBAAgB,YAAY,MAAM,QAAQ;AAI3E,cAAM,UAAU;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AACA,aAAK,OAAO,KAAK,EAAE,MAAM,UAAU,YAAY,gBAAgB,IAAI,MAAM,UAAU,CAAC;AAEpF,cAAM,UAAU,MAAM,KAAK,cAAc,YAAY,eAAe,OAAO;AAC3E,eAAO,EAAE,GAAG,eAAe,GAAG,SAAS,WAAW,KAAK,IAAI,EAAE;AAAA,MAC9D;AAAA,MAEA,MAAc,aACb,gBACA,YACA,IACgB;AAChB,aAAK,aAAa;AAElB,cAAM,gBAAgB,MAAM,KAAK,mBAAmB,gBAAgB,YAAY,EAAE;AAClF,YAAI,CAAC,eAAe;AACnB,gBAAM,IAAI,oBAAoB,gBAAgB,EAAE;AAAA,QACjD;AACA,aAAK,OAAO,KAAK,EAAE,MAAM,UAAU,YAAY,gBAAgB,GAAG,CAAC;AAAA,MACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,cACb,YACA,SACA,MACmC;AACnC,cAAM,WAAoC,CAAC;AAC3C,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,mBAAS,GAAG,QAAI,0BAAW,KAAK,QAAI,+BAAgB,QAAQ,GAAG,GAAG,KAAK,IAAI;AAAA,QAC5E;AACA,cAAM,SAAS,MAAM,kBAAkB,UAAU,YAAY,KAAK,OAAO,iBAAiB;AAC1F,eAAO,oBAAoB,QAAQ,WAAW,MAAM;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAc,mBACb,gBACA,YACA,IACmC;AACnC,cAAM,OAAO,MAAM,KAAK,OAAO,QAAQ;AAAA,UACtC,qBAAiB,0BAAW,cAAc,CAAC;AAAA,UAC3C,CAAC,EAAE;AAAA,QACJ;AACA,YAAI,SAAkC,KAAK,CAAC,IACzC,kBAAkB,KAAK,CAAC,GAAG,WAAW,MAAM,IAC5C;AAEH,mBAAW,SAAS,KAAK,QAAQ;AAChC,cAAI,MAAM,eAAe,eAAgB;AACzC,cAAI,MAAM,SAAS,UAAU;AAC5B,gBAAI,MAAM,OAAO,aAAa,GAAI;AAClC,kBAAM,MAAM,KAAK,IAAI;AACrB,qBAAS;AAAA,cACR;AAAA,cACA,GAAG,oBAAoB,MAAM,OAAO,MAAM,WAAW,MAAM;AAAA,cAC3D,WAAW;AAAA,cACX,WAAW;AAAA,YACZ;AAAA,UACD,WAAW,MAAM,OAAO,MAAM,MAAM,SAAS,UAAU;AACtD,gBAAI,QAAQ;AACX,kBAAI;AACJ,kBAAI;AACH,0BAAU,2BAA2B,gBAAgB,IAAI,YAAY,QAAQ,MAAM,IAAI;AAAA,cACxF,QAAQ;AAEP,0BAAU,CAAC;AAAA,cACZ;AACA,oBAAM,UAAU,MAAM,KAAK,cAAc,YAAY,QAAQ,OAAO;AACpE,uBAAS,EAAE,GAAG,QAAQ,GAAG,SAAS,WAAW,KAAK,IAAI,EAAE;AAAA,YACzD;AAAA,UACD,WAAW,MAAM,OAAO,IAAI;AAC3B,qBAAS;AAAA,UACV;AAAA,QACD;AAEA,eAAO;AAAA,MACR;AAAA,IACD;AAAA;AAAA;;;AChYA,eAAsB,kBACrB,SACA,QACgB;AAChB,QAAM,UAAU,oBAAI,IAAyB;AAC7C,aAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AACpE,YAAQ,IAAI,MAAM,IAAI,IAAI,WAAW,OAAO,CAAC;AAAA,EAC9C;AACA,aAAW,YAAY,OAAO,OAAO,OAAO,SAAS,GAAG;AACvD,YAAQ,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAAA,EAC/C;AAEA,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B;AAAA,EACD;AACA,QAAM,SAAS,IAAI,IAAI,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,IAAI,QAAQ,CAAC,CAAC;AAEtE,aAAW,CAAC,YAAY,MAAM,KAAK,SAAS;AAC3C,eAAW,SAAS,QAAQ;AAC3B,YAAM,aAAS,4CAA0B,YAAY,KAAK;AAC1D,YAAM,cAAU,sCAAoB,YAAY,KAAK;AACrD,UAAI,WAAW,QAAS;AACxB,UAAI,OAAO,IAAI,MAAM,MAAM,WAAY;AACvC,UAAI,OAAO,IAAI,OAAO,MAAM,WAAY;AACxC,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC7B,sCAAsC,UAAU,MAAM,CAAC;AAAA,MACxD;AACA,UAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,GAAG,SAAS,MAAO;AACxD,YAAM,QAAQ,QAAQ,4BAAwB,0BAAW,MAAM,CAAC,EAAE;AAAA,IACnE;AAAA,EACD;AACD;AAEA,SAAS,UAAU,OAAuB;AACzC,SAAO,IAAI,MAAM,QAAQ,MAAM,IAAI,CAAC;AACrC;AAvDA,IAAAC,eAEAC;AAFA;AAAA;AAAA;AAAA,IAAAD,gBAA2B;AAE3B,IAAAC,mBAA+D;AAAA;AAAA;;;ACsB/D,SAAS,cAAsC;AAC9C,QAAM,MAAO,WAA2D;AACxE,SAAO,KAAK,SAAS,OAAO,IAAI,MAAM,YAAY,aAAa,IAAI,QAAQ;AAC5E;AAGO,SAAS,aAAa,QAAgB,QAAwB;AACpE,SAAO,aAAa,MAAM,IAAI,MAAM;AACrC;AAMO,SAAS,gBAAgB,MAA0B;AACzD,QAAM,QAAQ,YAAY;AAC1B,MAAI,CAAC,MAAO,QAAO,MAAM;AAAA,EAAC;AAC1B,MAAI,UAAsB,MAAM;AAAA,EAAC;AACjC,MAAI,WAAW;AACf,QAAM,OAAO,IAAI,QAAc,CAAC,YAAY;AAC3C,cAAU,MAAM;AACf,iBAAW;AACX,cAAQ;AAAA,IACT;AAAA,EACD,CAAC;AACD,QACE,QAAQ,MAAM,EAAE,MAAM,YAAY,GAAG,YAAY;AACjD,QAAI,SAAU;AACd,UAAM;AAAA,EACP,CAAC,EACA,MAAM,MAAM;AAAA,EAEb,CAAC;AACF,SAAO,MAAM,QAAQ;AACtB;AAMO,SAAS,mBAAmB,MAA4C;AAC9E,QAAM,QAAQ,YAAY;AAC1B,MAAI,CAAC,MAAO,QAAO,QAAQ,QAAQ,MAAM;AAAA,EAAC,CAAC;AAC3C,SAAO,IAAI,QAAQ,CAAC,kBAAkB;AACrC,QAAI,UAAsB,MAAM;AAAA,IAAC;AACjC,UAAM,OAAO,IAAI,QAAc,CAAC,YAAY;AAC3C,gBAAU;AAAA,IACX,CAAC;AACD,UACE,QAAQ,MAAM,EAAE,MAAM,aAAa,aAAa,KAAK,GAAG,OAAO,SAAS;AACxE,UAAI,CAAC,MAAM;AACV,sBAAc,IAAI;AAClB;AAAA,MACD;AACA,oBAAc,MAAM,QAAQ,CAAC;AAC7B,YAAM;AAAA,IACP,CAAC,EACA,MAAM,MAAM,cAAc,IAAI,CAAC;AAAA,EAClC,CAAC;AACF;AAGA,eAAsB,eAAe,MAAgC;AACpE,QAAM,QAAQ,YAAY;AAC1B,MAAI,CAAC,OAAO,MAAO,QAAO;AAC1B,MAAI;AACH,UAAM,WAAW,MAAM,MAAM,MAAM;AACnC,YAAQ,SAAS,QAAQ,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI;AAAA,EAC/D,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AA/FA;AAAA;AAAA;AAAA;AAAA;;;AC4BA,eAAsB,4BACrB,SACA,QACoB;AACpB,QAAM,cAAc,OAAO,KAAK,OAAO,WAAW;AAGlD,QAAM,cAAc,CAAC,eACpB,OAAO,QAAQ,OAAO,YAAY,UAAU,GAAG,UAAU,CAAC,CAAC,EACzD,OAAO,CAAC,CAAC,EAAE,UAAU,MAAM,WAAW,SAAS,MAAM,EACrD,IAAI,CAAC,CAAC,KAAK,MAAM,KAAK;AACzB,QAAM,aAA4B,CAAC,QAAQ,QAAQ,MAA+B,GAAG;AACrF,QAAM,UAAoB,CAAC;AAC3B,aAAW,cAAc,aAAa;AACrC,UAAM,UAAU,UAAM,yCAAuB,YAAY,UAAU;AACnE,QACC,eACA,uDAAqC,SAAS,YAAY,UAAU,CAAC,EAAE,SAAS,GAC/E;AACD,cAAQ,KAAK,UAAU;AAAA,IACxB;AAAA,EACD;AACA,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAElC,QAAM,WAAW,MAAM,QAAQ,MAAgC,qBAAqB;AACpF,QAAM,gBAAgB,OAAO,SAAS,CAAC,GAAG,YAAY,MAAM;AAC5D,MAAI,cAAe,OAAM,QAAQ,QAAQ,2BAA2B;AACpE,QAAM,UAAoB,CAAC;AAC3B,MAAI;AACH,UAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,YAAM,QAAuB,CAAC,QAAQ,GAAG,MAA+B,GAAG;AAE3E,iBAAW,cAAc,SAAS;AACjC,cAAM,UAAU,UAAM,yCAAuB,OAAO,UAAU;AAC9D,YAAI,CAAC,QAAS;AACd,cAAM,iBAAa,uDAAqC,SAAS,YAAY,UAAU,CAAC;AACxF,YAAI,WAAW,WAAW,EAAG;AAC7B,mBAAW,OAAO,WAAY,OAAM,GAAG,QAAQ,GAAG;AAClD,gBAAQ,KAAK,UAAU;AAAA,MACxB;AAAA,IACD,CAAC;AAAA,EACF,UAAE;AACD,QAAI,cAAe,OAAM,QAAQ,QAAQ,0BAA0B;AAAA,EACpE;AACA,SAAO;AACR;AAzEA,IACAC;AADA;AAAA;AAAA;AACA,IAAAA,mBAIO;AAAA;AAAA;;;ACDP,SAAS,iBAAiB,QAAwB;AACjD,SAAO,iBAAiB,MAAM;AAC/B;AAKO,SAAS,iBAAiB,QAA+B;AAC/D,MAAI,OAAO,mBAAmB,aAAa;AAC1C,WAAO;AAAA,EACR;AACA,SAAO,eAAe,QAAQ,iBAAiB,MAAM,CAAC;AACvD;AAKO,SAAS,iBAAiB,QAAgB,QAAsB;AACtE,MAAI,OAAO,mBAAmB,aAAa;AAC1C;AAAA,EACD;AACA,iBAAe,QAAQ,iBAAiB,MAAM,GAAG,MAAM;AACxD;AAKO,SAAS,oBAAoB,QAAwB;AAC3D,QAAM,WAAW,iBAAiB,MAAM;AAExC,MAAI,YAAY,CAAC,SAAS,WAAW,OAAO,GAAG;AAC9C,WAAO;AAAA,EACR;AACA,QAAM,aAAS,8BAAe;AAC9B,mBAAiB,QAAQ,MAAM;AAC/B,SAAO;AACR;AAxCA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA+B;AAAA;AAAA;;;ACKxB,SAAS,kBAAkB,MAAc,OAAyB;AACxE,MAAI,iBAAiB,YAAY;AAChC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,gBAAU,OAAO,aAAa,MAAM,CAAC,CAAW;AAAA,IACjD;AACA,WAAO,EAAE,CAAC,cAAc,GAAG,KAAK,MAAM,EAAE;AAAA,EACzC;AACA,SAAO;AACR;AAKO,SAAS,iBAAiB,MAAc,OAAyB;AACvE,MACC,UAAU,QACV,OAAO,UAAU,YACjB,kBAAkB,SAClB,OAAQ,MAAkC,cAAc,MAAM,UAC7D;AACD,UAAM,UAAW,MAAkC,cAAc;AACjE,QAAI,OAAO,YAAY,UAAU;AAChC,aAAO;AAAA,IACR;AACA,UAAM,SAAS,KAAK,OAAO;AAC3B,UAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,YAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,IAC/B;AACA,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAKO,SAAS,mBAAmB,OAAwB;AAC1D,SAAO,KAAK,UAAU,OAAO,iBAAiB;AAC/C;AAKO,SAAS,qBAAwB,MAAiB;AACxD,SAAO,KAAK,MAAM,MAAM,gBAAgB;AACzC;AApDA,IAAM;AAAN;AAAA;AAAA;AAAA,IAAM,iBAAiB;AAAA;AAAA;;;ACAvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBO,SAAS,6BACf,OACsB;AACtB,SAAO;AAAA,IACN,QAAI,8BAAe;AAAA,IACnB,YAAY,KAAK,IAAI;AAAA,IACrB,WAAW,MAAM;AAAA,IACjB,YAAY,MAAM,SAAS,wBAAwB,MAAM,aAAa;AAAA,IACtE,OAAO,MAAM;AAAA,EACd;AACD;AAKA,eAAsB,iBACrB,SACA,OACgB;AAChB,QAAM,aAAa,MAAM,MAAM,WAAW;AAC1C,QAAM,WAAW,MAAM,MAAM,WAAW;AAExC,QAAM,QAAQ;AAAA,IACb;AAAA;AAAA;AAAA,IAGA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,MAAM,cAAc;AAAA,MACpB,mBAAmB,KAAK;AAAA,IACzB;AAAA,EACD;AACD;AAKA,eAAsB,gBACrB,SACA,OACiC;AACjC,QAAM,aAAuB,CAAC;AAC9B,QAAM,SAAoB,CAAC;AAE3B,MAAI,OAAO,eAAe,MAAM,YAAY,SAAS,GAAG;AACvD,UAAM,eAAe,MAAM,YAAY,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAC/D,eAAW,KAAK,kBAAkB,YAAY,GAAG;AACjD,WAAO,KAAK,GAAG,MAAM,WAAW;AAAA,EACjC;AACA,MAAI,OAAO,UAAU,QAAW;AAC/B,eAAW,KAAK,kBAAkB;AAClC,WAAO,KAAK,MAAM,KAAK;AAAA,EACxB;AACA,MAAI,OAAO,UAAU,QAAW;AAC/B,eAAW,KAAK,kBAAkB;AAClC,WAAO,KAAK,MAAM,KAAK;AAAA,EACxB;AAEA,QAAM,cAAc,WAAW,SAAS,IAAI,SAAS,WAAW,KAAK,OAAO,CAAC,KAAK;AAClF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B,oCAAoC,WAAW;AAAA,IAC/C;AAAA,EACD;AAEA,SAAO,KAAK,IAAI,mBAAmB;AACpC;AAEA,SAAS,oBAAoB,KAAyC;AACrE,SAAO,qBAA0C,IAAI,UAAU;AAChE;AAKA,eAAsB,iBAAiB,SAA0C;AAChF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,EACD;AACA,SAAO,KAAK,CAAC,GAAG,SAAS;AAC1B;AAKO,SAAS,sBAAsB,OAGpC;AACD,SAAO;AAAA,IACN,YAAY,MAAM,WAAW;AAAA,IAC7B,UAAU,MAAM,WAAW;AAAA,EAC5B;AACD;AAzHA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA+B;AAG/B;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,SAASC,eAAc,MAAc,SAAiC;AACrE,QAAM,YAAY,IAAI,YAAY,EAAE,OAAO,IAAI;AAC/C,QAAM,SAAS,IAAI,WAAW,CAAC;AAC/B,QAAM,OAAO,IAAI,SAAS,OAAO,MAAM;AACvC,OAAK,UAAU,GAAG,UAAU,QAAQ,IAAI;AACxC,OAAK,UAAU,GAAG,QAAQ,QAAQ,IAAI;AAEtC,QAAM,SAAS,IAAI,WAAW,OAAO,SAAS,UAAU,SAAS,QAAQ,MAAM;AAC/E,SAAO,IAAI,QAAQ,CAAC;AACpB,SAAO,IAAI,WAAW,CAAC;AACvB,SAAO,IAAI,SAAS,IAAI,UAAU,MAAM;AACxC,SAAO;AACR;AAEA,SAASC,mBAAkB,MAAc,MAA2B;AACnE,SAAOD,eAAc,MAAM,IAAI,YAAY,EAAE,OAAO,mBAAmB,IAAI,CAAC,CAAC;AAC9E;AAEA,SAASE,qBAAoB,MAAc,SAAgC;AAC1E,QAAM,QAAQ,GAAG,QAAQ,IAAI,CAAC,WAAW,mBAAmB,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA;AAC/E,SAAOF,eAAc,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AAC3D;AAEA,SAAS,WAAW,MAAgB,QAAwB;AAC3D,SAAO,KAAK,UAAU,QAAQ,IAAI;AACnC;AAOA,SAASG,eAAc,MAA6B;AACnD,QAAM,WAAsB,CAAC;AAC7B,QAAM,OAAO,IAAI,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AACvE,MAAI,SAAS;AAEb,SAAO,SAAS,KAAK,KAAK,YAAY;AACrC,UAAM,UAAU,WAAW,MAAM,MAAM;AACvC,UAAM,aAAa,WAAW,MAAM,SAAS,CAAC;AAC9C,cAAU;AAEV,QAAI,SAAS,UAAU,aAAa,KAAK,YAAY;AACpD;AAAA,IACD;AAEA,UAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,MAAM,QAAQ,SAAS,OAAO,CAAC;AAC1E,cAAU;AAEV,UAAM,UAAU,KAAK,MAAM,QAAQ,SAAS,UAAU;AACtD,cAAU;AAEV,aAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,EAChC;AAEA,SAAO;AACR;AAEA,SAASC,aAAY,UAAqB,MAAiC;AAC1E,aAAW,WAAW,UAAU;AAC/B,QAAI,QAAQ,SAAS,MAAM;AAC1B,aAAO,QAAQ;AAAA,IAChB;AAAA,EACD;AACA,SAAO;AACR;AAEA,eAAeC,eAAc,MAAgD;AAC5E,QAAM,aAAa,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AAC7D,SAAO,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC,EAC1C,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAChD,KAAK,EAAE;AACV;AAEA,eAAe,kBACd,SACA,QACA,kBACuB;AACvB,QAAM,cAAc,mBACjB,OAAO,KAAK,OAAO,WAAW,EAAE,OAAO,CAAC,SAAS,iBAAiB,SAAS,IAAI,CAAC,IAChF,OAAO,KAAK,OAAO,WAAW;AAEjC,QAAM,SAAsB,CAAC;AAC7B,aAAW,kBAAkB,aAAa;AACzC,UAAM,OAAO,MAAM,QAAQ;AAAA,MAC1B,qBAAiB,0BAAW,aAAa,cAAc,EAAE,CAAC;AAAA,IAC3D;AAEA,eAAW,OAAO,MAAM;AACvB,aAAO,KAAK,mCAAmC,KAAK,cAAc,CAAC;AAAA,IACpE;AAAA,EACD;AAEA,SAAO;AACR;AAEA,SAAS,8BACR,YACA,kBACc;AACd,MAAI,CAAC,oBAAoB,iBAAiB,WAAW,GAAG;AACvD,WAAO;AAAA,EACR;AACA,QAAM,UAAU,IAAI,IAAI,gBAAgB;AACxC,SAAO,WAAW,OAAO,CAAC,OAAO,QAAQ,IAAI,GAAG,UAAU,CAAC;AAC5D;AAKA,eAAsB,YACrB,SACA,QACA,QACA,eACA,SACsB;AACtB,QAAM,aAAa,SAAS,eAAe,MAAM;AAAA,EAAC;AAClD,QAAM,aAA8B;AAAA,IACnC,aAAa,SAAS;AAAA,IACtB,OAAO,SAAS;AAAA,IAChB,OAAO,SAAS;AAAA,EACjB;AAEA,aAAW,EAAE,OAAO,WAAW,UAAU,GAAG,SAAS,qBAAqB,CAAC;AAC3E,QAAM,aAAa;AAAA,IAClB,MAAM,kBAAkB,SAAS,QAAQ,SAAS,WAAW;AAAA,IAC7D,SAAS;AAAA,EACV;AAEA,aAAW,EAAE,OAAO,WAAW,UAAU,KAAK,SAAS,uBAAuB,CAAC;AAC/E,QAAM,cAAc,MAAM,gBAAgB,SAAS,UAAU;AAE7D,aAAW,EAAE,OAAO,WAAW,UAAU,KAAK,SAAS,wBAAwB,CAAC;AAChF,QAAM,WAAyB,CAAC;AAChC,MAAI,qBAAqB,IAAI,WAAW,CAAC;AAEzC,QAAM,aAAa,CAAC,YAA8B;AACjD,aAAS,KAAK,OAAO;AACrB,UAAM,WAAW,IAAI,WAAW,mBAAmB,SAAS,QAAQ,MAAM;AAC1E,aAAS,IAAI,oBAAoB,CAAC;AAClC,aAAS,IAAI,SAAS,mBAAmB,MAAM;AAC/C,yBAAqB;AAAA,EACtB;AAEA,aAAWH,qBAAoB,cAAc,UAAU,CAAC;AACxD,aAAWA,qBAAoB,gBAAgB,WAAW,CAAC;AAE3D,aAAW,EAAE,OAAO,aAAa,UAAU,KAAK,SAAS,qBAAqB,CAAC;AAC/E,QAAM,WAAW,MAAMG,eAAc,kBAA6C;AAElF,QAAM,WAAgC;AAAA,IACrC,SAAS;AAAA,IACT,YAAY,KAAK,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA,gBAAgB,WAAW;AAAA,IAC3B,iBAAiB,YAAY;AAAA,IAC7B;AAAA,EACD;AAEA,QAAM,kBAAkBJ,mBAAkB,YAAY,QAAQ;AAC9D,QAAM,kBAAkBD,eAAc,YAAY,IAAI,YAAY,EAAE,OAAO,QAAQ,CAAC;AAEpF,aAAW,EAAE,OAAO,WAAW,UAAU,GAAG,SAAS,aAAa,CAAC;AAEnE,QAAM,QAAQ,CAAC,iBAAiB,GAAG,UAAU,eAAe;AAC5D,QAAM,cAAc,IAAI,WAAW,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,QAAQ,CAAC,CAAC;AACpF,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACzB,gBAAY,IAAI,MAAM,MAAM;AAC5B,cAAU,KAAK;AAAA,EAChB;AAEA,SAAO;AACR;AAKO,SAAS,kBAAkB,MAAsC;AACvE,QAAM,WAAWG,eAAc,IAAI;AACnC,QAAM,WAAW,KAAK;AAAA,IACrB,IAAI,YAAY,EAAE,OAAOC,aAAY,UAAU,UAAU,KAAK,IAAI,WAAW,CAAC;AAAA,EAC/E;AAEA,QAAM,oBAAoBA,aAAY,UAAU,YAAY;AAC5D,QAAM,qBAAqBA,aAAY,UAAU,cAAc;AAE/D,QAAM,aAAa,mBAA8B,iBAAiB;AAClE,QAAM,cAAc,mBAAwC,kBAAkB;AAE9E,SAAO,EAAE,UAAU,YAAY,YAAY;AAC5C;AAKO,SAAS,wBAAwB,MAAuC;AAC9E,QAAM,WAAWD,eAAc,IAAI;AACnC,QAAM,kBAAkBC,aAAY,UAAU,UAAU;AACxD,MAAI,CAAC,iBAAiB;AACrB,UAAM,IAAI,MAAM,gDAAgD;AAAA,EACjE;AACA,SAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,eAAe,CAAC;AAC5D;AAKA,eAAsB,0BAA0B,MAAoC;AACnF,QAAM,WAAWD,eAAc,IAAI;AACnC,QAAM,WAAW,wBAAwB,IAAI;AAC7C,QAAM,kBAAkB,SAAS;AAAA,IAChC,CAAC,YAAY,QAAQ,SAAS,cAAc,QAAQ,SAAS;AAAA,EAC9D;AAEA,MAAI,UAAU,IAAI,WAAW,CAAC;AAC9B,aAAW,WAAW,iBAAiB;AACtC,UAAM,UAAUH,eAAc,QAAQ,MAAM,QAAQ,OAAO;AAC3D,UAAM,WAAW,IAAI,WAAW,QAAQ,SAAS,QAAQ,MAAM;AAC/D,aAAS,IAAI,SAAS,CAAC;AACvB,aAAS,IAAI,SAAS,QAAQ,MAAM;AACpC,cAAU;AAAA,EACX;AAEA,QAAM,WAAW,MAAMK,eAAc,OAAkC;AACvE,SAAO,aAAa,SAAS;AAC9B;AAEA,SAAS,mBAAsB,SAAiC;AAC/D,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACrC,WAAO,CAAC;AAAA,EACT;AACA,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,OAAO,EAAE,KAAK;AACpD,MAAI,KAAK,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACT;AACA,SAAO,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,qBAAwB,IAAI,CAAC;AACpE;AA/PA,IACAC;AADA;AAAA;AAAA;AACA,IAAAA,gBAA2B;AAC3B;AAGA;AACA;AAAA;AAAA;;;ACNA;AAAA;AAAA;AAAA;AAAA;AAwDA,eAAsB,aACrB,MACA,QACA,UACyB;AACzB,QAAM,yBAAyB,KAAK,SAAS,MAAM;AACnD,MAAI,WAAW;AACf,MAAI,UAAU;AACd,QAAM,YAAY,CAAC,WAA4B,KAAK,oBAAoB,MAAM,KAAK;AACnF,aAAW,aAAa,OAAO,YAAY;AAC1C,QAAI,CAAC,KAAK,OAAO,YAAY,UAAU,UAAU,EAAG;AAKpD,QAAI,UAAU,UAAU,MAAM,GAAG;AAChC;AACA;AAAA,IACD;AACA,QAAK,MAAM,KAAK,eAAe,SAAS,MAAO,UAAW;AAAA,EAC3D;AACA,MAAI,CAAC,YAAY,OAAO,cAAc,OAAO,GAAG;AAE/C,UAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,iBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,eAAe;AACtD,YAAI,UAAU,MAAM,EAAG;AACvB,cAAM,UAAU,IAAI,QAAQ,QAAQ;AAAA,MACrC;AAAA,IACD,CAAC;AAAA,EACF;AACA,SAAO;AAAA,IACN,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,yBAAyB;AAAA,EAC1B;AACD;AAoBA,eAAsB,eACrB,MACA,QACA,SACyB;AACzB,QAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,QAAM,UAAU,OAAO,KAAK,OAAO,WAAW,EAAE;AAAA,IAC/C,CAAC,SAAS,CAAC,QAAQ,eAAe,QAAQ,YAAY,SAAS,IAAI;AAAA,EACpE;AACA,QAAM,aAAa,OAAO,SAAS;AACnC,QAAM,aAAa,MAAM,KAAK,eAAe;AAC7C,QAAM,WAAW,IAAI,IAAI,WAAW,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC;AAC9D,QAAM,QAAQ,MAAM,iBAAiB,SAAS,UAAU;AAGxD,QAAM,OAAoB,CAAC;AAC3B,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,QAAQ,YAAY;AAC9B,UAAM,OAAO,KAAK,YAAY,QAAQ;AACtC,UAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK;AACxC,eAAW,cAAc,SAAS;AACjC,YAAM,OAAO,MAAM,QAAQ;AAAA,QAC1B,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,QACtD,CAAC,KAAK,QAAQ,KAAK;AAAA,MACpB;AACA,iBAAW,OAAO,MAAM;AACvB,YAAI,KAAM,MAAK,KAAK,mCAAmC,KAAK,UAAU,CAAC;AAAA,YAClE,SAAQ,IAAI,KAAK,MAAM;AAAA,MAC7B;AAAA,IACD;AAAA,EACD;AACA,OAAK,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAExE,QAAM,cAAc,IAAI;AAAA,IACvB,WACE,OAAO,CAAC,SAAS,CAAC,KAAK,YAAY,CAAC,QAAQ,kBAAkB,EAC9D,IAAI,CAAC,SAAS,KAAK,MAAM;AAAA,EAC5B;AAEA,QAAM,4BAA4B,OAAO;AACzC,MAAI,kBAAkB;AACtB,QAAM,eAAe,MAAM,YAAY,SAAS,mBAAmB;AACnE,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,eAAW,cAAc,SAAS;AACjC,YAAM,GAAG,QAAQ,mBAAe,0BAAW,aAAa,UAAU,EAAE,CAAC,EAAE;AACvE,YAAM,GAAG,QAAQ,mBAAe,0BAAW,UAAU,CAAC,EAAE;AACxD,YAAM,GAAG,QAAQ,4DAA4D,CAAC,UAAU,CAAC;AAGzF,YAAM,GAAG,QAAQ,eAAe,gBAAgB,yBAAyB,CAAC,UAAU,CAAC;AACrF,YAAM,GAAG,QAAQ,eAAe,eAAe,yBAAyB,CAAC,UAAU,CAAC;AACpF,YAAM,GAAG,QAAQ,eAAe,mBAAmB,yBAAyB,CAAC,UAAU,CAAC;AACxF,YAAM,GAAG,QAAQ,eAAe,qBAAqB,yBAAyB,CAAC,UAAU,CAAC;AAC1F,UAAI,cAAc;AACjB,cAAM,GAAG;AAAA,UACR,eAAe,mBAAmB;AAAA,UAClC,CAAC,UAAU;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAIA,UAAM,UAAU,MAAM,GAAG;AAAA,MACxB;AAAA,IACD;AACA,QAAI,CAAC,QAAQ,aAAa;AACzB,iBAAW,OAAO,SAAS;AAC1B,YAAI,CAAC,SAAS,IAAI,IAAI,OAAO,GAAG;AAC/B,gBAAM,GAAG,QAAQ,sDAAsD,CAAC,IAAI,OAAO,CAAC;AAAA,QACrF;AAAA,MACD;AAAA,IACD;AACA,eAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,eAAe;AACtD,UAAI,YAAY,IAAI,MAAM,EAAG;AAC7B,YAAM,UAAU,IAAI,QAAQ,QAAQ;AAAA,IACrC;AAIA,UAAM,GAAG,QAAQ,+DAA+D;AAAA,MAC/E;AAAA,MACA;AAAA,MACA,GAAG,2BAA2B;AAAA,IAC/B,CAAC;AACD,UAAM,GAAG,QAAQ,wCAAwC,CAAC,qBAAqB,CAAC;AAEhF,eAAW,SAAS,OAAO,oBAAoB;AAC9C,YAAM,GAAG;AAAA,QACR,yBAAyB,yBAAyB;AAAA,QAClD,CAAC,MAAM,aAAa,MAAM,QAAQ,MAAM,gBAAgB,MAAM,MAAM,MAAM,UAAU;AAAA,MACrF;AAAA,IACD;AAIA,eAAW,OAAO,OAAO,WAAW;AACnC,UAAI,CAAC,QAAQ,SAAS,IAAI,UAAU,EAAG;AACvC,YAAM,GAAG;AAAA,QACR,0BAA0B,eAAe;AAAA,QACzC,CAAC,IAAI,YAAY,IAAI,UAAU,IAAI,KAAK;AAAA,MACzC;AAAA,IACD;AACA,eAAW,OAAO,OAAO,eAAe;AACvC,UAAI,CAAC,QAAQ,SAAS,IAAI,UAAU,EAAG;AACvC,YAAM,GAAG;AAAA,QACR,0BAA0B,mBAAmB;AAAA,QAC7C,CAAC,IAAI,YAAY,IAAI,UAAU,IAAI,KAAK;AAAA,MACzC;AAAA,IACD;AACA,QAAI,CAAC,QAAQ,aAAa;AAEzB,YAAM,GAAG,QAAQ,eAAe,uBAAuB,EAAE;AACzD,iBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,kBAAkB;AACzD,cAAM,GAAG;AAAA,UACR,eAAe,uBAAuB;AAAA,UACtC,CAAC,QAAQ,QAAQ;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AAEA,QAAI,YAAY;AACf,iBAAW,aAAa,OAAO,YAAY;AAC1C,YAAI,CAAC,QAAQ,SAAS,UAAU,UAAU,EAAG;AAC7C,cAAM,mBAAmB,IAAI,SAAS;AAAA,MACvC;AACA,iBAAW,cAAc,SAAS;AACjC,cAAM,OAAO,OAAO,QAAQ,IAAI,UAAU,KAAK,CAAC;AAChD,YAAI,KAAK,WAAW,EAAG;AACvB,cAAM,UAAU,IAAI;AAAA,WAClB,MAAM,GAAG,MAAwB,yBAAqB,0BAAW,UAAU,CAAC,GAAG,GAAG;AAAA,YAClF,CAAC,WAAW,OAAO;AAAA,UACpB;AAAA,QACD;AACA,mBAAW,OAAO,MAAM;AACvB,gBAAM,OAAO,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,QAAQ,QAAQ,IAAI,GAAG,CAAC;AAC9D,gBAAM,GAAG;AAAA,YACR,8BAA0B,0BAAW,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,UAAM,0BAAW,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,aAAa,KAAK,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,YACzI,KAAK,IAAI,CAAC,QAAQ,WAAW,IAAI,GAAG,CAAC,CAAC;AAAA,UACvC;AACA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,WAAW,aACZ,OAAO,WAAW,OAAO,CAAC,cAAc,QAAQ,SAAS,UAAU,UAAU,CAAC,EAAE,SAChF;AACH,MAAI,CAAC,YAAY;AAEhB,eAAW,aAAa,OAAO,YAAY;AAC1C,UAAI,CAAC,QAAQ,SAAS,UAAU,UAAU,EAAG;AAC7C,UAAK,MAAM,KAAK,eAAe,SAAS,MAAO,UAAW;AAAA,IAC3D;AAAA,EACD;AACA,MAAI,qBAAqB;AACzB,aAAW,aAAa,MAAM;AAC7B,QAAK,MAAM,KAAK,eAAe,SAAS,MAAO,UAAW;AAAA,EAC3D;AAEA,QAAM,QAAQ,YAAY,OAAO,OAAO;AAEvC,eAAW,UAAU,aAAa;AACjC,YAAM,UAAU,MAAM,gBAAgB,IAAI,SAAS,MAAM;AACzD,YAAM,GAAG,QAAQ,sDAAsD,CAAC,MAAM,CAAC;AAC/E,UAAI,UAAU,GAAG;AAChB,cAAM,GAAG;AAAA,UACR;AAAA,UACA,CAAC,QAAQ,OAAO;AAAA,QACjB;AAAA,MACD;AAAA,IACD;AAEA,QAAI,QAAQ,OAAO,KAAK,CAAC,QAAQ,oBAAoB;AACpD,YAAM,QAAQ,QACZ,IAAI,CAAC,MAAM,sBAAkB,0BAAW,aAAa,CAAC,EAAE,CAAC,EAAE,EAC3D,KAAK,SAAS;AAChB,UAAI,OAAO;AACV,cAAM,GAAG,QAAQ,iDAAiD,KAAK,GAAG;AAAA,MAC3E;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO,EAAE,oBAAoB,UAAU,iBAAiB,mBAAmB;AAC5E;AAEA,eAAe,yBACd,SACA,QACgB;AAChB,MAAI,OAAO,mBAAmB,WAAW,EAAG;AAC5C,QAAM,4BAA4B,OAAO;AACzC,QAAM,QAAQ,YAAY,OAAO,OAAO;AACvC,eAAW,SAAS,OAAO,oBAAoB;AAC9C,YAAM,GAAG;AAAA,QACR,yBAAyB,yBAAyB;AAAA,QAClD,CAAC,MAAM,aAAa,MAAM,QAAQ,MAAM,gBAAgB,MAAM,MAAM,MAAM,UAAU;AAAA,MACrF;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAGA,eAAe,mBAAmB,IAAiB,WAAqC;AACvF,QAAM,YAAQ,0BAAW,aAAa,UAAU,UAAU,EAAE;AAC5D,QAAM,MAAM,mBAAmB,SAAS;AACxC,QAAM,WAAW,MAAM,GAAG,MAAsB,kBAAkB,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;AAChG,MAAI,SAAS,SAAS,EAAG;AACzB,QAAM,SAAS,MAAM,GAAG;AAAA,IACvB,kBAAkB,KAAK;AAAA,IACvB,CAAC,IAAI,SAAS,IAAI,eAAe;AAAA,EAClC;AACA,MAAI,OAAO,SAAS,GAAG;AACtB,UAAM;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,IAAI;AAAA,IACV;AACA;AAAA,EACD;AACA,QAAM,GAAG;AAAA,IACR,eAAe,KAAK;AAAA,IACpB;AAAA,MACC,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IACL;AAAA,EACD;AACD;AAEA,eAAe,UAAU,IAAiB,QAAgB,UAAiC;AAC1F,QAAM,GAAG;AAAA,IACR;AAAA;AAAA,IAEA,CAAC,QAAQ,QAAQ;AAAA,EAClB;AACD;AAEA,eAAe,gBACd,IACA,aACA,QACkB;AAClB,MAAI,UAAU;AACd,aAAW,cAAc,aAAa;AACrC,UAAM,OAAO,MAAM,GAAG;AAAA,MACrB,6CAAyC,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,MAC9E,CAAC,MAAM;AAAA,IACR;AACA,cAAU,KAAK,IAAI,SAAS,KAAK,CAAC,GAAG,KAAK,CAAC;AAAA,EAC5C;AACA,SAAO;AACR;AAMA,eAAe,iBACd,SACA,OAC+B;AAC/B,QAAM,YAAY,MAAM,0BAA0B,OAAO;AACzD,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,QAAQ,OAAO;AACzB,UAAM,SAAS,MAAM,oBAAoB,SAAS,KAAK,MAAM;AAC7D,WAAO,IAAI,KAAK,QAAQ,UAAU,UAAU,IAAI,KAAK,MAAM,KAAK,CAAC;AAAA,EAClE;AACA,SAAO;AACR;AAEA,eAAe,YAAY,SAAyB,MAAgC;AACnF,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA,CAAC,IAAI;AAAA,EACN;AACA,SAAO,KAAK,SAAS;AACtB;AAEA,SAAS,WAAW,OAAyB;AAC5C,MAAI,OAAO,UAAU,UAAW,QAAO,QAAQ,IAAI;AACnD,MAAI,iBAAiB,WAAY,QAAO;AACxC,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC5E,SAAO;AACR;AAxZA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAA+C;AAE/C;AAOA;AACA;AACA;AAKA;AACA;AAAA;AAAA;;;ACjBA;AAAA;AAAA;AAAA;AAAA;AAkOA,eAAe,uBAAuB,SAA+C;AACpF,QAAM,UAAU,oBAAI,IAAyB;AAC7C,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC5B;AAAA,IACA,CAAC,oBAAoB;AAAA,EACtB;AACA,MAAI,OAAO,WAAW,EAAG,QAAO,EAAE,SAAS,YAAY;AACvD,QAAM,OAAO,MAAM,QAAQ;AAAA,IAC1B,oCAAoC,oBAAoB;AAAA,EACzD;AACA,aAAW,OAAO,MAAM;AACvB,QAAI,WAAoB;AACxB,QAAI;AACH,iBAAY,KAAK,MAAM,IAAI,QAAQ,EAA8B;AAAA,IAClE,QAAQ;AACP,iBAAW;AAAA,IACZ;AACA,QAAI,OAAO,aAAa,YAAY,SAAS,SAAS,GAAG;AACxD,YAAM,MAAM,QAAQ,IAAI,IAAI,UAAU,KAAK,oBAAI,IAAY;AAC3D,UAAI,IAAI,QAAQ;AAChB,cAAQ,IAAI,IAAI,YAAY,GAAG;AAAA,IAChC,OAAO;AACN,kBAAY,IAAI,IAAI,UAAU;AAAA,IAC/B;AAAA,EACD;AACA,SAAO,EAAE,SAAS,YAAY;AAC/B;AAGA,eAAe,gCACd,SACA,QACoB;AACpB,QAAM,MAAgB,CAAC;AACvB,aAAW,cAAc,OAAO,KAAK,OAAO,WAAW,GAAG;AACzD,UAAM,OAAO,MAAM,QAAQ;AAAA,MAC1B,qBAAqB,gBAAgB;AAAA,MACrC,CAAC,UAAU;AAAA,IACZ;AACA,eAAW,OAAO,MAAM;AACvB,UAAI;AACJ,UAAI;AACH,oBAAQ,oCAAqB,IAAI,KAAK;AAAA,MACvC,QAAQ;AACP;AAAA,MACD;AACA,cAAI,oCAAqB,OAAO,MAAM,EAAE,SAAS,GAAG;AACnD,YAAI,KAAK,UAAU;AACnB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAOA,eAAe,mBAAmB,IAAiB,QAA+B;AACjF,QAAM,OAAO,MAAM,GAAG,MAAe,oDAAoD;AACzF,QAAM,WAAW,KAAK,CAAC,GAAG;AAC1B,MAAI,aAAa,OAAQ;AACzB,QAAM,SAAS,MAAM,GAAG,MAAe,8CAA8C;AAAA,IACpF;AAAA,EACD,CAAC;AACD,MAAI,OAAO,CAAC,KAAK,UAAU;AAC1B,UAAM,GAAG,QAAQ,+DAA+D;AAAA,MAC/E,aAAa,QAAQ;AAAA,MACrB,OAAO,CAAC,EAAE;AAAA,IACX,CAAC;AAAA,EACF;AACA,QAAM,GAAG,QAAQ,wCAAwC,CAAC,mBAAmB,CAAC;AAC9E,QAAM,GAAG,QAAQ,wEAAwE,CAAC,MAAM,CAAC;AAClG;AA06FA,SAAS,mBAAmB,IAA6B;AACxD,MAAI,SAAS,GAAG;AAChB,aAAW,WAAW,OAAO,OAAO,GAAG,iBAAiB,CAAC,CAAC,GAAG;AAC5D,QAAI,iCAAmB,QAAQ,SAAS,MAAM,IAAI,EAAG,UAAS;AAAA,EAC/D;AACA,SAAO;AACR;AA9tGA,IAAAC,eAyMM,oBAEA,0BAKA,qBAGO,qBAyGA;AA5Tb;AAAA;AAAA;AAAA,IAAAA,gBAiBO;AAaP;AAEA;AACA;AAEA;AACA;AACA;AACA;AAUA;AAKA;AAKA;AAQA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AAEA;AACA;AAMA;AACA;AAIA;AAsBA;AACA;AAGA;AAEA;AASA;AAsBA;AAgBA;AACA;AACA;AACA;AACA;AAOA;AACA;AAiBA,IAAM,qBAAqB;AAE3B,IAAM,2BAA2B;AAKjC,IAAM,sBAAsB;AAGrB,IAAM,sBAAN,cAAkC,wBAAU;AAAA,MAClD,YAAY,QAAgB,QAAgB;AAC3C;AAAA,UACC,YAAY,MAAM,MAAM,MAAM;AAAA,UAC9B;AAAA,UACA,EAAE,QAAQ,QAAQ,KAAK,wDAAwD;AAAA,QAChF;AACA,aAAK,OAAO;AAAA,MACb;AAAA,IACD;AAgGO,IAAM,QAAN,MAAoC;AAAA,MAClC,SAAS;AAAA,MACT,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,oBAA+B,mCAAoB;AAAA,MACnD,QAAmC;AAAA,MACnC,cAAc,oBAAI,IAAwB;AAAA,MAC1C;AAAA,MACA,kBAA0C;AAAA,MAEjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACT;AAAA,MACA,mBAA4C;AAAA,MAC5C,gBAAsC;AAAA,MAC7B;AAAA;AAAA,MAET,kBAAuC;AAAA;AAAA,MAE9B;AAAA;AAAA,MAEA;AAAA;AAAA,MAET,aAAa;AAAA;AAAA,MAEJ;AAAA;AAAA,MAEA;AAAA,MAEjB,YAAY,QAAqB;AAChC,aAAK,kBAAkB,OAAO,mBAAmB;AACjD,aAAK,sBAAsB,OAAO,uBAAuB,CAAC;AAC1D,aAAK,oBAAoB,OAAO;AAChC,aAAK,SACJ,KAAK,oBAAoB,SACtB,IAAI,aAAa,OAAO,QAAQ,KAAK,mBAAmB,IACxD;AACJ,aAAK,SAAS,OAAO;AACrB,aAAK,UAAU,OAAO;AACtB,aAAK,eAAe,OAAO;AAC3B,aAAK,SAAS,OAAO,UAAU;AAC/B,aAAK,YAAY,OAAO,aAAa;AACrC,aAAK,UAAU,OAAO,WAAW;AACjC,aAAK,uBAAuB,OAAO,wBAAwB;AAC3D,aAAK,oBAAoB,OAAO;AAChC,aAAK,sBAAsB,IAAI,oBAAoB;AAAA,UAClD,mBAAmB,OAAO;AAAA;AAAA,UAE1B,cAAc,CAAC,YAAY;AAC1B,kBAAM,OACL,QAAQ,iBAAiB,0BAAY,QAAQ,MAAM,OAAO,QAAQ,MAAM,QAAQ;AACjF,iBAAK,SAAS,KAAK;AAAA,cAClB,MAAM;AAAA,cACN,SAAS,QAAQ;AAAA,cACjB,YAAY,QAAQ;AAAA,cACpB,OAAO,QAAQ;AAAA,cACf;AAAA,cACA,SAAS,QAAQ,MAAM;AAAA,YACxB,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,OAAsB;AAC3B,YAAI;AACH,gBAAM,KAAK,QAAQ,KAAK,KAAK,MAAM;AAAA,QACpC,SAAS,OAAO;AACf,gBAAM,QACL,iBAAiB,0BACd,EAAE,QAAQ,MAAM,eAAe,MAAM,MAAM,YAAY,IACvD,iBAAiB,KAAK;AAC1B,cAAI,UAAU,KAAM,OAAM,KAAK,YAAY,MAAM,MAAM;AACvD,gBAAM;AAAA,QACP;AAIA,cAAM,SAAS;AAAA,UACd,MAAM,KAAK,QAAQ,MAA0B,yBAAyB;AAAA,QACvE;AACA,YAAI,SAAS,KAAK,OAAO,SAAS;AACjC,gBAAM,KAAK,QAAQ,MAAM,EAAE,MAAM,MAAM,MAAS;AAChD,gBAAM,KAAK,YAAY,MAAM;AAAA,QAC9B;AACA,cAAM,KAAK,QAAQ;AAAA,UAClB;AAAA,QACD;AACA,mBAAW,OAAO,gBAAiB,OAAM,KAAK,QAAQ,QAAQ,GAAG;AACjE,aAAK,aAAa;AAKlB,cAAM,4BAA4B,KAAK,SAAS,KAAK,MAAM;AAE3D,cAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;AAGjD,aAAK,SAAS,MAAM,KAAK,qBAAqB;AAE9C,cAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;AAIjD,cAAM,KAAK,QAAQ,OAAO;AAI1B,cAAM,yBAAyB,KAAK,SAAS,KAAK,QAAQ,KAAK,MAAM;AAGrE,cAAM,2BAA2B,KAAK,OAAO;AAG7C,cAAM,sBAAsB,KAAK,SAAS,KAAK,MAAM;AACrD,YAAI,KAAK,cAAc,aAAa,CAAC,KAAK,cAAc;AAGvD,eAAK,kBAAkB,gBAAgB,aAAa,KAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,QAC9E;AACA,aAAK,QAAQ,IAAI,iCAAmB,KAAK,MAAM;AAC/C,aAAK,gBAAgB,IAAI,4BAAc;AAKvC,YAAI,KAAK,QAAQ;AAChB,eAAK,OAAO,wBAAyB,MAAM,yBAAyB,KAAK,OAAO,KAAM,CAAC,CAAC;AACxF,eAAK,aACH,MAAM,KAAK,SAAS,6BAA6B,MAAO;AAAA,QAC3D;AAIA,YAAI;AAGH,gBAAM,KAAK,wBAAwB;AACnC,gBAAM,KAAK,sBAAsB;AACjC,gBAAM,KAAK,4BAA4B;AACvC,gBAAM,KAAK,sBAAsB;AAAA,QAClC,SAAS,OAAO;AACf,eAAK,kBAAkB;AACvB,eAAK,kBAAkB;AACvB,gBAAM;AAAA,QACP;AAGA,aAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS,KAAK,MAAM;AAGpE,aAAK,iBAAiB,MAAM,KAAK,mBAAmB;AACpD,aAAK,gBAAgB,MAAM,KAAK,kBAAkB;AAKlD,cAAM,eAAe,OAAO,KAAK,KAAK,OAAO,SAAS,EAAE,SAAS;AACjE,aAAK,mBAAmB,eAAe,IAAI,iBAAiB,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI;AAGvF,mBAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,WAAW,GAAG;AACzE,gBAAM,MAAM,IAAI;AAAA,YACf;AAAA,YACA;AAAA,YACA,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,CAAC,gBAAgB,cAAc,KAAK,sBAAsB,gBAAgB,SAAS;AAAA,YACnF,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,CAAC,UAAU,KAAK,mBAAmB,KAAK;AAAA,YACxC,MAAM,KAAK,WAAW;AAAA,YACtB,KAAK;AAAA,UACN;AACA,eAAK,YAAY,IAAI,MAAM,GAAG;AAAA,QAC/B;AAEA,aAAK,SAAS;AAAA,MACf;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAAuB;AAC5B,aAAK,oBAAoB,MAAM;AAC/B,aAAK,YAAY,MAAM;AACvB,aAAK,SAAS;AACd,YAAI;AACH,gBAAM,KAAK,QAAQ,MAAM;AAAA,QAC1B,UAAE;AACD,eAAK,kBAAkB;AACvB,eAAK,kBAAkB;AAAA,QACxB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,MAAM,mBAAmB,SAGO;AAC/B,aAAK,WAAW;AAChB,eAAO,KAAK,QAAQ,SAAS,QAAQ,QAAQ,SAAS,UAAU,IAAI;AAAA,MACrE;AAAA,MAEA,MAAc,QAAQ,MAAwB,SAAS,MAAmC;AACzF,cAAM,gBAAgB,MAAM,eAAe,KAAK,OAAO,GAAG,IAAI,CAAC,SAAS,KAAK,MAAM;AACnF,cAAM,SAAS,MAAM,iBAAiB,KAAK,SAAS,KAAK,QAAQ;AAAA,UAChE;AAAA,UACA;AAAA,UACA;AAAA,QACD,CAAC;AACD,YAAI,WAAW,OAAO,SAAS,SAAS,KAAK,OAAO,iBAAiB,SAAS,IAAI;AACjF,eAAK,SAAS,KAAK;AAAA,YAClB,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,UAAU,OAAO,SAAS;AAAA,YAC1B,aAAa,OAAO,iBAAiB;AAAA,YACrC,MAAM,OAAO,KAAK;AAAA,YAClB,OAAO,OAAO;AAAA,YACd,SAAS,qBAAqB,KAAK,MAAM,MAAM,OAAO,SAAS,MAAM,qBAAqB,OAAO,iBAAiB,MAAM,wBAAwB,oBAAoB;AAAA,UACrK,CAAC;AAAA,QACF;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,WAAW,MAAkC;AAC5C,aAAK,WAAW;AAChB,cAAM,MAAM,KAAK,YAAY,IAAI,IAAI;AACrC,YAAI,CAAC,KAAK;AACT,gBAAM,IAAI;AAAA,YACT,uBAAuB,IAAI,iBAAiB,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,UACpF;AAAA,QACD;AAEA,cAAM,aAAa,KAAK,OAAO,YAAY,IAAI;AAC/C,YAAI,CAAC,YAAY;AAChB,gBAAM,IAAI,MAAM,wCAAwC,IAAI,GAAG;AAAA,QAChE;AAEA,eAAO;AAAA,UACN,QAAQ,CAAC,SAAkC,IAAI,OAAO,IAAI;AAAA,UAC1D,UAAU,CAAC,OAAe,IAAI,SAAS,EAAE;AAAA,UACzC,QAAQ,CAAC,IAAY,SAAkC,IAAI,OAAO,IAAI,IAAI;AAAA,UAC1E,QAAQ,CAAC,OAAe,IAAI,OAAO,EAAE;AAAA,UACrC,OAAO,CAAC,eACP,IAAI;AAAA,YACH;AAAA,YACA;AAAA,YACA,KAAK;AAAA,YACL,KAAK;AAAA,YACL;AAAA,YACA,KAAK;AAAA,UACN;AAAA,QACF;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,mBAAkC;AACjC,aAAK,WAAW;AAChB,eAAO,IAAI,IAAI,KAAK,aAAa;AAAA,MAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,wBAAwB,UAAwB;AAC/C,aAAK,OAAO,mBAAmB,QAAQ;AAAA,MACxC;AAAA,MAEA,YAAoB;AACnB,aAAK,WAAW;AAChB,eAAO,KAAK;AAAA,MACb;AAAA;AAAA,MAGA,yBAAwD;AACvD,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,qBACL,QACA,SACuB;AACvB,aAAK,WAAW;AAEhB,cAAM,aAAa,OAAO;AAC1B,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU;AACrD,YAAI,CAAC,YAAY;AAChB,iBAAO;AAAA,QACR;AACA,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,MAAM;AAET,iBAAO,KAAK,kBAAkB,QAAQ,MAAM,OAAO;AAAA,QACpD;AAGA,cAAM,WAAO,mCAAoB,QAAQ,KAAK,OAAO,SAAS,KAAK,mBAAmB;AACtF,YAAI,SAAS,KAAM,QAAO;AAC1B,cAAM,KAAK;AAMX,cAAM,uBAAuB,SAAS,wBAAwB,GAAG;AACjE,cAAM,gBAAgB,oBAAoB,oBAAoB;AAC9D,cAAM,WAAW,qBAAqB;AACtC,cAAM,oBAAoB,SAAS,mBAAmB,GAAG;AAEzD,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,UAAU,EAAE,WAAW,OAAO,SAAS,MAAM;AAGnD,YAAI;AACH,gBAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAI5C,gBAAI,MAAM,kBAAkB,IAAI,YAAY,GAAG,EAAE,GAAG;AACnD,sBAAQ,YAAY;AACpB,oBAAM,YAAY,MAAM,GAAG;AAAA,gBAC1B;AAAA,gBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,cACzB;AACA,kBAAI,UAAU,SAAS,GAAG;AACzB,sBAAM,GAAG,QAAQ,cAAU,0BAAW,UAAU,CAAC,kCAAkC;AAAA,kBAClF,GAAG;AAAA,gBACJ,CAAC;AACD,sBAAM,GAAG;AAAA,kBACR;AAAA,kBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,gBACzB;AACA,wBAAQ,UAAU;AAAA,cACnB;AACA;AAAA,YACD;AAGA,gBAAI,KAAK,OAAO;AAGf,mBAAK,MAAM,QAAQ,GAAG,gBAAgB,mBAAmB,EAAE,IAAI,GAAG,SAAS;AAAA,YAC5E;AAMA,kBAAM,aAAa,CAAC,QAA4C;AAC/D,oBAAM,QAAQ,SAAS;AACvB,kBAAI,CAAC,OAAO;AACX;AAAA,cACD;AACA,oBAAM,UAAU,OAAO,KAAK,aAAa,WAAW,IAAI,WAAW;AACnE,oBAAM,gBACL,OAAO,KAAK,oBAAoB,WAAW,IAAI,kBAAkB;AAClE,kBAAI,YAAY,MAAM,WAAW,kBAAkB,MAAM,eAAe;AACvE,sBAAM,IAAI,oBAAoB,YAAY,GAAG,QAAQ;AAAA,cACtD;AAAA,YACD;AAEA,gBAAI,SAAS,SAAS;AAAA,YAItB,WACC,GAAG,SAAS,YACZ,GAAG,QACH,GAAG,iBACH,CAAC,SAAS,mBACV,CAAC,SAAS,oBACV,CAAC,SAAS,sBACT;AAED,oBAAM,KAAK,0BAA0B,IAAI,IAAI,YAAY,GAAG,MAAM,UAAU;AAAA,YAC7E,WAAW,GAAG,SAAS,YAAY,mBAAmB;AACrD,oBAAM,iBAAiB,gBAAgB,mBAAmB,WAAW,MAAM;AAC3E,oBAAM,WAAW,MAAM,GAAG;AAAA,gBACzB,gEAAgE,UAAU;AAAA,gBAC1E,CAAC,GAAG,QAAQ;AAAA,cACb;AACA,oBAAM,MAAM,SAAS,CAAC;AACtB,yBAAW,GAAG;AAEd,kBAAI,CAAC,KAAK;AACT,sBAAM,SAAkC;AAAA,kBACvC,IAAI,GAAG;AAAA,kBACP,GAAG;AAAA,kBACH,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,UAAU;AAAA;AAAA,kBAEV,iBAAiB;AAAA,oBAChB,uBAAuB,OAAO,KAAK,cAAc,GAAG,aAAa;AAAA,kBAClE;AAAA,gBACD;AACA,sBAAM,cAAc,iBAAiB,YAAY,MAAM;AACvD,sBAAM,GAAG,QAAQ,YAAY,KAAK,YAAY,MAAM;AAQpD,sBAAM,KAAK,uBAAuB,IAAI,YAAY,YAAY,GAAG,UAAU,EAAE;AAAA,cAC9E,WACC,IAAI,aAAa,MAEhB,MAAM,GAAG;AAAA,gBACR;AAAA,gBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,cACzB,GACC,SAAS,GACV;AAMD,sBAAM,EAAE,SAAS,OAAO,IAAI;AAAA,kBAC3B,mBAAmB,IAAI,eAAe;AAAA,kBACtC,OAAO,KAAK,cAAc;AAAA,kBAC1B;AAAA,kBACA,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AAAA,gBACnD;AACA,sBAAM,eAAwC;AAAA,kBAC7C,UAAU;AAAA,kBACV,iBAAiB,uBAAuB,MAAM;AAAA,gBAC/C;AACA,2BAAW,SAAS,SAAS;AAC5B,+BAAa,KAAK,IAAI,eAAe,KAAK;AAAA,gBAC3C;AAGA,sBAAM,aAAa;AAAA,kBAClB;AAAA,kBACA,GAAG;AAAA,kBACH;AAAA,kBACA;AAAA,kBACA;AAAA,gBACD;AACA,sBAAM,GAAG,QAAQ,WAAW,KAAK,WAAW,MAAM;AAClD,sBAAM,GAAG;AAAA,kBACR;AAAA,kBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,gBACzB;AAAA,cACD,WAAW,IAAI,aAAa,GAAG;AAG9B,oBAAI,uBAAuB,sBAAsB,GAAG,GAAG;AACtD,wBAAM,eAAwC;AAAA,oBAC7C,GAAG;AAAA,oBACH,UAAU;AAAA,oBACV,iBAAiB;AAAA,sBAChB,uBAAuB,OAAO,KAAK,cAAc,GAAG,aAAa;AAAA,oBAClE;AAAA,kBACD;AACA,wBAAM,SAAS;AAAA,oBACd;AAAA,oBACA,GAAG;AAAA,oBACH;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA,EAAE,cAAc,SAAS;AAAA,kBAC1B;AACA,wBAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAAA,gBAC3C;AAAA,cACD,OAAO;AAON,sBAAM,kBAAkB,mBAAmB,IAAI,eAAe;AAC9D,sBAAMC,cAAa,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AACrE,sBAAM,eAAwC,CAAC;AAC/C,oBAAI;AACJ,oBAAI,SAAS,kBAAkB;AAE9B,wBAAM,SAAS,EAAE,GAAG,gBAAgB;AACpC,6BAAW,SAAS,OAAO,KAAK,cAAc,GAAG;AAChD,iCAAa,KAAK,IAAI,eAAe,KAAK;AAC1C,2BAAO,KAAK,IAAI;AAAA,kBACjB;AACA,sCAAoB,uBAAuB,MAAM;AAAA,gBAClD,OAAO;AACN,wBAAM,EAAE,SAAS,OAAO,IAAI;AAAA,oBAC3B;AAAA,oBACA,OAAO,KAAK,cAAc;AAAA,oBAC1B;AAAA,oBACAA;AAAA,kBACD;AACA,6BAAW,SAAS,SAAS;AAC5B,iCAAa,KAAK,IAAI,eAAe,KAAK;AAAA,kBAC3C;AACA,sCAAoB,uBAAuB,MAAM;AAAA,gBAClD;AACA,sBAAM,SAAS;AAAA,kBACd;AAAA,kBACA,GAAG;AAAA,kBACH,EAAE,GAAG,cAAc,iBAAiB,kBAAkB;AAAA,kBACtD;AAAA,kBACA;AAAA,kBACA,EAAE,cAAc,SAAS;AAAA,gBAC1B;AACA,sBAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAAA,cAC3C;AAAA,YACD,WAAW,GAAG,SAAS,YAAY,mBAAmB;AACrD,oBAAM,oBAAoB,gBAAgB,mBAAmB,WAAW,MAAM;AAC9E,oBAAM,gBAAgB,OAAO,KAAK,iBAAiB;AAMnD,oBAAM,cAAc,MAAM,GAAG;AAAA,gBAC5B,6CAAyC,0BAAW,UAAU,CAAC;AAAA,gBAC/D,CAAC,GAAG,QAAQ;AAAA,cACb;AACA,oBAAM,aAAa,YAAY,CAAC;AAChC,yBAAW,UAAU;AAErB,kBAAI,YAAY;AACf,sBAAM,kBAAkB,mBAAmB,WAAW,eAAe;AACrE,sBAAMA,cACL,OAAO,WAAW,aAAa,WAAW,WAAW,WAAW;AAEjE,oBAAI,SAAS,kBAAkB;AAK9B,wBAAM,SAAS,EAAE,GAAG,gBAAgB;AACpC,6BAAW,SAAS,eAAe;AAClC,2BAAO,KAAK,IAAI;AAAA,kBACjB;AACA,wBAAM,eAAwC;AAAA,oBAC7C,GAAG;AAAA,oBACH,iBAAiB,uBAAuB,MAAM;AAAA,kBAC/C;AACA,sBAAI,SAAS,qBAAqB;AACjC,iCAAa,WAAW;AAAA,kBACzB;AACA,wBAAM,aAAa;AAAA,oBAClB;AAAA,oBACA,GAAG;AAAA,oBACH;AAAA,oBACA;AAAA,oBACA;AAAA,kBACD;AACA,wBAAM,GAAG,QAAQ,WAAW,KAAK,WAAW,MAAM;AAAA,gBACnD,OAAO;AAIN,wBAAM,EAAE,SAAS,OAAO,IAAI;AAAA,oBAC3B;AAAA,oBACA;AAAA,oBACA;AAAA,oBACAA;AAAA,kBACD;AACA,sBAAI,QAAQ,SAAS,KAAK,SAAS,qBAAqB;AACvD,0BAAM,iBAA0C;AAAA,sBAC/C,iBAAiB,uBAAuB,MAAM;AAAA,oBAC/C;AACA,+BAAW,SAAS,SAAS;AAC5B,qCAAe,KAAK,IAAI,kBAAkB,KAAK;AAAA,oBAChD;AACA,wBAAI,SAAS,qBAAqB;AACjC,qCAAe,WAAW;AAAA,oBAC3B;AACA,0BAAM,aAAa;AAAA,sBAClB;AAAA,sBACA,GAAG;AAAA,sBACH;AAAA,sBACA;AAAA,sBACA;AAAA,oBACD;AACA,0BAAM,GAAG,QAAQ,WAAW,KAAK,WAAW,MAAM;AAAA,kBACnD;AAAA,gBACD;AAAA,cACD;AAAA,YAID,WAAW,GAAG,SAAS,UAAU;AAChC,oBAAM,cAAc;AAAA,gBACnB;AAAA,gBACA,GAAG;AAAA,gBACH;AAAA,gBACA;AAAA,cACD;AACA,oBAAM,GAAG,QAAQ,YAAY,KAAK,YAAY,MAAM;AAAA,YACrD;AAGA,kBAAM,KAAK,yBAAyB,IAAI,MAAM;AAK9C,kBAAM,GAAG;AAAA,cACR;AAAA;AAAA,cAEA,CAAC,GAAG,QAAQ,GAAG,cAAc;AAAA,YAC9B;AAAA,UACD,CAAC;AAAA,QACF,SAAS,OAAO;AACf,eAAK,mBAAmB,KAAK;AAC7B,gBAAM;AAAA,QACP;AAKA,aAAK,wBAAwB,EAAE;AAC/B,YAAI,QAAQ,WAAW;AACtB,cAAI,QAAQ,SAAS;AACpB,iBAAK,oBAAoB,WAAW,UAAU;AAAA,UAC/C,OAAO;AACN,iBAAK,oBAAoB,OAAO,YAAY,EAAE;AAAA,UAC/C;AACA,iBAAO;AAAA,QACR;AAEA,aAAK,oBAAoB,OAAO,YAAY,EAAE;AAC9C,aAAK,SAAS,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,WAAW;AAAA,UACX,UAAU,KAAK,IAAI,IAAI;AAAA,QACxB,CAAC;AAED,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAc,kBACb,IACA,MACA,SACuB;AACvB,cAAM,aAAa,GAAG;AACtB,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,UAAU,EAAE,WAAW,OAAO,SAAS,OAAO,QAAQ,CAAC,EAAkB;AAC/E,YAAI;AACH,gBAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,gBAAK,MAAM,kBAAkB,IAAI,YAAY,GAAG,EAAE,KAAO,MAAM,YAAY,IAAI,EAAE,GAAI;AACpF,sBAAQ,YAAY;AACpB,oBAAM,YAAY,MAAM,GAAG;AAAA,gBAC1B;AAAA,gBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,cACzB;AACA,kBAAI,UAAU,SAAS,GAAG;AAGzB,sBAAM,QAAQ,MAAM,KAAK,UAAU,IAAI,YAAY,GAAG,QAAQ;AAC9D,oBAAI,OAAO;AACV,wBAAM,KAAK,eAAe,IAAI,OAAO,OAAO,EAAE,iBAAiB,KAAK,CAAC;AAAA,gBACtE,OAAO;AACN,wBAAM,GAAG;AAAA,oBACR;AAAA,oBACA,CAAC,YAAY,GAAG,QAAQ;AAAA,kBACzB;AAAA,gBACD;AACA,wBAAQ,UAAU;AAAA,cACnB;AACA;AAAA,YACD;AACA,gBAAI,KAAK,OAAO;AAGf,mBAAK,MAAM,QAAQ,GAAG,gBAAgB,mBAAmB,EAAE,IAAI,GAAG,SAAS;AAAA,YAC5E;AACA,kBAAM,KAAK,yBAAyB,IAAI,EAAE;AAC1C,kBAAM,UAAU,MAAM,KAAK,UAAU,IAAI,IAAI,QAAQ;AACrD,oBAAQ,SAAS,QAAQ;AACzB,kBAAM,GAAG;AAAA,cACR;AAAA;AAAA,cAEA,CAAC,GAAG,QAAQ,GAAG,cAAc;AAAA,YAC9B;AAAA,UACD,CAAC;AAAA,QACF,SAAS,OAAO;AACf,eAAK,mBAAmB,KAAK;AAC7B,gBAAM;AAAA,QACP;AAEA,aAAK,wBAAwB,EAAE;AAC/B,YAAI,QAAQ,WAAW;AACtB,cAAI,QAAQ,SAAS;AACpB,iBAAK,oBAAoB,WAAW,UAAU;AAAA,UAC/C,OAAO;AACN,iBAAK,oBAAoB,OAAO,YAAY,EAAE;AAAA,UAC/C;AACA,iBAAO;AAAA,QACR;AACA,aAAK,oBAAoB,OAAO,YAAY,EAAE;AAC9C,aAAK,gBAAgB,IAAI,QAAQ,MAAM;AACvC,iBAAS,gBAAgB,QAAQ,MAAM;AACvC,aAAK,SAAS,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,WAAW;AAAA,UACX,UAAU,KAAK,IAAI,IAAI;AAAA,QACxB,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA,MAGQ,gBAAgB,IAAe,QAA4B;AAClE,YAAI,CAAC,KAAK,WAAW,OAAO,WAAW,EAAG;AAC1C,cAAM,QAAQ,OAAO,CAAC;AACtB,aAAK,QAAQ,KAAK,EAAE,MAAM,iBAAiB,YAAY,MAAM,YAAY,YAAY,GAAG,CAAC;AACzF,mBAAW,SAAS,OAAQ,MAAK,QAAQ,KAAK,EAAE,MAAM,kBAAkB,MAAM,CAAC;AAC/E,aAAK,QAAQ,KAAK,EAAE,MAAM,mBAAmB,OAAO,MAAM,CAAC;AAAA,MAC5D;AAAA;AAAA,MAGQ,aAAuC;AAC9C,eAAO,KAAK,cAAc,KAAK,SAAS,KAAK,SAAS;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,aAAa,YAAoB,UAA6C;AACnF,aAAK,WAAW;AAChB,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,CAAC,KAAM,QAAO;AAClB,YAAI,QAA0B;AAC9B,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,kBAAQ,MAAM,KAAK,UAAU,IAAI,YAAY,QAAQ;AAAA,QACtD,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,qBAA8B;AAC7B,eAAO,KAAK,WAAW,MAAM;AAAA,MAC9B;AAAA,MAEA,MAAc,SAAS,KAAqC;AAC3D,cAAM,OAAO,MAAM,KAAK,QAAQ,MAAe,8CAA8C;AAAA,UAC5F;AAAA,QACD,CAAC;AACD,eAAO,KAAK,CAAC,GAAG,SAAS;AAAA,MAC1B;AAAA,MAEA,MAAc,UAAU,KAAa,OAA8B;AAClE,cAAM,KAAK,QAAQ,QAAQ,gEAAgE;AAAA,UAC1F;AAAA,UACA;AAAA,QACD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,8BAA6C;AAC1D,cAAM,SAAS,KAAK;AACpB,YAAI,CAAC,OAAQ;AACb,YAAK,MAAM,KAAK,SAAS,sBAAsB,MAAO,KAAM;AAC5D,cAAM,YAAY,MAAM,4BAA4B,KAAK,SAAS,KAAK,QAAQ,KAAK,MAAM;AAC1F,YAAI,UAAU,SAAS,KAAK,KAAK,YAAY;AAC5C,gBAAM,OAAO,oBAAI,IAAY;AAC7B,gBAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,uBAAW,EAAE,YAAY,SAAS,KAAK,WAAW;AACjD,oBAAM,MAAM,GAAG,UAAU,KAAS,QAAQ;AAC1C,kBAAI,KAAK,IAAI,GAAG,EAAG;AACnB,mBAAK,IAAI,GAAG;AACZ,oBAAM,OAAO,WAAW,IAAI,YAAY,QAAQ;AAAA,YACjD;AAAA,UACD,CAAC;AAAA,QACF;AACA,cAAM,KAAK,UAAU,wBAAwB,OAAO,UAAU,MAAM,CAAC;AAAA,MACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,MAAc,sBAAsB,gBAAgB,OAAsB;AACzE,cAAM,UAAU,MAAM,KAAK,SAAS,6BAA6B;AACjE,YAAI,CAAC,KAAK,QAAQ;AACjB,cAAI,YAAY,6BAA6B;AAC5C,kBAAM,KAAK,UAAU,+BAA+B,2BAA2B;AAAA,UAChF;AACA;AAAA,QACD;AACA,YAAI,YAAY,8BAA8B;AAC7C,eAAK,aAAa;AAClB,gBAAM,KAAK,eAAe;AAC1B;AAAA,QACD;AACA,cAAM,SAAS,MAAM,KAAK,QAAQ,MAAM;AAIxC,cAAM,OAAO,MAAM,uBAAuB,KAAK,OAAO;AAGtD,cAAM,kBAAkB,IAAI;AAAA,UAC3B,OAAO,YAAY,IAAI,CAAC,QAAQ,GAAG,IAAI,UAAU,EAAE,KAAS,IAAI,kBAAkB,EAAE,EAAE;AAAA,QACvF;AACA,cAAM,kBAAkB,OAAO,KAAK,OAAO,CAAC,QAAQ;AACnD,mBAAS,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;AACxC,gBAAI,CAAC,gBAAgB,IAAI,GAAG,IAAI,MAAM,KAAS,CAAC,EAAE,EAAG,QAAO;AAAA,UAC7D;AACA,iBAAO;AAAA,QACR,CAAC;AACD,cAAM,OACL,CAAC,iBAAiB,gBAAgB,WAAW,KAAK,OAAO,gBAAgB,OACtE,QACA;AACJ,cAAM,SAAS,MAAM,sBAAsB,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,MAAM,IAAI;AAC7F,cAAM,KAAK,UAAU,+BAA+B,4BAA4B;AAChF,cAAM,KAAK;AAAA,UACV;AAAA,UACA,KAAK,cAAU,oCAAqB,KAAK,QAAQ,KAAK,mBAAmB,CAAC;AAAA,QAC3E;AACA,aAAK,aAAa;AAClB,YAAI,OAAO,YAAY,EAAG,OAAM,KAAK,sBAAsB;AAC3D,YAAI,OAAO,cAAc,GAAG;AAE3B,qBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,iBAAK,oBAAoB,WAAW,UAAU;AAAA,UAC/C;AAAA,QACD;AACA,YAAI,OAAO,UAAU,GAAG;AACvB,eAAK,SAAS,KAAK;AAAA,YAClB,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,MAAM,OAAO;AAAA,YACb,SAAS,OAAO;AAAA,YAChB,aAAa,OAAO;AAAA,YACpB,SACC,OAAO,SAAS,SACb,qBAAqB,KAAK,MAAM,6FAA6F,OAAO,OAAO,+BAA+B,OAAO,WAAW,qBAC5L,mBAAmB,OAAO,OAAO,kBAAkB,KAAK,MAAM,8BAA8B,OAAO,IAAI,MAAM,OAAO,WAAW;AAAA,UACpI,CAAC;AAAA,QACF;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,0BAAyC;AACtD,cAAM,aAAa,KAAK;AACxB,YAAI,eAAe,UAAa,WAAW,WAAW,EAAG;AACzD,cAAM,WAAW,oBAAI,IAAY;AACjC,mBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B,gDAA4C,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,UAClF;AACA,qBAAW,OAAO,MAAM;AACvB,kBAAM,UAAU,OAAO,IAAI,CAAC;AAC5B,gBAAI,UAAU,KAAK,OAAO,QAAS,UAAS,IAAI,OAAO;AAAA,UACxD;AAAA,QACD;AACA;AAAA,UACC;AAAA,UACA,KAAK,OAAO;AAAA,UACZ;AAAA,UACA,mBAAmB,KAAK,MAAM;AAAA,QAC/B;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,MAAc,iBAAgC;AAC7C,cAAM,SAAS,KAAK;AACpB,YAAI,CAAC,OAAQ;AACb,cAAM,cAAU,oCAAqB,KAAK,QAAQ,KAAK,mBAAmB;AAC1E,cAAM,YAAY,MAAM,KAAK,SAAS,kBAAkB;AACxD,YAAI;AACJ,YAAI,cAAc,MAAM;AAGvB,oBAAU,MAAM,gCAAgC,KAAK,SAAS,KAAK,MAAM;AAAA,QAC1E,OAAO;AACN,cAAI,SAAkC,CAAC;AACvC,cAAI;AACH,qBAAS,KAAK,MAAM,SAAS;AAAA,UAC9B,QAAQ;AACP,qBAAS,CAAC;AAAA,UACX;AACA,oBAAU,OAAO,KAAK,OAAO,EAAE,OAAO,CAAC,SAAS,OAAO,IAAI,MAAM,QAAQ,IAAI,CAAC;AAAA,QAC/E;AACA,YAAI,QAAQ,SAAS,GAAG;AACvB,gBAAM,SAAS,MAAM;AAAA,YACpB,KAAK;AAAA,YACL,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD;AACA,cAAI,OAAO,YAAY,EAAG,OAAM,KAAK,sBAAsB;AAC3D,qBAAW,cAAc,QAAS,MAAK,oBAAoB,WAAW,UAAU;AAChF,eAAK,SAAS,KAAK;AAAA,YAClB,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,MAAM,OAAO;AAAA,YACb,SAAS,OAAO;AAAA,YAChB,aAAa,OAAO;AAAA,YACpB,SAAS,oBAAoB,QAAQ,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,gCAAgC,OAAO,OAAO,kBAAkB,KAAK,MAAM,MAAM,OAAO,WAAW;AAAA,UAC9K,CAAC;AAAA,QACF;AACA,cAAM,KAAK,UAAU,oBAAoB,KAAK,UAAU,OAAO,CAAC;AAAA,MACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAc,wBAAuC;AACpD,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,gBAAM,GAAG,QAAQ,+DAA+D;AAAA,YAC/E;AAAA,YACA;AAAA,YACA,GAAG,2BAA2B;AAAA,UAC/B,CAAC;AACD,gBAAM,GAAG,QAAQ,wCAAwC,CAAC,qBAAqB,CAAC;AAChF,gBAAM,GAAG,QAAQ,gEAAgE;AAAA,YAChF;AAAA,YACA;AAAA,UACD,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,qBAA+E;AACpF,aAAK,WAAW;AAChB,cAAM,SAAS,KAAK;AACpB,YAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,YAAI,MAAuD,CAAC;AAC5D,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,gBAAM,MAAM,OAAO,oBAAoB,EAAE;AAAA,QAC1C,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,MAAM,mBAAmB,UAAyC,CAAC,GAAoB;AACtF,aAAK,WAAW;AAChB,cAAM,SAAS,KAAK,WAAW;AAC/B,YAAI,CAAC,OAAQ,QAAO;AACpB,cAAM,UACL,QAAQ,oBAAoB,QAC3B,MAAM,KAAK,SAAS,wBAAwB,MAAO;AACrD,YAAI,UAAU;AACd,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,qBAAW,EAAE,YAAY,SAAS,KAAK,MAAM,OAAO,uBAAuB,EAAE,GAAG;AAC/E,kBAAM,OAAO,kBAAkB,IAAI,YAAY,UAAU,IAAI;AAC7D,kBAAM,OAAO,WAAW,IAAI,YAAY,QAAQ;AAChD,oBAAQ,IAAI,UAAU;AAAA,UACvB;AACA,cAAI,SAAS;AACZ,uBAAW,EAAE,YAAY,SAAS,KAAK,MAAM,OAAO,oBAAoB,EAAE,GAAG;AAC5E,kBAAI,MAAM,OAAO,mBAAmB,IAAI,YAAY,QAAQ,GAAG;AAC9D,2BAAW;AACX,wBAAQ,IAAI,UAAU;AAAA,cACvB;AAAA,YACD;AACA,kBAAM,GAAG,QAAQ,wCAAwC,CAAC,wBAAwB,CAAC;AAAA,UACpF;AAAA,QACD,CAAC;AACD,mBAAW,cAAc,QAAS,MAAK,oBAAoB,WAAW,UAAU;AAChF,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,MAAM,4BACL,QACA,SAQkB;AAClB,aAAK,WAAW;AAChB,cAAM,SAAS,KAAK,WAAW;AAC/B,YAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO;AAC5C,cAAM,UAAU,oBAAI,IAAY;AAChC,YAAI,UAAU;AAGd,cAAM,QAAQ,IAAI,iCAAmB,qBAAqB;AAAA,UACzD,KAAK,MAAM,OAAO,UAAU;AAAA,QAC7B,CAAC;AACD,cAAM,UAAU,OAAO,SAAS;AAChC,cAAM,QAAqB,CAAC;AAC5B,mBAAW,UAAU,SAAS;AAC7B,cAAI,CAAC,KAAK,OAAO,YAAY,OAAO,UAAU,EAAG;AACjD,gBAAM,KAAgB;AAAA,YACrB,IAAI,UAAM,oCAAqB,OAAO,IAAI,eAAe,OAAO,MAAM,IAAI,OAAO,QAAQ;AAAA,YACzF,QAAQ;AAAA,YACR,MAAM,OAAO;AAAA,YACb,YAAY,OAAO;AAAA,YACnB,UAAU,OAAO;AAAA,YACjB,MAAM,OAAO,SAAS,WAAW,OAAO,OAAO;AAAA,YAC/C,cAAc,OAAO,SAAS,WAAW,OAAO,OAAO;AAAA,YACvD,WAAW,MAAM,IAAI;AAAA,YACrB,gBAAgB;AAAA,YAChB,YAAY,CAAC,OAAO,EAAE;AAAA,YACtB,eAAe,KAAK,OAAO;AAAA,UAC5B;AACA,gBAAM,KAAK,EAAE;AAAA,QACd;AACA,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,qBAAW,MAAM,OAAO;AACvB,kBAAM,OAAO,qBAAqB,IAAI,IAAI,OAAO,EAAE;AACnD,oBAAQ,IAAI,GAAG,UAAU;AACzB,uBAAW;AAAA,UACZ;AAAA,QACD,CAAC;AACD,mBAAW,cAAc,QAAS,MAAK,oBAAoB,WAAW,UAAU;AAChF,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkBA,MAAM,wBACL,SACA,iBAAoC,CAAC,GACrB;AAChB,aAAK,WAAW;AAChB,cAAM,SAAS,KAAK;AACpB,cAAM,YAAY,MAAM,yBAAyB,KAAK,OAAO;AAC7D,cAAM,mBAAmB,MAAM,gCAAgC,KAAK,OAAO;AAC3E,cAAM,UAAU,IAAI;AAAA,UACnB,CAAC,GAAG,kBAAkB,GAAG,cAAc,EAAE,OAAO,CAAC,OAAO,KAAC,8BAAe,EAAE,CAAC;AAAA,QAC5E;AACA,YAAI,QAAQ,OAAO,iBAAiB,QAAQ;AAC3C,gBAAM,gCAAgC,KAAK,SAAS,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC;AAAA,QACxE;AACA,cAAM,WAAW,IAAI;AAAA,UACpB,CAAC,GAAI,aAAa,CAAC,GAAI,GAAI,SAAS,OAAO,wBAAwB,IAAI,CAAC,CAAE,EAAE;AAAA,YAC3E,CAAC,OAAO,KAAC,8BAAe,EAAE;AAAA,UAC3B;AAAA,QACD;AACA,cAAM,QAAQ,IAAI,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AACpE,cAAM,UAAU,SAAS,OAAO,MAAM;AACtC,cAAM,UAAU,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE;AAAA,UACrC,CAAC,OAAO,KAAC,8BAAe,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;AAAA,QACjE;AACA,cAAM,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,EAAE,KAAK;AACzC,cAAM,SAAS,cAAc,OAAO,OAAO,CAAC,GAAG,SAAS,EAAE,KAAK;AAC/D,YAAI,WAAW,QAAQ,KAAK,UAAU,MAAM,MAAM,KAAK,UAAU,IAAI,GAAG;AAGvE,gBAAM,yBAAyB,KAAK,SAAS,IAAI;AAAA,QAClD;AACA,YAAI,CAAC,OAAQ;AACb,eAAO,wBAAwB,IAAI;AACnC,YAAI,QAAQ,WAAW,KAAK,YAAY,EAAG;AAC3C,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,CAAC,KAAM;AACX,mBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,cAAI,CAAC,KAAK,uBAAuB,UAAU,EAAG;AAC9C,gBAAM,MAAM,MAAM,KAAK,QAAQ;AAAA,YAC9B,yBAAyB,gBAAgB;AAAA,YACzC,CAAC,UAAU;AAAA,UACZ;AACA,gBAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,uBAAW,EAAE,UAAU,KAAK,IAAK,OAAM,KAAK,WAAW,IAAI,YAAY,SAAS;AAAA,UACjF,CAAC;AACD,eAAK,oBAAoB,WAAW,UAAU;AAAA,QAC/C;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAc,gBAAgB,cAAgD;AAC7E,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,CAAC,QAAQ,aAAa,WAAW,EAAG;AACxC,cAAM,UAAU,oBAAI,IAAyB;AAC7C,mBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,gBAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,mBAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK,KAAK;AAClD,kBAAM,QAAQ,aAAa,MAAM,GAAG,IAAI,GAAG;AAC3C,kBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,cAC/B,kCAAkC,KAAK,iBAAiB,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,cACvF;AAAA,YACD;AACA,uBAAW,OAAO,MAAM;AACvB,oBAAM,MAAM,QAAQ,IAAI,UAAU,KAAK,oBAAI,IAAY;AACvD,kBAAI,IAAI,IAAI,SAAS;AACrB,sBAAQ,IAAI,YAAY,GAAG;AAAA,YAC5B;AAAA,UACD;AAAA,QACD;AACA,YAAI,QAAQ,SAAS,EAAG;AACxB,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,qBAAW,CAAC,YAAY,OAAO,KAAK,SAAS;AAC5C,uBAAW,YAAY,QAAS,OAAM,KAAK,WAAW,IAAI,YAAY,QAAQ;AAAA,UAC/E;AAAA,QACD,CAAC;AACD,mBAAW,CAAC,YAAY,OAAO,KAAK,SAAS;AAC5C,eAAK,oBAAoB,WAAW,YAAY,CAAC,GAAG,OAAO,CAAC;AAAA,QAC7D;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAc,yBAAyB,IAAiB,IAA8B;AACrF,cAAM,YAAQ,0BAAW,aAAa,GAAG,UAAU,EAAE;AACrD,cAAM,SAAS,MAAM,GAAG;AAAA,UACvB,kBAAkB,KAAK;AAAA,UACvB,CAAC,GAAG,QAAQ,GAAG,cAAc;AAAA,QAC9B;AACA,cAAM,QAAQ,mBAAmB,EAAE;AACnC,YAAI,OAAO,SAAS,GAAG;AACtB,gBAAM;AAAA,YACL;AAAA,YACA,GAAG;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,KAAK,IAAI;AAAA,UACV;AACA;AAAA,QACD;AACA,cAAM,WAAW;AAAA,UAChB,aAAa,GAAG,UAAU;AAAA,UAC1B;AAAA,QACD;AACA,cAAM,GAAG,QAAQ,SAAS,KAAK,SAAS,MAAM;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,qBAAqB,YAAoB,UAAiC;AAC/E,aAAK,WAAW;AAChB,YAAI,CAAC,KAAK,OAAO,YAAY,UAAU,EAAG;AAC1C,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,gBAAM,GAAG,QAAQ,cAAU,0BAAW,UAAU,CAAC,kCAAkC,CAAC,QAAQ,CAAC;AAC7F,gBAAM,GAAG;AAAA,YACR;AAAA,YACA,CAAC,YAAY,QAAQ;AAAA,UACtB;AAAA,QACD,CAAC;AACD,aAAK,oBAAoB,WAAW,YAAY,CAAC,QAAQ,CAAC;AAAA,MAC3D;AAAA;AAAA,MAGA,MAAM,oBACL,QAC2D;AAC3D,aAAK,WAAW;AAChB,cAAM,cAA+D,CAAC;AACtE,mBAAW,CAAC,YAAY,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,WAAW,GAAG;AAC/E,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B,qBAAiB,0BAAW,UAAU,CAAC;AAAA,UACxC;AACA,gBAAM,YAAY,OAAO,UAAU;AACnC,qBAAW,OAAO,MAAM;AACvB,kBAAM,SAAS,kBAAkB,KAAK,WAAW,MAAM;AACvD,kBAAM,UACL,cAAc,UACd,OAAO,QAAQ,SAAS,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ,MAAM;AACtD,kBACC,YACA,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,QAAQ,KACvB,SAAS,UACR;AACD,sBAAM,SAAU,SAA+B;AAC/C,uBACC,MAAM,QAAQ,MAAM,KAAK,OAAO,KAAK,CAAC,UAAU,OAAO,GAAG,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,cAEjF;AACA,qBAAO,OAAO,GAAG,OAAO,KAAK,GAAG,QAAQ;AAAA,YACzC,CAAC;AACF,gBAAI,CAAC,SAAS;AACb,oBAAM,KAAK,qBAAqB,YAAY,OAAO,OAAO,EAAE,CAAC;AAC7D,0BAAY,KAAK,EAAE,YAAY,UAAU,OAAO,OAAO,EAAE,EAAE,CAAC;AAAA,YAC7D;AAAA,UACD;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAqBA,MAAc,0BACb,IACA,IACA,YACA,MACA,YACgB;AAChB,cAAM,aAAa,GAAG;AACtB,cAAM,aAAa,gBAAgB,MAAM,WAAW,MAAM;AAC1D,cAAM,WAAW,GAAG,iBAAiB,CAAC;AACtC,cAAM,SAAS,mBAAmB,EAAE;AACpC,cAAM,gBAAgB,oBAAoB,MAAM;AAChD,cAAM,WAA0B,CAAC;AACjC,mBAAW,SAAS,OAAO,KAAK,UAAU,GAAG;AAG5C,gBAAM,UAAU,SAAS,KAAK;AAC9B,mBAAS,KAAK,IAAI,UAAU,oBAAoB,OAAO,IAAI;AAAA,QAC5D;AAEA,cAAM,OAAO,MAAM,GAAG;AAAA,UACrB,oEAAgE,0BAAW,UAAU,CAAC;AAAA,UACtF,CAAC,GAAG,QAAQ;AAAA,QACb;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,mBAAW,GAAG;AAEd,YAAI,CAAC,KAAK;AACT,gBAAM,SAAkC;AAAA,YACvC,IAAI,GAAG;AAAA,YACP,GAAG;AAAA,YACH,aAAa,GAAG,UAAU;AAAA,YAC1B,aAAa,OAAO;AAAA,YACpB,UAAU;AAAA,YACV,iBAAiB,uBAAuB,QAAQ;AAAA,UACjD;AACA,gBAAM,cAAc,iBAAiB,YAAY,MAAM;AACvD,gBAAM,GAAG,QAAQ,YAAY,KAAK,YAAY,MAAM;AACpD,gBAAM,KAAK,uBAAuB,IAAI,YAAY,YAAY,GAAG,UAAU,EAAE;AAC7E;AAAA,QACD;AAEA,YAAI,YAAY;AAChB,YAAI,IAAI,aAAa,GAAG;AACvB,uBAEE,MAAM,GAAG;AAAA,YACR;AAAA,YACA,CAAC,YAAY,GAAG,QAAQ;AAAA,UACzB,GACC,SAAS;AAEZ,cAAI,CAAC,aAAa,CAAC,uBAAuB,QAAQ,GAAG,EAAG;AAAA,QACzD;AAEA,cAAM,UAAU,mBAAmB,IAAI,eAAe;AACtD,cAAMA,cAAa,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AACrE,cAAM,SAAwB,EAAE,GAAG,QAAQ;AAC3C,cAAM,UAAmC,CAAC;AAC1C,mBAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACxD,cAAI,UAAU,sBAAsB,SAAS,OAAOA,WAAU,GAAG;AAChE,oBAAQ,KAAK,IAAI,WAAW,KAAK;AACjC,mBAAO,KAAK,IAAI;AAAA,UACjB;AAAA,QACD;AACA,YAAI,IAAI,aAAa,GAAG;AACvB,kBAAQ,WAAW;AAAA,QACpB;AACA,gBAAQ,kBAAkB,uBAAuB,MAAM;AACvD,cAAM,SAAS;AAAA,UACd;AAAA,UACA,GAAG;AAAA,UACH;AAAA,UACA;AAAA,UACA,OAAO;AAAA,QACR;AACA,cAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM;AAC1C,YAAI,WAAW;AACd,gBAAM,GAAG;AAAA,YACR;AAAA,YACA,CAAC,YAAY,GAAG,QAAQ;AAAA,UACzB;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaA,MAAc,uBACb,IACA,YACA,YACA,UACA,UACgB;AAChB,cAAM,aAAa;AAAA,UAClB,GAAI,MAAM,GAAG;AAAA,YACZ,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,YACtD,CAAC,QAAQ;AAAA,UACV;AAAA,UACA,GAAI,MAAM;AAAA,YACT,CAAC,KAAK,WAAW,GAAG,MAAM,KAAK,MAAM;AAAA,YACrC;AAAA,YACA;AAAA,YACA,CAAC,UAAU,QAAQ;AAAA,UACpB;AAAA,QACD;AACA,YAAI,WAAW,WAAW,GAAG;AAC5B;AAAA,QACD;AAEA,cAAM,UAAU,WACd,IAAI,CAAC,MAAM,mCAAmC,GAAG,UAAU,CAAC,EAC5D,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AAErE,mBAAW,UAAU,SAAS;AAC7B,gBAAM,gBAAgB,oBAAoB,OAAO,SAAS;AAC1D,gBAAM,aAAa,OAAO,UAAU;AAEpC,cAAI,OAAO,SAAS,YAAY,OAAO,MAAM;AAC5C,kBAAM,gBAAgB,gBAAgB,OAAO,MAAM,WAAW,MAAM;AACpE,kBAAM,OAAO,MAAM,GAAG;AAAA,cACrB,6CAAyC,0BAAW,UAAU,CAAC;AAAA,cAC/D,CAAC,QAAQ;AAAA,YACV;AACA,kBAAM,UAAU,KAAK,CAAC;AACtB,gBAAI,CAAC,SAAS;AACb;AAAA,YACD;AACA,kBAAM,EAAE,SAAS,OAAO,IAAI;AAAA,cAC3B,mBAAmB,QAAQ,eAAe;AAAA,cAC1C,OAAO,KAAK,aAAa;AAAA,cACzB;AAAA,cACA,OAAO,QAAQ,aAAa,WAAW,QAAQ,WAAW;AAAA,YAC3D;AACA,gBAAI,QAAQ,SAAS,GAAG;AACvB,oBAAM,iBAA0C;AAAA,gBAC/C,iBAAiB,uBAAuB,MAAM;AAAA,cAC/C;AACA,yBAAW,SAAS,SAAS;AAC5B,+BAAe,KAAK,IAAI,cAAc,KAAK;AAAA,cAC5C;AACA,oBAAM,QAAQ;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACD;AACA,oBAAM,GAAG,QAAQ,MAAM,KAAK,MAAM,MAAM;AAAA,YACzC;AAAA,UACD,WAAW,OAAO,SAAS,UAAU;AACpC,kBAAM,QAAQ,wBAAwB,YAAY,UAAU,YAAY,aAAa;AACrF,kBAAM,GAAG,QAAQ,MAAM,KAAK,MAAM,MAAM;AAAA,UACzC;AAAA,QACD;AAUA,cAAM,eAAe,oBAAI,IAAY;AACrC,mBAAW,UAAU,SAAS;AAC7B,cAAI,OAAO,SAAS,YAAY,OAAO,WAAW;AACjD,uBAAW,SAAS,OAAO,KAAK,OAAO,SAAS,GAAG;AAClD,2BAAa,IAAI,KAAK;AAAA,YACvB;AAAA,UACD;AAAA,QACD;AACA,YAAI,aAAa,OAAO,GAAG;AAE1B,gBAAM,cAAU,8CAA+B,CAAC,UAAU,GAAG,OAAO,CAAC;AACrE,gBAAM,aAAS,yCAA0B,OAAO;AAChD,cAAI,QAAQ;AACX,kBAAM,WAAoC,CAAC;AAC3C,uBAAW,SAAS,cAAc;AACjC,kBAAI,SAAS,QAAQ;AACpB,yBAAS,KAAK,IAAI,OAAO,KAAK;AAAA,cAC/B;AAAA,YACD;AACA,kBAAM,aAAa,gBAAgB,UAAU,WAAW,MAAM;AAC9D,kBAAM,OAAO,OAAO,KAAK,UAAU;AACnC,gBAAI,KAAK,SAAS,GAAG;AACpB,oBAAM,YAAY,KAAK,IAAI,CAAC,MAAM,OAAG,0BAAW,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI;AACnE,oBAAM,GAAG,QAAQ,cAAU,0BAAW,UAAU,CAAC,QAAQ,SAAS,iBAAiB;AAAA,gBAClF,GAAG,KAAK,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC;AAAA,gBAChC;AAAA,cACD,CAAC;AAAA,YACF;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,SAAS,QAAgB,SAAiB,OAAqC;AACpF,eAAO,KAAK,kBAAkB,QAAQ,SAAS,KAAK;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAkB,QAAgB,SAAiB,OAAqC;AAC7F,aAAK,WAAW;AAChB,cAAM,SAAsB,CAAC;AAE7B,mBAAW,kBAAkB,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAClE,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B,qBAAiB,0BAAW,aAAa,cAAc,EAAE,CAAC;AAAA,YAC1D,CAAC,QAAQ,SAAS,KAAK;AAAA,UACxB;AACA,qBAAW,OAAO,MAAM;AACvB,mBAAO,KAAK,mCAAmC,KAAK,cAAc,CAAC;AAAA,UACpE;AAAA,QACD;AAGA,eAAO,KAAK,CAAC,GAAG,MAAM,EAAE,iBAAiB,EAAE,cAAc;AACzD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,mBAAyC;AAC9C,aAAK,WAAW;AAChB,cAAM,SAAsB,CAAC;AAE7B,mBAAW,kBAAkB,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAClE,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B,qBAAiB,0BAAW,aAAa,cAAc,EAAE,CAAC;AAAA,UAC3D;AACA,qBAAW,OAAO,MAAM;AACvB,mBAAO,KAAK,mCAAmC,KAAK,cAAc,CAAC;AAAA,UACpE;AAAA,QACD;AAEA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,SAAS,aAA8C;AAC5D,aAAK,WAAW;AAChB,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,SAAS,MAAM,KAAK,iBAAiB;AAC3C,cAAM,YAAY,MAAM,KAAK,QAAQ;AAAA,UACpC,gCAAgC,mBAAmB;AAAA,QACpD;AACA,cAAM,UAAU,IAAI,IAAI,UAAU,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,YAAY,CAAC,CAAC;AAC1E,cAAM,WAAW;AAAA,UAChB,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QACN;AAEA,YAAI,KAAK,SAAS;AACjB,eAAK,QAAQ,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,mBAAmB;AAAA,YACnB,mBAAmB,SAAS,kBAAkB;AAAA,YAC9C,UAAU,KAAK,IAAI,IAAI;AAAA,UACxB,CAAC;AAAA,QACF;AAEA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAiB,OAAoE;AAC1F,aAAK,WAAW;AAChB,cAAM,EAAE,kBAAkB,OAAO,IAAI,MAAM;AAC3C,cAAM,OAAO,KAAK,SAAS,KAAK;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eACL,OAC0D;AAC1D,aAAK,WAAW;AAChB,cAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,eAAOA,iBAAgB,KAAK,SAAS,KAAK;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,SAA4E;AAC7F,aAAK,WAAW;AAChB,cAAM,EAAE,aAAa,SAAS,IAAI,MAAM;AACxC,eAAO,SAAS,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,KAAK,OAAO,SAAS,OAAO;AAAA,MACrF;AAAA;AAAA;AAAA;AAAA,MAKA,YAA8B;AAC7B,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA,MAKA,wBAAwB,SAA4C;AACnE,aAAK,uBAAuB;AAC5B,mBAAW,OAAO,KAAK,YAAY,OAAO,GAAG;AAC5C,cAAI,mBAAmB,OAAO;AAAA,QAC/B;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,wBAAwB,WAA4B;AACnD,aAAK,WAAW;AAChB,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU,UAAU;AAC/D,YAAI,CAAC,YAAY;AAChB;AAAA,QACD;AACA,aAAK,wBAAwB,SAAS;AACtC,aAAK,oBAAoB,mBAAmB,UAAU,UAAU;AAAA,MACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,qBAAqB,YAA0B;AAC9C,aAAK,WAAW;AAChB,YAAI,CAAC,KAAK,OAAO,YAAY,UAAU,EAAG;AAC1C,aAAK,oBAAoB,mBAAmB,UAAU;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,iBAAiB,UAA6C;AAC7D,eAAO,KAAK,oBAAoB,iBAAiB,QAAQ;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,sBACC,YACA,SASuB;AACvB,aAAK,WAAW;AAChB,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU;AACrD,YAAI,CAAC,cAAc,CAAC,KAAK,OAAO;AAC/B,gBAAM,IAAI,kBAAkB;AAAA,QAC7B;AACA,cAAM,oBAAoB,KAAK,sBAAsB;AACrD,cAAM,OAAO,KAAK,WAAW;AAC7B,eAAO;AAAA,UACN,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACvB;AAAA,UACA;AAAA,UACA,QAAQ,KAAK;AAAA,UACb,SAAS,KAAK;AAAA,UACd,OAAO,SAAS,SAAS,KAAK;AAAA,UAC9B,QAAQ,KAAK;AAAA,UACb,YAAY,CAAC,gBAAgB,cAC5B,KAAK,sBAAsB,gBAAgB,SAAS;AAAA,UACrD,kBAAkB,KAAK;AAAA,UACvB,eAAe,KAAK;AAAA,UACpB,GAAI,SAAS,kBAAkB,EAAE,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC;AAAA,UAC/E,GAAI,KAAK,oBAAoB,EAAE,mBAAmB,KAAK,kBAAkB,IAAI,CAAC;AAAA,UAC9E,GAAI,KAAK,sBAAsB,SAC5B,EAAE,mBAAmB,KAAK,kBAAkB,IAC5C,CAAC;AAAA,UACJ,GAAI,oBACD,EAAE,mBAAmB,kBAAkB,KAAK,KAAK,oBAAoB,EAAE,IACvE,CAAC;AAAA,UACJ,gBAAgB,CAAC,UAAU,KAAK,mBAAmB,KAAK;AAAA,QACzD;AAAA,MACD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,oBACL,YACA,UAC0C;AAC1C,aAAK,WAAW;AAChB,cAAM,aAAa,KAAK,OAAO,YAAY,UAAU;AACrD,YAAI,CAAC,YAAY;AAChB,iBAAO;AAAA,QACR;AAEA,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B,qBAAiB,0BAAW,UAAU,CAAC;AAAA,UACvC,CAAC,QAAQ;AAAA,QACV;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,CAAC,KAAK;AACT,iBAAO;AAAA,QACR;AAEA,eAAO;AAAA,UACN,QAAQ,kBAAkB,KAAK,WAAW,MAAM;AAAA,UAChD,SAAS,IAAI,aAAa;AAAA,QAC3B;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,mBAAmB,YAAoB,UAAmD;AAC/F,aAAK,WAAW;AAChB,YAAI,CAAC,KAAK,OAAO,YAAY,UAAU,GAAG;AACzC,iBAAO;AAAA,QACR;AACA,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B,6CAAyC,0BAAW,UAAU,CAAC;AAAA,UAC/D,CAAC,QAAQ;AAAA,QACV;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,CAAC,KAAK;AACT,iBAAO;AAAA,QACR;AACA,eAAO;AAAA,UACN,SAAS,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AAAA,UAC3D,eAAe,OAAO,IAAI,oBAAoB,WAAW,IAAI,kBAAkB;AAAA,QAChF;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,4BAAoD;AACzD,aAAK,WAAW;AAChB,eAAO,0BAA0B,KAAK,OAAO;AAAA,MAC9C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,0BAA0B,QAAsC;AACrE,aAAK,WAAW;AAChB,cAAM,0BAA0B,KAAK,SAAS,MAAM;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,cAAc,QAAyC;AAC5D,aAAK,WAAW;AAChB,eAAO,cAAc,KAAK,SAAS,UAAU,KAAK,MAAM;AAAA,MACzD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,cAAc,OAAe,QAAgC;AAClE,aAAK,WAAW;AAChB,cAAM,cAAc,KAAK,SAAS,OAAO,UAAU,KAAK,MAAM;AAAA,MAC/D;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,2BAAqD;AAC1D,aAAK,WAAW;AAChB,eAAO,yBAAyB,KAAK,OAAO;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,yBAAyB,SAAkC;AAChE,cAAM,KAAK,wBAAwB,OAAO;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAA0C;AAC/C,aAAK,WAAW;AAChB,eAAO,gBAAgB,KAAK,OAAO;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,gBAAgB,QAAsC;AAC3D,aAAK,WAAW;AAChB,cAAM,gBAAgB,KAAK,SAAS,MAAM;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,sBAAsB,YAAY,IAAqB;AAC5D,aAAK,WAAW;AAChB,eAAO,sBAAsB,KAAK,SAAS,SAAS;AAAA,MACrD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,WAAmB,WAAkC;AAChF,aAAK,WAAW;AAChB,cAAM,sBAAsB,KAAK,SAAS,WAAW,SAAS;AAAA,MAC/D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,4BAA6D;AAClE,aAAK,WAAW;AAChB,eAAO,0BAA0B,KAAK,OAAO;AAAA,MAC9C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,wBAAwB,WAAkC;AAC/D,aAAK,WAAW;AAChB,cAAM,wBAAwB,KAAK,SAAS,SAAS;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,sBACL,SACA,WACgB;AAChB,aAAK,WAAW;AAChB,cAAM,wBAAwB,KAAK,SAAS,SAAS,SAAS;AAAA,MAC/D;AAAA;AAAA,MAGA,MAAM,wBAAuD;AAC5D,aAAK,WAAW;AAChB,eAAO,wBAAwB,KAAK,OAAO;AAAA,MAC5C;AAAA;AAAA,MAGA,MAAM,wBAAwB,cAAuC;AACpE,aAAK,WAAW;AAChB,cAAM,0BAA0B,KAAK,SAAS,YAAY;AAAA,MAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,oBAAoB,QAAwC;AACjE,aAAK,WAAW;AAChB,eAAO,oBAAoB,KAAK,SAAS,MAAM;AAAA,MAChD;AAAA;AAAA,MAGA,MAAM,oBAAoB,QAAgB,UAAiC;AAC1E,aAAK,WAAW;AAChB,cAAM,oBAAoB,KAAK,SAAS,QAAQ,QAAQ;AAAA,MACzD;AAAA;AAAA,MAGA,MAAM,4BAAqF;AAC1F,aAAK,WAAW;AAChB,eAAO,0BAA0B,KAAK,OAAO;AAAA,MAC9C;AAAA;AAAA,MAGA,MAAM,0BACL,OACgB;AAChB,aAAK,WAAW;AAChB,cAAM,0BAA0B,KAAK,SAAS,KAAK;AAAA,MACpD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,cAAmD;AAC9E,aAAK,WAAW;AAChB,eAAO;AAAA,UACN,KAAK,iBAAiB;AAAA,UACtB;AAAA,UACA,CAAC,QAAQ,SAAS,UAAU,KAAK,kBAAkB,QAAQ,SAAS,KAAK;AAAA,QAC1E;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAwBA,MAAM,aAAa,eAAsD;AACxE,aAAK,WAAW;AAChB,YAAI,KAAK,gBAAgB,KAAK,cAAc,WAAW;AACtD,gBAAM,IAAI;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,cACC,QAAQ,KAAK;AAAA,cACb,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AACA,cAAM,YAAY,KAAK;AACvB,cAAM,WAAW,KAAK;AACtB,cAAM,cAAc,MAAM,eAAe,KAAK,OAAO,GAAG;AAAA,UACvD,CAAC,SAAS,KAAK,WAAW;AAAA,QAC3B;AACA,cAAM,SAAS,MAAM;AAAA,UACpB,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,cACA,8BAAe;AAAA,QAChB;AACA,cAAM,kBAAkB,KAAK,SAAS,OAAO,MAAM;AAGnD,YAAI,YAAY,WAAW;AAC1B,gBAAM;AAAA,YACL,KAAK;AAAA,YACL,OAAO;AAAA,YACP,WAAW;AAAA,YACX,WAAW,WAAW;AAAA,UACvB;AAAA,QACD;AACA,aAAK,SAAS,OAAO;AACrB,cAAM,QAAQ,IAAI,iCAAmB,KAAK,MAAM;AAChD,YAAI,UAAU;AACb,gBAAM,OAAO,SAAS,IAAI;AAC1B,gBAAM,UAAU,EAAE,GAAG,MAAM,QAAQ,KAAK,OAAO,CAAC;AAChD,gBAAM,SAAS,SAAS,mBAAmB;AAC3C,cAAI,WAAW,KAAM,OAAM,mBAAmB,MAAM;AAAA,QACrD;AACA,aAAK,QAAQ;AACb,aAAK,gBAAgB,IAAI,4BAAc;AACvC,aAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS,KAAK,MAAM;AACpE,aAAK,gBAAgB,MAAM,KAAK,kBAAkB;AAElD,aAAK,iBAAiB,KAAK,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,WAAW;AAC/E,mBAAW,cAAc,KAAK,YAAY,OAAO,GAAG;AACnD,qBAAW,WAAW,OAAO,KAAK,QAAQ,KAAK,kBAAkB,KAAK,aAAa;AAAA,QACpF;AAGA,cAAM,KAAK,gBAAgB,OAAO,WAAW,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;AAC/D,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,aAAa,QAA+B;AACjD,aAAK,WAAW;AAChB,YAAI,KAAK,gBAAgB,KAAK,cAAc,WAAW;AACtD,gBAAM,IAAI;AAAA,YACT;AAAA,YACA;AAAA,YACA,EAAE,QAAQ,KAAK,OAAO;AAAA,UACvB;AAAA,QACD;AACA,YAAI,WAAW,KAAK,OAAQ;AAC5B,gBAAI,gCAAiB,MAAM,EAAG,OAAM,IAAI,oBAAoB,QAAQ,cAAc;AAClF,cAAM,SAAS,MAAM,eAAe,KAAK,OAAO,GAAG,KAAK,CAAC,SAAS,KAAK,WAAW,MAAM;AACxF,YAAI,CAAC,OAAO;AACX,gBAAM,IAAI;AAAA,YACT,YAAY,MAAM;AAAA,YAClB;AAAA,YACA,EAAE,OAAO;AAAA,UACV;AAAA,QACD;AACA,cAAM,KAAK,QAAQ,YAAY,CAAC,OAAO,mBAAmB,IAAI,MAAM,CAAC;AACrE,cAAM,KAAK,aAAa,MAAM;AAAA,MAC/B;AAAA;AAAA,MAGA,MAAc,aAAa,QAA+B;AACzD,cAAM,WAAW,KAAK;AACtB,aAAK,SAAS;AACd,cAAM,QAAQ,IAAI,iCAAmB,KAAK,MAAM;AAChD,YAAI,UAAU;AACb,gBAAM,OAAO,SAAS,IAAI;AAC1B,gBAAM,UAAU,EAAE,GAAG,MAAM,QAAQ,KAAK,OAAO,CAAC;AAChD,gBAAM,SAAS,SAAS,mBAAmB;AAC3C,cAAI,WAAW,KAAM,OAAM,mBAAmB,MAAM;AAAA,QACrD;AACA,aAAK,QAAQ;AACb,aAAK,gBAAgB,IAAI,4BAAc;AACvC,aAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS,KAAK,MAAM;AACpE,aAAK,gBAAgB,MAAM,KAAK,kBAAkB;AAClD,aAAK,iBAAiB,KAAK,cAAc,IAAI,KAAK,MAAM,KAAK;AAC7D,mBAAW,cAAc,KAAK,YAAY,OAAO,GAAG;AACnD,qBAAW,WAAW,OAAO,KAAK,QAAQ,KAAK,kBAAkB,KAAK,aAAa;AAAA,QACpF;AAAA,MACD;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;AAAA;AAAA;AAAA,MA+BA,MAAM,cAAc,WAA8C;AACjE,aAAK,WAAW;AAChB,cAAM,iBAAiB,KAAK;AAC5B,cAAM,QAAQ,MAAM,eAAe,KAAK,OAAO;AAC/C,cAAM,UAAU,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,KAAK,MAAM;AAChE,cAAM,QAAQ,SAAS,aAAa;AACpC,YAAI,UAAU,WAAW;AACxB,iBAAO,EAAE,QAAQ,KAAK,QAAQ,gBAAgB,UAAU,OAAO,UAAU,MAAM;AAAA,QAChF;AACA,YAAI,UAAU,MAAM;AACnB,gBAAM,WAAW,MAAM,KAAK,kBAAkB,GAAG,IAAI,KAAK,MAAM,KAAK;AACrE,cAAI,YAAY,KAAK,EAAE,SAAS,YAAY,QAAQ;AACnD,kBAAM,sBAAsB,KAAK,SAAS,KAAK,QAAQ,WAAW,OAAO;AACzE,mBAAO,EAAE,QAAQ,KAAK,QAAQ,gBAAgB,UAAU,OAAO,UAAU,MAAM;AAAA,UAChF;AACA,cAAI,KAAK,cAAc;AAEtB,mBAAO,EAAE,QAAQ,KAAK,QAAQ,gBAAgB,UAAU,OAAO,UAAU,MAAM;AAAA,UAChF;AAAA,QACD,WAAW,KAAK,cAAc;AAC7B,iBAAO,EAAE,QAAQ,KAAK,QAAQ,gBAAgB,UAAU,OAAO,UAAU,KAAK;AAAA,QAC/E;AACA,YAAI,KAAK,cAAc,WAAW;AAEjC,gBAAMC,aAAQ,8BAAe;AAC7B,gBAAM,kBAAkB,KAAK,SAASA,MAAK;AAC3C,gBAAM,sBAAsB,KAAK,SAASA,QAAO,WAAW,OAAO;AACnE,2BAAiB,KAAK,QAAQA,MAAK;AACnC,eAAK,kBAAkB;AACvB,eAAK,kBAAkB,gBAAgB,aAAa,KAAK,QAAQA,MAAK,CAAC;AACvE,gBAAM,KAAK,aAAaA,MAAK;AAC7B,iBAAO,EAAE,QAAQA,QAAO,gBAAgB,UAAU,MAAM,UAAU,MAAM;AAAA,QACzE;AACA,cAAM,MAAM,MACV,OAAO,CAAC,SAAS,KAAK,cAAc,aAAa,CAAC,KAAK,IAAI,EAC3D,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC7C,YAAI,KAAK;AACR,gBAAM,KAAK,aAAa,IAAI,MAAM;AAClC,iBAAO,EAAE,QAAQ,IAAI,QAAQ,gBAAgB,UAAU,MAAM,UAAU,MAAM;AAAA,QAC9E;AACA,cAAM,YAAQ,8BAAe;AAC7B,cAAM,KAAK,QAAQ,YAAY,CAAC,OAAO,mBAAmB,IAAI,KAAK,CAAC;AACpE,cAAM,kBAAkB,KAAK,SAAS,KAAK;AAC3C,cAAM,sBAAsB,KAAK,SAAS,OAAO,WAAW,OAAO;AACnE,cAAM,KAAK,aAAa,KAAK;AAC7B,eAAO,EAAE,QAAQ,OAAO,gBAAgB,UAAU,MAAM,UAAU,MAAM;AAAA,MACzE;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,qBAAqB,QAAgB,WAAkC;AAC5E,aAAK,WAAW;AAChB,cAAM,0BAA0B,KAAK,SAAS,QAAQ,SAAS;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,qBAAqB,QAAgB,WAAkC;AAC5E,aAAK,WAAW;AAChB,cAAM,0BAA0B,KAAK,SAAS,QAAQ,SAAS;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,oBAAoB,QAAgB,WAAqC;AAC9E,aAAK,WAAW;AAChB,YAAI,WAAW,KAAK,OAAQ,QAAO;AACnC,eAAO,yBAAyB,KAAK,SAAS,QAAQ,SAAS;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,cAAc,QAA+B;AAClD,aAAK,WAAW;AAChB,YAAI,WAAW,KAAK,OAAQ;AAC5B,cAAM,cAAc,KAAK,SAAS,MAAM;AAAA,MACzC;AAAA;AAAA,MAGA,MAAM,uBAAkD;AACvD,aAAK,WAAW;AAChB,eAAO,qBAAqB,KAAK,OAAO;AAAA,MACzC;AAAA;AAAA,MAGA,MAAM,qBAAqB,UAA2C;AACrE,aAAK,WAAW;AAChB,cAAM,qBAAqB,KAAK,SAAS,QAAQ;AAAA,MAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,MAAM,mBAAmB,QAAgB,OAAiC;AACzE,aAAK,WAAW;AAChB,YAAI,SAAS;AACb,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,gBAAM,OAAO,MAAM,GAAG;AAAA,YACrB;AAAA,YACA,CAAC,MAAM;AAAA,UACR;AACA,gBAAM,UAAU,KAAK,CAAC,GAAG,mBAAmB;AAC5C,cAAI,SAAS,QAAS;AACtB,gBAAM,GAAG;AAAA,YACR;AAAA;AAAA,YAEA,CAAC,QAAQ,KAAK;AAAA,UACf;AACA,mBAAS;AAAA,QACV,CAAC;AACD,YAAI,QAAQ;AACX,gBAAM,WAAW,KAAK,cAAc,IAAI,MAAM,KAAK;AACnD,eAAK,cAAc,IAAI,QAAQ,KAAK,IAAI,UAAU,KAAK,CAAC;AACxD,cAAI,WAAW,KAAK,OAAQ,MAAK,iBAAiB,KAAK,IAAI,KAAK,gBAAgB,KAAK;AAAA,QACtF;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAsBA,MAAM,oBACL,aACA,QACA,OACA,uBAA0C,CAAC,GACR;AACnC,aAAK,WAAW;AAChB,cAAM,QAA6C,EAAE,QAAQ,KAAK;AAClE,cAAM,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW;AACvD,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,qBAAW,cAAc,aAAa;AACrC,kBAAM,YAAQ,0BAAW,aAAa,UAAU,EAAE;AAClD,kBAAM,OAAO,MAAM,GAAG;AAAA,cACrB,iBAAiB,KAAK;AAAA,cACtB,CAAC,aAAa,MAAM;AAAA,YACrB;AACA,kBAAM,MAAM,KAAK,CAAC;AAClB,gBAAI,CAAC,IAAK;AACV,kBAAM,GAAG;AAAA,cACR;AAAA;AAAA,cAEA,CAAC,QAAQ,KAAK;AAAA,YACf;AACA,kBAAM,WAAW,MAAM,kCAAkC,IAAI,MAAM;AAGnE,kBAAM,QAAQ,MAAM,qBAAqB,IAAI,YAAY,KAAK,QAAQ;AACtE,kBAAM;AAAA,cACL;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN;AAAA,cACA,KAAK,IAAI;AAAA,YACV;AACA,kBAAM,YAAoC,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;AAC1F,kBAAM,aAAa,IAAI,IAAI,oBAAoB;AAC/C,uBAAW,OAAO,IAAI,EAAE;AACxB,kBAAM,aACL,MAAM,OAAO,IAAI,KACd,MAAM,sBAAsB,IAAI,aAAa,QAAQ,WAAW,UAAU,IAC1E,CAAC;AACL,kBAAM,SAAS,EAAE,WAAW,OAAO,YAAY,UAAU;AACzD;AAAA,UACD;AAAA,QACD,CAAC;AACD,cAAM,SAAS,MAAM;AACrB,YAAI,CAAC,OAAQ,QAAO;AACpB,aAAK,wBAAwB,OAAO,SAAS;AAC7C,YAAI,OAAO,KAAK,OAAO,SAAS,EAAE,SAAS,GAAG;AAC7C,gBAAM,KAAK,gBAAgB,CAAC,OAAO,UAAU,IAAI,GAAG,OAAO,WAAW,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;AAAA,QAC1F;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,gBAA+B;AACpC,aAAK,WAAW;AAChB,cAAM,KAAK,QAAQ,gBAAgB;AAAA,MACpC;AAAA;AAAA,MAGA,MAAM,yBAAyB,SAA6C;AAC3E,aAAK,WAAW;AAChB,cAAM,yBAAyB,KAAK,SAAS,OAAO;AAGpD,cAAM,KAAK,gBAAgB,QAAQ,IAAI,CAAC,UAAU,MAAM,WAAW,CAAC;AAAA,MACrE;AAAA;AAAA,MAGA,MAAM,uBAAuB,cAA8C;AAC1E,aAAK,WAAW;AAChB,eAAO,uBAAuB,KAAK,SAAS,YAAY;AAAA,MACzD;AAAA;AAAA,MAGA,MAAM,iBAA6C;AAClD,aAAK,WAAW;AAChB,eAAO,eAAe,KAAK,OAAO;AAAA,MACnC;AAAA;AAAA,MAGA,MAAM,gBAAgB,QAA+B;AACpD,aAAK,WAAW;AAChB,YAAI,WAAW,KAAK,OAAQ;AAC5B,cAAM,gBAAgB,KAAK,SAAS,MAAM;AAAA,MAC3C;AAAA;AAAA,MAGA,MAAM,oBAAqC;AAC1C,aAAK,WAAW;AAChB,eAAO,kBAAkB,KAAK,OAAO;AAAA,MACtC;AAAA;AAAA,MAGA,MAAM,sBAAsB,QAA+B;AAC1D,aAAK,WAAW;AAChB,cAAM,sBAAsB,KAAK,SAAS,MAAM;AAAA,MACjD;AAAA;AAAA,MAGA,MAAM,qBAAqB,QAAgB,MAA8B;AACxE,aAAK,WAAW;AAChB,cAAM,qBAAqB,KAAK,SAAS,QAAQ,IAAI;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,eAAe,QAA8C;AAClE,aAAK,WAAW;AAChB,YAAI,WAAW,KAAK,OAAQ,QAAO;AACnC,eAAO,mBAAmB,aAAa,KAAK,QAAQ,MAAM,CAAC;AAAA,MAC5D;AAAA;AAAA,MAGA,MAAM,gBAAgB,QAAkC;AACvD,aAAK,WAAW;AAChB,YAAI,WAAW,KAAK,OAAQ,QAAO;AACnC,eAAO,eAAe,aAAa,KAAK,QAAQ,MAAM,CAAC;AAAA,MACxD;AAAA,MAEA,MAAM,yBACL,eACA,gBAC6B;AAC7B,aAAK,WAAW;AAChB,cAAM,SAAS,MAAM;AAAA,UACpB,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACD;AACA,YAAI,OAAO,mBAAmB,KAAK,OAAO;AACzC,eAAK,MAAM,UAAU,OAAO,eAAe;AAAA,QAC5C;AAEA,cAAM,KAAK,gBAAgB,OAAO,WAAW,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;AAC/D,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,wBAAwB,cAA8C;AAC3E,cAAM,MAAM,MAAM,KAAK,sBAAsB,YAAY;AACzD,eAAO,IAAI;AAAA,MACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,MAAM,QAAQ,UAAyD;AACtE,aAAK,WAAW;AAChB,cAAM,OAAO,KAAK,WAAW;AAC7B,YAAI,SAAS,SAAS,SAAS;AAC9B,iBAAO,oBAAoB,KAAK,SAAS,KAAK,QAAQ,cAAU,mCAAoB,CAAC;AAAA,QACtF;AAEA,cAAM,eAAe,SAAS,gBAAiB,MAAM,0BAA0B,KAAK,OAAO;AAC3F,YAAI,MAAM;AACT,iBAAO,iBAAiB,KAAK,SAAS,KAAK,QAAQ,MAAM,UAAU,YAAY;AAAA,QAChF;AACA,eAAO,oBAAoB,KAAK,SAAS,KAAK,QAAQ,UAAU,YAAY;AAAA,MAC7E;AAAA;AAAA;AAAA;AAAA,MAKA,mBAAmB,eAA8B,iBAA+C;AAC/F,eAAO,oBAAoB,iBAAiB,aAAa;AAAA,MAC1D;AAAA,MAEA,MAAM,iCACL,YACA,UAC4B;AAC5B,aAAK,WAAW;AAChB,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,UACtD,CAAC,KAAK,QAAQ,QAAQ;AAAA,QACvB;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,CAAC,KAAK;AACT,iBAAO;AAAA,QACR;AACA,eAAO,mCAAmC,KAAK,UAAU;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,4BACL,YACA,UAC4B;AAC5B,aAAK,WAAW;AAChB,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,UACtD,CAAC,QAAQ;AAAA,QACV;AAEA,YAAI,SAA2B;AAC/B,mBAAW,OAAO,MAAM;AACvB,gBAAM,KAAK,mCAAmC,KAAK,UAAU;AAC7D,cAAI,CAAC,UAAU,iCAAmB,QAAQ,GAAG,WAAW,OAAO,SAAS,IAAI,GAAG;AAC9E,qBAAS;AAAA,UACV;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAM,uBAAuB,YAAoB,UAAwC;AACxF,aAAK,WAAW;AAChB,cAAM,OAAO;AAAA,UACZ,GAAI,MAAM,KAAK,QAAQ;AAAA,YACtB,qBAAiB,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,YACtD,CAAC,QAAQ;AAAA,UACV;AAAA;AAAA;AAAA,UAGA,GAAI,MAAM;AAAA,YACT,CAAC,KAAK,WAAW,KAAK,QAAQ,MAAM,KAAK,MAAM;AAAA,YAC/C;AAAA,YACA;AAAA,UACD;AAAA,QACD;AACA,cAAM,MAAM,KAAK,IAAI,CAAC,QAAQ,mCAAmC,KAAK,UAAU,CAAC;AACjF,YAAI,KAAK,CAAC,GAAG,MAAM,iCAAmB,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC;AACvE,eAAO;AAAA,MACR;AAAA;AAAA,MAGA,yBAA8C;AAC7C,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,qBAAsC;AACrC,aAAK,WAAW;AAChB,YAAI,CAAC,KAAK,iBAAiB;AAC1B,gBAAM,IAAI,kBAAkB;AAAA,QAC7B;AACA,eAAO,KAAK;AAAA,MACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,oBAAwC;AACvC,aAAK,WAAW;AAChB,YAAI,CAAC,KAAK,OAAO;AAChB,gBAAM,IAAI,kBAAkB;AAAA,QAC7B;AACA,cAAM,oBAAoB,KAAK,sBAAsB;AACrD,cAAM,OAAO,KAAK,WAAW;AAC7B,eAAO,IAAI,mBAAmB;AAAA,UAC7B,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACvB,QAAQ,KAAK;AAAA,UACb,SAAS,KAAK;AAAA,UACd,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,kBAAkB,KAAK;AAAA,UACvB,eAAe,KAAK;AAAA,UACpB,GAAI,KAAK,oBAAoB,EAAE,mBAAmB,KAAK,kBAAkB,IAAI,CAAC;AAAA,UAC9E,GAAI,oBACD,EAAE,mBAAmB,kBAAkB,KAAK,KAAK,oBAAoB,EAAE,IACvE,CAAC;AAAA,UACJ,gBAAgB,CAAC,UAAU,KAAK,mBAAmB,KAAK;AAAA,QACzD,CAAC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYA,MAAM,YAAY,IAAqE;AACtF,cAAM,KAAK,KAAK,kBAAkB;AAClC,YAAI;AACH,gBAAM,GAAG,EAAE;AAAA,QACZ,SAAS,OAAO;AACf,aAAG,SAAS;AACZ,gBAAM;AAAA,QACP;AACA,cAAM,EAAE,WAAW,IAAI,MAAM,GAAG,OAAO;AAGvC,mBAAW,MAAM,YAAY;AAC5B,eAAK,sBAAsB,GAAG,YAAY,EAAE;AAAA,QAC7C;AAEA,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,aAAa,SAA8C;AAChE,aAAK,WAAW;AAChB,cAAM,EAAE,cAAc,SAAS,IAAI,MAAM;AACzC,eAAO,SAAS,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,KAAK,OAAO,SAAS,OAAO;AAAA,MACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAsBA,MAAM,aACL,MACA,SACA,UACyB;AACzB,aAAK,WAAW;AAChB,cAAM,UAAU,KAAK,IAAI;AACzB,cAAM,aAAa,SAAS,eAAe,MAAM;AAAA,QAAC;AAClD,cAAM,EAAE,mBAAAC,oBAAmB,aAAAC,aAAY,IAAI,MAAM;AACjD,cAAM,EAAE,cAAAC,eAAc,gBAAAC,gBAAe,IAAI,MAAM;AAC/C,mBAAW,EAAE,OAAO,aAAa,UAAU,GAAG,SAAS,mBAAmB,CAAC;AAC3E,YAAI;AACJ,YAAI;AACH,mBAAS,MAAMF;AAAA,YACd;AAAA,YACA,SAAS,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI;AAAA,UAC/D;AAAA,QACD,SAAS,OAAO;AACf,cAAI,EAAE,iBAAiBD,oBAAoB,OAAM;AACjD,iBAAO;AAAA,YACN,oBAAoB;AAAA,YACpB,iBAAiB;AAAA,YACjB,SAAS;AAAA,YACT,OAAO,MAAM;AAAA,YACb,WAAW,MAAM;AAAA,YACjB,UAAU,KAAK,IAAI,IAAI;AAAA,UACxB;AAAA,QACD;AACA,YAAI,OAAO,SAAS,gBAAgB,KAAK,OAAO,SAAS;AACxD,iBAAO;AAAA,YACN,oBAAoB;AAAA,YACpB,iBAAiB;AAAA,YACjB,SAAS;AAAA,YACT,OAAO,4CAA4C,OAAO,SAAS,aAAa,2BAA2B,KAAK,OAAO,OAAO;AAAA,YAC9H,WAAW;AAAA,YACX,UAAU,KAAK,IAAI,IAAI;AAAA,UACxB;AAAA,QACD;AACA,mBAAW,EAAE,OAAO,aAAa,UAAU,KAAK,SAAS,YAAY,CAAC;AACtE,cAAM,sBAAsB,IAAI,IAAK,MAAM,yBAAyB,KAAK,OAAO,KAAM,CAAC,CAAC;AACxF,cAAM,OAAO;AAAA,UACZ,SAAS,KAAK;AAAA,UACd,QAAQ,KAAK;AAAA,UACb,gBACC,UAAU,mBAAmB,CAAC,OAAkB,KAAK,qBAAqB,EAAE;AAAA,UAC7E,gBAAgB,MAAM,eAAe,KAAK,OAAO;AAAA,UACjD,mBAAmB,CAAC,eACnB,gCAAiB,MAAM,KAAK,oBAAoB,IAAI,MAAM;AAAA,QAC5D;AACA,YAAI,SAAS,MAAO,OAAM,KAAK,qBAAqB,QAAQ,QAAQ,gBAAgB,MAAS;AAC7F,cAAM,SAAS,SAAS,QACrB,MAAME,cAAa,MAAM,QAAQ,QAAQ,gBAAgB,MAAS,IAClE,MAAMC,gBAAe,MAAM,QAAQ;AAAA,UACnC,aAAa,SAAS,eAAe;AAAA,UACrC,oBAAoB,SAAS,sBAAsB;AAAA,QACpD,CAAC;AACH,YAAI,CAAC,SAAS,SAAS,KAAK,QAAQ;AAKnC,gBAAM,KAAK,QAAQ,QAAQ,wCAAwC;AAAA,YAClE;AAAA,UACD,CAAC;AACD,eAAK,aAAa;AAClB,gBAAM,KAAK,sBAAsB,OAAO,SAAS,sBAAsB,IAAI;AAAA,QAC5E;AACA,cAAM,KAAK,eAAe;AAC1B,mBAAW,EAAE,OAAO,aAAa,UAAU,GAAG,SAAS,OAAO,CAAC;AAC/D,eAAO;AAAA,UACN,oBAAoB,OAAO;AAAA,UAC3B,iBAAiB,OAAO;AAAA,UACxB,GAAI,SAAS,QAAQ,CAAC,IAAI,EAAE,oBAAoB,OAAO,mBAAmB;AAAA,UAC1E,GAAI,OAAO,0BACR,EAAE,yBAAyB,OAAO,wBAAwB,IAC1D,CAAC;AAAA,UACJ,SAAS;AAAA,UACT,UAAU,KAAK,IAAI,IAAI;AAAA,QACxB;AAAA,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAc,qBACb,QACA,UACgB;AAChB,cAAM,SAAS,KAAK,WAAW;AAC/B,YAAI,CAAC,OAAQ;AACb,cAAM,UAAU,oBAAI,IAAyB;AAC7C,cAAM,KAAK,QAAQ,YAAY,OAAO,OAAO;AAC5C,qBAAW,CAAC,MAAM,IAAI,KAAK;AAAA,YAC1B,CAAC,OAAO,WAAW,MAAM;AAAA,YACzB,CAAC,OAAO,eAAe,UAAU;AAAA,UAClC,GAAY;AACX,uBAAW,OAAO,MAAM;AACvB,kBAAI,CAAC,KAAK,OAAO,YAAY,IAAI,UAAU,EAAG;AAC9C,kBAAI;AACJ,kBAAI;AACH,4BAAQ,oCAAqB,IAAI,KAAK;AAAA,cACvC,QAAQ;AACP;AAAA,cACD;AACA,kBAAI,MAAM,MAAM,IAAI,cAAc,MAAM,MAAM,IAAI,SAAU;AAC5D,kBAAI,SAAS,OAAQ,OAAM,OAAO,aAAa,IAAI,KAAK;AAAA,kBACnD,OAAM,OAAO,aAAa,IAAI,KAAK;AACxC,oBAAM,MAAM,QAAQ,IAAI,IAAI,UAAU,KAAK,oBAAI,IAAY;AAC3D,kBAAI,IAAI,IAAI,QAAQ;AACpB,sBAAQ,IAAI,IAAI,YAAY,GAAG;AAAA,YAChC;AAAA,UACD;AACA,cAAI,CAAC,UAAU;AACd,uBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,kBAAkB;AACzD,oBAAM,GAAG;AAAA,gBACR,eAAe,uBAAuB;AAAA;AAAA,gBAEtC,CAAC,QAAQ,QAAQ;AAAA,cAClB;AAAA,YACD;AAAA,UACD;AACA,qBAAW,CAAC,YAAY,GAAG,KAAK,SAAS;AACxC,uBAAW,YAAY,IAAK,OAAM,OAAO,WAAW,IAAI,YAAY,QAAQ;AAAA,UAC7E;AAAA,QACD,CAAC;AACD,mBAAW,CAAC,YAAY,GAAG,KAAK;AAC/B,eAAK,oBAAoB,WAAW,YAAY,CAAC,GAAG,GAAG,CAAC;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,MAAM,iBAAgC;AACrC,aAAK,WAAW;AAChB,YAAI,SAAS,KAAK;AAClB,YAAI,CAAC,KAAK,gBAAgB,KAAK,cAAc,WAAW;AACvD,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B;AAAA,UACD;AACA,mBAAS,KAAK,CAAC,GAAG,SAAS,KAAK;AAAA,QACjC;AACA,cAAM,KAAK,aAAa,MAAM;AAC9B,cAAM,SAAS,MAAM,KAAK,uBAAuB;AACjD,YAAI,UAAU,KAAK,OAAO;AACzB,eAAK,MAAM,UAAU,EAAE,GAAG,QAAQ,QAAQ,KAAK,OAAO,CAAC;AAAA,QACxD;AACA,mBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,eAAK,oBAAoB,WAAW,UAAU;AAAA,QAC/C;AAAA,MACD;AAAA;AAAA,MAGA,MAAc,yBAAuD;AACpE,YAAI,SAAwB;AAC5B,mBAAW,cAAc,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAC9D,gBAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,YAC/B,uCAAmC,0BAAW,aAAa,UAAU,EAAE,CAAC;AAAA,UACzE;AACA,gBAAM,QAAQ,KAAK,CAAC,GAAG,KAAK;AAC5B,cAAI,UAAU,SAAS,WAAW,QAAQ,QAAQ,QAAS,UAAS;AAAA,QACrE;AACA,eAAO,WAAW,OAAO,OAAO,iCAAmB,YAAY,MAAM;AAAA,MACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,OAAO,mBAAmB,MAAkC;AAC3D,eAAO,mBAAa,IAAI;AAAA,MACzB;AAAA,MAEQ,wBAAwB,WAA4B;AAC3D,cAAM,OAAO,KAAK,cAAc,IAAI,UAAU,MAAM,KAAK;AACzD,YAAI,UAAU,iBAAiB,MAAM;AACpC,eAAK,cAAc,IAAI,UAAU,QAAQ,UAAU,cAAc;AAAA,QAClE;AACA,YAAI,UAAU,WAAW,KAAK,QAAQ;AACrC,eAAK,iBAAiB,KAAK,IAAI,KAAK,gBAAgB,UAAU,cAAc;AAAA,QAC7E;AAAA,MACD;AAAA;AAAA,MAGQ,sBAAsB,YAAoB,WAA4B;AAC7E,aAAK,wBAAwB,SAAS;AACtC,aAAK,oBAAoB,OAAO,YAAY,SAAS;AACrD,aAAK,SAAS,KAAK,EAAE,MAAM,qBAAqB,UAAU,CAAC;AAAA,MAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOQ,mBAAmB,OAAsB;AAChD,YAAI,CAAC,mBAAmB,KAAK,EAAG;AAChC,aAAK,SAAS,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,QAAQ,KAAK;AAAA,UACb,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC/D,CAAC;AAAA,MACF;AAAA;AAAA,MAGQ,YAAY,eAAgD;AACnE,cAAM,QAAQ,IAAI,wBAAwB,KAAK,QAAQ,eAAe,KAAK,OAAO,OAAO;AACzF,aAAK,SAAS,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,QAAQ,KAAK;AAAA,UACb;AAAA,UACA,aAAa,KAAK,OAAO;AAAA,UACzB,SAAS,MAAM;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,wBAAuC;AACpD,cAAM,QAAQ,KAAK;AACnB,YAAI,CAAC,MAAO,OAAM,IAAI,kBAAkB;AACxC,cAAM,OAAO,KAAK,WAAW;AAC7B,cAAM,oBAAoB;AAAA,UACzB,SAAS,KAAK;AAAA,UACd,QAAQ,KAAK;AAAA,UACb,KAAK;AAAA,YACJ,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,YACvB,QAAQ,KAAK;AAAA,YACb;AAAA,YACA,QAAQ,KAAK;AAAA,YACb,kBAAkB;AAAA,YAClB,GAAI,KAAK,oBAAoB,EAAE,mBAAmB,KAAK,kBAAkB,IAAI,CAAC;AAAA,UAC/E;AAAA,UACA,eAAe,KAAK;AAAA,UACpB,aAAa,CAAC,cAAc,KAAK,sBAAsB,UAAU,YAAY,SAAS;AAAA,QACvF,CAAC;AAAA,MACF;AAAA,MAEA,MAAc,uBAAwC;AAGrD,YAAI,KAAK,oBAAgB,gCAAiB,KAAK,YAAY,GAAG;AAC7D,gBAAM,IAAI,oBAAoB,KAAK,cAAc,oBAAoB;AAAA,QACtE;AACA,YAAI,KAAK,cAAc;AACtB,cAAI,KAAK,cAAc,WAAW;AACjC,kBAAM,KAAK,QAAQ;AAAA,cAClB;AAAA,cACA,CAAC,KAAK,YAAY;AAAA,YACnB;AAAA,UACD;AACA,iBAAO,KAAK;AAAA,QACb;AAEA,YAAI,KAAK,cAAc,WAAW;AACjC,iBAAO,oBAAoB,KAAK,MAAM;AAAA,QACvC;AAGA,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B;AAAA,QACD;AACA,YAAI,KAAK,CAAC,KAAK,KAAC,gCAAiB,KAAK,CAAC,EAAE,KAAK,GAAG;AAChD,iBAAO,KAAK,CAAC,EAAE;AAAA,QAChB;AAKA,cAAM,gBAAY,8BAAe;AACjC,cAAM,KAAK,QAAQ;AAAA,UAClB;AAAA,UACA,CAAC,SAAS;AAAA,QACX;AACA,eAAO;AAAA,MACR;AAAA,MAEA,MAAc,qBAAsC;AACnD,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B;AAAA,UACA,CAAC,KAAK,MAAM;AAAA,QACb;AACA,eAAO,KAAK,CAAC,GAAG,mBAAmB;AAAA,MACpC;AAAA,MAEA,MAAc,oBAA4C;AACzD,cAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,UAC/B;AAAA,QACD;AACA,cAAM,aAAS,mCAAoB;AACnC,mBAAW,OAAO,MAAM;AACvB,iBAAO,IAAI,IAAI,SAAS,IAAI,eAAe;AAAA,QAC5C;AACA,eAAO;AAAA,MACR;AAAA,MAEQ,aAAmB;AAC1B,YAAI,CAAC,KAAK,QAAQ;AACjB,gBAAM,IAAI,kBAAkB;AAAA,QAC7B;AAAA,MACD;AAAA,IACD;AAAA;AAAA;;;ACvsGA;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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BA;AAsBA;AACA;AAMA;AAiBA;AASA;AAIA;AACA;AACA;;;ACvCA,SAAS,wBAA0D;AAClE,QAAM,MAAO,WAAuE;AACpF,SAAO,KAAK,WAAW;AACxB;AAEA,SAAS,aAAa,OAAwB;AAC7C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC7D;AAgBO,IAAM,qBAAN,MAAyB;AAAA,EACvB,UAAoC;AAAA,IAC3C,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,EACZ;AAAA,EACQ,kBAA4D;AAAA,EACnD;AAAA,EACA;AAAA,EAEjB,YAAY,UAAqC,CAAC,GAAG;AACpD,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,kBAAkB,QAAQ;AAAA,EAChC;AAAA;AAAA,EAGA,SAAmC;AAClC,WAAO,EAAE,GAAG,KAAK,QAAQ;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAA2C;AAChD,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,WAAW,OAAO,QAAQ,cAAc,YAAY;AACxD,WAAK,OAAO,EAAE,OAAO,eAAe,WAAW,MAAM,CAAC;AACtD,UAAI,QAAS,MAAK,KAAK,eAAe,KAAK;AAC3C,aAAO,KAAK,OAAO;AAAA,IACpB;AACA,QAAI;AACH,YAAM,YAAa,MAAM,QAAQ,UAAU,MAAO;AAElD,UAAI,CAAC,KAAK,QAAQ,WAAW;AAC5B,aAAK,OAAO,EAAE,OAAO,YAAY,cAAc,eAAe,UAAU,CAAC;AAAA,MAC1E;AACA,WAAK,KAAK,WAAW,KAAK,QAAQ,SAAS;AAAA,IAC5C,SAAS,OAAO;AACf,WAAK,OAAO,EAAE,OAAO,SAAS,WAAW,OAAO,WAAW,aAAa,KAAK,EAAE,CAAC;AAChF,WAAK,KAAK,SAAS,OAAO,aAAa,KAAK,CAAC;AAAA,IAC9C;AACA,WAAO,KAAK,OAAO;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAA6C;AAC5C,QAAI,KAAK,gBAAiB,QAAO,KAAK;AACtC,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,WAAW,OAAO,QAAQ,YAAY,YAAY;AACtD,WAAK,OAAO,EAAE,OAAO,eAAe,WAAW,MAAM,CAAC;AACtD,UAAI,QAAS,MAAK,KAAK,eAAe,KAAK;AAC3C,aAAO,QAAQ,QAAQ,KAAK,OAAO,CAAC;AAAA,IACrC;AACA,QAAI,KAAK,QAAQ,UAAW,QAAO,QAAQ,QAAQ,KAAK,OAAO,CAAC;AAChE,UAAM,UAAU,QAAQ,QAAQ,KAAK,OAAO;AAC5C,SAAK,UAAU,EAAE,GAAG,KAAK,SAAS,WAAW,KAAK;AAClD,UAAM,WAAW,YAA+C;AAC/D,UAAI;AACH,cAAM,YAAa,MAAM,QAAQ,MAAO;AACxC,aAAK,OAAO,EAAE,OAAO,YAAY,cAAc,eAAe,UAAU,CAAC;AACzE,aAAK,KAAK,aAAa,SAAS;AAAA,MACjC,SAAS,OAAO;AACf,aAAK,OAAO,EAAE,OAAO,SAAS,WAAW,OAAO,WAAW,aAAa,KAAK,EAAE,CAAC;AAChF,aAAK,KAAK,SAAS,OAAO,aAAa,KAAK,CAAC;AAAA,MAC9C,UAAE;AACD,aAAK,kBAAkB;AAAA,MACxB;AACA,aAAO,KAAK,OAAO;AAAA,IACpB,GAAG;AACH,SAAK,kBAAkB;AACvB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,oBAAoB,SAAyC;AAC5D,QAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,UAAW;AACtD,SAAK,KAAK,QAAQ;AAAA,EACnB;AAAA,EAEQ,UAA4C;AACnD,WAAO,KAAK,oBAAoB,SAAY,sBAAsB,IAAI,KAAK;AAAA,EAC5E;AAAA,EAEQ,OAAO,MAAyD;AACvE,SAAK,UAAU,EAAE,GAAG,MAAM,WAAW,KAAK,QAAQ,UAAU;AAAA,EAC7D;AAAA,EAEQ,KACP,OACA,WACA,SACO;AACP,SAAK,SAAS,KAAK;AAAA,MAClB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACF;AACD;;;ACpLA,IAAM,cAAkC,OAAO,OAAO,CAAC,CAAC;AASjD,IAAM,aAAN,MAAuC;AAAA,EACrC,WAAyB;AAAA,EACzB,YAAY,oBAAI,IAAgB;AAAA,EAChC,mBAAwC;AAAA,EACxC,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,QAAsB;AAAA,EACb;AAAA,EAEjB,YAAY,cAA+B;AAC1C,SAAK,eAAe;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,CAAC,kBAA4C;AACxD,SAAK,UAAU,IAAI,aAAa;AAEhC,QAAI,CAAC,KAAK,QAAQ;AACjB,WAAK,kBAAkB;AAAA,IACxB;AAEA,WAAO,MAAM;AACZ,WAAK,UAAU,OAAO,aAAa;AACnC,UAAI,KAAK,UAAU,SAAS,GAAG;AAC9B,aAAK,iBAAiB;AAAA,MACvB;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAGA,cAAc,MAAoB;AACjC,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,MAAe;AAC5B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,MAAoB;AAC9B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,UAAgB;AACf,SAAK,iBAAiB;AACtB,SAAK,UAAU,MAAM;AACrB,SAAK,WAAW;AAChB,SAAK,qBAAqB;AAC1B,SAAK,QAAQ;AAAA,EACd;AAAA,EAEQ,oBAA0B;AACjC,SAAK,SAAS;AACd,SAAK,mBAAmB,KAAK,aAAa;AAAA,MACzC,CAAC,YAA0B;AAC1B,YAAI,CAAC,KAAK,OAAQ;AAClB,aAAK,qBAAqB;AAC1B,aAAK,QAAQ;AACb,aAAK,WAAW,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC;AAC1C,aAAK,gBAAgB;AAAA,MACtB;AAAA,MACA;AAAA;AAAA;AAAA,QAGC,SAAS,CAAC,YAAY;AACrB,cAAI,CAAC,KAAK,OAAQ;AAClB,eAAK,QAAQ,QAAQ;AACrB,eAAK,gBAAgB;AAAA,QACtB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,mBAAyB;AAChC,SAAK,SAAS;AACd,QAAI,KAAK,kBAAkB;AAC1B,WAAK,iBAAiB;AACtB,WAAK,mBAAmB;AAAA,IACzB;AAAA,EACD;AAAA,EAEQ,kBAAwB;AAC/B,eAAW,YAAY,KAAK,WAAW;AACtC,eAAS;AAAA,IACV;AAAA,EACD;AACD;;;ACnHA,IAAAC,gBAAiC;AAGjC,IAAM,4BAA4B;AAK3B,SAAS,iBAAiB,OAAoC;AACpE,QAAM,aAAa,MAAM,cAAc;AACvC,MAAI,WAAW,eAAe,2BAA2B;AACxD,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACD;;;ACdA;AAaO,IAAM,kBAAN,MAAsB;AAAA,EAG5B,YAA6B,WAAW,WAAW;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAFrB,UAAU,oBAAI,IAAwB;AAAA,EAI9C,YAAe,cAA8C;AAC5D,UAAM,MAAM,KAAK,OAAO,YAAY;AACpC,UAAM,WAAW,KAAK,QAAQ,IAAI,GAAG;AAErC,QAAI,UAAU;AACb,eAAS;AACT,aAAO,SAAS;AAAA,IACjB;AAEA,UAAM,aAAa,IAAI,WAAc,YAAY;AACjD,SAAK,QAAQ,IAAI,KAAK;AAAA,MACrB;AAAA,MACA,UAAU;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,cAA2C;AAClD,UAAM,MAAM,KAAK,OAAO,YAAY;AACpC,UAAM,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAClC,QAAI,CAAC,OAAO;AACX;AAAA,IACD;AAEA,UAAM;AACN,QAAI,MAAM,YAAY,GAAG;AACxB,YAAM,WAAW,QAAQ;AACzB,WAAK,QAAQ,OAAO,GAAG;AAAA,IACxB;AAAA,EACD;AAAA,EAEA,QAAc;AACb,eAAW,SAAS,KAAK,QAAQ,OAAO,GAAG;AAC1C,YAAM,WAAW,QAAQ;AAAA,IAC1B;AACA,SAAK,QAAQ,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,OAAe;AAClB,WAAO,KAAK,QAAQ;AAAA,EACrB;AAAA,EAEQ,OAAO,cAA6C;AAC3D,WAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,aAAa,cAAc,CAAC,CAAC;AAAA,EAClE;AACD;AAEA,IAAI,cAAsC;AAQnC,SAAS,2BAA4C;AAC3D,MAAI,CAAC,aAAa;AACjB,kBAAc,IAAI,gBAAgB;AAAA,EACnC;AACA,SAAO;AACR;;;AJ+BA;AASA;AAGA;AAGA;AAOA;AAOA;;;AK3IA,IAAAC,KAAmB;AACnB;AAUA,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAMC,YAAW;AACjB,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAMrB,SAAS,yBACf,SACqB;AACrB,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,EACD,IAAI;AAEJ,QAAM,MAAM,IAAM,OAAI;AACtB,QAAM,OAAO,IAAI,QAAQA,SAAQ;AACjC,QAAM,cAAc,IAAM,eAAY,IAAI;AAE1C,MAAI,OAAO,QAAQ;AACnB,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,QAAsB;AAC1B,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,UAAgC,CAAC;AAErC,QAAM,YAAY,oBAAI,IAAgB;AACtC,MAAI,WAAuC;AAAA,IAC1C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS,CAAC;AAAA,EACX;AACA,QAAM,gBAAgB,EAAE,SAAS,KAA0B;AAC3D,QAAM,mBAAmB,EAAE,SAAS,CAAC,EAAkB;AACvD,QAAM,sBAAsB,EAAE,SAAS,MAAM;AAC7C,MAAI,eAAqD;AAEzD,MAAI,oBAAyC;AAC7C,MAAI,wBAA6C;AACjD,MAAI,uBAA4C;AAEhD,QAAM,kBAAkB,MAAY;AACnC,eAAW;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,CAAC,GAAG,OAAO;AAAA,IACrB;AAAA,EACD;AAEA,QAAM,SAAS,MAAY;AAC1B,oBAAgB;AAChB,eAAW,YAAY,WAAW;AACjC,eAAS;AAAA,IACV;AAAA,EACD;AAEA,QAAM,mBAAmB,MAAY;AACpC,cAAU,YAAY,UAAU,SAAS;AACzC,cAAU,YAAY,UAAU,SAAS;AACzC,WAAO;AAAA,EACR;AAEA,QAAM,cAAc,MAAkC;AAEtD,QAAM,uBAAuB,MAA6B;AACzD,QAAI,MAAM;AACT,aAAO;AAAA,IACR;AACA,QAAI,YAAY;AACf,YAAM,WAAW,WAAW,oBAAoB,EAAE,cAAc,GAAG;AACnE,UAAI,UAAU;AACb,eAAO;AAAA,MACR;AAAA,IACD;AACA,WAAO;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,IACR;AAAA,EACD;AAEA,QAAM,YAAY,CAAC,QAAgB,SAAuB;AACzD,QAAI,CAAC,YAAY;AAChB;AAAA,IACD;AAEA,UAAM,YAAY,WAAW,oBAAoB;AACjD,UAAM,QAAgC;AAAA,MACrC,MAAM,qBAAqB;AAAA,MAC3B,QAAQ;AAAA,QACP,YAAY;AAAA,QACZ;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MACD;AAAA,IACD;AACA,cAAU,cAAc,KAAK;AAAA,EAC9B;AAEA,QAAM,cAAc,MAAY;AAC/B,QAAI,CAAC,YAAY;AAChB;AAAA,IACD;AAEA,UAAM,YAAY,WAAW,oBAAoB;AACjD,UAAM,UAAU,UAAU,cAAc;AACxC,QAAI,CAAC,SAAS,QAAQ;AACrB;AAAA,IACD;AACA,QACC,QAAQ,OAAO,eAAe,kBAC9B,QAAQ,OAAO,aAAa,YAC5B,QAAQ,OAAO,UAAU,WACxB;AACD;AAAA,IACD;AAEA,cAAU,cAAc,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EAC/C;AAEA,QAAM,sBAAsB,CAAC,UAAyB;AACrD,UAAM,UAAU,oBAAoB,KAAK;AACzC,QAAI,CAAC,SAAS;AACb;AAAA,IACD;AAEA,UAAM,kBAAoB,uBAAoB,GAAG;AACjD,QAAI,aAAa,iBAAiB,OAAO,GAAG;AAC3C;AAAA,IACD;AAEA,IAAE,eAAY,KAAK,SAAS,aAAa;AACzC,kBAAc,UAAU;AACxB,qBAAiB,UAAU,CAAC;AAC5B,qBAAiB;AAAA,EAClB;AAEA,QAAM,eAAe,YAA2B;AAC/C,UAAMC,YAAW,wBAAwB,cAAc,SAAS,iBAAiB,OAAO;AACxF,QAAI,iBAAiB,QAAQ,UAAU,sBAAsB;AAC5D,oBAAc,UAAUA;AACxB,uBAAiB,UAAU,CAAC;AAAA,IAC7B;AAEA,QAAI;AACH,YAAM,WAAW,OAAO,UAAU;AAAA,QACjC,CAAC,SAAS,GAAGA;AAAA,MACd,CAAC;AAAA,IACF,SAAS,OAAO;AACf,UAAI,CAAC,UAAU;AACd,gBAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAChE,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,QAAM,kBAAkB,MAAY;AACnC,QAAI,cAAc;AACjB,mBAAa,YAAY;AAAA,IAC1B;AACA,mBAAe,WAAW,MAAM;AAC/B,qBAAe;AACf,WAAK,aAAa;AAAA,IACnB,GAAG,mBAAmB;AAAA,EACvB;AAEA,QAAM,cAAc,CAAC,QAAoB,WAA0B;AAClE,qBAAiB;AACjB,QAAI,WAAW,eAAe,WAAW,iBAAiB,WAAW,oBAAoB;AACxF;AAAA,IACD;AAEA,qBAAiB,QAAQ,KAAK,MAAM;AAEpC,QAAI,oBAAoB,WAAW,YAAY;AAC9C,iBAAW,wBAAwB,EAAE,KAAK,gBAAgB,UAAU,WAAW,MAAM;AACrF,sBAAgB;AAChB;AAAA,IACD;AAEA,SAAK,aAAa;AAAA,EACnB;AAEA,QAAM,yBAAyB,MAAY;AAC1C,wBAAoB;AACpB,wBAAoB,MAClB,WAAW,cAAc,EACzB,MAAM,EAAE,IAAI,SAAS,CAAC,EACtB,UAAU,CAAC,YAAY;AACvB,YAAM,SAAS,QAAQ,CAAC;AACxB,UAAI,CAAC,QAAQ;AACZ;AAAA,MACD;AACA,0BAAoB,OAAO,SAAS,CAAC;AAAA,IACtC,CAAC;AAAA,EACH;AAEA,QAAM,sBAAsB,MAAY;AACvC,4BAAwB;AACxB,QAAI,CAAC,SAAS,CAAC,cAAc,CAAC,oBAAoB,SAAS;AAC1D;AAAA,IACD;AAEA,UAAM,UAAU,WAAW,wBAAwB;AACnD,QAAI,CAAC,SAAS;AACb;AAAA,IACD;AAEA,4BAAwB,QAAQ,UAAU,gBAAgB,UAAU,WAAW,CAAC,WAAW;AAC1F,MAAE,eAAY,KAAK,QAAQ,kBAAkB;AAC7C,uBAAiB;AAAA,IAClB,CAAC;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAY;AACjC,QAAI,CAAC,YAAY;AAChB,gBAAU,CAAC;AACX,aAAO;AACP;AAAA,IACD;AAEA,UAAM,YAAY,WAAW,oBAAoB;AACjD,UAAM,gBAAgB,UAAU;AAChC,UAAM,SAAS,UAAU,UAAU;AACnC,UAAM,eAAqC,CAAC;AAE5C,eAAW,CAAC,UAAU,KAAK,KAAK,QAAQ;AACvC,UAAI,aAAa,cAAe;AAChC,UAAI,CAAC,MAAM,OAAQ;AACnB,UACC,MAAM,OAAO,eAAe,kBAC5B,MAAM,OAAO,aAAa,YAC1B,MAAM,OAAO,UAAU,WACtB;AACD;AAAA,MACD;AACA,mBAAa,KAAK;AAAA,QACjB;AAAA,QACA,UAAU,MAAM,KAAK;AAAA,QACrB,OAAO,MAAM,KAAK;AAAA,QAClB,QAAQ,MAAM,OAAO;AAAA,QACrB,MAAM,MAAM,OAAO;AAAA,MACpB,CAAC;AAAA,IACF;AAEA,cAAU;AACV,WAAO;AAAA,EACR;AAEA,QAAM,qBAAqB,MAAY;AACtC,2BAAuB;AACvB,QAAI,CAAC,YAAY;AAChB,gBAAU,CAAC;AACX,aAAO;AACP;AAAA,IACD;AAEA,UAAM,YAAY,WAAW,oBAAoB;AACjD,2BAAuB,UAAU,GAAG,UAAU,MAAM;AACnD,oBAAc;AAAA,IACf,CAAC;AACD,kBAAc;AAAA,EACf;AAEA,QAAM,aAAa,YAA2B;AAC7C,YAAQ;AACR,YAAQ;AACR,WAAO;AAEP,QAAI;AACH,YAAM,SAAS,MAAM,WAAW,SAAS,QAAQ;AACjD,UAAI,SAAU;AAEd,UAAI,SAAS,MAAM;AAClB,cAAM,SAAS,IAAI,QAAQD,SAAQ;AACnC,eAAO,OAAO,GAAG,OAAO,MAAM;AAAA,MAC/B,GAAG,WAAW;AAEd,YAAM,UAAU,oBAAoB,SAAS,SAAS,CAAC;AACvD,oBAAc,UAAU;AACxB,uBAAiB,UAAU,CAAC;AAC5B,UAAI,SAAS;AACZ,QAAE,eAAY,KAAK,SAAS,WAAW;AAAA,MACxC;AAEA,YAAM,UAAU,YAAY,wBAAwB;AACpD,0BAAoB,UACnB,SAAS,iBAAiB,SAAS,UAAU,GAAG,aAAa,KAAK;AAEnE,cAAQ;AACR,uBAAiB;AACjB,6BAAuB;AACvB,0BAAoB;AACpB,yBAAmB;AACnB,aAAO;AAAA,IACR,SAAS,OAAO;AACf,UAAI,SAAU;AACd,cAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAChE,aAAO;AAAA,IACR;AAAA,EACD;AAEA,MAAI,GAAG,UAAU,WAAW;AAC5B,OAAK,WAAW;AAEhB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,UAAU;AACnB,gBAAU,IAAI,QAAQ;AACtB,aAAO,MAAM;AACZ,kBAAU,OAAO,QAAQ;AAAA,MAC1B;AAAA,IACD;AAAA,IACA,OAAO;AACN,kBAAY,KAAK;AACjB,uBAAiB;AAAA,IAClB;AAAA,IACA,OAAO;AACN,kBAAY,KAAK;AACjB,uBAAiB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,UAA6C;AACpD,aAAO;AAAA,IACR;AAAA,IACA,UAAU;AACT,UAAI,UAAU;AACb;AAAA,MACD;AACA,iBAAW;AACX,UAAI,cAAc;AACjB,qBAAa,YAAY;AACzB,uBAAe;AAAA,MAChB;AACA,UAAI,IAAI,UAAU,WAAW;AAC7B,0BAAoB;AACpB,8BAAwB;AACxB,6BAAuB;AACvB,kBAAY;AACZ,kBAAY,QAAQ;AACpB,oBAAc,UAAU;AACxB,uBAAiB,UAAU,CAAC;AAC5B,0BAAoB,UAAU;AAC9B,gBAAU,MAAM;AAAA,IACjB;AAAA,EACD;AACD;AAEA,SAAS,oBAAoB,OAAmC;AAC/D,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,MAAI;AACH,WAAO,eAAe,KAA6C;AAAA,EACpE,QAAQ;AACP,QAAI,OAAO,UAAU,UAAU;AAC9B,YAAM,cAAc,IAAM,OAAI;AAC9B,kBAAY,QAAQA,SAAQ,EAAE,OAAO,GAAG,KAAK;AAC7C,aAAS,uBAAoB,WAAW;AAAA,IACzC;AACA,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC5F;AACD;AAEA,SAAS,wBAAwB,MAAyB,QAAkC;AAC3F,QAAM,YAAY,IAAM,OAAI;AAC5B,MAAI,MAAM;AACT,IAAE,eAAY,WAAW,IAAI;AAAA,EAC9B;AAEA,aAAW,SAAS,QAAQ;AAC3B,IAAE,eAAY,WAAW,KAAK;AAAA,EAC/B;AAEA,SAAS,uBAAoB,SAAS;AACvC;AAEA,SAAS,aAAa,MAAkB,OAA4B;AACnE,MAAI,KAAK,WAAW,MAAM,QAAQ;AACjC,WAAO;AAAA,EACR;AACA,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS;AACjD,QAAI,KAAK,KAAK,MAAM,MAAM,KAAK,GAAG;AACjC,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;;;AC1ZO,SAAS,qBAAqB,QAA4C;AAChF,MAAI,UAAU,MAAM;AACnB,WAAO;AAAA,EACR;AACA,SAAO;AACR;;;AN+IA;AAQA;;;AOlKA;;;APwLA;;;AQxLA;AAOA;AAMA;;;ACbA,IAAAE,gBAA4E;AAMrE,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC7C,YACU,cACA,YACR;AACD,UAAM,mDAAmD,YAAY,cAAc,UAAU,EAAE;AAHtF;AACA;AAGT,SAAK,OAAO;AAAA,EACb;AAAA,EALU;AAAA,EACA;AAKX;AAyCO,IAAM,kBAAN,MAA2D;AAAA,EAChD,QAAQ,oBAAI,IAAwB;AAAA,EAErD,MAAM,IAAI,OAAmB,WAA4B,CAAC,GAAqB;AAC9E,UAAM,MAAM,UAAM,6BAAc,OAAO,QAAQ;AAC/C,QAAI,CAAC,KAAK,MAAM,IAAI,IAAI,IAAI,GAAG;AAE9B,YAAM,SAAS,IAAI,WAAW,MAAM,UAAU;AAC9C,aAAO,IAAI,KAAK;AAChB,WAAK,MAAM,IAAI,IAAI,MAAM,MAAM;AAAA,IAChC;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,IAAI,MAA0C;AACnD,UAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAClC,QAAI,WAAW,QAAW;AACzB,aAAO;AAAA,IACR;AACA,UAAM,aAAa,UAAM,wBAAS,MAAM;AACxC,QAAI,eAAe,MAAM;AACxB,YAAM,IAAI,mBAAmB,MAAM,UAAU;AAAA,IAC9C;AAEA,UAAM,MAAM,IAAI,WAAW,OAAO,UAAU;AAC5C,QAAI,IAAI,MAAM;AACd,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,IAAI,MAAgC;AACzC,WAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,OAAO,MAAgC;AAC5C,WAAO,KAAK,MAAM,OAAO,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,OAAwB;AAC7B,WAAO,KAAK,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,OAA0B;AAC/B,WAAO,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC;AAAA,EAC7B;AACD;;;ACnGA,IAAAC,gBAA4E;AA2CrE,IAAM,gBAAN,MAAyD;AAAA,EAC/D,YAA6B,KAAwB;AAAxB;AAAA,EAAyB;AAAA,EAAzB;AAAA,EAErB,SAAS,MAAsB;AAEtC,WAAO,KAAK,MAAM,GAAG,CAAC;AAAA,EACvB;AAAA,EAEA,MAAM,IAAI,OAAmB,WAA4B,CAAC,GAAqB;AAC9E,UAAM,MAAM,UAAM,6BAAc,OAAO,QAAQ;AAC/C,UAAM,QAAQ,KAAK,SAAS,IAAI,IAAI;AAGpC,QAAI,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI,GAAG;AACxC,aAAO;AAAA,IACR;AAGA,UAAM,MAAM,IAAI,WAAW,MAAM,UAAU;AAC3C,QAAI,IAAI,KAAK;AACb,UAAM,KAAK,IAAI,MAAM,OAAO,IAAI,MAAM,GAAG;AACzC,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,IAAI,MAA0C;AACnD,UAAM,QAAQ,MAAM,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,IAAI;AAC3D,QAAI,UAAU,MAAM;AACnB,aAAO;AAAA,IACR;AACA,UAAM,SAAS,UAAM,wBAAS,KAAK;AACnC,QAAI,WAAW,MAAM;AACpB,YAAM,IAAI,mBAAmB,MAAM,MAAM;AAAA,IAC1C;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,IAAI,MAAgC;AACzC,WAAO,KAAK,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EAC9C;AAAA,EAEA,MAAM,OAAO,MAAgC;AAC5C,WAAO,KAAK,IAAI,OAAO,KAAK,SAAS,IAAI,GAAG,IAAI;AAAA,EACjD;AAAA,EAEA,MAAM,OAAwB;AAC7B,WAAO,KAAK,IAAI,MAAM;AAAA,EACvB;AAAA,EAEA,MAAM,OAA0B;AAC/B,WAAO,KAAK,IAAI,KAAK;AAAA,EACtB;AACD;AAwBA,SAAS,oBAAwC;AAChD,QAAM,MAAO,WAA2E;AACxF,MAAI,CAAC,KAAK,WAAW,OAAO,IAAI,QAAQ,iBAAiB,YAAY;AACpE,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,SAAO,IAAI;AACZ;AAEA,SAAS,gBAAgB,OAAyB;AACjD,SACC,OAAO,UAAU,YACjB,UAAU,QACT,MAA4B,SAAS;AAExC;AAUA,eAAsB,wBACrB,cAAc,cACe;AAC7B,QAAM,UAAU,kBAAkB;AAKlC,QAAM,WAAW,MAAM,QAAQ,aAAa;AAC5C,QAAM,OAAO,MAAM,SAAS,mBAAmB,aAAa,EAAE,QAAQ,KAAK,CAAC;AAE5E,iBAAe,YAAY,OAAe,QAAsD;AAC/F,QAAI;AACH,aAAO,MAAM,KAAK,mBAAmB,OAAO,EAAE,OAAO,CAAC;AAAA,IACvD,SAAS,OAAO;AACf,UAAI,gBAAgB,KAAK,GAAG;AAC3B,eAAO;AAAA,MACR;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AAAA,IACN,MAAM,KAAK,OAAO,MAAM;AACvB,YAAM,MAAM,MAAM,YAAY,OAAO,KAAK;AAC1C,UAAI,CAAC,KAAK;AACT,eAAO;AAAA,MACR;AACA,UAAI;AACJ,UAAI;AACH,iBAAS,MAAM,IAAI,cAAc,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,MACzD,SAAS,OAAO;AACf,YAAI,gBAAgB,KAAK,GAAG;AAC3B,iBAAO;AAAA,QACR;AACA,cAAM;AAAA,MACP;AACA,YAAM,OAAO,MAAM,OAAO,QAAQ;AAClC,aAAO,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AAAA,IAC/C;AAAA,IACA,MAAM,MAAM,OAAO,MAAM,OAAO;AAC/B,YAAM,MAAM,MAAM,KAAK,mBAAmB,OAAO,EAAE,QAAQ,KAAK,CAAC;AACjE,YAAM,SAAS,MAAM,IAAI,cAAc,MAAM,EAAE,QAAQ,KAAK,CAAC;AAI7D,YAAM,WAAW,MAAM,OAAO,eAAe,EAAE,kBAAkB,MAAM,CAAC;AACxE,UAAI;AACH,cAAM,SAAS,MAAM,KAAK;AAAA,MAC3B,UAAE;AACD,cAAM,SAAS,MAAM;AAAA,MACtB;AAAA,IACD;AAAA,IACA,MAAM,OAAO,OAAO,MAAM;AACzB,YAAM,MAAM,MAAM,YAAY,OAAO,KAAK;AAC1C,UAAI,CAAC,KAAK;AACT,eAAO;AAAA,MACR;AACA,UAAI;AACH,cAAM,IAAI,YAAY,IAAI;AAC1B,eAAO;AAAA,MACR,SAAS,OAAO;AACf,YAAI,gBAAgB,KAAK,GAAG;AAC3B,iBAAO;AAAA,QACR;AACA,cAAM;AAAA,MACP;AAAA,IACD;AAAA,IACA,MAAM,IAAI,OAAO,MAAM;AACtB,YAAM,MAAM,MAAM,YAAY,OAAO,KAAK;AAC1C,UAAI,CAAC,KAAK;AACT,eAAO;AAAA,MACR;AACA,UAAI;AACH,cAAM,IAAI,cAAc,MAAM,EAAE,QAAQ,MAAM,CAAC;AAC/C,eAAO;AAAA,MACR,SAAS,OAAO;AACf,YAAI,gBAAgB,KAAK,GAAG;AAC3B,iBAAO;AAAA,QACR;AACA,cAAM;AAAA,MACP;AAAA,IACD;AAAA,IACA,MAAM,QAAQ;AACb,UAAI,QAAQ;AACZ,uBAAiB,SAAS,KAAK,KAAK,GAAG;AACtC,cAAM,MAAM,MAAM,YAAY,OAAO,KAAK;AAC1C,YAAI,CAAC,KAAK;AACT;AAAA,QACD;AACA,yBAAiB,QAAQ,IAAI,KAAK,GAAG;AACpC,cAAI,CAAC,KAAK,SAAS,MAAM,GAAG;AAC3B;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,aAAO;AAAA,IACR;AAAA,IACA,MAAM,OAAO;AACZ,YAAM,QAAkB,CAAC;AACzB,uBAAiB,SAAS,KAAK,KAAK,GAAG;AACtC,cAAM,MAAM,MAAM,YAAY,OAAO,KAAK;AAC1C,YAAI,CAAC,KAAK;AACT;AAAA,QACD;AACA,yBAAiB,QAAQ,IAAI,KAAK,GAAG;AACpC,cAAI,CAAC,KAAK,SAAS,MAAM,GAAG;AAC3B,kBAAM,KAAK,IAAI;AAAA,UAChB;AAAA,QACD;AAAA,MACD;AACA,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAQA,eAAsB,oBAAoB,cAAc,cAAsC;AAC7F,SAAO,IAAI,cAAc,MAAM,wBAAwB,WAAW,CAAC;AACpE;;;AC5QA,IAAAC,gBAAyB;AAIlB,IAAM,qBAAqB,MAAM;AAqCxC,eAAsB,UACrB,OACA,YAAoB,oBACpB,WAAiC,CAAC,GACqC;AACvE,MAAI,aAAa,GAAG;AACnB,UAAM,IAAI,MAAM,gDAAgD,SAAS,EAAE;AAAA,EAC5E;AAEA,QAAM,cAAwB,CAAC;AAC/B,QAAM,SAAS,oBAAI,IAAwB;AAE3C,WAAS,SAAS,GAAG,SAAS,MAAM,YAAY,UAAU,WAAW;AACpE,UAAM,MAAM,KAAK,IAAI,SAAS,WAAW,MAAM,UAAU;AACzD,UAAM,QAAQ,IAAI,WAAW,MAAM,MAAM;AACzC,UAAM,IAAI,MAAM,SAAS,QAAQ,GAAG,CAAC;AACrC,UAAM,OAAO,UAAM,wBAAS,KAAK;AACjC,gBAAY,KAAK,IAAI;AAGrB,QAAI,CAAC,OAAO,IAAI,IAAI,GAAG;AACtB,aAAO,IAAI,MAAM,KAAK;AAAA,IACvB;AAAA,EACD;AAEA,QAAM,WAAW,UAAM,wBAAS,KAAK;AACrC,QAAM,WAAyB;AAAA,IAC9B;AAAA,IACA,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,EACD;AACA,MAAI,SAAS,aAAa,QAAW;AACpC,aAAS,WAAW,SAAS;AAAA,EAC9B;AACA,MAAI,SAAS,aAAa,QAAW;AACpC,aAAS,WAAW,SAAS;AAAA,EAC9B;AAEA,SAAO,EAAE,UAAU,OAAO;AAC3B;AAaA,eAAsB,eACrB,UACA,YACsB;AACtB,QAAM,QAAsB,CAAC;AAC7B,MAAI,QAAQ;AAEZ,aAAW,QAAQ,SAAS,aAAa;AACxC,UAAM,QAAQ,MAAM,WAAW,IAAI,IAAI;AACvC,QAAI,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,0BAA0B,SAAS,QAAQ,mBAAmB,IAAI,EAAE;AAAA,IACrF;AACA,UAAM,KAAK,KAAK;AAChB,aAAS,MAAM;AAAA,EAChB;AAEA,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACzB,QAAI,IAAI,MAAM,MAAM;AACpB,cAAU,KAAK;AAAA,EAChB;AAEA,QAAM,SAAS,UAAM,wBAAS,GAAG;AACjC,MAAI,WAAW,SAAS,UAAU;AACjC,UAAM,IAAI,mBAAmB,SAAS,UAAU,MAAM;AAAA,EACvD;AACA,SAAO;AACR;;;AC1HA,IAAAC,gBAAuC;AAwDvC,eAAsB,YACrB,UACA,UACA,QAC6B;AAC7B,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAKpB,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,SAAS,aAAa;AACxC,QAAI,KAAK,IAAI,IAAI,GAAG;AACnB;AAAA,IACD;AACA,SAAK,IAAI,IAAI;AAEb,QAAI,MAAM,OAAO,WAAW,IAAI,IAAI,GAAG;AACtC;AACA;AAAA,IACD;AAEA,UAAM,QAAQ,MAAM,SAAS,SAAS,IAAI;AAC1C,QAAI,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,yDAAyD,IAAI,EAAE;AAAA,IAChF;AACA,UAAM,SAAS,UAAM,wBAAS,KAAK;AACnC,QAAI,WAAW,MAAM;AACpB,YAAM,IAAI,mBAAmB,MAAM,MAAM;AAAA,IAC1C;AACA,UAAM,OAAO,WAAW,IAAI,KAAK;AACjC;AAAA,EACD;AAEA,QAAM,OAAO,MAAM,eAAe,UAAU,OAAO,UAAU;AAC7D,QAAM,MAAM,MAAM,OAAO,UAAU,IAAI,MAAM;AAAA,IAC5C,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,EACpB,CAAC;AAED,SAAO,EAAE,KAAK,eAAe,cAAc;AAC5C;AAYA,eAAsB,mBACrB,OACA,YACA,UAAwE,CAAC,GACV;AAC/D,QAAM,EAAE,UAAU,OAAO,IAAI,MAAM,UAAU,OAAO,QAAQ,WAAW;AAAA,IACtE,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,EACnB,CAAC;AACD,aAAW,SAAS,OAAO,OAAO,GAAG;AACpC,UAAM,WAAW,IAAI,KAAK;AAAA,EAC3B;AACA,QAAM,WAA0B;AAAA,IAC/B,UAAU,CAAC,SAAS,WAAW,IAAI,IAAI;AAAA,EACxC;AACA,SAAO,EAAE,UAAU,SAAS;AAC7B;;;AC9HA,IAAAC,gBAA6D;AAYtD,SAAS,sBAAsB,UAAoC;AACzE,QAAMC,aAAqC;AAAA,IAC1C,UAAU,SAAS;AAAA,IACnB,MAAM,SAAS;AAAA,IACf,WAAW,SAAS;AAAA,IACpB,aAAa,SAAS;AAAA,EACvB;AACA,MAAI,SAAS,aAAa,QAAW;AACpC,IAAAA,WAAU,WAAW,SAAS;AAAA,EAC/B;AACA,MAAI,SAAS,aAAa,QAAW;AACpC,IAAAA,WAAU,WAAW,SAAS;AAAA,EAC/B;AACA,SAAO,IAAI,YAAY,EAAE,OAAO,KAAK,UAAUA,UAAS,CAAC;AAC1D;AAMO,SAAS,kBAAkB,OAAiC;AAClE,QAAM,SAAkB,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AAClE,MAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AAClD,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACvD;AACA,QAAM,MAAM;AACZ,MAAI,OAAO,IAAI,aAAa,UAAU;AACrC,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC1D;AACA,MAAI,OAAO,IAAI,SAAS,YAAY,OAAO,IAAI,cAAc,UAAU;AACtE,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACnE;AACA,MAAI,CAAC,MAAM,QAAQ,IAAI,WAAW,KAAK,IAAI,YAAY,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AAC1F,UAAM,IAAI,MAAM,gEAAgE;AAAA,EACjF;AACA,QAAM,WAAyB;AAAA,IAC9B,UAAU,IAAI;AAAA,IACd,MAAM,IAAI;AAAA,IACV,WAAW,IAAI;AAAA,IACf,aAAa,IAAI;AAAA,EAClB;AACA,MAAI,OAAO,IAAI,aAAa,UAAU;AACrC,aAAS,WAAW,IAAI;AAAA,EACzB;AACA,MAAI,OAAO,IAAI,aAAa,UAAU;AACrC,aAAS,WAAW,IAAI;AAAA,EACzB;AACA,SAAO;AACR;AAgBA,eAAsB,mBACrB,OACA,OACA,UAAoD,CAAC,GACD;AACpD,QAAM,EAAE,UAAU,OAAO,IAAI,MAAM,UAAU,OAAO,QAAQ,WAAW;AAAA,IACtE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IACvE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EACxE,CAAC;AACD,aAAW,SAAS,OAAO,OAAO,GAAG;AACpC,UAAM,MAAM,IAAI,KAAK;AAAA,EACtB;AAEA,QAAM,UAAU,MAAM,MAAM,IAAI,OAAO;AAAA,IACtC,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IACvE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EACxE,CAAC;AAED,QAAM,cAAc,MAAM,MAAM,IAAI,sBAAsB,QAAQ,CAAC;AACnE,SAAO,EAAE,KAAK,EAAE,GAAG,SAAS,cAAc,YAAY,KAAK,GAAG,SAAS;AACxE;AAcA,eAAsB,kBACrB,UACA,cACwB;AACxB,QAAM,QAAQ,MAAM,SAAS,SAAS,YAAY;AAClD,MAAI,UAAU,MAAM;AACnB,UAAM,IAAI,MAAM,iBAAiB,YAAY,yCAAyC;AAAA,EACvF;AACA,QAAM,SAAS,UAAM,wBAAS,KAAK;AACnC,MAAI,WAAW,cAAc;AAC5B,UAAM,IAAI,mBAAmB,cAAc,MAAM;AAAA,EAClD;AACA,SAAO,kBAAkB,KAAK;AAC/B;AASA,eAAsB,oBACrB,UACA,KACwB;AACxB,MAAI,IAAI,iBAAiB,QAAW;AACnC,UAAM,IAAI;AAAA,MACT,QAAQ,IAAI,IAAI;AAAA,IACjB;AAAA,EACD;AACA,SAAO,kBAAkB,UAAU,IAAI,YAAY;AACpD;;;AC9IA,IAAAC,gBAAyB;AA2BlB,SAAS,sBAAsB,OAAuD;AAC5F,SAAO;AAAA,IACN,kBAAkB,CAAC,SAAS,MAAM,IAAI,IAAI;AAAA,IAC1C,MAAM,iBAAiB,MAAM,OAAO;AAInC,YAAM,SAAS,UAAM,wBAAS,KAAK;AACnC,UAAI,WAAW,MAAM;AACpB;AAAA,MACD;AACA,YAAM,MAAM,IAAI,KAAK;AAAA,IACtB;AAAA,EACD;AACD;AAOO,SAAS,8BAGd;AACD,QAAM,QAAQ,IAAI,gBAAgB;AAClC,SAAO,EAAE,OAAO,WAAW,sBAAsB,KAAK,EAAE;AACzD;;;ACtDA,IAAAC,gBAAwC;AA2BjC,SAAS,gBAAgB,QAA4C;AAC3E,QAAM,OAAkB,CAAC;AACzB,aAAW,SAAS,OAAO,OAAO,MAAM,GAAG;AAC1C,YAAI,yBAAU,KAAK,GAAG;AACrB,WAAK,KAAK,KAAK;AAAA,IAChB;AAAA,EACD;AACA,SAAO;AACR;AA0BA,eAAsB,mBACrB,OACA,UACA,UAAyB,CAAC,GACF;AACxB,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,UAAU;AAC3B,SAAK,IAAI,IAAI,IAAI;AACjB,QAAI,IAAI,iBAAiB,QAAW;AACnC;AAAA,IACD;AACA,SAAK,IAAI,IAAI,YAAY;AACzB,QAAI;AACH,YAAM,gBAAgB,MAAM,MAAM,IAAI,IAAI,YAAY;AACtD,UAAI,kBAAkB,MAAM;AAC3B,cAAM,WAAW,kBAAkB,aAAa;AAChD,mBAAW,aAAa,SAAS,aAAa;AAC7C,eAAK,IAAI,SAAS;AAAA,QACnB;AAAA,MACD;AAAA,IACD,QAAQ;AAAA,IAGR;AAAA,EACD;AAEA,QAAM,MAAM,MAAM,MAAM,KAAK;AAC7B,QAAM,kBAA4B,CAAC;AACnC,aAAW,QAAQ,KAAK;AACvB,QAAI,KAAK,IAAI,IAAI,GAAG;AACnB;AAAA,IACD;AACA,oBAAgB,KAAK,IAAI;AACzB,QAAI,CAAC,QAAQ,QAAQ;AACpB,YAAM,MAAM,OAAO,IAAI;AAAA,IACxB;AAAA,EACD;AAEA,SAAO;AAAA,IACN,SAAS,IAAI;AAAA,IACb,MAAM,KAAK;AAAA,IACX,WAAW,gBAAgB;AAAA,IAC3B;AAAA,EACD;AACD;;;ACzGA,IAAAC,gBAA+B;AA2ExB,SAAS,0BACf,MACA,UAAsC,CAAC,GACjB;AACtB,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,oBAAoB,QAAQ,qBAAqB,KAAK;AAC5D,QAAM,aAAa,QAAQ,sBAAsB;AACjD,QAAM,aAAa,QAAQ,sBAAsB;AACjD,QAAM,UAAU,oBAAI,IAUlB;AAEF,QAAM,aAAa,CAAC,WAAmB,SACtC,WAAW,MAAM;AAChB,UAAM,QAAQ,QAAQ,IAAI,SAAS;AACnC,QAAI,CAAC,MAAO;AACZ,YAAQ,OAAO,SAAS;AACxB,UAAM,OAAO,IAAI,MAAM,0BAA0B,IAAI,oBAAoB,SAAS,IAAI,CAAC;AAAA,EACxF,GAAG,SAAS;AAEb,OAAK,UAAU,CAAC,YAAY;AAC3B,QAAI,QAAQ,SAAS,uBAAuB;AAC3C;AAAA,IACD;AACA,UAAM,QAAQ,QAAQ,IAAI,QAAQ,SAAS;AAC3C,QAAI,CAAC,OAAO;AACX;AAAA,IACD;AACA,iBAAa,MAAM,KAAK;AACxB,QAAI,QAAQ,cAAc,MAAM;AAE/B,YAAM,kBAAkB;AACxB,YAAM,UAAU,KAAK,IAAI,YAAY,aAAa,MAAM,MAAM,iBAAiB,EAAE;AACjF,YAAM,QAAQ,KAAK,IAAI,YAAY,KAAK,IAAI,YAAY,QAAQ,gBAAgB,OAAO,CAAC;AACxF,UAAI,KAAK,IAAI,IAAI,QAAQ,MAAM,cAAc,mBAAmB;AAC/D,gBAAQ,OAAO,QAAQ,SAAS;AAChC,cAAM;AAAA,UACL,IAAI;AAAA,YACH,0BAA0B,MAAM,IAAI,kCAAkC,iBAAiB;AAAA,UACxF;AAAA,QACD;AACA;AAAA,MACD;AACA,YAAM,QAAQ,WAAW,MAAM;AAC9B,YAAI,QAAQ,IAAI,QAAQ,SAAS,MAAM,MAAO;AAC9C,cAAM,QAAQ,WAAW,QAAQ,WAAW,MAAM,IAAI;AACtD,aAAK,KAAK,EAAE,MAAM,sBAAsB,WAAW,QAAQ,WAAW,MAAM,MAAM,KAAK,CAAC;AAAA,MACzF,GAAG,KAAK;AACR;AAAA,IACD;AACA,YAAQ,OAAO,QAAQ,SAAS;AAChC,UAAM,QAAQ,QAAQ,KAAK;AAAA,EAC5B,CAAC;AAED,SAAO;AAAA,IACN,cAAc,MAAM,QAAQ;AAAA,IAC5B,SAAS,MAA0C;AAClD,YAAM,gBAAY,8BAAe;AACjC,aAAO,IAAI,QAA2B,CAAC,SAAS,WAAW;AAC1D,gBAAQ,IAAI,WAAW;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,WAAW,WAAW,IAAI;AAAA,UACjC,aAAa,KAAK,IAAI;AAAA,UACtB,gBAAgB;AAAA,QACjB,CAAC;AACD,aAAK,KAAK,EAAE,MAAM,sBAAsB,WAAW,KAAK,CAAC;AAAA,MAC1D,CAAC;AAAA,IACF;AAAA,EACD;AACD;AAUO,SAAS,gBACf,MACA,WACO;AACP,OAAK,UAAU,CAAC,YAAY;AAC3B,QAAI,QAAQ,SAAS,sBAAsB;AAC1C;AAAA,IACD;AACA,SAAK,UAAU,IAAI,QAAQ,IAAI,EAAE;AAAA,MAChC,CAAC,UAAU;AACV,aAAK,KAAK,EAAE,MAAM,uBAAuB,WAAW,QAAQ,WAAW,MAAM,CAAC;AAAA,MAC/E;AAAA,MACA,MAAM;AAGL,aAAK,KAAK,EAAE,MAAM,uBAAuB,WAAW,QAAQ,WAAW,OAAO,KAAK,CAAC;AAAA,MACrF;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAOO,SAAS,sBAAoE;AACnF,QAAM,YAA8C,CAAC;AACrD,QAAM,YAA8C,CAAC;AAErD,QAAM,IAAsB;AAAA,IAC3B,KAAK,SAAS;AACb,qBAAe,MAAM;AACpB,mBAAW,WAAW,WAAW;AAChC,kBAAQ,OAAO;AAAA,QAChB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,UAAU,SAAS;AAClB,gBAAU,KAAK,OAAO;AAAA,IACvB;AAAA,EACD;AACA,QAAM,IAAsB;AAAA,IAC3B,KAAK,SAAS;AACb,qBAAe,MAAM;AACpB,mBAAW,WAAW,WAAW;AAChC,kBAAQ,OAAO;AAAA,QAChB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,UAAU,SAAS;AAClB,gBAAU,KAAK,OAAO;AAAA,IACvB;AAAA,EACD;AACA,SAAO,EAAE,GAAG,EAAE;AACf;","names":["import_core","import_core","import_core","import_core","import_core","import_core","import_core","import_core","import_core","Y","import_core","bytesReplacer","Store","import_core","import_core","import_core","rowVersion","import_core","import_core","import_core","import_core","import_core","import_core","canonical","import_core","import_core","import_core","import_core","propName","import_core","import_core","import_internal","import_core","import_core","import_core","import_core","import_core","import_core","import_internal","import_internal","import_core","import_core","encodeSection","encodeJsonSection","encodeNdjsonSection","parseSections","findSection","computeSha256","import_core","import_core","import_core","rowVersion","readAuditTraces","fresh","BackupFormatError","parseBackup","restoreMerge","restoreReplace","import_core","Y","TEXT_KEY","snapshot","import_core","import_core","import_core","import_core","import_core","canonical","import_core","import_core","import_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/compaction/types.ts","../src/compaction/compact-operation-log.ts","../src/lww/row-version.ts","../src/serialization/op-data-encoding.ts","../src/serialization/richtext-serializer.ts","../src/serialization/serializer.ts","../src/query/sql-builder.ts","../src/sync/rehash-operation.ts","../src/store/sequence-allocator.ts","../src/store/sequence-repair.ts","../src/sync/sync-state.ts","../src/sync/sync-durability.ts","../src/sync/local-sync-records.ts","../src/fold/record-folder.ts","../src/log-integrity/log-integrity.ts","../src/backup/backup.ts","../src/mutations/write-context.ts","../src/mutations/run-local-write.ts","../src/lww/field-versions.ts","../src/state-machine/state-validator.ts","../src/mutations/secret-write.ts","../src/mutations/write-ops.ts","../src/mutations/execute-delete.ts","../src/mutations/execute-insert.ts","../src/mutations/execute-update.ts","../src/collection/collection.ts","../src/fold/compact-folded-log.ts","../src/fold/legacy-bodies.ts","../src/fold/rematerialize.ts","../src/migrations/run-migrations.ts","../src/migrations/schema-ceiling.ts","../src/subscription/result-equality.ts","../src/query/pluralize.ts","../src/query/query-key.ts","../src/query/query-builder.ts","../src/relations/relation-lookup.ts","../src/relations/relation-enforcer.ts","../src/replay/replay-to.ts","../src/sequences/sequence-manager.ts","../src/serialization/stored-text-migration.ts","../src/subscription/bloom-filter.ts","../src/subscription/subscription-manager.ts","../src/sync/rebase-unsynced-operations.ts","../src/sync/rotate-node-id.ts","../src/transaction/transaction-context.ts","../src/store/legacy-indexes.ts","../src/store/node-lock.ts","../src/store/relax-constraints.ts","../src/store/tab-node-id.ts","../src/audit/audit-json.ts","../src/audit/audit-trace-store.ts","../src/audit/export-audit.ts","../src/backup/restore.ts","../src/store/store.ts","../src/index.ts","../src/persistence/storage-persistence.ts","../src/reactivity/query-store.ts","../src/reactivity/assert-query-ready.ts","../src/reactivity/query-store-cache.ts","../src/richtext/create-richtext-controller.ts","../src/richtext/as-rich-text-sync-engine.ts","../src/backup/index.ts","../src/audit/index.ts","../src/blob/content-addressed-blob-store.ts","../src/blob/opfs-blob-store.ts","../src/blob/blob-chunking.ts","../src/blob/blob-transfer.ts","../src/blob/blob-manifest-transfer.ts","../src/blob/server-blob-callbacks.ts","../src/blob/blob-gc.ts","../src/blob/blob-chunk-transport.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\n\n/**\n * Thrown when a query is invalid (bad field names, invalid operators, etc.).\n */\nexport class QueryError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'QUERY_ERROR', context)\n\t\tthis.name = 'QueryError'\n\t}\n}\n\n/**\n * Thrown when a record is not found by ID (findById, update, delete on missing record).\n */\nexport class RecordNotFoundError extends KoraError {\n\tconstructor(collection: string, recordId: string) {\n\t\tsuper(`Record \"${recordId}\" not found in collection \"${collection}\"`, 'RECORD_NOT_FOUND', {\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t})\n\t\tthis.name = 'RecordNotFoundError'\n\t}\n}\n\n/**\n * Thrown inside `applyRemoteOperation` when the row's version state changed\n * between the caller's snapshot read and the guarded write (a concurrent local\n * mutation landed in the window). The transaction is rolled back with nothing\n * written; the caller re-reads fresh state, recomputes its merge, and retries.\n * This is the optimistic-concurrency guard that keeps merge-engine results\n * (richtext, add-wins arrays, constraint resolutions) from clobbering newer\n * local edits they never saw.\n */\nexport class OptimisticLockError extends KoraError {\n\tconstructor(collection: string, recordId: string) {\n\t\tsuper(\n\t\t\t`Row version changed while merging record \"${recordId}\" in \"${collection}\"; retry with fresh state`,\n\t\t\t'OPTIMISTIC_LOCK',\n\t\t\t{ collection, recordId },\n\t\t)\n\t\tthis.name = 'OptimisticLockError'\n\t}\n}\n\n/**\n * Thrown when a storage adapter operation fails.\n */\nexport class AdapterError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'ADAPTER_ERROR', context)\n\t\tthis.name = 'AdapterError'\n\t}\n}\n\n/**\n * Thrown when a write reaches a storage adapter that could not obtain durable\n * storage (it opened, or was promoted to leader, on a non-persistent in-memory\n * database). Kora refuses such writes instead of accepting data that would be\n * lost on reload. Reads still work.\n *\n * Fix: close other tabs or apps using the same origin's OPFS storage and reopen,\n * or opt in explicitly with `allowNonDurable: true` if in-memory storage is\n * acceptable for this app.\n */\nexport class StorageDurabilityError extends KoraError {\n\tconstructor(dbName: string, phase: 'open' | 'promotion', reason: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" has no durable storage (${reason} during ${phase}); writes are refused so they are not silently lost on reload. Close other tabs or apps using this origin's storage and reload, or set allowNonDurable: true to accept in-memory storage.`,\n\t\t\t'STORAGE_DURABILITY_LOST',\n\t\t\t{ dbName, phase, reason },\n\t\t)\n\t\tthis.name = 'StorageDurabilityError'\n\t}\n}\n\n/**\n * Thrown when the store opens a database a NEWER build of the app already migrated: its\n * stored schema version is above this code's `schema.version` (RT-109). Running older\n * code against it would write operations of the old schema into the new one, or fail\n * part-way, so the store refuses before changing anything and emits `store:schema-ahead`.\n *\n * Fix: run the newer build (reload while online, or accept the app's update prompt).\n * Never lower `schema.version` in a deployed app.\n */\nexport class SchemaVersionAheadError extends KoraError {\n\tconstructor(\n\t\tpublic readonly dbName: string,\n\t\tpublic readonly storedVersion: number,\n\t\tpublic readonly codeVersion: number,\n\t) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is at schema version ${storedVersion}, newer than this build's schema version ${codeVersion}: a newer build of the app already migrated it. It was not opened and nothing in it changed. Run the newer build (reload while online, or accept the update); never lower schema.version in a deployed app.`,\n\t\t\t'SCHEMA_VERSION_AHEAD',\n\t\t\t{ dbName, storedVersion, codeVersion },\n\t\t)\n\t\tthis.name = 'SchemaVersionAheadError'\n\t}\n}\n\n/**\n * Thrown when an operation is attempted on a store that has not been opened.\n */\nexport class StoreNotOpenError extends KoraError {\n\tconstructor() {\n\t\tsuper('Store is not open. Call store.open() before performing operations.', 'STORE_NOT_OPEN')\n\t\tthis.name = 'StoreNotOpenError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker fails to initialize (WASM load failure, OPFS unavailable, etc.).\n */\nexport class WorkerInitError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Worker initialization failed: ${message}`, 'WORKER_INIT_ERROR', context)\n\t\tthis.name = 'WorkerInitError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker does not respond within the configured timeout.\n */\nexport class WorkerTimeoutError extends KoraError {\n\tconstructor(operation: string, timeoutMs: number) {\n\t\tsuper(\n\t\t\t`Worker did not respond within ${timeoutMs}ms for operation \"${operation}\"`,\n\t\t\t'WORKER_TIMEOUT',\n\t\t\t{ operation, timeoutMs },\n\t\t)\n\t\tthis.name = 'WorkerTimeoutError'\n\t}\n}\n\n/**\n * Thrown when a follower tab cannot reach a live leader tab over the multi-tab\n * broadcast channel (the leader tab was closed, crashed, or is unresponsive).\n * Distinct from {@link WorkerTimeoutError}: this fails fast on a confirmed-absent\n * leader instead of waiting out the full RPC timeout.\n */\nexport class NoLeaderError extends KoraError {\n\tconstructor(\n\t\toperation: string,\n\t\tmessage = `No live leader tab is answering multi-tab storage RPC for operation \"${operation}\"`,\n\t\tcode = 'NO_LEADER',\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message, code, { operation, ...context })\n\t\tthis.name = 'NoLeaderError'\n\t}\n}\n\n/**\n * Thrown to a follower tab's pending storage requests when the leader tab that\n * was answering stopped sending heartbeats (hung, frozen, or suspended). The\n * request may or may not have been applied: retry it with the same `requestId`\n * (in the error context) and the leader de-duplicates it. Retriable.\n */\nexport class LeaderUnresponsiveError extends NoLeaderError {\n\tconstructor(operation: string, silentMs: number, requestId: string) {\n\t\tsuper(\n\t\t\toperation,\n\t\t\t`The leader tab stopped responding (no heartbeat for ${silentMs}ms) during \"${operation}\". The request may or may not have been applied; retry it with the same requestId and the leader de-duplicates it.`,\n\t\t\t'LEADER_UNRESPONSIVE',\n\t\t\t{ silentMs, requestId, retriable: true },\n\t\t)\n\t\tthis.name = 'LeaderUnresponsiveError'\n\t}\n}\n\n/**\n * Thrown to pending storage requests when their bridge was torn down, typically\n * because this tab was just promoted to leader or the leader handed over.\n * Retriable: the next attempt goes to the new leader.\n */\nexport class BridgeTerminatedError extends KoraError {\n\tconstructor(operation: string, reason: string) {\n\t\tsuper(\n\t\t\t`Storage request \"${operation}\" was interrupted (${reason}); retry it against the new storage leader.`,\n\t\t\t'BRIDGE_TERMINATED',\n\t\t\t{ operation, reason, retriable: true },\n\t\t)\n\t\tthis.name = 'BridgeTerminatedError'\n\t}\n}\n\n/** Thrown when a storage request is cancelled through its `AbortSignal`. */\nexport class RequestAbortedError extends KoraError {\n\tconstructor(operation: string, requestId: string) {\n\t\tsuper(\n\t\t\t`Storage request \"${operation}\" was aborted by the caller. A write may already have reached the leader; retry with the same requestId to stay idempotent.`,\n\t\t\t'REQUEST_ABORTED',\n\t\t\t{ operation, requestId },\n\t\t)\n\t\tthis.name = 'RequestAbortedError'\n\t}\n}\n\n/**\n * Thrown by `deleteDatabase()` when the database is open in some tab or worker\n * on this origin. Close it everywhere (or call `app.close()`) and retry.\n */\nexport class StorageInUseError extends KoraError {\n\tconstructor(dbName: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is open in a tab on this origin; close it before deleting it.`,\n\t\t\t'STORAGE_IN_USE',\n\t\t\t{ dbName },\n\t\t)\n\t\tthis.name = 'StorageInUseError'\n\t}\n}\n\n/**\n * Thrown by `deleteDatabase()` when the database still holds operations that\n * never reached the server. Sync first, or pass `{ force: true }` to discard them.\n */\nexport class UnsyncedDataError extends KoraError {\n\tconstructor(dbName: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" has unsynced operations; deleting it would lose them. Sync first, or pass { force: true } to discard them deliberately.`,\n\t\t\t'UNSYNCED_DATA',\n\t\t\t{ dbName },\n\t\t)\n\t\tthis.name = 'UnsyncedDataError'\n\t}\n}\n\n/**\n * Thrown when a database's data lives in a storage backend this runtime cannot\n * read (for example it was written to OPFS, and OPFS is unavailable now). Kora\n * refuses to start an empty, disjoint copy rather than hide the existing data.\n */\nexport class StorageBackendMismatchError extends KoraError {\n\tconstructor(dbName: string, recorded: string, requested: string, reason: string) {\n\t\tsuper(\n\t\t\t`Database \"${dbName}\" is stored in ${recorded}, but this session can only use ${requested} (${reason}). Kora will not start a separate empty copy; reload in a browser profile where ${recorded} is available.`,\n\t\t\t'STORAGE_BACKEND_MISMATCH',\n\t\t\t{ dbName, recorded, requested, reason },\n\t\t)\n\t\tthis.name = 'StorageBackendMismatchError'\n\t}\n}\n\n/**\n * Thrown when IndexedDB persistence operations fail (serialize/deserialize).\n */\nexport class PersistenceError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Persistence error: ${message}`, 'PERSISTENCE_ERROR', context)\n\t\tthis.name = 'PersistenceError'\n\t}\n}\n\n/**\n * Thrown by a local write while the store's pinned node id (an auth device id) belongs\n * to another user than the one signed in (F9): a browser two users shared. The write\n * could only be stored under the owner's node and would later upload as the owner's.\n */\nexport class NodeOwnedByAnotherUserError extends KoraError {\n\tconstructor(nodeId: string, principal: string | null) {\n\t\tsuper(\n\t\t\t\"This device belongs to another account, so changes made while this account is signed in here cannot be saved: they would be uploaded as the device owner's. Sign in as the device's owner, or use this account on its own device.\",\n\t\t\t'NODE_OWNED_BY_ANOTHER_USER',\n\t\t\t{ nodeId, principal },\n\t\t)\n\t\tthis.name = 'NodeOwnedByAnotherUserError'\n\t}\n}\n","import type { VersionVector } from '@korajs/core'\n\n/**\n * How the local operation log may be compacted.\n * Materialized collection rows are always kept as the convergence baseline.\n */\nexport type CompactionStrategy =\n\t| { mode: 'never' }\n\t| {\n\t\t\tmode: 'after-ack'\n\t\t\t/** Server version vector; defaults to persisted last-acked vector on the store. */\n\t\t\tserverVector?: VersionVector\n\t }\n\t| {\n\t\t\tmode: 'after-days'\n\t\t\t/** Delete only ops older than this many days (still requires ack watermark). */\n\t\t\tdays: number\n\t\t\tserverVector?: VersionVector\n\t }\n\n/**\n * Result of a compaction run.\n */\nexport interface CompactionResult {\n\t/** Number of operation log rows removed. */\n\tdeletedCount: number\n\t/** Per-node sequence ceiling used for deletion (from server ack vector). */\n\twatermark: VersionVector\n}\n\nexport const COMPACTION_BASELINE_META_KEY = 'compaction_baseline_at'\n","import type { SchemaDefinition, VersionVector } from '@korajs/core'\nimport { HybridLogicalClock, createVersionVector, quoteIdent } from '@korajs/core'\nimport type { StorageAdapter, Transaction } from '../types'\nimport type { CompactionResult, CompactionStrategy } from './types'\nimport { COMPACTION_BASELINE_META_KEY } from './types'\n\n/**\n * Compute per-node sequence watermarks safe to compact (server has acknowledged these ops).\n */\nexport function computeAckCompactionWatermark(serverVector: VersionVector): VersionVector {\n\tconst watermark = createVersionVector()\n\tfor (const [nodeId, seq] of serverVector) {\n\t\tif (seq > 0) {\n\t\t\twatermark.set(nodeId, seq)\n\t\t}\n\t}\n\treturn watermark\n}\n\n/**\n * Remove acknowledged, materialized operation log entries from `_kora_ops_*` tables.\n * Does not modify collection rows — they are the compaction baseline snapshot.\n */\nexport async function compactOperationLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tstrategy: CompactionStrategy,\n\tserverVector: VersionVector,\n): Promise<CompactionResult> {\n\tif (strategy.mode === 'never') {\n\t\treturn { deletedCount: 0, watermark: createVersionVector() }\n\t}\n\n\tconst watermark = computeAckCompactionWatermark(serverVector)\n\tif (watermark.size === 0) {\n\t\treturn { deletedCount: 0, watermark }\n\t}\n\n\tconst ageCutoffWall =\n\t\tstrategy.mode === 'after-days' ? Date.now() - strategy.days * 24 * 60 * 60 * 1000 : null\n\tconst ageCutoffSerialized =\n\t\tageCutoffWall !== null\n\t\t\t? HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: ageCutoffWall,\n\t\t\t\t\tlogical: 0,\n\t\t\t\t\tnodeId: '',\n\t\t\t\t}).slice(0, 15)\n\t\t\t: null\n\n\tlet deletedCount = 0\n\tconst collectionNames = Object.keys(schema.collections)\n\n\tawait adapter.transaction(async (tx: Transaction) => {\n\t\tfor (const collectionName of collectionNames) {\n\t\t\t// Already quoted here so the buildCountSql / buildDeleteSql helpers can\n\t\t\t// interpolate it verbatim (they do not route through sql-builder).\n\t\t\tconst table = quoteIdent(`_kora_ops_${collectionName}`)\n\t\t\tfor (const [nodeId, maxSeq] of watermark) {\n\t\t\t\tif (maxSeq <= 0) continue\n\n\t\t\t\tconst countSql = buildCountSql(table, ageCutoffSerialized !== null)\n\t\t\t\tconst countParams =\n\t\t\t\t\tageCutoffSerialized !== null ? [nodeId, maxSeq, ageCutoffSerialized] : [nodeId, maxSeq]\n\t\t\t\tconst countRows = await tx.query<{ count: number }>(countSql, countParams)\n\t\t\t\tdeletedCount += countRows[0]?.count ?? 0\n\n\t\t\t\tconst deleteSql = buildDeleteSql(table, ageCutoffSerialized !== null)\n\t\t\t\tawait tx.execute(deleteSql, countParams)\n\t\t\t}\n\t\t}\n\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\n\treturn { deletedCount, watermark }\n}\n\nfunction buildCountSql(table: string, withAge: boolean): string {\n\tif (withAge) {\n\t\treturn `SELECT COUNT(*) as count FROM ${table} WHERE node_id = ? AND sequence_number <= ? AND SUBSTR(timestamp, 1, 15) < ?`\n\t}\n\treturn `SELECT COUNT(*) as count FROM ${table} WHERE node_id = ? AND sequence_number <= ?`\n}\n\nfunction buildDeleteSql(table: string, withAge: boolean): string {\n\tif (withAge) {\n\t\treturn `DELETE FROM ${table} WHERE node_id = ? AND sequence_number <= ? AND SUBSTR(timestamp, 1, 15) < ?`\n\t}\n\treturn `DELETE FROM ${table} WHERE node_id = ? AND sequence_number <= ?`\n}\n","import { type HLCTimestamp, HybridLogicalClock } from '@korajs/core'\nimport type { RawCollectionRow } from '../types'\n\n/** Empty _version means legacy rows (compare by wallTime only via fallback). */\nexport const EMPTY_ROW_VERSION = ''\n\n/**\n * Serialize an HLC timestamp for storage in the `_version` column.\n * Lexicographic order matches {@link HybridLogicalClock.compare}.\n */\nexport function serializeRowVersion(timestamp: HLCTimestamp): string {\n\treturn HybridLogicalClock.serialize(timestamp)\n}\n\n/**\n * Read the version stamp stored on a materialized row.\n * Legacy rows without `_version` fall back to wallTime with logical 0.\n */\nexport function rowVersionFromRecord(\n\trow: Pick<RawCollectionRow, '_updated_at' | '_version'>,\n): HLCTimestamp {\n\tconst version = row._version\n\tif (typeof version === 'string' && version.length > 0) {\n\t\treturn HybridLogicalClock.deserialize(version)\n\t}\n\treturn { wallTime: row._updated_at, logical: 0, nodeId: '' }\n}\n\n/**\n * Returns true when `incoming` is strictly newer than the version on `row`.\n */\nexport function isIncomingNewerThanRow(\n\tincoming: HLCTimestamp,\n\trow: Pick<RawCollectionRow, '_updated_at' | '_version'>,\n): boolean {\n\treturn HybridLogicalClock.compare(incoming, rowVersionFromRecord(row)) > 0\n}\n\n/**\n * SQL fragment and params for LWW guards: apply only when row is missing or older.\n * Uses serialized `_version` for total order (matches HLC compare).\n */\nexport function lwwVersionWhereClause(remoteVersion: string): { sql: string; params: string[] } {\n\treturn {\n\t\tsql: '(_version = ? OR _version < ?)',\n\t\tparams: [EMPTY_ROW_VERSION, remoteVersion],\n\t}\n}\n","import {\n\ttype KoraBytesValue,\n\tbase64ToBytes,\n\tbytesToBase64,\n\tdecodeBytesFromOpData,\n\tencodeBytesForOpData,\n\tisKoraBytesValue,\n\tisLegacyNumericByteObject,\n} from '@korajs/core'\nimport type { FieldDescriptor } from '@korajs/core'\n\n/**\n * The canonical binary op-data encoding lives in `@korajs/core` because\n * `op.data` is a core concept shared by store (creation, persistence) and merge\n * (CRDT merge). These re-exports keep existing store-internal import paths\n * working while the single source of truth is the core module.\n */\nexport type { KoraBytesValue }\nexport { base64ToBytes, bytesToBase64, isKoraBytesValue, isLegacyNumericByteObject }\n\n/** @deprecated Use {@link encodeRichtextForOpData}; kept for existing imports. */\nexport const encodeRichtextForOpData = encodeBytesForOpData\n/** @deprecated Use {@link decodeRichtextOpDataValue}; kept for existing imports. */\nexport const decodeRichtextOpDataValue = decodeBytesFromOpData\n\n/**\n * Apply {@link encodeBytesForOpData} to every richtext-typed field in an\n * operation's data payload. Called at operation creation, BEFORE the payload\n * is content-hashed, so the hash input, persisted JSON, wire payload, and the\n * value the merge engine sees are the identical canonical value. Non-richtext\n * fields are untouched.\n */\nexport function encodeRichtextFieldsForOpData(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...data }\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (fields[key]?.kind !== 'richtext') {\n\t\t\tcontinue\n\t\t}\n\t\tif (typeof value === 'string' || value instanceof Uint8Array || value instanceof ArrayBuffer) {\n\t\t\tresult[key] = encodeBytesForOpData(value)\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Reverse of {@link encodeRichtextFieldsForOpData}: decode tagged (or legacy\n * numeric-key) richtext values in an op-data payload back to record-shaped\n * values (string or Uint8Array). Null/undefined and plain strings pass\n * through, preserving pre-fix behavior exactly.\n */\nexport function decodeRichtextFieldsFromOpData(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...data }\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (fields[key]?.kind !== 'richtext' || value === null || value === undefined) {\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = decodeBytesFromOpData(value)\n\t}\n\treturn result\n}\n","import * as Y from 'yjs'\nimport {\n\ttype KoraBytesValue,\n\tdecodeRichtextOpDataValue,\n\tisKoraBytesValue,\n\tisLegacyNumericByteObject,\n} from './op-data-encoding'\n\nconst TEXT_KEY = 'content'\n\nexport type RichtextInput = string | Uint8Array | ArrayBuffer | null | undefined\n\n/**\n * Encodes richtext values into Yjs document updates.\n *\n * Also accepts the tagged `{ $koraBytes }` form that binary richtext values\n * take inside `op.data` (and, for old dev databases, the pre-fix numeric-key\n * object shape), so every consumer that writes op-data values to columns\n * inherits the decoding. Plain strings keep their exact historical behavior:\n * encoded as a fresh Yjs document containing the string.\n */\nexport function encodeRichtext(value: RichtextInput | KoraBytesValue): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof value === 'string') {\n\t\tconst doc = new Y.Doc()\n\t\t// Deterministic clientId so the same string encodes to the same bytes on every\n\t\t// device (a plain string is a replacement, not a collaborative actor). A random\n\t\t// clientId would make a string-derived richtext column diverge byte-wise across\n\t\t// replicas even when the text is identical.\n\t\tdoc.clientID = 0\n\t\tdoc.getText(TEXT_KEY).insert(0, value)\n\t\treturn Y.encodeStateAsUpdate(doc)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tif (isKoraBytesValue(value) || isLegacyNumericByteObject(value)) {\n\t\tconst decoded = decodeRichtextOpDataValue(value)\n\t\t// Both accepted shapes decode to bytes; strings were handled above.\n\t\treturn decoded instanceof Uint8Array ? decoded : null\n\t}\n\n\tthrow new Error('Richtext value must be a string, Uint8Array, ArrayBuffer, null, or undefined.')\n}\n\n/**\n * Decodes driver-provided richtext values into Uint8Array.\n */\nexport function decodeRichtext(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tthrow new Error(\n\t\t'Richtext storage value must be Uint8Array, ArrayBuffer, Buffer, null, or undefined.',\n\t)\n}\n\n/**\n * Reads plain text from a richtext Yjs state update.\n */\nexport function richtextToPlainText(value: RichtextInput): string {\n\tconst encoded = encodeRichtext(value)\n\tif (!encoded) return ''\n\n\tconst doc = new Y.Doc()\n\tY.applyUpdate(doc, encoded)\n\treturn doc.getText(TEXT_KEY).toString()\n}\n\n/**\n * Compares two richtext values by decoded plain text.\n * Yjs update bytes are not stable across separate encodes of the same string.\n */\nexport function richtextStatesEqual(a: unknown, b: unknown): boolean {\n\ttry {\n\t\treturn richtextToPlainText(a as RichtextInput) === richtextToPlainText(b as RichtextInput)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import { HybridLogicalClock, decodeStoredText, encodeStoredText } from '@korajs/core'\nimport type { CollectionDefinition, FieldDescriptor, Operation } from '@korajs/core'\nimport type { CollectionRecord, OperationRow, RawCollectionRow } from '../types'\nimport { decodeRichtext, encodeRichtext } from './richtext-serializer'\n\n/**\n * Serialize a JS record to SQL-compatible values for INSERT/UPDATE.\n * Transforms: boolean → 0/1, array → JSON string, richtext → Yjs binary update.\n *\n * @param data - The record data with JS-native types\n * @param fields - The field descriptors from the schema\n * @returns An object with SQL-compatible values\n */\nexport function serializeRecord(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tconst descriptor = fields[key]\n\t\tif (!descriptor) {\n\t\t\tresult[key] = value\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = serializeValue(value, descriptor)\n\t}\n\treturn result\n}\n\n/**\n * Deserialize a SQL row to JS-native types for the application layer.\n * Transforms: 0/1 → boolean, JSON string → array, strips _deleted, maps _created_at/_updated_at.\n *\n * @param row - The raw SQL row\n * @param fields - The field descriptors from the schema\n * @returns A CollectionRecord with JS-native types\n */\nexport function deserializeRecord(\n\trow: RawCollectionRow,\n\tfields: Record<string, FieldDescriptor>,\n): CollectionRecord {\n\tconst result: CollectionRecord = {\n\t\tid: row.id,\n\t\tcreatedAt: row._created_at,\n\t\tupdatedAt: row._updated_at,\n\t}\n\n\tfor (const [key, descriptor] of Object.entries(fields)) {\n\t\tconst rawValue = row[key]\n\t\tif (rawValue === undefined || rawValue === null) {\n\t\t\tresult[key] = rawValue ?? null\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = deserializeValue(rawValue, descriptor)\n\t}\n\n\treturn result\n}\n\n/**\n * Internal key used to embed atomicOps metadata in the data JSON column.\n * This avoids adding a new column to the ops table (no migration needed).\n */\nconst ATOMIC_OPS_KEY = '__kora_atomic_ops__'\n\n/**\n * Internal key used to embed transactionId in the data JSON column.\n */\nconst TX_ID_KEY = '__kora_tx_id__'\n\n/**\n * Internal key used to embed mutationName in the data JSON column.\n */\nconst MUTATION_NAME_KEY = '__kora_mutation__'\n\n/**\n * Internal key used to embed a scope-entry insert's per-field versions (RT-27) in the\n * data JSON column, so a later fold of the record's log places each field correctly.\n */\nconst FIELD_VERSIONS_KEY = '__kora_field_versions__'\n\n/**\n * Internal key used to embed the operation's content-hash version (CORE-1, protocol\n * v2) in the data JSON column. Absent means version 1. Kept in the row so id\n * verification and re-hashing (rebase, rotation, resequence) use the right version.\n */\nconst HASH_VERSION_KEY = '__kora_hash_version__'\n\n/**\n * Serialize an Operation to a row for the operations log table.\n *\n * @param op - The operation to serialize\n * @returns An OperationRow suitable for SQL INSERT\n */\nexport function serializeOperation(op: Operation): OperationRow {\n\tconst hasMetadata =\n\t\top.transactionId !== undefined || op.mutationName !== undefined || op.hashVersion !== undefined\n\tlet dataPayload: Record<string, unknown> | null = null\n\tif (op.data) {\n\t\t// Embed metadata in the data JSON when present\n\t\tdataPayload = { ...op.data }\n\t\tif (op.atomicOps !== undefined && Object.keys(op.atomicOps).length > 0) {\n\t\t\tdataPayload[ATOMIC_OPS_KEY] = op.atomicOps\n\t\t}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t\tif (op.fieldVersions !== undefined) {\n\t\t\tdataPayload[FIELD_VERSIONS_KEY] = op.fieldVersions\n\t\t}\n\t\tif (op.hashVersion !== undefined) {\n\t\t\tdataPayload[HASH_VERSION_KEY] = op.hashVersion\n\t\t}\n\t} else if (hasMetadata) {\n\t\t// For delete operations (data is null), we still need to store metadata\n\t\tdataPayload = {}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t\tif (op.hashVersion !== undefined) {\n\t\t\tdataPayload[HASH_VERSION_KEY] = op.hashVersion\n\t\t}\n\t}\n\n\treturn {\n\t\tid: op.id,\n\t\tnode_id: op.nodeId,\n\t\ttype: op.type,\n\t\trecord_id: op.recordId,\n\t\tdata: dataPayload ? JSON.stringify(dataPayload) : null,\n\t\tprevious_data: op.previousData ? JSON.stringify(op.previousData) : null,\n\t\ttimestamp: HybridLogicalClock.serialize(op.timestamp),\n\t\tsequence_number: op.sequenceNumber,\n\t\tcausal_deps: JSON.stringify(op.causalDeps),\n\t\tschema_version: op.schemaVersion,\n\t}\n}\n\n/**\n * Deserialize a row from the operations log table back to an Operation.\n *\n * @param row - The raw operation row from SQL\n * @returns The deserialized Operation object\n */\nexport function deserializeOperation(row: OperationRow): Operation {\n\tlet data: Record<string, unknown> | null = null\n\tlet atomicOps: Record<string, unknown> | undefined\n\tlet transactionId: string | undefined\n\tlet mutationName: string | undefined\n\tlet fieldVersions: Operation['fieldVersions']\n\tlet hashVersion: Operation['hashVersion']\n\n\tif (row.data) {\n\t\tconst parsed = JSON.parse(row.data) as Record<string, unknown>\n\t\t// Extract embedded metadata keys\n\t\tif (ATOMIC_OPS_KEY in parsed) {\n\t\t\tatomicOps = parsed[ATOMIC_OPS_KEY] as Record<string, unknown>\n\t\t}\n\t\tif (TX_ID_KEY in parsed) {\n\t\t\ttransactionId = parsed[TX_ID_KEY] as string\n\t\t}\n\t\tif (MUTATION_NAME_KEY in parsed) {\n\t\t\tmutationName = parsed[MUTATION_NAME_KEY] as string\n\t\t}\n\t\tif (FIELD_VERSIONS_KEY in parsed) {\n\t\t\tfieldVersions = parsed[FIELD_VERSIONS_KEY] as Operation['fieldVersions']\n\t\t}\n\t\tif (HASH_VERSION_KEY in parsed) {\n\t\t\thashVersion = parsed[HASH_VERSION_KEY] as Operation['hashVersion']\n\t\t}\n\t\t// Remove metadata keys from data\n\t\tconst {\n\t\t\t[ATOMIC_OPS_KEY]: _a,\n\t\t\t[TX_ID_KEY]: _t,\n\t\t\t[MUTATION_NAME_KEY]: _m,\n\t\t\t[FIELD_VERSIONS_KEY]: _f,\n\t\t\t[HASH_VERSION_KEY]: _h,\n\t\t\t...rest\n\t\t} = parsed\n\t\t// An insert or update always carries data, possibly `{}` (an insert of only\n\t\t// optional fields): its id covers `{}`, so `{}` is read back, never `null`. Only a\n\t\t// delete's payload is metadata alone (RT-80).\n\t\tdata = row.type !== 'delete' || Object.keys(rest).length > 0 ? rest : null\n\t}\n\n\treturn {\n\t\tid: row.id,\n\t\tnodeId: row.node_id,\n\t\ttype: row.type as Operation['type'],\n\t\tcollection: '', // Collection name is derived from the table name by the caller\n\t\trecordId: row.record_id,\n\t\tdata,\n\t\tpreviousData: row.previous_data\n\t\t\t? (JSON.parse(row.previous_data) as Record<string, unknown>)\n\t\t\t: null,\n\t\ttimestamp: HybridLogicalClock.deserialize(row.timestamp),\n\t\tsequenceNumber: row.sequence_number,\n\t\tcausalDeps: JSON.parse(row.causal_deps) as string[],\n\t\tschemaVersion: row.schema_version,\n\t\t...(atomicOps !== undefined ? { atomicOps: atomicOps as Operation['atomicOps'] } : {}),\n\t\t...(transactionId !== undefined ? { transactionId } : {}),\n\t\t...(mutationName !== undefined ? { mutationName } : {}),\n\t\t...(fieldVersions !== undefined ? { fieldVersions } : {}),\n\t\t...(hashVersion !== undefined ? { hashVersion } : {}),\n\t}\n}\n\n/**\n * Deserialize an operation row with collection name already known.\n */\nexport function deserializeOperationWithCollection(\n\trow: OperationRow,\n\tcollection: string,\n): Operation {\n\tconst op = deserializeOperation(row)\n\treturn { ...op, collection }\n}\n\n/**\n * The read form of record-shaped values the developer wrote: a richtext field written\n * as a string or ArrayBuffer is returned as the Yjs bytes it is stored (and read back)\n * as, so `insert()` / `update()` (and their transaction previews) return the same\n * value shape as `findById()` and queries. Other fields are returned as given.\n *\n * @param data - Record-shaped values (validated, at rest)\n * @param fields - The collection's field descriptors\n * @returns `data`, or a copy with richtext values in their read form\n */\nexport function toRichtextReadShape(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tlet out = data\n\tfor (const [name, descriptor] of Object.entries(fields)) {\n\t\tif (descriptor.kind !== 'richtext' || !(name in data)) continue\n\t\tconst value = data[name]\n\t\tif (value === null || value === undefined || value instanceof Uint8Array) continue\n\t\tif (out === data) out = { ...data }\n\t\tout[name] = encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t}\n\treturn out\n}\n\nfunction serializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value ? 1 : 0\n\t\tcase 'array':\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\t\treturn JSON.stringify(value)\n\t\tcase 'richtext':\n\t\t\t// May be a record-shaped value (string/bytes) or an op-data value\n\t\t\t// (tagged { $koraBytes }) — encodeRichtext accepts every form.\n\t\t\treturn encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t\tdefault:\n\t\t\t// Raw string columns: SQLite binds strings as UTF-8, which cannot hold a lone\n\t\t\t// surrogate (stored as U+FFFD) and SQLite WASM reads TEXT up to a NUL. The\n\t\t\t// shared stored-text codec keeps every JS string (RT-65); JSON columns above\n\t\t\t// need none (JSON.stringify escapes both).\n\t\t\treturn typeof value === 'string' && isRawTextKind(descriptor.kind)\n\t\t\t\t? encodeStoredText(value)\n\t\t\t\t: value\n\t}\n}\n\n/**\n * Field kinds whose column holds the raw string (the stored-text codec applies). Not\n * `enum`: its column holds the schema's literal values verbatim; an enum value SQL text\n * cannot store exactly (U+0000, U+FFFF, a lone surrogate) is refused by `t.enum()` itself\n * (the table no longer has a `CHECK`, RT-101).\n */\nconst RAW_TEXT_KINDS: ReadonlySet<string> = new Set(['string', 'secret'])\n\n/** True for a field kind stored as a raw string, encoded with the stored-text codec. */\nexport function isRawTextKind(kind: string): boolean {\n\treturn RAW_TEXT_KINDS.has(kind)\n}\n\n/**\n * Encode a filter value compared against a field's column: a raw-string field stores\n * the encoded form, and the codec is injective, so equality and `IN` stay exact.\n *\n * @param value - The value from the developer's `where`\n * @param descriptor - The field's descriptor, when the field is known\n */\nexport function encodeStoredFilterValue(\n\tvalue: unknown,\n\tdescriptor: FieldDescriptor | undefined,\n): unknown {\n\treturn typeof value === 'string' && descriptor !== undefined && isRawTextKind(descriptor.kind)\n\t\t? encodeStoredText(value)\n\t\t: value\n}\n\nfunction deserializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value === 1 || value === true\n\t\tcase 'array':\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn JSON.parse(value) as unknown[]\n\t\t\t}\n\t\t\treturn value\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn JSON.parse(value) as unknown\n\t\t\t}\n\t\t\treturn value\n\t\tcase 'richtext':\n\t\t\treturn decodeRichtext(value)\n\t\tdefault:\n\t\t\treturn typeof value === 'string' && isRawTextKind(descriptor.kind)\n\t\t\t\t? decodeStoredText(value)\n\t\t\t\t: value\n\t}\n}\n","import type { CollectionDefinition, FieldDescriptor } from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport { lwwVersionWhereClause } from '../lww/row-version'\nimport { encodeStoredFilterValue } from '../serialization/serializer'\nimport type { QueryDescriptor, WhereOperators } from '../types'\n\n/**\n * Result of building a SQL query: the parameterized SQL string and its bound values.\n */\nexport interface SqlQuery {\n\tsql: string\n\tparams: unknown[]\n}\n\n/**\n * Build a SELECT query from a QueryDescriptor.\n * Automatically adds `WHERE _deleted = 0` to exclude soft-deleted records.\n *\n * @param descriptor - The query descriptor\n * @param fields - The field descriptors from the collection schema\n * @returns A parameterized SQL query\n */\nexport function buildSelectQuery(\n\tdescriptor: QueryDescriptor,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery {\n\tconst params: unknown[] = []\n\tconst parts = [`SELECT * FROM ${quoteIdent(descriptor.collection)}`]\n\n\tconst whereClause = buildWhereClauseParts(descriptor.where, fields, params)\n\t// Always filter out soft-deleted records\n\tconst deletedFilter = '_deleted = 0'\n\tif (whereClause) {\n\t\tparts.push(`WHERE ${deletedFilter} AND ${whereClause}`)\n\t} else {\n\t\tparts.push(`WHERE ${deletedFilter}`)\n\t}\n\n\tif (descriptor.orderBy.length > 0) {\n\t\tconst orderParts = descriptor.orderBy.map((o) => {\n\t\t\tvalidateFieldName(o.field, fields)\n\t\t\t// SEC-7: the direction is whitelisted to a fixed keyword, never spliced from\n\t\t\t// the caller's string (a runtime value cast to the type is untrusted input).\n\t\t\treturn `${quoteIdent(resolveColumnName(o.field, fields))} ${sqlSortDirection(o.direction, o.field)}`\n\t\t})\n\t\tparts.push(`ORDER BY ${orderParts.join(', ')}`)\n\t}\n\n\t// SEC-7: LIMIT / OFFSET are bound as parameters after a safe-integer check, so a\n\t// value that only claims to be a number can never become SQL text.\n\tconst limit = descriptor.limit !== undefined ? assertQueryCount(descriptor.limit, 'limit') : null\n\tconst offset =\n\t\tdescriptor.offset !== undefined ? assertQueryCount(descriptor.offset, 'offset') : null\n\tif (limit !== null) {\n\t\tparts.push('LIMIT ?')\n\t\tparams.push(limit)\n\t}\n\tif (offset !== null) {\n\t\t// SQLite accepts OFFSET only after LIMIT; LIMIT -1 means \"no limit\".\n\t\tif (limit === null) parts.push('LIMIT -1')\n\t\tparts.push('OFFSET ?')\n\t\tparams.push(offset)\n\t}\n\n\treturn { sql: parts.join(' '), params }\n}\n\n/**\n * Build a COUNT query from a QueryDescriptor.\n * Automatically adds `WHERE _deleted = 0`.\n *\n * @param descriptor - The query descriptor\n * @param fields - The field descriptors from the collection schema\n * @returns A parameterized SQL query that returns { count: number }\n */\nexport function buildCountQuery(\n\tdescriptor: QueryDescriptor,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery {\n\tconst params: unknown[] = []\n\tconst parts = [`SELECT COUNT(*) as count FROM ${quoteIdent(descriptor.collection)}`]\n\n\tconst whereClause = buildWhereClauseParts(descriptor.where, fields, params)\n\tconst deletedFilter = '_deleted = 0'\n\tif (whereClause) {\n\t\tparts.push(`WHERE ${deletedFilter} AND ${whereClause}`)\n\t} else {\n\t\tparts.push(`WHERE ${deletedFilter}`)\n\t}\n\n\treturn { sql: parts.join(' '), params }\n}\n\n/**\n * Build an INSERT query for a collection record.\n *\n * @param collection - The collection name\n * @param record - The record data (already serialized with id, _created_at, _updated_at)\n * @returns A parameterized SQL query\n */\nexport function buildInsertQuery(collection: string, record: Record<string, unknown>): SqlQuery {\n\tconst columns = Object.keys(record)\n\tconst placeholders = columns.map(() => '?')\n\tconst params = Object.values(record)\n\n\tconst quotedColumns = columns.map((col) => quoteIdent(col))\n\tconst sql = `INSERT INTO ${quoteIdent(collection)} (${quotedColumns.join(', ')}) VALUES (${placeholders.join(', ')})`\n\treturn { sql, params }\n}\n\n/**\n * Build an UPDATE query for a collection record.\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param changes - The fields to update (already serialized)\n * @returns A parameterized SQL query\n */\nexport function buildUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tchanges: Record<string, unknown>,\n): SqlQuery {\n\tconst setClauses = Object.keys(changes).map((col) => `${quoteIdent(col)} = ?`)\n\tconst params = [...Object.values(changes), id]\n\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ?`\n\treturn { sql, params }\n}\n\n/**\n * Build a field-level fast-forward UPDATE: writes the changed field values\n * unconditionally (the caller has already proven per-field that the local value\n * still equals the base the remote wrote from, so the remote is the newest known\n * writer of those fields), while advancing the row's `_version` / `_updated_at`\n * watermark MONOTONICALLY — never regressing it below its current value.\n *\n * This is what makes per-field LWW correct on a per-row `_version` column: a\n * concurrent edit to a different field may have pushed `_version` past this\n * operation's timestamp, but that must not cause this operation's own field\n * change to be dropped, nor may materializing it move the watermark backward\n * (which would let a genuinely stale later operation win).\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param fieldChanges - Serialized field values to write unconditionally (must NOT include _version / _updated_at)\n * @param remoteVersion - The operation's serialized row version (lexicographically comparable)\n * @param wallTime - The operation's wall-clock time in ms\n * @param options - Optional extras. `maxCreatedAt` advances `_created_at` to the\n * greater of its current value and the given wall time — used for insert\n * collisions so every node converges on the max insert wall time regardless\n * of arrival order.\n */\nexport function buildFieldFastForwardUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tfieldChanges: Record<string, unknown>,\n\tremoteVersion: string,\n\twallTime: number,\n\toptions?: { maxCreatedAt?: number },\n): SqlQuery {\n\tconst fieldClauses = Object.keys(fieldChanges).map((col) => `${quoteIdent(col)} = ?`)\n\t// _version is a lexicographically-sortable string; _updated_at is a number.\n\t// Keep the greater of the current and incoming value for each (monotonic).\n\tconst setClauses = [\n\t\t...fieldClauses,\n\t\t'_version = CASE WHEN _version >= ? THEN _version ELSE ? END',\n\t\t'_updated_at = CASE WHEN _updated_at >= ? THEN _updated_at ELSE ? END',\n\t]\n\tconst params: unknown[] = [\n\t\t...Object.values(fieldChanges),\n\t\tremoteVersion,\n\t\tremoteVersion,\n\t\twallTime,\n\t\twallTime,\n\t]\n\tif (options?.maxCreatedAt !== undefined) {\n\t\tsetClauses.push('_created_at = CASE WHEN _created_at >= ? THEN _created_at ELSE ? END')\n\t\tparams.push(options.maxCreatedAt, options.maxCreatedAt)\n\t}\n\tparams.push(id)\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ?`\n\treturn { sql, params }\n}\n\n/**\n * Build a soft-delete query (SET _deleted = 1).\n *\n * @param collection - The collection name\n * @param id - The record ID\n * @param updatedAt - The timestamp to set on _updated_at\n * @returns A parameterized SQL query\n */\nexport function buildSoftDeleteQuery(\n\tcollection: string,\n\tid: string,\n\tupdatedAt: number,\n\tversion?: string,\n): SqlQuery {\n\tif (version !== undefined) {\n\t\treturn {\n\t\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ?`,\n\t\t\tparams: [updatedAt, version, id],\n\t\t}\n\t}\n\treturn {\n\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ? WHERE id = ?`,\n\t\tparams: [updatedAt, id],\n\t}\n}\n\n/**\n * Build an UPDATE that applies only when the row is missing or older than `remoteVersion`\n * (serialized HLC). Prevents stale remote sync from overwriting newer local materialized state.\n */\nexport function buildLwwUpdateQuery(\n\tcollection: string,\n\tid: string,\n\tchanges: Record<string, unknown>,\n\tremoteVersion: string,\n): SqlQuery {\n\tconst setClauses = Object.keys(changes).map((col) => `${quoteIdent(col)} = ?`)\n\tconst lww = lwwVersionWhereClause(remoteVersion)\n\tconst sql = `UPDATE ${quoteIdent(collection)} SET ${setClauses.join(', ')} WHERE id = ? AND ${lww.sql}`\n\tconst params = [...Object.values(changes), id, ...lww.params]\n\treturn { sql, params }\n}\n\n/**\n * Build a soft-delete that applies only when the row is older than `remoteVersion`.\n */\nexport function buildLwwSoftDeleteQuery(\n\tcollection: string,\n\tid: string,\n\tupdatedAt: number,\n\tversion: string,\n): SqlQuery {\n\tconst lww = lwwVersionWhereClause(version)\n\treturn {\n\t\tsql: `UPDATE ${quoteIdent(collection)} SET _deleted = 1, _updated_at = ?, _version = ? WHERE id = ? AND ${lww.sql}`,\n\t\tparams: [updatedAt, version, id, ...lww.params],\n\t}\n}\n\n/**\n * Build a WHERE clause from conditions, validating field names against the schema.\n *\n * @param where - The where conditions\n * @param fields - The field descriptors from the collection schema\n * @returns The SQL WHERE clause string and params, or null if no conditions\n */\nexport function buildWhereClause(\n\twhere: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): SqlQuery | null {\n\tconst params: unknown[] = []\n\tconst result = buildWhereClauseParts(where, fields, params)\n\tif (!result) return null\n\treturn { sql: result, params }\n}\n\n// --- Internal helpers ---\n\nconst VALID_OPERATORS = new Set(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in'])\n\nfunction buildWhereClauseParts(\n\twhere: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n\tparams: unknown[],\n): string | null {\n\tconst conditions: string[] = []\n\n\tfor (const [fieldName, value] of Object.entries(where)) {\n\t\tvalidateFieldName(fieldName, fields)\n\t\tconst descriptor = fields[fieldName]\n\t\tconst column = resolveColumnName(fieldName, fields)\n\n\t\tif (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// Operator object: { $gt: 5, $lt: 10 }\n\t\t\tconst ops = value as WhereOperators\n\t\t\tfor (const [op, opValue] of Object.entries(ops)) {\n\t\t\t\tif (!VALID_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new QueryError(`Unknown operator \"${op}\" on field \"${fieldName}\"`, {\n\t\t\t\t\t\tfield: fieldName,\n\t\t\t\t\t\toperator: op,\n\t\t\t\t\t\tvalidOperators: [...VALID_OPERATORS],\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconditions.push(buildOperatorCondition(fieldName, column, op, opValue, descriptor, params))\n\t\t\t}\n\t\t} else {\n\t\t\t// Shorthand: { completed: false } means { completed: { $eq: false } }\n\t\t\tconditions.push(buildOperatorCondition(fieldName, column, '$eq', value, descriptor, params))\n\t\t}\n\t}\n\n\tif (conditions.length === 0) return null\n\treturn conditions.join(' AND ')\n}\n\nfunction buildOperatorCondition(\n\tfieldName: string,\n\tcolumnName: string,\n\toperator: string,\n\tvalue: unknown,\n\tdescriptor: FieldDescriptor | undefined,\n\tparams: unknown[],\n): string {\n\t// Serialize boolean values to 0/1 and raw strings to their stored form (RT-65)\n\tconst sqlValue = toSqlFilterValue(value, descriptor)\n\n\tconst column = quoteIdent(columnName)\n\n\tswitch (operator) {\n\t\tcase '$eq':\n\t\t\tif (sqlValue === null) {\n\t\t\t\treturn `${column} IS NULL`\n\t\t\t}\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} = ?`\n\t\tcase '$ne':\n\t\t\tif (sqlValue === null) {\n\t\t\t\treturn `${column} IS NOT NULL`\n\t\t\t}\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} != ?`\n\t\tcase '$gt':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} > ?`\n\t\tcase '$gte':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} >= ?`\n\t\tcase '$lt':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} < ?`\n\t\tcase '$lte':\n\t\t\tparams.push(sqlValue)\n\t\t\treturn `${column} <= ?`\n\t\tcase '$in': {\n\t\t\tif (!Array.isArray(sqlValue)) {\n\t\t\t\tthrow new QueryError(`$in operator requires an array value for field \"${fieldName}\"`, {\n\t\t\t\t\tfield: fieldName,\n\t\t\t\t\treceived: typeof sqlValue,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst placeholders = sqlValue.map(() => '?')\n\t\t\tfor (const item of sqlValue) {\n\t\t\t\tparams.push(toSqlFilterValue(item, descriptor))\n\t\t\t}\n\t\t\treturn `${column} IN (${placeholders.join(', ')})`\n\t\t}\n\t\tdefault:\n\t\t\tthrow new QueryError(`Unknown operator \"${operator}\"`, { operator })\n\t}\n}\n\nfunction toSqlFilterValue(value: unknown, descriptor: FieldDescriptor | undefined): unknown {\n\tif (descriptor?.kind === 'boolean' && typeof value === 'boolean') return value ? 1 : 0\n\treturn encodeStoredFilterValue(value, descriptor)\n}\n\n/**\n * Record metadata exposed on every record under a camelCase name and backed by a\n * system column (STORE-11): `where({ updatedAt: { $gt: t } })` and\n * `orderBy('createdAt', 'desc')` filter and sort on these columns. A schema field\n * declared with the same name wins and its own column is used instead.\n */\nexport const VIRTUAL_TIMESTAMP_FIELDS = Object.freeze({\n\tcreatedAt: '_created_at',\n\tupdatedAt: '_updated_at',\n} as const)\n\n/** Name of a virtual record-metadata field usable in `where` and `orderBy`. */\nexport type VirtualTimestampField = keyof typeof VIRTUAL_TIMESTAMP_FIELDS\n\n/** Every virtual record-metadata field name, for typing `where` / `orderBy` keys. */\nexport const VIRTUAL_TIMESTAMP_FIELD_NAMES: readonly VirtualTimestampField[] = Object.freeze([\n\t'createdAt',\n\t'updatedAt',\n] as const)\n\nconst SORT_DIRECTIONS: Readonly<Record<string, 'ASC' | 'DESC'>> = Object.freeze({\n\tasc: 'ASC',\n\tdesc: 'DESC',\n})\n\n/** Map a query field name to the column it reads (STORE-11 virtual fields). */\nfunction resolveColumnName(fieldName: string, fields: Record<string, FieldDescriptor>): string {\n\tif (Object.hasOwn(fields, fieldName)) return fieldName\n\tif (fieldName === 'createdAt' || fieldName === 'updatedAt') {\n\t\treturn VIRTUAL_TIMESTAMP_FIELDS[fieldName]\n\t}\n\treturn fieldName\n}\n\nfunction sqlSortDirection(direction: unknown, field: string): 'ASC' | 'DESC' {\n\tconst key = typeof direction === 'string' ? direction.toLowerCase() : ''\n\tconst keyword = Object.hasOwn(SORT_DIRECTIONS, key) ? SORT_DIRECTIONS[key] : undefined\n\tif (keyword === undefined) {\n\t\tthrow new QueryError(`Invalid sort direction for field \"${field}\". Use 'asc' or 'desc'.`, {\n\t\t\tfield,\n\t\t\tdirection: typeof direction === 'string' ? direction.slice(0, 64) : typeof direction,\n\t\t})\n\t}\n\treturn keyword\n}\n\nfunction assertQueryCount(value: unknown, clause: 'limit' | 'offset'): number {\n\tif (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new QueryError(\n\t\t\t`Invalid ${clause}: expected a non-negative safe integer. Pass a whole number, for example .${clause}(10).`,\n\t\t\t{ clause, received: typeof value === 'number' ? value : typeof value },\n\t\t)\n\t}\n\treturn value\n}\n\nfunction validateFieldName(fieldName: string, fields: Record<string, FieldDescriptor>): void {\n\t// Allow schema fields plus metadata fields that map to query-able columns\n\tconst allowedFields = new Set([\n\t\t...Object.keys(fields),\n\t\t'id',\n\t\t...VIRTUAL_TIMESTAMP_FIELD_NAMES,\n\t\t'_created_at',\n\t\t'_updated_at',\n\t])\n\tif (!allowedFields.has(fieldName)) {\n\t\tthrow new QueryError(\n\t\t\t`Unknown field \"${fieldName}\" in query. Available fields: ${[...allowedFields].join(', ')}`,\n\t\t\t{ field: fieldName },\n\t\t)\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { Operation } from '@korajs/core'\nimport { computeOperationId } from '@korajs/core/internal'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, Transaction } from '../types'\n\n/** Result of `Store.resequenceOperation` (RT-35 renumbering). */\nexport interface ResequenceResult {\n\t/** The renumbered operation (a version-2 one under a new id). */\n\toperation: Operation\n\t/** Never-sent dependents rewritten to name the new id (re-hashed), in sequence order. */\n\tdependents: Operation[]\n\t/** Old id -> new id, for the operation and every re-hashed dependent. */\n\tidMapping: Record<string, string>\n}\n\n/**\n * The content-addressed id of an operation whose stamp, node, sequence or causal deps\n * were rewritten locally before it was ever shared (clock rebase, node rotation,\n * SEQUENCE_CONFLICT renumbering). Uses the operation's own hash version: a version-2\n * operation (protocol v2) gets a version-2 id over all its semantic fields, and a\n * version-1 operation (written before beta.13) keeps the version-1 hash, so neither\n * fails id verification on its receivers.\n *\n * @param op - The operation with its new content (its `id` is ignored)\n * @returns The id matching that content under the operation's hash version\n */\nexport async function rehashOperation(op: Operation): Promise<string> {\n\treturn computeOperationId(\n\t\t{\n\t\t\tnodeId: op.nodeId,\n\t\t\ttype: op.type,\n\t\t\tcollection: op.collection,\n\t\t\trecordId: op.recordId,\n\t\t\tdata: op.data,\n\t\t\tpreviousData: op.previousData,\n\t\t\ttimestamp: op.timestamp,\n\t\t\tsequenceNumber: op.sequenceNumber,\n\t\t\tcausalDeps: op.causalDeps,\n\t\t\tschemaVersion: op.schemaVersion,\n\t\t\t...(op.atomicOps !== undefined ? { atomicOps: op.atomicOps } : {}),\n\t\t},\n\t\top.hashVersion === 2 ? 2 : 1,\n\t)\n}\n\n/**\n * Give a logged operation row a new sequence number inside `tx` (SEQUENCE_CONFLICT\n * recovery, RT-35; legacy duplicate repair, W6). A version-1 operation keeps its id:\n * its hash never covered the sequence number. A version-2 operation's id does cover it\n * (CORE-1), so it is re-hashed and its row replaced under the new id; it was never\n * stored by the server (that is why it is renumbered), so no replica knows the old id.\n *\n * @returns The operation as it is now logged\n */\nexport async function renumberOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\tsequenceNumber: number,\n): Promise<Operation> {\n\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\tconst current = deserializeOperationWithCollection(row, collection)\n\tconst renumbered: Operation = { ...current, sequenceNumber }\n\tif (current.hashVersion !== 2) {\n\t\tawait tx.execute(`UPDATE ${table} SET sequence_number = ? WHERE id = ?`, [\n\t\t\tsequenceNumber,\n\t\t\trow.id,\n\t\t])\n\t\treturn renumbered\n\t}\n\tconst id = await rehashOperation(renumbered)\n\tconst moved: Operation = { ...renumbered, id }\n\tawait replaceOperationRow(tx, collection, row.id, moved)\n\treturn moved\n}\n\nasync function replaceOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\toldId: string,\n\tnext: Operation,\n): Promise<void> {\n\tawait tx.execute(`DELETE FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`, [oldId])\n\tconst insert = buildInsertQuery(\n\t\t`_kora_ops_${collection}`,\n\t\tserializeOperation(next) as unknown as Record<string, unknown>,\n\t)\n\tawait tx.execute(insert.sql, insert.params)\n}\n\n/**\n * After operations were re-hashed under new ids (`idMapping`, old id -> new id), make\n * the local operations that name an old id in `causalDeps` name the new one, inside\n * `tx`. Only operations in `rewritable` are touched: those the server never stored\n * (never sent). Each rewritten operation covers its causalDeps in its id (version 2),\n * so it is re-hashed too and its own dependents follow, transitively, in sequence\n * order (sequence order is authoring order, so a dependency is always rewritten before\n * its dependents). A version-1 operation keeps its id (its hash does not cover\n * causalDeps) but still gets the new dep. `idMapping` is extended in place.\n *\n * An operation outside `rewritable` (already sent: the server may hold it under its\n * id) is never rewritten; its dep on an old id resolves through `_kora_seq_conflicts`\n * (`reemitted_as`) on this device.\n *\n * @returns The rewritten operations, in sequence order\n */\nexport async function rewriteDependentsInTx(\n\ttx: Transaction,\n\tcollections: readonly string[],\n\tnodeId: string,\n\tidMapping: Record<string, string>,\n\trewritable: ReadonlySet<string>,\n): Promise<Operation[]> {\n\tif (rewritable.size === 0) return []\n\tconst candidates: Array<{ collection: string; row: OperationRow; op: Operation }> = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tif (!rewritable.has(row.id)) continue\n\t\t\tcandidates.push({ collection, row, op: deserializeOperationWithCollection(row, collection) })\n\t\t}\n\t}\n\tcandidates.sort((a, b) => a.op.sequenceNumber - b.op.sequenceNumber)\n\tconst rewritten: Operation[] = []\n\tfor (const { collection, row, op } of candidates) {\n\t\tif (!op.causalDeps.some((dep) => idMapping[dep] !== undefined)) continue\n\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\tconst updated: Operation = { ...op, causalDeps }\n\t\tconst id = op.hashVersion === 2 ? await rehashOperation(updated) : op.id\n\t\tconst next: Operation = { ...updated, id }\n\t\tawait replaceOperationRow(tx, collection, row.id, next)\n\t\tif (id !== op.id) idMapping[op.id] = id\n\t\trewritten.push(next)\n\t}\n\treturn rewritten\n}\n","import type { StorageAdapter, Transaction } from '../types'\n\ninterface SequenceRow {\n\tsequence_number: number\n}\n\n/**\n * Reserve the next sequence number for a node inside a write transaction\n * (UPSERT ... RETURNING on `_kora_version_vector`).\n *\n * This is the ONLY way a local operation gets its number: the reservation\n * commits or rolls back with the operation that uses it, and transactions are\n * serialized, so the numbers of one commit are contiguous and never shared. There\n * is deliberately no variant that allocates outside a transaction (W6).\n */\nexport async function allocateNextSequenceInTransaction(\n\ttx: Transaction,\n\tnodeId: string,\n): Promise<number> {\n\tconst rows = await tx.query<SequenceRow>(\n\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, 1)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = sequence_number + 1\n RETURNING sequence_number`,\n\t\t[nodeId],\n\t)\n\tconst seq = rows[0]?.sequence_number\n\tif (seq === undefined) {\n\t\tthrow new Error(`Failed to allocate sequence number for node \"${nodeId}\" in transaction`)\n\t}\n\treturn seq\n}\n\n/**\n * Read the current sequence for a node without incrementing.\n */\nexport async function readSequenceNumber(adapter: StorageAdapter, nodeId: string): Promise<number> {\n\tconst rows = await adapter.query<SequenceRow>(\n\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t[nodeId],\n\t)\n\treturn rows[0]?.sequence_number ?? 0\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport { renumberOperationRow } from '../sync/rehash-operation'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport { allocateNextSequenceInTransaction } from './sequence-allocator'\n\n/**\n * Audit table for operation rows whose `(node_id, sequence_number)` identity\n * collided with another operation (STORE-1 / STORE-2 duplicates written by\n * beta.12, or a conflicting remote operation). Rows here are never deleted.\n *\n * - `reemitted_as` set: the operation was given a fresh sequence number and still\n * lives in the operation log under that number (`new_sequence_number`).\n * - `reemitted_as` NULL: the operation is kept ONLY here (another node's\n * operation whose number this log already holds). It still takes part in\n * dedup and in record folds, so no data is lost.\n */\nexport const SEQ_CONFLICTS_TABLE = '_kora_seq_conflicts'\n\nconst REPAIR_DONE_META_KEY = 'seq_unique_repair_v1'\n\n/** DDL for {@link SEQ_CONFLICTS_TABLE}. */\nconst CREATE_SEQ_CONFLICTS_SQL = `CREATE TABLE IF NOT EXISTS ${SEQ_CONFLICTS_TABLE} (\n id TEXT PRIMARY KEY NOT NULL,\n collection TEXT NOT NULL,\n node_id TEXT NOT NULL,\n type TEXT NOT NULL,\n record_id TEXT NOT NULL,\n data TEXT,\n previous_data TEXT,\n timestamp TEXT NOT NULL,\n sequence_number INTEGER NOT NULL,\n causal_deps TEXT NOT NULL,\n schema_version INTEGER NOT NULL,\n reason TEXT NOT NULL,\n reemitted_as TEXT,\n new_sequence_number INTEGER,\n recorded_at INTEGER NOT NULL\n)`\n\n/** Name of the unique `(node_id, sequence_number)` index on a collection's op log. */\nexport function uniqueSequenceIndexName(collection: string): string {\n\treturn `uidx_kora_ops_${collection.length}_${collection}_node_seq`\n}\n\n/** Outcome of {@link repairSequenceUniqueness}. */\nexport interface SequenceRepairResult {\n\t/** Own-node operations that were given a fresh sequence number. */\n\tresequenced: number\n\t/** Other nodes' operations moved out of the log into the conflicts table. */\n\tretained: number\n}\n\n/**\n * Make `(node_id, sequence_number)` unique in the local operation log, then\n * enforce it with a UNIQUE index on every operation table (W6 step 2).\n *\n * beta.12 could give two different operations of this device the same sequence\n * number (STORE-1/2). A plain UNIQUE index cannot be created over such a log, and\n * dropping either row would lose a write. The repair, in one transaction:\n *\n * 1. Raises this node's persisted counter to at least the highest sequence number\n * in its log (beta.12 could leave it behind, which would make the next write\n * collide).\n * 2. For every duplicated `(node, seq)` — across all collections, since one node\n * numbers all its operations in one sequence — keeps the first row by id.\n * 3. Every other row of THIS node is re-emitted with a fresh sequence number from\n * the counter, keeping its id and content (see the note below), and recorded\n * in {@link SEQ_CONFLICTS_TABLE}.\n * 4. Rows of OTHER nodes (this device cannot number them) move to\n * {@link SEQ_CONFLICTS_TABLE} with `reemitted_as` NULL; the store keeps using\n * them for dedup and record folds.\n * 5. Creates the UNIQUE index on every operation table.\n *\n * Why the re-emitted operation keeps its id: protocol v1 content-addresses\n * operations without the sequence number, and changing any hashed content (data\n * or HLC timestamp) would change what the write means under last-write-wins.\n * With the id kept, a server that already stored the operation deduplicates it\n * (acknowledging the new number), and a server that never got it — beta.12 could\n * skip the second of two same-numbered operations — stores it. Either way atomic\n * increments are never applied twice and no write is lost.\n *\n * Idempotent: the scan runs once per database (a meta flag records completion);\n * the index creation runs on every open so collections added later are covered.\n *\n * @param adapter - The store's adapter (already opened)\n * @param schema - The schema whose operation tables are repaired\n * @param nodeId - This device's node id\n */\nexport async function repairSequenceUniqueness(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\tawait adapter.execute(CREATE_SEQ_CONFLICTS_SQL)\n\tconst collections = Object.keys(schema.collections)\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\n\tconst done = await adapter.query<{ value: string }>(\n\t\t'SELECT value FROM _kora_meta WHERE key = ?',\n\t\t[REPAIR_DONE_META_KEY],\n\t)\n\tif (done.length === 0 && collections.length > 0) {\n\t\tawait runRepair(adapter, collections, nodeId, result)\n\t}\n\n\tfor (const collection of collections) {\n\t\tconst createIndex = `CREATE UNIQUE INDEX IF NOT EXISTS ${quoteIdent(uniqueSequenceIndexName(collection))} ON ${quoteIdent(`_kora_ops_${collection}`)} (node_id, sequence_number)`\n\t\ttry {\n\t\t\tawait adapter.execute(createIndex)\n\t\t} catch (error) {\n\t\t\t// Duplicates written after an earlier repair (for example by an older\n\t\t\t// Kora version opening this database again): repair once more, then\n\t\t\t// create the index. A second failure propagates.\n\t\t\tif (!/UNIQUE/i.test(error instanceof Error ? error.message : String(error))) throw error\n\t\t\tawait runRepair(adapter, collections, nodeId, result)\n\t\t\tawait adapter.execute(createIndex)\n\t\t}\n\t}\n\treturn result\n}\n\nasync function runRepair(\n\tadapter: StorageAdapter,\n\tcollections: string[],\n\tnodeId: string,\n\tresult: SequenceRepairResult,\n): Promise<void> {\n\tlet resequenced = 0\n\tlet retained = 0\n\tawait adapter.transaction(async (tx) => {\n\t\tawait raiseOwnCounterToLog(tx, collections, nodeId)\n\t\tconst repaired = await repairDuplicates(tx, collections, nodeId)\n\t\tresequenced = repaired.resequenced\n\t\tretained = repaired.retained\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tREPAIR_DONE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\tresult.resequenced += resequenced\n\tresult.retained += retained\n\tif (resequenced > 0 || retained > 0) {\n\t\tconsole.warn(\n\t\t\t`[kora] Repaired ${resequenced + retained} operation(s) that shared a sequence number (written by an earlier Kora version). ${resequenced} were given fresh sequence numbers; ${retained} from other devices were kept in ${SEQ_CONFLICTS_TABLE}. No data was removed.`,\n\t\t)\n\t}\n}\n\nasync function raiseOwnCounterToLog(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<void> {\n\tlet maxSeq = 0\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ max_seq: number | null }>(\n\t\t\t`SELECT MAX(sequence_number) AS max_seq FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tmaxSeq = Math.max(maxSeq, rows[0]?.max_seq ?? 0)\n\t}\n\tif (maxSeq > 0) {\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t[nodeId, maxSeq],\n\t\t)\n\t}\n}\n\ninterface LoggedIdentity {\n\tcollection: string\n\tid: string\n\tnode_id: string\n\tsequence_number: number\n}\n\nasync function repairDuplicates(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\t// One node numbers all its operations in one sequence, so duplicates are\n\t// found across every collection's table, not per table.\n\tconst all: LoggedIdentity[] = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<Omit<LoggedIdentity, 'collection'>>(\n\t\t\t`SELECT id, node_id, sequence_number FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t)\n\t\tfor (const row of rows) all.push({ collection, ...row })\n\t}\n\tconst groups = new Map<string, LoggedIdentity[]>()\n\tfor (const row of all) {\n\t\tconst key = `${row.node_id}\\u0000${row.sequence_number}`\n\t\tconst group = groups.get(key)\n\t\tif (group) group.push(row)\n\t\telse groups.set(key, [row])\n\t}\n\n\tconst losers: LoggedIdentity[] = []\n\tfor (const group of groups.values()) {\n\t\tif (group.length < 2) continue\n\t\t// A version-2 operation (beta.13+) keeps its place: renumbering would re-hash it\n\t\t// under a new id, and if the server already stored it under the old id the new\n\t\t// copy would be stored as a second write (an atomic increment applied twice). A\n\t\t// version-1 loser keeps its id, which the server deduplicates (RT-31). Ties by id.\n\t\tconst version2 = new Set<string>()\n\t\tfor (const member of group) {\n\t\t\tif (await isVersion2Row(tx, member)) version2.add(member.id)\n\t\t}\n\t\tgroup.sort((a, b) => {\n\t\t\tconst va = version2.has(a.id) ? 0 : 1\n\t\t\tconst vb = version2.has(b.id) ? 0 : 1\n\t\t\tif (va !== vb) return va - vb\n\t\t\treturn a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n\t\t})\n\t\tlosers.push(...group.slice(1))\n\t}\n\t// Re-emit in original order so the new numbers keep the authoring order.\n\tlosers.sort((a, b) =>\n\t\ta.sequence_number !== b.sequence_number\n\t\t\t? a.sequence_number - b.sequence_number\n\t\t\t: a.id < b.id\n\t\t\t\t? -1\n\t\t\t\t: a.id > b.id\n\t\t\t\t\t? 1\n\t\t\t\t\t: 0,\n\t)\n\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\tconst now = Date.now()\n\tfor (const loser of losers) {\n\t\tconst table = quoteIdent(`_kora_ops_${loser.collection}`)\n\t\tconst rows = await tx.query<OperationRow>(`SELECT * FROM ${table} WHERE id = ?`, [loser.id])\n\t\tconst row = rows[0]\n\t\tif (!row) continue\n\t\tif (loser.node_id === nodeId) {\n\t\t\tconst newSeq = await allocateNextSequenceInTransaction(tx, nodeId)\n\t\t\tconst moved = await renumberOperationRow(tx, loser.collection, row, newSeq)\n\t\t\tawait insertConflictRow(\n\t\t\t\ttx,\n\t\t\t\tloser.collection,\n\t\t\t\trow,\n\t\t\t\t'duplicate-sequence',\n\t\t\t\tmoved.id,\n\t\t\t\tnewSeq,\n\t\t\t\tnow,\n\t\t\t)\n\t\t\tresult.resequenced++\n\t\t} else {\n\t\t\tawait insertConflictRow(tx, loser.collection, row, 'duplicate-sequence', null, null, now)\n\t\t\tawait tx.execute(`DELETE FROM ${table} WHERE id = ?`, [loser.id])\n\t\t\tresult.retained++\n\t\t}\n\t}\n\treturn result\n}\n\n/** Whether a logged operation declares content-hash version 2. */\nasync function isVersion2Row(tx: Transaction, identity: LoggedIdentity): Promise<boolean> {\n\tconst rows = await tx.query<OperationRow>(\n\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${identity.collection}`)} WHERE id = ?`,\n\t\t[identity.id],\n\t)\n\tconst row = rows[0]\n\tif (!row) return false\n\treturn deserializeOperationWithCollection(row, identity.collection).hashVersion === 2\n}\n\n/**\n * Record an operation row in {@link SEQ_CONFLICTS_TABLE}.\n *\n * @param reemittedAs - Id of the operation that carries it in the log, or null\n * when the row is kept only in the conflicts table\n * @param newSequenceNumber - The sequence number it was re-emitted under\n */\nexport async function insertConflictRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\treason: string,\n\treemittedAs: string | null,\n\tnewSequenceNumber: number | null,\n\trecordedAt: number,\n): Promise<void> {\n\tawait tx.execute(\n\t\t`INSERT OR IGNORE INTO ${SEQ_CONFLICTS_TABLE} (id, collection, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version, reason, reemitted_as, new_sequence_number, recorded_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\trow.id,\n\t\t\tcollection,\n\t\t\trow.node_id,\n\t\t\trow.type,\n\t\t\trow.record_id,\n\t\t\trow.data,\n\t\t\trow.previous_data,\n\t\t\trow.timestamp,\n\t\t\trow.sequence_number,\n\t\t\trow.causal_deps,\n\t\t\trow.schema_version,\n\t\t\treason,\n\t\t\treemittedAs,\n\t\t\tnewSequenceNumber,\n\t\t\trecordedAt,\n\t\t],\n\t)\n}\n\n/**\n * Operation rows kept only in the conflicts table for a record (other nodes'\n * operations whose sequence number collided). Record folds include them.\n */\nexport async function loadRetainedConflictRows(\n\tquery: <T>(sql: string, params?: unknown[]) => Promise<T[]>,\n\tcollection: string,\n\trecordId: string,\n\ttypes?: readonly string[],\n): Promise<OperationRow[]> {\n\tconst typeFilter =\n\t\ttypes && types.length > 0 ? ` AND type IN (${types.map(() => '?').join(', ')})` : ''\n\treturn query<OperationRow>(\n\t\t`SELECT id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND record_id = ? AND reemitted_as IS NULL${typeFilter}`,\n\t\t[collection, recordId, ...(types ?? [])],\n\t)\n}\n\n/** Whether an operation id is already recorded (log or retained conflict). */\nexport async function isOperationLogged(\n\ttx: Transaction,\n\tcollection: string,\n\topId: string,\n): Promise<boolean> {\n\tconst inLog = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`,\n\t\t[opId],\n\t)\n\tif (inLog.length > 0) return true\n\tconst retained = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${SEQ_CONFLICTS_TABLE} WHERE id = ? AND reemitted_as IS NULL`,\n\t\t[opId],\n\t)\n\treturn retained.length > 0\n}\n","import type { Operation, VersionVector } from '@korajs/core'\nimport { createVersionVector } from '@korajs/core'\nimport type { MetaRow, StorageAdapter } from '../types'\n\nexport const LAST_ACKED_SERVER_VECTOR_META_KEY = 'last_acked_server_vector'\nexport const DELTA_CURSOR_META_KEY = 'delta_cursor'\nexport const DELIVERY_WATERMARK_META_KEY = 'delivery_watermark'\nexport const NODE_TOKEN_META_KEY = 'sync_node_token'\nexport const AUTHORITATIVE_NODE_IDS_META_KEY = 'sync_authoritative_node_ids'\n\n/**\n * Serialize a version vector for `_kora_meta` storage.\n */\nexport function serializeVersionVectorToMeta(vector: VersionVector): string {\n\tconst record: Record<string, number> = {}\n\tfor (const [nodeId, seq] of vector) {\n\t\trecord[nodeId] = seq\n\t}\n\treturn JSON.stringify(record)\n}\n\n/**\n * Deserialize a version vector from `_kora_meta`.\n */\nexport function deserializeVersionVectorFromMeta(value: string): VersionVector {\n\tconst parsed = JSON.parse(value) as Record<string, number>\n\tconst vector = createVersionVector()\n\tfor (const [nodeId, seq] of Object.entries(parsed)) {\n\t\tif (typeof seq === 'number' && seq >= 0) {\n\t\t\tvector.set(nodeId, seq)\n\t\t}\n\t}\n\treturn vector\n}\n\n/**\n * Merge two version vectors, keeping the maximum sequence per node.\n */\nexport function mergeVersionVectors(a: VersionVector, b: VersionVector): VersionVector {\n\tconst merged = new Map(a)\n\tfor (const [nodeId, seq] of b) {\n\t\tmerged.set(nodeId, Math.max(merged.get(nodeId) ?? 0, seq))\n\t}\n\treturn merged\n}\n\n/**\n * Operations present locally but not yet on the server (per server version vector).\n */\nexport async function collectOperationsAheadOfServer(\n\tlocalVector: VersionVector,\n\tserverVector: VersionVector,\n\tfetchRange: (nodeId: string, fromSeq: number, toSeq: number) => Promise<Operation[]>,\n): Promise<Operation[]> {\n\tconst missing: Operation[] = []\n\tfor (const [nodeId, localSeq] of localVector) {\n\t\tconst serverSeq = serverVector.get(nodeId) ?? 0\n\t\tif (localSeq > serverSeq) {\n\t\t\tconst ops = await fetchRange(nodeId, serverSeq + 1, localSeq)\n\t\t\tmissing.push(...ops)\n\t\t}\n\t}\n\tmissing.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\treturn missing\n}\n\n/**\n * Load persisted last-acked server vector from `_kora_meta`.\n */\nexport async function loadLastAckedServerVector(adapter: StorageAdapter): Promise<VersionVector> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\t])\n\tconst row = rows[0]\n\tif (!row?.value) {\n\t\treturn createVersionVector()\n\t}\n\ttry {\n\t\treturn deserializeVersionVectorFromMeta(row.value)\n\t} catch {\n\t\treturn createVersionVector()\n\t}\n}\n\n/**\n * Persist the last-acked server version vector to `_kora_meta`.\n */\nexport async function saveLastAckedServerVector(\n\tadapter: StorageAdapter,\n\tvector: VersionVector,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\t\tserializeVersionVectorToMeta(vector),\n\t])\n}\n\n/**\n * Load the per-device node token the sync server issued for this node id (RT-12).\n */\nexport async function loadNodeToken(\n\tadapter: StorageAdapter,\n\tnodeId?: string,\n): Promise<string | null> {\n\tif (nodeId !== undefined) {\n\t\tconst own = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tnodeTokenKey(nodeId),\n\t\t])\n\t\tif (own[0]) return own[0].value\n\t\t// The legacy single key belongs to the database's node id (`_kora_meta.node_id`).\n\t\tconst meta = await adapter.query<MetaRow>(\"SELECT value FROM _kora_meta WHERE key = 'node_id'\")\n\t\tif (meta[0]?.value !== nodeId) return null\n\t}\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tNODE_TOKEN_META_KEY,\n\t])\n\treturn rows[0]?.value ?? null\n}\n\n/** `_kora_meta` key of one node id's token (RT-38/RT-40: a database may use several). */\nexport function nodeTokenKey(nodeId: string): string {\n\treturn `${NODE_TOKEN_META_KEY}:${nodeId}`\n}\n\n/**\n * Persist the per-device node token next to the node id in `_kora_meta`. With a node\n * id, the token is stored under that node's own key: a database that uses several node\n * ids (a rotated identity, per-tab isolation) keeps each node's token.\n */\nexport async function saveNodeToken(\n\tadapter: StorageAdapter,\n\ttoken: string,\n\tnodeId?: string,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tnodeId === undefined ? NODE_TOKEN_META_KEY : nodeTokenKey(nodeId),\n\t\ttoken,\n\t])\n}\n\n/**\n * Load a persisted delta cursor for resuming paginated initial sync.\n */\nexport async function loadDeltaCursor(adapter: StorageAdapter): Promise<string | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tDELTA_CURSOR_META_KEY,\n\t])\n\treturn rows[0]?.value ?? null\n}\n\n/**\n * Persist or clear the delta cursor in `_kora_meta`.\n */\nexport async function saveDeltaCursor(\n\tadapter: StorageAdapter,\n\tcursor: string | null,\n): Promise<void> {\n\tif (cursor === null) {\n\t\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\t\treturn\n\t}\n\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tDELTA_CURSOR_META_KEY,\n\t\tcursor,\n\t])\n}\n\n/**\n * The `_kora_meta` key for a view's delivery watermark. The default (empty) signature\n * uses the bare key for backward compatibility; other views suffix the signature.\n */\nexport function deliveryWatermarkKey(signature: string): string {\n\treturn signature === ''\n\t\t? DELIVERY_WATERMARK_META_KEY\n\t\t: `${DELIVERY_WATERMARK_META_KEY}:${signature}`\n}\n\n/**\n * Load the persisted delivery watermark for a view signature (0 when none recorded).\n */\nexport async function loadDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tdeliveryWatermarkKey(signature),\n\t])\n\tconst value = rows[0]?.value\n\tif (value === undefined || value === null) {\n\t\treturn 0\n\t}\n\tconst parsed = Number(value)\n\treturn Number.isFinite(parsed) && parsed >= 0 ? parsed : 0\n}\n\n/**\n * Persist the delivery watermark for a view signature in `_kora_meta`.\n */\nexport async function saveDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n\twatermark: number,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tdeliveryWatermarkKey(signature),\n\t\tString(watermark),\n\t])\n}\n\n/**\n * Delete a persisted view watermark. Dropping a watermark is always safe: the view simply\n * back-fills from 0 (deduplicated) the next time it is visited. This bounds the number of\n * `_kora_meta` rows an app that churns through many distinct views can accumulate.\n */\nexport async function deleteDeliveryWatermark(\n\tadapter: StorageAdapter,\n\tsignature: string,\n): Promise<void> {\n\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [deliveryWatermarkKey(signature)])\n}\n\n/**\n * Load every persisted view watermark, keyed by signature (the default view is '').\n */\nexport async function loadAllDeliveryWatermarks(\n\tadapter: StorageAdapter,\n): Promise<Record<string, number>> {\n\tconst rows = await adapter.query<MetaRow & { key: string }>(\n\t\t'SELECT key, value FROM _kora_meta WHERE key = ? OR key LIKE ?',\n\t\t[DELIVERY_WATERMARK_META_KEY, `${DELIVERY_WATERMARK_META_KEY}:%`],\n\t)\n\tconst result: Record<string, number> = {}\n\tconst prefix = `${DELIVERY_WATERMARK_META_KEY}:`\n\tfor (const row of rows) {\n\t\tconst signature = row.key === DELIVERY_WATERMARK_META_KEY ? '' : row.key.slice(prefix.length)\n\t\tconst parsed = Number(row.value)\n\t\tif (Number.isFinite(parsed) && parsed >= 0) {\n\t\t\tresult[signature] = parsed\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Persist the node ids the sync server named authoritative (protocol v2): their\n * operations are server-authored. Stored as a JSON array in `_kora_meta`.\n */\nexport async function saveAuthoritativeNodeIds(\n\tadapter: StorageAdapter,\n\tnodeIds: string[],\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tAUTHORITATIVE_NODE_IDS_META_KEY,\n\t\tJSON.stringify(nodeIds),\n\t])\n}\n\n/** `_kora_meta` key of the explicit authoritative ids a server revoked (RT-81). */\nconst REVOKED_AUTHORITATIVE_NODE_IDS_META_KEY = 'sync_revoked_authoritative_node_ids'\n\n/**\n * Persist the explicit authoritative node ids a sync server revoked (RT-81). A revoked\n * id is never authoritative again on this device, whatever a later handshake lists.\n */\nexport async function saveRevokedAuthoritativeNodeIds(\n\tadapter: StorageAdapter,\n\tnodeIds: string[],\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tREVOKED_AUTHORITATIVE_NODE_IDS_META_KEY,\n\t\tJSON.stringify(nodeIds),\n\t])\n}\n\n/** Load the persisted revoked authoritative node ids (empty when none, or unreadable). */\nexport async function loadRevokedAuthoritativeNodeIds(adapter: StorageAdapter): Promise<string[]> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tREVOKED_AUTHORITATIVE_NODE_IDS_META_KEY,\n\t])\n\tconst raw = rows[0]?.value\n\tif (raw === undefined) return []\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw)\n\t\tif (Array.isArray(parsed)) return parsed.filter((id): id is string => typeof id === 'string')\n\t} catch {\n\t\t// Unreadable: no revocation known; the next handshake that carries one rewrites it.\n\t}\n\treturn []\n}\n\n/**\n * Load the persisted authoritative node ids, or null when no protocol-2 server ever\n * answered (or the stored value is unreadable).\n */\nexport async function loadAuthoritativeNodeIds(adapter: StorageAdapter): Promise<string[] | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tAUTHORITATIVE_NODE_IDS_META_KEY,\n\t])\n\tconst raw = rows[0]?.value\n\tif (raw === undefined) return null\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw)\n\t\tif (Array.isArray(parsed) && parsed.every((id) => typeof id === 'string')) {\n\t\t\treturn parsed as string[]\n\t\t}\n\t} catch {\n\t\t// Unreadable: treated as never received; the next handshake rewrites it.\n\t}\n\treturn null\n}\n","import type { Operation } from '@korajs/core'\nimport type { MetaRow, StorageAdapter } from '../types'\nimport { deliveryWatermarkKey } from './sync-state'\n\n/** `_kora_meta` key of this device's contiguous acknowledged own-operation prefix (W3). */\nexport const OWN_ACKED_THROUGH_META_KEY = 'own_acked_through'\n/** `_kora_meta` key of the downlink scope the sync server last accepted (SYNC-11). */\nexport const ACCEPTED_DOWNLINK_SCOPE_META_KEY = 'accepted_downlink_scope'\n\n/**\n * Durable inbound quarantine (W4): delivered operations the client deliberately did not\n * apply, kept so they are never silently lost and can be replayed. Created on first use\n * so existing databases need no migration.\n */\nconst UNAPPLIED_OPS_DDL =\n\t'CREATE TABLE IF NOT EXISTS _kora_unapplied_ops (\\n' +\n\t' op_id TEXT PRIMARY KEY NOT NULL,\\n' +\n\t' collection TEXT NOT NULL,\\n' +\n\t' delivery_seq INTEGER,\\n' +\n\t' code TEXT NOT NULL,\\n' +\n\t' message TEXT NOT NULL,\\n' +\n\t' payload TEXT NOT NULL,\\n' +\n\t' quarantined_at INTEGER NOT NULL\\n' +\n\t')'\n\n/** A delivered operation the client did not apply, as stored in `_kora_unapplied_ops`. */\nexport interface UnappliedOperation {\n\t/** The operation as delivered (still encrypted when decryption failed). */\n\toperation: Operation\n\t/** Delivery sequence of the batch that carried it, or null for a legacy batch. */\n\tdeliverySequence: number | null\n\t/** Machine-readable reason. */\n\tcode: string\n\t/** Human-readable explanation. */\n\tmessage: string\n\t/** Wall-clock time (ms) it was quarantined. Display only. */\n\tquarantinedAt: number\n}\n\ninterface UnappliedRow {\n\top_id: string\n\tdelivery_seq: number | null\n\tcode: string\n\tmessage: string\n\tpayload: string\n\tquarantined_at: number\n}\n\nconst ensuredAdapters = new WeakSet<StorageAdapter>()\n\nasync function ensureUnappliedTable(adapter: StorageAdapter): Promise<void> {\n\tif (ensuredAdapters.has(adapter)) return\n\tawait adapter.execute(UNAPPLIED_OPS_DDL)\n\tensuredAdapters.add(adapter)\n}\n\n/**\n * Record quarantined operations and, when given, advance a view's delivery watermark in\n * the SAME transaction, so the watermark can never pass an operation that is neither\n * applied nor recorded here (the W4 invariant).\n */\nexport async function saveUnappliedOperations(\n\tadapter: StorageAdapter,\n\tentries: UnappliedOperation[],\n\twatermark?: { signature: string; watermark: number },\n): Promise<void> {\n\tawait ensureUnappliedTable(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of entries) {\n\t\t\tawait tx.execute(\n\t\t\t\t'INSERT OR REPLACE INTO _kora_unapplied_ops (op_id, collection, delivery_seq, code, message, payload, quarantined_at) VALUES (?, ?, ?, ?, ?, ?, ?)',\n\t\t\t\t[\n\t\t\t\t\tentry.operation.id,\n\t\t\t\t\tentry.operation.collection,\n\t\t\t\t\tentry.deliverySequence,\n\t\t\t\t\tentry.code,\n\t\t\t\t\tentry.message,\n\t\t\t\t\tJSON.stringify(entry.operation),\n\t\t\t\t\tentry.quarantinedAt,\n\t\t\t\t],\n\t\t\t)\n\t\t}\n\t\tif (watermark) {\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tdeliveryWatermarkKey(watermark.signature),\n\t\t\t\tString(watermark.watermark),\n\t\t\t])\n\t\t}\n\t})\n}\n\n/** Every quarantined operation, oldest delivery first. */\nexport async function loadUnappliedOperations(\n\tadapter: StorageAdapter,\n): Promise<UnappliedOperation[]> {\n\tawait ensureUnappliedTable(adapter)\n\tconst rows = await adapter.query<UnappliedRow>(\n\t\t'SELECT op_id, delivery_seq, code, message, payload, quarantined_at FROM _kora_unapplied_ops ORDER BY delivery_seq ASC, quarantined_at ASC',\n\t)\n\treturn rows.map((row) => ({\n\t\toperation: JSON.parse(row.payload) as Operation,\n\t\tdeliverySequence: row.delivery_seq === null ? null : Number(row.delivery_seq),\n\t\tcode: row.code,\n\t\tmessage: row.message,\n\t\tquarantinedAt: Number(row.quarantined_at),\n\t}))\n}\n\n/** Remove quarantined operations by operation id (applied on replay, or reconciled). */\nexport async function removeUnappliedOperations(\n\tadapter: StorageAdapter,\n\toperationIds: string[],\n): Promise<void> {\n\tif (operationIds.length === 0) return\n\tawait ensureUnappliedTable(adapter)\n\tconst placeholders = operationIds.map(() => '?').join(', ')\n\tawait adapter.execute(\n\t\t`DELETE FROM _kora_unapplied_ops WHERE op_id IN (${placeholders})`,\n\t\toperationIds,\n\t)\n}\n\n/** `_kora_meta` key of a node's prefix when the legacy single key holds another node's. */\nexport function ownAckedThroughKey(nodeId: string): string {\n\treturn `${OWN_ACKED_THROUGH_META_KEY}:${nodeId}`\n}\n\nfunction parseLegacyPrefix(value: string | undefined): { nodeId: string; sequence: number } | null {\n\tif (value === undefined || value === null) return null\n\ttry {\n\t\tconst parsed = JSON.parse(value) as { nodeId?: unknown; sequence?: unknown }\n\t\tif (typeof parsed.nodeId !== 'string') return null\n\t\tconst sequence =\n\t\t\ttypeof parsed.sequence === 'number' && parsed.sequence >= 0 ? parsed.sequence : null\n\t\treturn sequence === null ? null : { nodeId: parsed.nodeId, sequence }\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/**\n * Load the acknowledged own-operation prefix for a node id. Null when none was ever\n * recorded for this node (an upgrade from a release that persisted a max instead).\n *\n * The first node a database tracks keeps the single legacy key (`own_acked_through`, as\n * earlier releases wrote it); any other local node (a rotated node, another tab's node\n * under per-tab isolation, RT-40) has its own key, so tracking one node never erases\n * another node's prefix.\n */\nexport async function loadOwnAckedThrough(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n): Promise<number | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tOWN_ACKED_THROUGH_META_KEY,\n\t])\n\tconst legacy = parseLegacyPrefix(rows[0]?.value)\n\tif (legacy && legacy.nodeId === nodeId) return legacy.sequence\n\tconst own = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\townAckedThroughKey(nodeId),\n\t])\n\tconst value = own[0]?.value\n\tif (value === undefined || value === null) return null\n\tconst sequence = Number(value)\n\treturn Number.isInteger(sequence) && sequence >= 0 ? sequence : null\n}\n\n/** Persist the acknowledged own-operation prefix for a node id. */\nexport async function saveOwnAckedThrough(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tsequence: number,\n): Promise<void> {\n\tawait adapter.transaction(async (tx) => {\n\t\tconst rows = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tOWN_ACKED_THROUGH_META_KEY,\n\t\t])\n\t\tconst legacy = parseLegacyPrefix(rows[0]?.value)\n\t\tif (legacy === null || legacy.nodeId === nodeId) {\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tOWN_ACKED_THROUGH_META_KEY,\n\t\t\t\tJSON.stringify({ nodeId, sequence }),\n\t\t\t])\n\t\t\treturn\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\townAckedThroughKey(nodeId),\n\t\t\tString(sequence),\n\t\t])\n\t})\n}\n\n/** Load the downlink scope the sync server last accepted (null when none). */\nexport async function loadAcceptedDownlinkScope(\n\tadapter: StorageAdapter,\n): Promise<Record<string, Record<string, unknown>> | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t])\n\tconst value = rows[0]?.value\n\tif (value === undefined || value === null) return null\n\ttry {\n\t\tconst parsed = JSON.parse(value) as unknown\n\t\treturn parsed !== null && typeof parsed === 'object'\n\t\t\t? (parsed as Record<string, Record<string, unknown>>)\n\t\t\t: null\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/** Persist (or clear) the downlink scope the sync server last accepted. */\nexport async function saveAcceptedDownlinkScope(\n\tadapter: StorageAdapter,\n\tscope: Record<string, Record<string, unknown>> | null,\n): Promise<void> {\n\tif (scope === null) {\n\t\tawait adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [\n\t\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t\t])\n\t\treturn\n\t}\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tACCEPTED_DOWNLINK_SCOPE_META_KEY,\n\t\tJSON.stringify(scope),\n\t])\n}\n","import type { MetaRow, StorageAdapter, Transaction } from '../types'\nimport { OWN_ACKED_THROUGH_META_KEY } from './sync-durability'\nimport { NODE_TOKEN_META_KEY, nodeTokenKey } from './sync-state'\n\n/**\n * Durable sync bookkeeping that belongs to the device, not to the app (Phase 2 RT-36,\n * RT-38, RT-40): the operations the server refused for good, and the node ids this\n * database authored operations under.\n *\n * Both tables are created on first use, so existing databases need no migration.\n */\n\n/**\n * Operations the server refused with a non-retriable rejection (RT-36). Unlike\n * `_kora_sync_rejected` (the app's reconciliation list, which `clearRejectedOperations`\n * empties), a row here is never removed: a refused operation stays refused, so a later\n * rescan of the device's own history never submits it again.\n */\nexport const TERMINAL_REJECTIONS_TABLE = '_kora_terminal_rejections'\n\n/**\n * Node ids this database authored operations under (RT-38, RT-40): the node in use,\n * nodes it rotated away from, and other tabs' nodes under per-tab isolation.\n */\nexport const LOCAL_NODES_TABLE = '_kora_local_nodes'\n\n/** Meta key: count of accepted sync handshakes on this database (refusal cycles, RT-38). */\nexport const ACCEPTED_CYCLE_META_KEY = 'sync_accepted_cycle'\n\n/** Meta key: terminal rejections were seeded from the pre-Phase-2 rejected list once. */\nconst TERMINAL_SEED_META_KEY = 'terminal_rejections_seeded_v1'\n\n/**\n * Rejection codes that never become a terminal marker: the operation was not judged on\n * its content, so a later upload of it may be accepted.\n *\n * - `SEQUENCE_CONFLICT`: the device's sequence number collided with an operation the\n * server holds (a lost local tail, RT-35, or a beta.12 duplicate pair, RT-37); the\n * operation is renumbered and uploaded again.\n * - `NODE_ID_MISMATCH`: uploaded on another node's session.\n * - `OUT_OF_UPLINK_SCOPE`: judged by the client against the scope it had then.\n */\nexport const NON_TERMINAL_REJECTION_CODES: ReadonlySet<string> = new Set([\n\t'SEQUENCE_CONFLICT',\n\t'NODE_ID_MISMATCH',\n\t'OUT_OF_UPLINK_SCOPE',\n])\n\nconst TERMINAL_REJECTIONS_DDL = `CREATE TABLE IF NOT EXISTS ${TERMINAL_REJECTIONS_TABLE} (\n operation_id TEXT PRIMARY KEY NOT NULL,\n node_id TEXT,\n sequence_number INTEGER,\n code TEXT NOT NULL,\n rejected_at INTEGER NOT NULL\n)`\n\nconst LOCAL_NODES_DDL = `CREATE TABLE IF NOT EXISTS ${LOCAL_NODES_TABLE} (\n node_id TEXT PRIMARY KEY NOT NULL,\n created_at INTEGER NOT NULL,\n accepted INTEGER NOT NULL DEFAULT 0,\n held INTEGER NOT NULL DEFAULT 0,\n refused_cycle INTEGER,\n principal TEXT,\n binding TEXT,\n refused_principals TEXT\n)`\n\n/**\n * How a local node's {@link LocalNodeRecord.principal} was learned (RT-50):\n *\n * - `fresh`: the node had no writes when it was bound to the signed-in user, so every\n * write under it was made by that user.\n * - `server`: a sync handshake as the node was accepted for that user (the server's node\n * claims are authoritative).\n * - `app`: the app assigned a held node to the signed-in user\n * (`app.sync.assignHeld`). A guess: cleared if the server refuses the node for them.\n */\nexport type LocalNodeBinding = 'fresh' | 'server' | 'app'\n\nconst LOCAL_NODE_BINDINGS: readonly LocalNodeBinding[] = ['fresh', 'server', 'app']\n\n/** At most this many principals are remembered as refused for one node (RT-50). */\nconst MAX_REFUSED_PRINCIPALS = 32\n\n/** Meta key: per-node adoption schedule (parked adoptions, upload progress; RT-46). */\nexport const ADOPTION_SCHEDULE_META_KEY = 'sync_adoption_schedule_v1'\n\n/** Adapters whose `_kora_local_nodes` table is known to have every column (this process). */\nconst migratedAdapters = new WeakSet<StorageAdapter>()\n\n/** A terminal rejection to record (RT-36). */\nexport interface TerminalRejection {\n\toperationId: string\n\t/** Authoring node and sequence, when known (null for rows seeded from the old list). */\n\tnodeId: string | null\n\tsequenceNumber: number | null\n\tcode: string\n\trejectedAt: number\n}\n\n/** A node id this database authored operations under (RT-38, RT-40). */\nexport interface LocalNodeRecord {\n\tnodeId: string\n\t/** Wall-clock time (ms) the node was registered. Display only. */\n\tcreatedAt: number\n\t/** A sync handshake as this node was accepted at least once. */\n\taccepted: boolean\n\t/**\n\t * The server refused this node (`NODE_ID_CLAIMED`) after it had been accepted: it\n\t * belongs to a principal that is not signed in. Its unsynced operations are held for\n\t * that principal, never uploaded under another one.\n\t */\n\theld: boolean\n\t/** {@link ACCEPTED_CYCLE_META_KEY} value when the server last refused it, or null. */\n\trefusedCycle: number | null\n\t/**\n\t * The signed-in user the node's writes belong to (RT-42), or null when the app never\n\t * told the store who was signed in while it was in use. A node bound to one user is\n\t * never used for, uploaded under, or adopted by another user's session.\n\t */\n\tprincipal: string | null\n\t/**\n\t * How {@link principal} was learned (RT-50), or null when unbound, or bound by a release\n\t * that did not record it (treated as a guess).\n\t */\n\tbinding: LocalNodeBinding | null\n\t/**\n\t * Users the server refused this UNBOUND node for (`NODE_ID_CLAIMED`, RT-50): it is\n\t * not theirs, so it is never tried again on their sessions. An unbound node that was\n\t * accepted before belongs to whichever user the server accepts it for.\n\t */\n\trefusedPrincipals: string[]\n}\n\ninterface LocalNodeRow {\n\tnode_id: string\n\tcreated_at: number\n\taccepted: number\n\theld: number\n\trefused_cycle: number | null\n\tprincipal: string | null\n\tbinding: string | null\n\trefused_principals: string | null\n}\n\n/** A parked adoption (RT-46): the node made no upload progress in its last session. */\nexport interface ParkedAdoption {\n\t/** {@link AdoptionSchedule.progress} when it was parked: retried once it moves. */\n\tprogressMark: number\n\t/** Wall-clock time (ms) after which it is retried anyway. Scheduling only. */\n\tuntilMs: number\n\t/** Consecutive parks (backoff exponent). */\n\tcount: number\n\t/** Wall-clock time (ms) it was parked. Scheduling only. */\n\tparkedAtMs: number\n}\n\n/**\n * Which local nodes' adoptions are parked (RT-46), and a counter of upload progress on\n * this database: a parked node is retried once anything else uploaded (its deferral may\n * have depended on it) or after its backoff.\n */\nexport interface AdoptionSchedule {\n\tprogress: number\n\tparked: Record<string, ParkedAdoption>\n}\n\n/**\n * Create both tables. `Store.open` runs it (through {@link registerLocalNode}), so the\n * read paths, which run often, assume the tables exist and never issue DDL (on the\n * IndexedDB adapter every statement schedules a snapshot).\n */\nexport async function ensureLocalSyncRecordTables(adapter: StorageAdapter): Promise<void> {\n\tawait adapter.execute(TERMINAL_REJECTIONS_DDL)\n\tawait adapter.execute(LOCAL_NODES_DDL)\n\tif (migratedAdapters.has(adapter)) return\n\t// A table created by an earlier release lacks the principal column (RT-42).\n\t// ... and the binding columns (RT-50).\n\tconst columns = await adapter.query<{ name: string }>(`PRAGMA table_info(${LOCAL_NODES_TABLE})`)\n\tfor (const column of ['principal', 'binding', 'refused_principals']) {\n\t\tif (!columns.some((existing) => existing.name === column)) {\n\t\t\tawait adapter.execute(`ALTER TABLE ${LOCAL_NODES_TABLE} ADD COLUMN ${column} TEXT`)\n\t\t}\n\t}\n\tmigratedAdapters.add(adapter)\n}\n\n/** Record terminal rejections (idempotent by operation id; the first record wins). */\nexport async function recordTerminalRejections(\n\tadapter: StorageAdapter,\n\tentries: TerminalRejection[],\n): Promise<void> {\n\tconst recordable = entries.filter((entry) => !NON_TERMINAL_REJECTION_CODES.has(entry.code))\n\tif (recordable.length === 0) return\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of recordable) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\t})\n}\n\n/** Which of `operationIds` carry a terminal rejection marker. */\nexport async function findTerminalRejections(\n\tadapter: StorageAdapter,\n\toperationIds: string[],\n): Promise<Set<string>> {\n\tconst found = new Set<string>()\n\tif (operationIds.length === 0) return found\n\tconst CHUNK = 500\n\tfor (let i = 0; i < operationIds.length; i += CHUNK) {\n\t\tconst chunk = operationIds.slice(i, i + CHUNK)\n\t\tconst rows = await adapter.query<{ operation_id: string }>(\n\t\t\t`SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE} WHERE operation_id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\tchunk,\n\t\t)\n\t\tfor (const row of rows) found.add(row.operation_id)\n\t}\n\treturn found\n}\n\n/**\n * Seed terminal markers once from `_kora_sync_rejected`, the list earlier releases kept\n * (and the app may have cleared since). Rows whose code is not terminal are skipped:\n * in particular a pre-release device's `SEQUENCE_CONFLICT` rejections (RT-37) stay eligible\n * for the one-time re-upload, which is how those writes reach the server.\n */\nexport async function seedTerminalRejectionsOnce(adapter: StorageAdapter): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tconst done = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tTERMINAL_SEED_META_KEY,\n\t])\n\tif (done.length > 0) return\n\tconst tables = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_kora_sync_rejected'\",\n\t)\n\tawait adapter.transaction(async (tx) => {\n\t\tif (tables.length > 0) {\n\t\t\tconst placeholders = [...NON_TERMINAL_REJECTION_CODES].map(() => '?').join(', ')\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at)\n SELECT operation_id, NULL, NULL, code, rejected_at FROM _kora_sync_rejected\n WHERE retriable = 0 AND code NOT IN (${placeholders})`,\n\t\t\t\t[...NON_TERMINAL_REJECTION_CODES],\n\t\t\t)\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tTERMINAL_SEED_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n}\n\nfunction rowToRecord(row: LocalNodeRow): LocalNodeRecord {\n\treturn {\n\t\tnodeId: row.node_id,\n\t\tcreatedAt: Number(row.created_at),\n\t\taccepted: Number(row.accepted) === 1,\n\t\theld: Number(row.held) === 1,\n\t\trefusedCycle: row.refused_cycle === null ? null : Number(row.refused_cycle),\n\t\tprincipal: typeof row.principal === 'string' ? row.principal : null,\n\t\tbinding:\n\t\t\ttypeof row.principal === 'string' &&\n\t\t\tLOCAL_NODE_BINDINGS.includes(row.binding as LocalNodeBinding)\n\t\t\t\t? (row.binding as LocalNodeBinding)\n\t\t\t\t: null,\n\t\trefusedPrincipals: parsePrincipalList(row.refused_principals),\n\t}\n}\n\nfunction parsePrincipalList(value: string | null): string[] {\n\tif (typeof value !== 'string' || value.length === 0) return []\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn Array.isArray(parsed)\n\t\t\t? parsed.filter((entry): entry is string => typeof entry === 'string')\n\t\t\t: []\n\t} catch {\n\t\treturn []\n\t}\n}\n\n/**\n * Register a node id this database authors operations under. A node registered for the\n * first time that a claims-aware server already accepted here (a database from a build\n * with node claims) is recorded as accepted, so a later refusal holds its writes\n * instead of re-authoring them under another principal (RT-38).\n *\n * Sync history alone is not that evidence (RT-92): beta.12 and older servers recorded\n * no node claims, so a node only they accepted belongs to nobody on an upgraded server.\n * It registers as not accepted, and a refusal re-authors its never-sent writes under a\n * fresh node (RT-21) instead of holding them for an owner that does not exist.\n */\nexport async function registerLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tconst existing = await adapter.query<{ node_id: string }>(\n\t\t`SELECT node_id FROM ${LOCAL_NODES_TABLE} WHERE node_id = ?`,\n\t\t[nodeId],\n\t)\n\tif (existing.length > 0) return\n\tconst accepted = await hasSyncHistory(adapter, nodeId)\n\tawait adapter.execute(\n\t\t`INSERT OR IGNORE INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, ?, 0, NULL)`,\n\t\t[nodeId, Date.now(), accepted ? 1 : 0],\n\t)\n}\n\n/**\n * Whether a claims-aware server accepted `nodeId` on this database before the registry\n * existed: a node token it issued (anonymous claims), or the acknowledged-prefix record\n * builds with node claims keep. beta.12's `last_acked_server_vector` does not count: its\n * server recorded no claims (RT-92).\n */\nasync function hasSyncHistory(adapter: StorageAdapter, nodeId: string): Promise<boolean> {\n\tconst rows = await adapter.query<MetaRow & { key: string }>(\n\t\t'SELECT key, value FROM _kora_meta WHERE key IN (?, ?, ?)',\n\t\t[NODE_TOKEN_META_KEY, nodeTokenKey(nodeId), OWN_ACKED_THROUGH_META_KEY],\n\t)\n\tconst nodeIdRows = await adapter.query<MetaRow>(\n\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t)\n\tconst isMetaNode = nodeIdRows[0]?.value === nodeId\n\tfor (const row of rows) {\n\t\tif (row.key === nodeTokenKey(nodeId)) return true\n\t\tif (row.key === NODE_TOKEN_META_KEY) {\n\t\t\tif (isMetaNode) return true\n\t\t\tcontinue\n\t\t}\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(row.value) as Record<string, unknown>\n\t\t\tif (row.key === OWN_ACKED_THROUGH_META_KEY) {\n\t\t\t\tif (parsed.nodeId === nodeId && typeof parsed.sequence === 'number' && parsed.sequence > 0)\n\t\t\t\t\treturn true\n\t\t\t}\n\t\t} catch {\n\t\t\t// An unreadable row is no evidence either way.\n\t\t}\n\t}\n\treturn false\n}\n\n/** Every registered local node, oldest first. */\nexport async function listLocalNodes(adapter: StorageAdapter): Promise<LocalNodeRecord[]> {\n\tconst rows = await adapter.query<LocalNodeRow>(\n\t\t`SELECT node_id, created_at, accepted, held, refused_cycle, principal, binding, refused_principals FROM ${LOCAL_NODES_TABLE} ORDER BY created_at ASC, node_id ASC`,\n\t)\n\treturn rows.map(rowToRecord)\n}\n\nasync function readAcceptedCycle(tx: Transaction): Promise<number> {\n\tconst rows = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_CYCLE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/**\n * Record an accepted handshake as `nodeId`: the node is accepted and no longer held,\n * and a new refusal cycle starts (every node may be tried again after a refusal).\n */\nexport async function markLocalNodeAccepted(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst cycle = await readAcceptedCycle(tx)\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, 1, 0, NULL)\n ON CONFLICT(node_id) DO UPDATE SET accepted = 1, held = 0, refused_cycle = NULL`,\n\t\t\t[nodeId, Date.now()],\n\t\t)\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tACCEPTED_CYCLE_META_KEY,\n\t\t\tString(cycle + 1),\n\t\t])\n\t})\n}\n\n/**\n * Record that the server refused `nodeId` (`NODE_ID_CLAIMED`) in the current refusal\n * cycle. `held` marks its unsynced operations as held for the principal owning it.\n */\nexport async function markLocalNodeRefused(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\theld: boolean,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst cycle = await readAcceptedCycle(tx)\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle) VALUES (?, ?, 0, ?, ?)\n ON CONFLICT(node_id) DO UPDATE SET held = MAX(held, excluded.held), refused_cycle = excluded.refused_cycle`,\n\t\t\t[nodeId, Date.now(), held ? 1 : 0, cycle],\n\t\t)\n\t})\n}\n\n/**\n * Forget a local node that has nothing left to upload (bounds the registry under per-tab\n * isolation, where every tab adds a node). A node that writes again is registered again\n * when its store opens. Never the database's own node id.\n */\nexport async function forgetLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`DELETE FROM ${LOCAL_NODES_TABLE} WHERE node_id = ? AND held = 0 AND node_id NOT IN (SELECT value FROM _kora_meta WHERE key = 'node_id')`,\n\t\t[nodeId],\n\t)\n}\n\n/**\n * Bind a local node to the signed-in user whose writes it carries (RT-42), recording how\n * that was learned (RT-50). The node is registered if it is not yet.\n */\nexport async function setLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n\tbinding: LocalNodeBinding,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle, principal, binding) VALUES (?, ?, 0, 0, NULL, ?, ?)\n ON CONFLICT(node_id) DO UPDATE SET principal = excluded.principal, binding = excluded.binding`,\n\t\t[nodeId, Date.now(), principal, binding],\n\t)\n}\n\n/** A binding that is only a guess: cleared when the server refuses the node (RT-50). */\nfunction isGuessedBinding(node: LocalNodeRecord): boolean {\n\treturn node.principal !== null && (node.binding === null || node.binding === 'app')\n}\n\nasync function findLocalNode(\n\tadapter: StorageAdapter | Transaction,\n\tnodeId: string,\n): Promise<LocalNodeRecord | null> {\n\tconst rows = await adapter.query<LocalNodeRow>(\n\t\t`SELECT node_id, created_at, accepted, held, refused_cycle, principal, binding, refused_principals FROM ${LOCAL_NODES_TABLE} WHERE node_id = ?`,\n\t\t[nodeId],\n\t)\n\tconst row = rows[0]\n\treturn row ? rowToRecord(row) : null\n}\n\n/**\n * A sync handshake as `nodeId` was accepted for `principal` (RT-50): the server's node\n * claims say the node is theirs. Binds an unbound node, or replaces a guessed binding,\n * as `server`. A node bound from evidence (`fresh` or `server`) to another user keeps\n * its binding: the engine never runs such a session.\n */\nexport async function confirmLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (node && node.principal !== null && node.principal !== principal && !isGuessedBinding(node))\n\t\t\treturn\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${LOCAL_NODES_TABLE} (node_id, created_at, accepted, held, refused_cycle, principal, binding) VALUES (?, ?, 0, 0, NULL, ?, 'server')\n ON CONFLICT(node_id) DO UPDATE SET principal = excluded.principal, binding = 'server', refused_principals = NULL`,\n\t\t\t[nodeId, Date.now(), principal],\n\t\t)\n\t})\n}\n\n/**\n * The server refused `nodeId` for `principal` (`NODE_ID_CLAIMED`, RT-50): another user\n * owns it. A guessed binding is cleared (it was wrong), and an unbound node remembers\n * that it is not `principal`'s, so it is tried on another user's session instead.\n */\nexport async function recordLocalNodeRefusedFor(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (!node) return\n\t\tif (node.principal !== null && !isGuessedBinding(node)) return\n\t\tconst refused = node.refusedPrincipals.filter((entry) => entry !== principal)\n\t\trefused.push(principal)\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${LOCAL_NODES_TABLE} SET principal = NULL, binding = NULL, refused_principals = ? WHERE node_id = ?`,\n\t\t\t[JSON.stringify(refused.slice(-MAX_REFUSED_PRINCIPALS)), nodeId],\n\t\t)\n\t})\n}\n\n/**\n * The app assigned a held, unbound local node to `principal` (RT-50,\n * `app.sync.assignHeld`): its writes upload on their sessions from now on. A guess, so\n * a later refusal by the server clears it again.\n *\n * @returns false when the node is unknown, already bound, or was refused for `principal`\n */\nexport async function assignLocalNodePrincipal(\n\tadapter: StorageAdapter,\n\tnodeId: string,\n\tprincipal: string,\n): Promise<boolean> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tlet assigned = false\n\tawait adapter.transaction(async (tx) => {\n\t\tconst node = await findLocalNode(tx, nodeId)\n\t\tif (!node || node.principal !== null || node.refusedPrincipals.includes(principal)) return\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${LOCAL_NODES_TABLE} SET principal = ?, binding = 'app', held = 0, refused_cycle = NULL WHERE node_id = ?`,\n\t\t\t[principal, nodeId],\n\t\t)\n\t\tassigned = true\n\t})\n\treturn assigned\n}\n\n/** Forget a local node whatever its state (its writes were discarded by the app, RT-50). */\nexport async function dropLocalNode(adapter: StorageAdapter, nodeId: string): Promise<void> {\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.execute(\n\t\t`DELETE FROM ${LOCAL_NODES_TABLE} WHERE node_id = ? AND node_id NOT IN (SELECT value FROM _kora_meta WHERE key = 'node_id')`,\n\t\t[nodeId],\n\t)\n}\n\n/** The adoption schedule (RT-46); empty when none was saved. */\nexport async function loadAdoptionSchedule(adapter: StorageAdapter): Promise<AdoptionSchedule> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tADOPTION_SCHEDULE_META_KEY,\n\t])\n\tconst empty: AdoptionSchedule = { progress: 0, parked: {} }\n\tconst raw = rows[0]?.value\n\tif (!raw) return empty\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as Partial<AdoptionSchedule>\n\t\treturn {\n\t\t\tprogress: typeof parsed.progress === 'number' ? parsed.progress : 0,\n\t\t\tparked: parsed.parked && typeof parsed.parked === 'object' ? parsed.parked : {},\n\t\t}\n\t} catch {\n\t\t// An unreadable schedule only costs an earlier retry of a parked adoption.\n\t\treturn empty\n\t}\n}\n\n/** Persist the adoption schedule (RT-46). */\nexport async function saveAdoptionSchedule(\n\tadapter: StorageAdapter,\n\tschedule: AdoptionSchedule,\n): Promise<void> {\n\tawait adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\tADOPTION_SCHEDULE_META_KEY,\n\t\tJSON.stringify(schedule),\n\t])\n}\n\n/** The current refusal cycle (count of accepted handshakes on this database). */\nexport async function loadAcceptedCycle(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tACCEPTED_CYCLE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/** Read access to a database (an open adapter, or a reader handed to a delete check). */\nexport interface DatabaseQuery {\n\tquery<T>(sql: string, params?: unknown[]): Promise<T[]>\n}\n\n/**\n * Whether any local node has operations above its contiguous acknowledged prefix that\n * the server did not refuse for good (RT-41): the authoritative \"unsynced\" (W3), which\n * the outbound queue only approximates. A local node is one in the registry, the\n * database's node id, or the node of the legacy prefix key; a node with no recorded\n * prefix counts from 0. Works on a database no store has opened in this release.\n */\nexport async function hasUnsyncedOwnOperations(db: DatabaseQuery): Promise<boolean> {\n\tconst tables = new Set(\n\t\t(await db.query<{ name: string }>(\"SELECT name FROM sqlite_master WHERE type = 'table'\")).map(\n\t\t\t(row) => row.name,\n\t\t),\n\t)\n\tconst opsTables = [...tables].filter((name) => name.startsWith('_kora_ops_'))\n\tif (opsTables.length === 0 || !tables.has('_kora_meta')) return false\n\n\tconst nodes = new Set<string>()\n\tif (tables.has(LOCAL_NODES_TABLE)) {\n\t\tfor (const row of await db.query<{ node_id: string }>(\n\t\t\t`SELECT node_id FROM ${LOCAL_NODES_TABLE}`,\n\t\t)) {\n\t\t\tnodes.add(row.node_id)\n\t\t}\n\t}\n\tconst meta = await db.query<{ key: string; value: string }>(\n\t\t\"SELECT key, value FROM _kora_meta WHERE key = 'node_id' OR key = ? OR key LIKE ?\",\n\t\t[OWN_ACKED_THROUGH_META_KEY, `${OWN_ACKED_THROUGH_META_KEY}:%`],\n\t)\n\tconst prefixes = new Map<string, number>()\n\tfor (const row of meta) {\n\t\tif (row.key === 'node_id') {\n\t\t\tnodes.add(row.value)\n\t\t} else if (row.key === OWN_ACKED_THROUGH_META_KEY) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(row.value) as { nodeId?: unknown; sequence?: unknown }\n\t\t\t\tif (typeof parsed.nodeId === 'string') {\n\t\t\t\t\tnodes.add(parsed.nodeId)\n\t\t\t\t\tif (typeof parsed.sequence === 'number') prefixes.set(parsed.nodeId, parsed.sequence)\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Unreadable: the node (if known otherwise) counts from 0.\n\t\t\t}\n\t\t} else {\n\t\t\tconst nodeId = row.key.slice(OWN_ACKED_THROUGH_META_KEY.length + 1)\n\t\t\t// The legacy key wins for its node (loadOwnAckedThrough reads it first).\n\t\t\tconst sequence = Number(row.value)\n\t\t\tif (!prefixes.has(nodeId) && Number.isInteger(sequence)) prefixes.set(nodeId, sequence)\n\t\t}\n\t}\n\tconst exclude = tables.has(TERMINAL_REJECTIONS_TABLE)\n\t\t? ` AND id NOT IN (SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE})`\n\t\t: ''\n\tfor (const nodeId of nodes) {\n\t\tconst prefix = prefixes.get(nodeId) ?? 0\n\t\tfor (const table of opsTables) {\n\t\t\tconst rows = await db.query<{ n: number }>(\n\t\t\t\t`SELECT COUNT(*) AS n FROM \"${table.replace(/\"/g, '\"\"')}\" WHERE node_id = ? AND sequence_number > ?${exclude}`,\n\t\t\t\t[nodeId, prefix],\n\t\t\t)\n\t\t\tif (Number(rows[0]?.n ?? 0) > 0) return true\n\t\t}\n\t}\n\treturn false\n}\n","import {\n\tFOLD_STATE_VERSION,\n\ttype FoldOptions,\n\ttype FoldState,\n\tFoldStateError,\n\ttype FoldTrace,\n\tHybridLogicalClock,\n\ttype MergeTrace,\n\ttype Operation,\n\ttype OperationTransform,\n\ttype SchemaDefinition,\n\tadaptFoldState,\n\tbase64ToBytes,\n\tcreateFoldState,\n\tdeserializeFoldState,\n\tgetFoldFieldVersionStrings,\n\tisFoldStateLive,\n\tjoinStates,\n\tmaterialize,\n\tmergeOp,\n\tmismatchedFoldFields,\n\tquoteIdent,\n\tserializeFoldState,\n\ttoMergeTrace,\n} from '@korajs/core'\nimport * as Y from 'yjs'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeRecord } from '../serialization/serializer'\nimport { loadRetainedConflictRows } from '../store/sequence-repair'\nimport { TERMINAL_REJECTIONS_TABLE } from '../sync/local-sync-records'\nimport type { OperationRow, RawCollectionRow, Transaction } from '../types'\n\n/** Per-record fold state (serialized `FoldState`) of every record this database holds. */\nexport const FOLD_STATE_TABLE = '_kora_fold_state'\n/**\n * Per-record base state of operations no longer in the log (compacted, or a snapshot\n * of a row whose history was compacted or quarantined before W7). A record's state\n * is always `join(base, fold(log))`.\n */\nexport const FOLD_BASE_TABLE = '_kora_fold_base'\n/** Per-node sequence prefix removed by compaction: ids at or below it are duplicates. */\nexport const COMPACTED_THROUGH_TABLE = '_kora_compacted_through'\n/**\n * Per-record row snapshots (RT-68): the base built from a materialized row when the\n * record's history is not all in the log (a pre-W7 compaction, quarantined log rows).\n * Kept apart from `_kora_fold_base` (which holds only exact, operation-built states)\n * so the approximation can be dropped once the record's history is complete again:\n * when the server's fold state arrives in a scope entry, or after a full resync.\n * A record's state is `join(base, snapshot, fold(log))`.\n */\nexport const FOLD_SNAPSHOT_TABLE = '_kora_fold_snapshot'\n/**\n * Local-only provisional side effects (RT-69): the cascades / set-nulls a device\n * derives for a REMOTE delete. They fold into the record like operations but are\n * never logged, sequenced or uploaded (the server derives and relays its own\n * copy); each is retired when the server's copy for the same parent and record\n * arrives, or when the device's delivery stream has caught up.\n\n */\nexport const PROVISIONAL_OPS_TABLE = '_kora_provisional_ops'\n/**\n * Terminal-rejection codes the fold does NOT exclude: the user discarded a held\n * node's writes (they stay in the local database; only their upload stops).\n */\nconst KEPT_REJECTION_CODES: readonly string[] = ['HELD_DISCARDED']\n/** `_kora_meta` key recording how the rows of this database are materialized. */\nexport const FOLD_MATERIALIZATION_META_KEY = 'fold_materialization'\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} once rows are materializations of the current fold. */\nexport const FOLD_MATERIALIZATION_CURRENT = `fold-v${FOLD_STATE_VERSION}`\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} while the legacy (beta.12) paths write rows. */\nexport const FOLD_MATERIALIZATION_LEGACY = 'legacy'\n\n/** DDL for the fold tables. Idempotent. */\nexport const FOLD_TABLES_DDL: readonly string[] = [\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_STATE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_BASE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${COMPACTED_THROUGH_TABLE} (node_id TEXT PRIMARY KEY, sequence_number INTEGER NOT NULL)`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_SNAPSHOT_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${PROVISIONAL_OPS_TABLE} (id TEXT PRIMARY KEY, collection TEXT NOT NULL, record_id TEXT NOT NULL, parent_id TEXT NOT NULL, operation TEXT NOT NULL)`,\n\t`CREATE INDEX IF NOT EXISTS ${PROVISIONAL_OPS_TABLE}_record ON ${PROVISIONAL_OPS_TABLE} (collection, record_id)`,\n]\n\n/**\n * Merges richtext Yjs updates for the fold (core has no Yjs dependency): applies\n * every update to one fresh document and encodes its state. The encoding depends\n * only on the document's content, not on how it was split into updates, so every\n * replica materializes byte-identical richtext.\n */\nexport function mergeYjsUpdates(updates: Uint8Array[]): Uint8Array {\n\tconst doc = new Y.Doc()\n\tfor (const update of updates) Y.applyUpdate(doc, update)\n\treturn Y.encodeStateAsUpdate(doc)\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n\tif (a.length !== b.length) return false\n\tfor (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\n\treturn true\n}\n\n/**\n * Whether Yjs update `a` adds nothing to update `b` (the fold's richtext space\n * bound): the canonical encoding of `b` alone equals that of `a` and `b` merged.\n */\nexport function yjsSubsumes(a: Uint8Array, b: Uint8Array): boolean {\n\treturn sameBytes(mergeYjsUpdates([b]), mergeYjsUpdates([a, b]))\n}\n\n/**\n * Whether an operation lies in a node's compacted prefix: its row is gone from the\n * log, but its effect is in the record's base state, so it is a duplicate (STORE-14).\n */\nexport async function isCompacted(tx: Transaction, op: Operation): Promise<boolean> {\n\tconst rows = await tx.query<{ sequence_number: number }>(\n\t\t`SELECT sequence_number FROM ${COMPACTED_THROUGH_TABLE} WHERE node_id = ?`,\n\t\t[op.nodeId],\n\t)\n\tconst through = rows[0]?.sequence_number\n\treturn through !== undefined && op.sequenceNumber <= through\n}\n\n/** Which fields of a row to (re)write from the fold state. */\nexport type MaterializeFields = 'all' | ReadonlySet<string>\n\n/** Result of merging one operation into its record. */\nexport interface FoldApplyOutcome {\n\t/** The merge changed the record's state. */\n\tchanged: boolean\n\t/** Merge traces (MergeTrace form), for `merge:*` events. */\n\ttraces: MergeTrace[]\n}\n\n/**\n * The client side of the W7 fold: every write to a materialized row — local\n * writes, remote operations, scope entries, rejection re-merges, re-materialization\n * — goes through this class, inside the write transaction that appends the\n * operation (\"append, then merge\"). A row is always the materialization of its\n * record's fold state.\n */\nexport class RecordFolder {\n\tprivate authoritative: ReadonlySet<string> = new Set()\n\n\tconstructor(\n\t\tprivate readonly schema: SchemaDefinition,\n\t\tprivate readonly transforms: readonly OperationTransform[] = [],\n\t) {}\n\n\t/** The schema transforms every merge applies (transforms at fold time, RT-84). */\n\tgetOperationTransforms(): readonly OperationTransform[] {\n\t\treturn this.transforms\n\t}\n\n\t/**\n\t * The fields an operation's merge can change: its own data's keys, or every field\n\t * when the fold reads it through a schema transform (whose view may name others).\n\t */\n\tprivate touchedFields(op: Operation): MaterializeFields {\n\t\tif (this.transforms.length > 0 && op.schemaVersion !== this.schema.version) return 'all'\n\t\treturn new Set(Object.keys(op.data ?? {}))\n\t}\n\n\t/** Node ids whose writes win `merge('server-authoritative')` fields. */\n\tgetAuthoritativeNodeIds(): ReadonlySet<string> {\n\t\treturn this.authoritative\n\t}\n\n\t/** @internal Set by the store from persisted meta / the sync handshake. */\n\tsetAuthoritativeNodeIds(ids: Iterable<string>): void {\n\t\tthis.authoritative = new Set(ids)\n\t}\n\n\t/** Fold options every merge of this database uses. */\n\toptions(traces: FoldOptions['traces'] = 'none'): FoldOptions {\n\t\treturn {\n\t\t\trichtext: mergeYjsUpdates,\n\t\t\trichtextSubsumes: yjsSubsumes,\n\t\t\ttraces,\n\t\t\t...(this.authoritative.size > 0 ? { authoritativeNodeIds: this.authoritative } : {}),\n\t\t\t...(this.transforms.length > 0 ? { transforms: this.transforms } : {}),\n\t\t}\n\t}\n\n\t/** Whether the schema has a `merge('server-authoritative')` field in `collection`. */\n\thasAuthoritativeFields(collection: string): boolean {\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return false\n\t\treturn Object.values(definition.fields).some(\n\t\t\t(field) => field.mergeStrategy === 'server-authoritative',\n\t\t)\n\t}\n\n\t/**\n\t * Merge one operation (already appended to the log) into its record and\n\t * re-materialize the row.\n\t *\n\t * @param tx - The write transaction that appended the operation\n\t * @param op - The operation\n\t * @param mode - 'remote' emits merge traces; 'local' does not (a local write is\n\t * computed from the row it updates, so it is never concurrent with it)\n\t */\n\tasync applyInTx(\n\t\ttx: Transaction,\n\t\top: Operation,\n\t\tmode: 'local' | 'remote',\n\t): Promise<FoldApplyOutcome> {\n\t\tconst scopeEntry = op.type === 'insert'\n\t\tif (mode === 'remote') {\n\t\t\t// The record's approximations end here: a provisional cascade of this parent\n\t\t\t// is replaced by the real one (RT-69), and a row snapshot by the server's\n\t\t\t// complete fold state (RT-68). The operation is already in the log, so the\n\t\t\t// record is re-folded without them.\n\t\t\tconst retired = await this.deleteProvisional(tx, op.collection, op.recordId, op.causalDeps)\n\t\t\tconst replaced = await this.dropSnapshotForCarriedState(tx, op)\n\t\t\tif (retired > 0 || replaced) {\n\t\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\t\treturn { changed: true, traces: [] }\n\t\t\t}\n\t\t}\n\t\t// A local insert has a fresh UUIDv7 record id: no state, log or row precedes it.\n\t\tconst fresh = mode === 'local' && op.type === 'insert'\n\t\tconst prior = fresh\n\t\t\t? { state: createFoldState(op.collection, op.recordId), rebuilt: false }\n\t\t\t: await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tlet result: ReturnType<typeof mergeOp>\n\t\ttry {\n\t\t\tresult = mergeOp(\n\t\t\t\tprior.state,\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(mode === 'remote' ? 'conflicts' : 'none'),\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof FoldStateError)) throw error\n\t\t\t// A stored state the current plan cannot take (RT-63): re-fold the record from\n\t\t\t// its base and log (the operation is already appended) once. A second\n\t\t\t// FoldStateError propagates; the sync engine then quarantines the operation\n\t\t\t// instead of stalling its delivery stream.\n\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\treturn { changed: true, traces: [] }\n\t\t}\n\t\tif (!result.changed && !prior.rebuilt && !scopeEntry) {\n\t\t\treturn { changed: false, traces: await this.toMergeTraces(tx, result.traces) }\n\t\t}\n\t\tawait this.saveState(tx, result.state)\n\t\tconst revived = isDeadState(prior.state) && !isDeadState(result.state)\n\t\tconst fields: MaterializeFields =\n\t\t\tprior.rebuilt || revived || op.foldState !== undefined ? 'all' : this.touchedFields(op)\n\t\tawait this.materializeRow(tx, result.state, fields, {\n\t\t\tclearRetraction: scopeEntry,\n\t\t\t...(fresh ? { absent: true } : {}),\n\t\t})\n\t\treturn { changed: result.changed, traces: await this.toMergeTraces(tx, result.traces) }\n\t}\n\n\t/**\n\t * Fold a record from its base state and its log, leaving out operations the\n\t * server terminally rejected, and re-materialize its row (all fields).\n\t *\n\t * @returns The new state (null when nothing of the record remains)\n\t */\n\tasync refoldInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\toptions: { clearRetraction?: boolean } = {},\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.foldFromLog(tx, collection, recordId)\n\t\tif (state === null) {\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t])\n\t\t\t// Nothing of the record remains (its insert was refused): hide the row.\n\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 1 WHERE id = ?`, [recordId])\n\t\t\treturn null\n\t\t}\n\t\tawait this.saveState(tx, state)\n\t\tawait this.materializeRow(tx, state, 'all', {\n\t\t\tclearRetraction: options.clearRetraction ?? false,\n\t\t})\n\t\treturn state\n\t}\n\n\t/**\n\t * `join(base, snapshot, fold(log - terminally rejected, provisional effects))`, or\n\t * null when none exists. Base and snapshot are adapted to the current fold plan\n\t * (RT-63): a field whose kind changed is rebuilt from its materialized value.\n\t */\n\tasync foldFromLog(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst ops = [\n\t\t\t...(await this.loadRecordOperations(tx, collection, recordId)),\n\t\t\t...(await this.loadProvisional(tx, collection, recordId)),\n\t\t]\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tconst snapshot = await this.loadSnapshot(tx, collection, recordId)\n\t\tlet state =\n\t\t\tbase !== null && snapshot !== null\n\t\t\t\t? joinStates(base, snapshot, this.schema)\n\t\t\t\t: (base ?? snapshot)\n\t\tfor (const op of ops) {\n\t\t\tif (rejected.has(op.id)) continue\n\t\t\tstate = mergeOp(\n\t\t\t\tstate ?? createFoldState(collection, recordId),\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(),\n\t\t\t).state\n\t\t}\n\t\treturn state\n\t}\n\n\t/** The record's operations (log + retained sequence-conflict rows). */\n\tasync loadRecordOperations(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = [\n\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t)),\n\t\t]\n\t\treturn rows.map((row) => deserializeOperationWithCollection(row, collection))\n\t}\n\n\t/**\n\t * Which of `ids` the fold leaves out: operations with a terminal-rejection marker\n\t * from the server (or quarantined by a scope retraction, which the server never\n\t * receives). Writes the user chose to discard from a held node are NOT left out:\n\t * discarding stops the upload, it is not a rollback.\n\t */\n\tasync loadTerminalRejections(tx: Transaction, ids: readonly string[]): Promise<Set<string>> {\n\t\tconst found = new Set<string>()\n\t\tconst CHUNK = 500\n\t\tfor (let i = 0; i < ids.length; i += CHUNK) {\n\t\t\tconst chunk = ids.slice(i, i + CHUNK)\n\t\t\tconst rows = await tx.query<{ operation_id: string }>(\n\t\t\t\t`SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE} WHERE code NOT IN (${KEPT_REJECTION_CODES.map(() => '?').join(', ')}) AND operation_id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t[...KEPT_REJECTION_CODES, ...chunk],\n\t\t\t)\n\t\t\tfor (const row of rows) found.add(row.operation_id)\n\t\t}\n\t\treturn found\n\t}\n\n\t/**\n\t * The record's stored state, or null (none, another format version, or a field\n\t * whose fold kind the schema has changed since: the caller re-folds, RT-63).\n\t */\n\tasync loadState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t\tif (state === null || mismatchedFoldFields(state, this.schema).length > 0) return null\n\t\treturn state\n\t}\n\n\t/** The stored state as it is, even when the plan changed (a snapshot seed). */\n\tasync loadStoredState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\treturn this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t}\n\n\t/** The record's compacted base, adapted to the current fold plan (RT-63). */\n\tasync loadBase(tx: Transaction, collection: string, recordId: string): Promise<FoldState | null> {\n\t\tconst base = await this.readStateRow(tx, FOLD_BASE_TABLE, collection, recordId)\n\t\treturn base === null ? null : adaptFoldState(base, this.schema, this.options()).state\n\t}\n\n\t/** The record's row snapshot (RT-68), adapted to the current fold plan. */\n\tasync loadSnapshot(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst snapshot = await this.readStateRow(tx, FOLD_SNAPSHOT_TABLE, collection, recordId)\n\t\treturn snapshot === null ? null : adaptFoldState(snapshot, this.schema, this.options()).state\n\t}\n\n\t/** Store `snapshot` as the record's row snapshot (joined with an existing one). */\n\tasync saveSnapshot(tx: Transaction, snapshot: FoldState): Promise<void> {\n\t\tconst existing = await this.loadSnapshot(tx, snapshot.c, snapshot.r)\n\t\tconst state = existing === null ? snapshot : joinStates(existing, snapshot, this.schema)\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_SNAPSHOT_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/**\n\t * A scope entry carrying the server's fold state (RT-29) replaces the record's row\n\t * snapshot (RT-68): the server's state is built from every operation of the record\n\t * the device was missing, so with the device's own log it is the exact state.\n\t * Only a carried state this schema can read and join counts (otherwise the entry\n\t * merges by its data and the snapshot stays).\n\t *\n\t * @returns Whether a snapshot was dropped\n\t */\n\tprivate async dropSnapshotForCarriedState(tx: Transaction, op: Operation): Promise<boolean> {\n\t\tif (op.type !== 'insert' || op.foldState === undefined) return false\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[op.collection, op.recordId],\n\t\t)\n\t\tif ((rows[0]?.n ?? 0) === 0) return false\n\t\tlet carried: FoldState\n\t\ttry {\n\t\t\tcarried = deserializeFoldState(op.foldState)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FoldStateError) return false\n\t\t\tthrow error\n\t\t}\n\t\tif (carried.c !== op.collection || carried.r !== op.recordId) return false\n\t\tif (mismatchedFoldFields(carried, this.schema).length > 0) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\top.collection,\n\t\t\top.recordId,\n\t\t])\n\t\treturn true\n\t}\n\n\t/** Records that still fold against a row snapshot (approximate, RT-68). */\n\tasync listSnapshotRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT collection, record_id FROM ${FOLD_SNAPSHOT_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\t/**\n\t * After a full resync, a record whose log holds its insert again no longer needs\n\t * its row snapshot: drop it and re-fold the record from base and log (RT-68).\n\t *\n\t * @returns Whether the snapshot was dropped\n\t */\n\tasync settleSnapshotInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst ops = await this.loadRecordOperations(tx, collection, recordId)\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst hasInsert = ops.some((op) => op.type === 'insert' && !rejected.has(op.id))\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tif (!hasInsert && (base?.cr ?? null) === null) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t])\n\t\tawait this.refoldInTx(tx, collection, recordId)\n\t\treturn true\n\t}\n\n\t/**\n\t * Fold a local-only provisional side effect (RT-69) into its record: stored apart\n\t * from the log (never sequenced, never uploaded) and kept until the real copy of\n\t * the effect arrives or the delivery stream catches up.\n\t *\n\t * @param parentId - The remote operation that caused it (the parent delete)\n\t */\n\tasync applyProvisionalInTx(tx: Transaction, op: Operation, parentId: string): Promise<void> {\n\t\tconst existing = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE id = ?`,\n\t\t\t[op.id],\n\t\t)\n\t\tif (existing.length > 0) return\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${PROVISIONAL_OPS_TABLE} (id, collection, record_id, parent_id, operation) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t[op.id, op.collection, op.recordId, parentId, JSON.stringify(op)],\n\t\t)\n\t\tconst prior = await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tconst result = mergeOp(prior.state, op, this.schema, this.options())\n\t\tif (!result.changed && !prior.rebuilt) return\n\t\tawait this.saveState(tx, result.state)\n\t\tawait this.materializeRow(tx, result.state, prior.rebuilt ? 'all' : this.touchedFields(op), {\n\t\t\tclearRetraction: false,\n\t\t})\n\t}\n\n\t/**\n\t * Remove provisional effects of a record (those caused by one of `parentIds`, or\n\t * all of them when null). The caller re-folds the record.\n\t *\n\t * @returns How many were removed\n\t */\n\tasync deleteProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tparentIds: readonly string[] | null,\n\t): Promise<number> {\n\t\tif (parentIds !== null && parentIds.length === 0) return 0\n\t\tconst filter =\n\t\t\tparentIds === null ? '' : ` AND parent_id IN (${parentIds.map(() => '?').join(', ')})`\n\t\tconst rows = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?${filter}`,\n\t\t\t[collection, recordId, ...(parentIds ?? [])],\n\t\t)\n\t\tif (rows.length === 0) return 0\n\t\tawait tx.execute(\n\t\t\t`DELETE FROM ${PROVISIONAL_OPS_TABLE} WHERE id IN (${rows.map(() => '?').join(', ')})`,\n\t\t\trows.map((row) => row.id),\n\t\t)\n\t\treturn rows.length\n\t}\n\n\t/** Records with provisional effects. */\n\tasync listProvisionalRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT DISTINCT collection, record_id FROM ${PROVISIONAL_OPS_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\tprivate async loadProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = await tx.query<{ operation: string }>(\n\t\t\t`SELECT operation FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn rows.map((row) => JSON.parse(row.operation) as Operation)\n\t}\n\n\tasync saveState(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_STATE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\tasync saveBase(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_BASE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/** Join `addition` into the record's base state. */\n\tasync joinIntoBase(tx: Transaction, addition: FoldState): Promise<void> {\n\t\tconst base = await this.loadBase(tx, addition.c, addition.r)\n\t\tawait this.saveBase(tx, base === null ? addition : joinStates(base, addition, this.schema))\n\t}\n\n\t/**\n\t * Write the row of a record from its fold state.\n\t *\n\t * - No insert merged: no row (an existing one is hidden).\n\t * - Otherwise the row holds the fold's values (also while deleted: a tombstone\n\t * keeps its last values), `_deleted` from the record's liveness, and versions\n\t * from the state: `_version` / `_updated_at` = newest operation, `_created_at` =\n\t * creation, `_field_versions` = each field's newest write.\n\t * - Only `fields` are written to an existing row; columns the fold never wrote\n\t * (a column a schema migration added with a default, a local-only backfill)\n\t * keep their stored value.\n\t * - A row hidden by a scope retraction stays hidden unless `clearRetraction`\n\t * (a scope-entry insert) is set.\n\t */\n\tasync materializeRow(\n\t\ttx: Transaction,\n\t\tstate: FoldState,\n\t\tfields: MaterializeFields,\n\t\toptions: { clearRetraction: boolean; absent?: boolean },\n\t): Promise<void> {\n\t\tconst collection = state.c\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return\n\t\tconst table = quoteIdent(collection)\n\t\tconst rows = options.absent\n\t\t\t? []\n\t\t\t: await tx.query<RawCollectionRow>(`SELECT id, _deleted FROM ${table} WHERE id = ?`, [\n\t\t\t\t\tstate.r,\n\t\t\t\t])\n\t\tconst existing = rows[0]\n\t\tif (state.cr === null || state.u === null) {\n\t\t\tif (existing && existing._deleted !== 1) {\n\t\t\t\tawait tx.execute(`UPDATE ${table} SET _deleted = 1 WHERE id = ?`, [state.r])\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst asLive: FoldState = { ...state, d: null }\n\t\tconst values = materialize(asLive, { richtext: mergeYjsUpdates }) ?? {}\n\t\tconst latest = HybridLogicalClock.deserialize(state.u.t)\n\t\tconst created = HybridLogicalClock.deserialize(state.cr.t)\n\t\t// Sorted keys: replicas holding the same state write byte-identical columns.\n\t\tconst fieldVersions = getFoldFieldVersionStrings(state)\n\t\tlet deleted = isDeadState(state) ? 1 : 0\n\t\tif (existing && deleted === 0) {\n\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t[collection, state.r],\n\t\t\t)\n\t\t\tif (retracted.length > 0) {\n\t\t\t\tif (options.clearRetraction) {\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, state.r],\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tdeleted = 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst known = Object.keys(definition.fields)\n\t\t// A tombstone keeps the values it had when it was deleted: a write that lost to\n\t\t// the delete never shows, not even in the hidden row. A revival rewrites them all.\n\t\tconst writable =\n\t\t\texisting && deleted === 1\n\t\t\t\t? []\n\t\t\t\t: known.filter((field) => field in state.f && (fields === 'all' || fields.has(field)))\n\t\tconst fieldValues: Record<string, unknown> = {}\n\t\tfor (const field of writable) {\n\t\t\tconst value = values[field] ?? null\n\t\t\t// A richtext field with a single live update materializes as that update's\n\t\t\t// own bytes; re-encode it so every replica stores the same canonical bytes,\n\t\t\t// however its state happens to be split into updates.\n\t\t\tfieldValues[field] =\n\t\t\t\tdefinition.fields[field]?.kind === 'richtext' &&\n\t\t\t\tvalue !== null &&\n\t\t\t\ttypeof value === 'object' &&\n\t\t\t\t'$koraBytes' in value\n\t\t\t\t\t? mergeYjsUpdates([base64ToBytes(String((value as { $koraBytes: string }).$koraBytes))])\n\t\t\t\t\t: value\n\t\t}\n\t\tconst serialized = serializeRecord(fieldValues, definition.fields)\n\t\tconst meta: Record<string, unknown> = {\n\t\t\t_updated_at: latest.wallTime,\n\t\t\t_version: state.u.t,\n\t\t\t_field_versions: JSON.stringify(fieldVersions),\n\t\t\t_deleted: deleted,\n\t\t}\n\t\tif (!existing) {\n\t\t\tconst insert = buildInsertQuery(collection, {\n\t\t\t\tid: state.r,\n\t\t\t\t...serialized,\n\t\t\t\t...meta,\n\t\t\t\t_created_at: created.wallTime,\n\t\t\t})\n\t\t\tawait tx.execute(insert.sql, insert.params)\n\t\t\treturn\n\t\t}\n\t\tconst changes: Record<string, unknown> = {\n\t\t\t...serialized,\n\t\t\t...meta,\n\t\t\t_created_at: created.wallTime,\n\t\t}\n\t\tconst columns = Object.keys(changes)\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${table} SET ${columns.map((c) => `${quoteIdent(c)} = ?`).join(', ')} WHERE id = ?`,\n\t\t\t[...columns.map((c) => changes[c]), state.r],\n\t\t)\n\t}\n\n\t/**\n\t * Load the record's state; rebuild it from base + log when it is missing or in\n\t * another format version. `rebuilt` tells the caller to rewrite the whole row.\n\t */\n\tprivate async loadOrRebuild(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tappendedId: string,\n\t): Promise<{ state: FoldState; rebuilt: boolean }> {\n\t\tconst stored = await this.loadState(tx, collection, recordId)\n\t\tif (stored !== null) return { state: stored, rebuilt: false }\n\t\tconst hasRow = await this.hasStateRow(tx, collection, recordId)\n\t\tconst others = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ? AND id != ?`,\n\t\t\t[recordId, appendedId],\n\t\t)\n\t\tconst retained = await loadRetainedConflictRows(\n\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t)\n\t\tconst hasBase =\n\t\t\t(await this.loadBase(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadSnapshot(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadProvisional(tx, collection, recordId)).some((p) => p.id !== appendedId)\n\t\tif (\n\t\t\t!hasRow &&\n\t\t\t!hasBase &&\n\t\t\t(others[0]?.n ?? 0) === 0 &&\n\t\t\tretained.every((row) => row.id === appendedId)\n\t\t) {\n\t\t\t// A new record: nothing to rebuild.\n\t\t\treturn { state: createFoldState(collection, recordId), rebuilt: false }\n\t\t}\n\t\tconst rebuilt = await this.foldFromLog(tx, collection, recordId)\n\t\treturn { state: rebuilt ?? createFoldState(collection, recordId), rebuilt: true }\n\t}\n\n\tprivate async hasStateRow(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn (rows[0]?.n ?? 0) > 0\n\t}\n\n\tprivate async readStateRow(\n\t\ttx: Transaction,\n\t\ttable: string,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst rows = await tx.query<{ state: string }>(\n\t\t\t`SELECT state FROM ${table} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\tconst raw = rows[0]?.state\n\t\tif (raw === undefined) return null\n\t\ttry {\n\t\t\treturn deserializeFoldState(raw)\n\t\t} catch (error) {\n\t\t\t// Another format version: the caller re-folds the record.\n\t\t\tif (error instanceof FoldStateError) return null\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprivate async toMergeTraces(tx: Transaction, traces: FoldTrace[]): Promise<MergeTrace[]> {\n\t\tconst out: MergeTrace[] = []\n\t\tfor (const trace of traces) {\n\t\t\tlet prior: Operation | null = null\n\t\t\tif (trace.priorOperationId !== null) {\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${trace.operation.collection}`)} WHERE id = ?`,\n\t\t\t\t\t[trace.priorOperationId],\n\t\t\t\t)\n\t\t\t\tconst row = rows[0]\n\t\t\t\tif (row) prior = deserializeOperationWithCollection(row, trace.operation.collection)\n\t\t\t}\n\t\t\tout.push(toMergeTrace(trace, prior))\n\t\t}\n\t\treturn out\n\t}\n}\n\n/** No insert merged yet, or the newest delete is later than the newest write. */\n/**\n * The stored form of a fold state: plain JSON, read back by `deserializeFoldState`.\n * The canonical form (`serializeFoldState`, sorted keys) is for comparing and\n * exchanging states; a local row only needs to round-trip, and plain JSON is several\n * times cheaper on the write path.\n */\nfunction persistedForm(state: FoldState): string {\n\treturn JSON.stringify(state)\n}\n\nfunction isDeadState(state: FoldState): boolean {\n\treturn !isFoldStateLive(state)\n}\n","import { HybridLogicalClock, quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport { deserializeOperation, serializeOperation } from '../serialization/serializer'\nimport type { MetaRow, OperationRow, StorageAdapter, Transaction } from '../types'\n\n/**\n * Log-integrity scan (W8 step 0).\n *\n * Every later fold of the operation log (W7 re-materialization, replay, compaction)\n * trusts that each stored row is a canonical operation. Two earlier releases could\n * break that:\n *\n * - beta.12's backup restore wrote `JSON.stringify(timestamp)` into the timestamp\n * column, which `HybridLogicalClock.deserialize` reads as `wallTime: NaN` (a `null`\n * once re-exported), and a second restore of such a backup nested the damage;\n * - compaction deletes acknowledged operations, leaving holes in a node's sequence.\n *\n * The scan detects rows that do not round-trip through `deserializeOperation` /\n * `serializeOperation`, repairs the ones whose original value is recoverable from the\n * row itself (the JSON-encoded timestamp), and moves the rest to\n * {@link LOG_QUARANTINE_TABLE} (never deleted), so no fold ever reads them. It also\n * reports sequence gaps in this database's own nodes. Remote nodes' gaps are normal\n * (scoped sync only delivers part of another device's log) and are not reported.\n */\n\n/** Rows that could not be repaired, kept verbatim. Never cleared automatically. */\nexport const LOG_QUARANTINE_TABLE = '_kora_log_quarantine'\n\nconst QUARANTINE_DDL = `CREATE TABLE IF NOT EXISTS ${LOG_QUARANTINE_TABLE} (\n collection TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n node_id TEXT,\n sequence_number INTEGER,\n problem TEXT NOT NULL,\n detail TEXT NOT NULL,\n row_json TEXT NOT NULL,\n quarantined_at INTEGER NOT NULL,\n PRIMARY KEY (collection, operation_id)\n)`\n\n/** What is wrong with an operation row. */\nexport type LogRowProblem =\n\t/** The timestamp is a JSON-encoded HLC (beta.12 backup restore). Repairable. */\n\t| 'timestamp-json'\n\t/** The timestamp cannot be read as an HLC and is not recoverable. */\n\t| 'timestamp-malformed'\n\t/** `id`, `node_id` or `record_id` is missing. */\n\t| 'identity-malformed'\n\t/** `type` is not insert, update or delete. */\n\t| 'type-invalid'\n\t/** `sequence_number` is not a positive integer. */\n\t| 'sequence-invalid'\n\t/** `data` or `previous_data` is not a JSON object. */\n\t| 'data-malformed'\n\t/** `causal_deps` is not a JSON array of operation ids. */\n\t| 'causal-deps-malformed'\n\t/** The row cannot be turned into an operation and back. */\n\t| 'round-trip-failed'\n\n/** One operation row the scan repaired or quarantined. */\nexport interface LogIntegrityRow {\n\tcollection: string\n\toperationId: string\n\tnodeId: string | null\n\tsequenceNumber: number | null\n\tproblem: LogRowProblem\n\t/** Human-readable detail: the bad value, or how it was repaired. */\n\tdetail: string\n}\n\n/** Sequence numbers missing from one of this database's own nodes. */\nexport interface LogSequenceGap {\n\tnodeId: string\n\t/** First missing sequence number (inclusive). */\n\tfrom: number\n\t/** Last missing sequence number (inclusive). */\n\tto: number\n}\n\n/**\n * Result of {@link scanLogIntegrity} / `Store.verifyLogIntegrity()`.\n *\n * `clean` is the precondition for rebuilding state from the log (W7): every row is\n * canonical, nothing is quarantined, and this database's own nodes have no holes\n * below their highest stored sequence number.\n */\nexport interface LogIntegrityReport {\n\t/** True when the log can be folded as-is (no quarantined rows, no own-node gaps). */\n\tclean: boolean\n\t/** `full`: every row was checked in JS. `quick`: SQL prefilter, suspects checked in JS. */\n\tmode: 'full' | 'quick'\n\t/** Rows checked in JS (all rows in full mode, suspects in quick mode). */\n\tcheckedRows: number\n\t/** Rows this scan repaired in place. */\n\trepaired: LogIntegrityRow[]\n\t/** Rows this scan moved to the quarantine table. */\n\tnewlyQuarantined: LogIntegrityRow[]\n\t/** Every row in the quarantine table (this scan's and earlier ones'). */\n\tquarantined: LogIntegrityRow[]\n\t/** Holes in this database's own nodes' sequences (compaction, a lost tail). */\n\tgaps: LogSequenceGap[]\n\t/** When the log was last compacted (epoch ms), or null when never. */\n\tcompactedAt: number | null\n\t/** False when the scan only reported (`repair: false`). */\n\trepairApplied: boolean\n}\n\n/** Options for {@link scanLogIntegrity}. */\nexport interface LogIntegrityScanOptions {\n\t/** Check every row in JS (default) or only the rows a SQL prefilter flags. */\n\tmode?: 'full' | 'quick'\n\t/** Repair and quarantine (default true). False only reports. */\n\trepair?: boolean\n\t/** Node ids this database authors under (gaps are reported for these only). */\n\tlocalNodeIds: readonly string[]\n}\n\nconst OPERATION_TYPES = new Set(['insert', 'update', 'delete'])\nconst CANONICAL_TIMESTAMP = /^\\d{15}:\\d{5}:.+$/\nconst PAGE_SIZE = 500\n\n/**\n * SQL prefilter: rows that cannot be canonical. Cheap enough to run on every open; the\n * JS check then confirms each suspect. `CASE` keeps `json_type` from seeing invalid JSON.\n */\nconst SUSPECT_WHERE = `id IS NULL OR node_id IS NULL OR record_id IS NULL\n OR type NOT IN ('insert', 'update', 'delete')\n OR typeof(sequence_number) != 'integer' OR sequence_number < 1\n OR typeof(timestamp) != 'text' OR length(timestamp) < 23\n OR substr(timestamp, 16, 1) != ':' OR substr(timestamp, 22, 1) != ':'\n OR substr(timestamp, 1, 15) GLOB '*[^0-9]*' OR substr(timestamp, 17, 5) GLOB '*[^0-9]*'\n OR causal_deps IS NULL\n OR (CASE WHEN json_valid(causal_deps) THEN json_type(causal_deps) != 'array' ELSE 1 END)\n OR (data IS NOT NULL AND (CASE WHEN json_valid(data) THEN json_type(data) != 'object' ELSE 1 END))\n OR (previous_data IS NOT NULL AND (CASE WHEN json_valid(previous_data) THEN json_type(previous_data) != 'object' ELSE 1 END))`\n\ntype RowWithRowid = OperationRow & { __rowid: number }\n\n/** Outcome of {@link checkOperationRow}. */\nexport type LogRowVerdict =\n\t| { kind: 'ok' }\n\t| { kind: 'repair'; problem: LogRowProblem; detail: string; timestamp: string }\n\t| { kind: 'quarantine'; problem: LogRowProblem; detail: string }\n\n/**\n * Scan the operation log of every schema collection; repair and quarantine (unless\n * `repair: false`), then report. Repairs and quarantine moves run in one transaction.\n *\n * @param adapter - An opened storage adapter\n * @param schema - The schema whose operation tables are scanned\n * @param options - Scan mode, repair switch and this database's own node ids\n */\nexport async function scanLogIntegrity(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\toptions: LogIntegrityScanOptions,\n): Promise<LogIntegrityReport> {\n\tconst repair = options.repair ?? true\n\tlet mode = options.mode ?? 'full'\n\tawait adapter.execute(QUARANTINE_DDL)\n\n\tconst actions: Array<{ collection: string; row: RowWithRowid; verdict: LogRowVerdict }> = []\n\tlet checkedRows = 0\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\tlet rows: RowWithRowid[] | null = null\n\t\tif (mode === 'quick') {\n\t\t\ttry {\n\t\t\t\trows = await adapter.query<RowWithRowid>(\n\t\t\t\t\t`SELECT rowid AS __rowid, * FROM ${table} WHERE ${SUSPECT_WHERE}`,\n\t\t\t\t)\n\t\t\t} catch {\n\t\t\t\t// No JSON functions in this SQLite build: check every row instead.\n\t\t\t\tmode = 'full'\n\t\t\t}\n\t\t}\n\t\tif (rows !== null) {\n\t\t\tfor (const row of rows) {\n\t\t\t\tcheckedRows++\n\t\t\t\tconst verdict = checkOperationRow(row)\n\t\t\t\tif (verdict.kind !== 'ok') actions.push({ collection, row, verdict })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tlet after = 0\n\t\tfor (;;) {\n\t\t\tconst page = await adapter.query<RowWithRowid>(\n\t\t\t\t`SELECT rowid AS __rowid, * FROM ${table} WHERE rowid > ? ORDER BY rowid LIMIT ${PAGE_SIZE}`,\n\t\t\t\t[after],\n\t\t\t)\n\t\t\tfor (const row of page) {\n\t\t\t\tcheckedRows++\n\t\t\t\tconst verdict = checkOperationRow(row)\n\t\t\t\tif (verdict.kind !== 'ok') actions.push({ collection, row, verdict })\n\t\t\t}\n\t\t\tif (page.length < PAGE_SIZE) break\n\t\t\tafter = page[page.length - 1]?.__rowid ?? after\n\t\t}\n\t}\n\n\tconst repaired: LogIntegrityRow[] = []\n\tconst newlyQuarantined: LogIntegrityRow[] = []\n\tfor (const { collection, row, verdict } of actions) {\n\t\tif (verdict.kind === 'ok') continue\n\t\tconst entry = describeRow(collection, row, verdict.problem, verdict.detail)\n\t\tif (verdict.kind === 'repair') repaired.push(entry)\n\t\telse newlyQuarantined.push(entry)\n\t}\n\n\tif (repair && actions.length > 0) {\n\t\tconst now = Date.now()\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tfor (const { collection, row, verdict } of actions) {\n\t\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\t\tif (verdict.kind === 'repair') {\n\t\t\t\t\tawait tx.execute(`UPDATE ${table} SET timestamp = ? WHERE rowid = ?`, [\n\t\t\t\t\t\tverdict.timestamp,\n\t\t\t\t\t\trow.__rowid,\n\t\t\t\t\t])\n\t\t\t\t} else if (verdict.kind === 'quarantine') {\n\t\t\t\t\tawait quarantineRow(tx, collection, row, verdict.problem, verdict.detail, now)\n\t\t\t\t\tawait tx.execute(`DELETE FROM ${table} WHERE rowid = ?`, [row.__rowid])\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tconst quarantined = await loadQuarantine(adapter)\n\tconst gaps = await findOwnSequenceGaps(adapter, schema, options.localNodeIds)\n\tconst compactedAt = await loadCompactedAt(adapter)\n\tconst pendingQuarantine = repair ? 0 : newlyQuarantined.length\n\treturn {\n\t\tclean: quarantined.length === 0 && pendingQuarantine === 0 && gaps.length === 0,\n\t\tmode,\n\t\tcheckedRows,\n\t\trepaired,\n\t\tnewlyQuarantined,\n\t\tquarantined,\n\t\tgaps,\n\t\tcompactedAt,\n\t\trepairApplied: repair,\n\t}\n}\n\n/**\n * Judge one operation row: canonical, repairable (with the repaired timestamp), or\n * to be quarantined.\n */\nexport function checkOperationRow(row: OperationRow): LogRowVerdict {\n\tif (\n\t\t!isNonEmptyString(row.id) ||\n\t\t!isNonEmptyString(row.node_id) ||\n\t\t!isNonEmptyString(row.record_id)\n\t) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'identity-malformed',\n\t\t\tdetail: 'id, node_id or record_id is missing',\n\t\t}\n\t}\n\tif (!OPERATION_TYPES.has(row.type)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'type-invalid',\n\t\t\tdetail: `type ${JSON.stringify(row.type)}`,\n\t\t}\n\t}\n\tif (!Number.isInteger(row.sequence_number) || row.sequence_number < 1) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'sequence-invalid',\n\t\t\tdetail: `sequence_number ${JSON.stringify(row.sequence_number)}`,\n\t\t}\n\t}\n\tif (!isJsonObjectOrNull(row.data) || !isJsonObjectOrNull(row.previous_data)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'data-malformed',\n\t\t\tdetail: 'data or previous_data is not a JSON object',\n\t\t}\n\t}\n\tif (!isJsonStringArray(row.causal_deps)) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'causal-deps-malformed',\n\t\t\tdetail: `causal_deps ${truncate(String(row.causal_deps))}`,\n\t\t}\n\t}\n\n\tlet timestamp = row.timestamp\n\tlet repairedFrom: string | null = null\n\tif (!isCanonicalTimestamp(timestamp)) {\n\t\tconst recovered = recoverTimestamp(timestamp)\n\t\tif (recovered === null) {\n\t\t\treturn {\n\t\t\t\tkind: 'quarantine',\n\t\t\t\tproblem: 'timestamp-malformed',\n\t\t\t\tdetail: `timestamp ${truncate(String(timestamp))}`,\n\t\t\t}\n\t\t}\n\t\trepairedFrom = String(timestamp)\n\t\ttimestamp = recovered\n\t}\n\n\ttry {\n\t\tconst op = deserializeOperation({ ...row, timestamp })\n\t\tconst again = serializeOperation({ ...op, collection: '' })\n\t\tif (again.timestamp !== timestamp) {\n\t\t\tthrow new Error(`timestamp ${again.timestamp} != ${timestamp}`)\n\t\t}\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: 'quarantine',\n\t\t\tproblem: 'round-trip-failed',\n\t\t\tdetail: error instanceof Error ? error.message : String(error),\n\t\t}\n\t}\n\n\tif (repairedFrom !== null) {\n\t\treturn {\n\t\t\tkind: 'repair',\n\t\t\tproblem: 'timestamp-json',\n\t\t\tdetail: `timestamp ${truncate(repairedFrom)} -> ${timestamp}`,\n\t\t\ttimestamp,\n\t\t}\n\t}\n\treturn { kind: 'ok' }\n}\n\n/** Whether `value` is the zero-padded `wall:logical:node` form that sorts like HLC order. */\nfunction isCanonicalTimestamp(value: unknown): value is string {\n\tif (typeof value !== 'string' || !CANONICAL_TIMESTAMP.test(value)) return false\n\ttry {\n\t\treturn HybridLogicalClock.serialize(HybridLogicalClock.deserialize(value)) === value\n\t} catch {\n\t\treturn false\n\t}\n}\n\ninterface LooseTimestamp {\n\twallTime: unknown\n\tlogical: unknown\n\tnodeId: unknown\n}\n\n/**\n * Recover the canonical timestamp from a JSON-encoded HLC (beta.12 restore wrote\n * `JSON.stringify(timestamp)`). A backup exported from such a database and restored\n * again nests the damage: `deserialize` read the JSON as `wallTime: NaN` (exported as\n * `null`), `logical: <wallTime>` and `nodeId: '<logical>,\"nodeId\":\"<nodeId>\"}'`, which\n * is undone level by level.\n */\nexport function recoverTimestamp(value: unknown): string | null {\n\tif (typeof value !== 'string' || !value.startsWith('{')) return null\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(value)\n\t} catch {\n\t\treturn null\n\t}\n\tlet candidate = parsed as LooseTimestamp\n\tfor (let depth = 0; depth < 8; depth++) {\n\t\tif (candidate === null || typeof candidate !== 'object') return null\n\t\tconst { wallTime, logical, nodeId } = candidate\n\t\tif (Number.isInteger(wallTime) && Number.isInteger(logical) && isNonEmptyString(nodeId)) {\n\t\t\ttry {\n\t\t\t\treturn HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: wallTime as number,\n\t\t\t\t\tlogical: logical as number,\n\t\t\t\t\tnodeId,\n\t\t\t\t})\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t}\n\t\t// One level of nesting: wallTime lost, logical holds the wall time, and nodeId\n\t\t// holds the rest of the inner JSON object.\n\t\tif (wallTime !== null || !Number.isInteger(logical) || typeof nodeId !== 'string') return null\n\t\tconst match = /^(\\d+),\"nodeId\":(\".*\")\\}$/.exec(nodeId)\n\t\tif (!match?.[1] || !match[2]) return null\n\t\tlet innerNode: unknown\n\t\ttry {\n\t\t\tinnerNode = JSON.parse(match[2])\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t\tcandidate = { wallTime: logical, logical: Number(match[1]), nodeId: innerNode }\n\t}\n\treturn null\n}\n\nasync function quarantineRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: RowWithRowid,\n\tproblem: LogRowProblem,\n\tdetail: string,\n\tnow: number,\n): Promise<void> {\n\tconst { __rowid: _rowid, ...original } = row\n\tawait tx.execute(\n\t\t`INSERT OR REPLACE INTO ${LOG_QUARANTINE_TABLE} (collection, operation_id, node_id, sequence_number, problem, detail, row_json, quarantined_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\tcollection,\n\t\t\ttypeof row.id === 'string' ? row.id : `rowid:${row.__rowid}`,\n\t\t\ttypeof row.node_id === 'string' ? row.node_id : null,\n\t\t\tNumber.isInteger(row.sequence_number) ? row.sequence_number : null,\n\t\t\tproblem,\n\t\t\tdetail,\n\t\t\tJSON.stringify(original, bytesReplacer),\n\t\t\tnow,\n\t\t],\n\t)\n}\n\ninterface QuarantineRow {\n\tcollection: string\n\toperation_id: string\n\tnode_id: string | null\n\tsequence_number: number | null\n\tproblem: string\n\tdetail: string\n}\n\nasync function loadQuarantine(adapter: StorageAdapter): Promise<LogIntegrityRow[]> {\n\tconst rows = await adapter.query<QuarantineRow>(\n\t\t`SELECT collection, operation_id, node_id, sequence_number, problem, detail FROM ${LOG_QUARANTINE_TABLE} ORDER BY quarantined_at ASC, collection ASC, operation_id ASC`,\n\t)\n\treturn rows.map((row) => ({\n\t\tcollection: row.collection,\n\t\toperationId: row.operation_id,\n\t\tnodeId: row.node_id,\n\t\tsequenceNumber: row.sequence_number,\n\t\tproblem: row.problem as LogRowProblem,\n\t\tdetail: row.detail,\n\t}))\n}\n\n/**\n * Holes in each own node's sequence below its highest stored number. Numbers held only\n * by `_kora_seq_conflicts` re-emissions are in the log under their new number, so the\n * log tables alone decide.\n */\nasync function findOwnSequenceGaps(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeIds: readonly string[],\n): Promise<LogSequenceGap[]> {\n\tconst collections = Object.keys(schema.collections)\n\tif (collections.length === 0) return []\n\tconst gaps: LogSequenceGap[] = []\n\tconst union = collections\n\t\t.map((c) => `SELECT sequence_number FROM ${quoteIdent(`_kora_ops_${c}`)} WHERE node_id = ?`)\n\t\t.join(' UNION ALL ')\n\tfor (const nodeId of [...new Set(nodeIds)]) {\n\t\tconst params = collections.map(() => nodeId)\n\t\tconst summary = await adapter.query<{ n: number; m: number | null }>(\n\t\t\t`SELECT COUNT(DISTINCT sequence_number) AS n, MAX(sequence_number) AS m FROM (${union})`,\n\t\t\tparams,\n\t\t)\n\t\tconst count = summary[0]?.n ?? 0\n\t\tconst max = summary[0]?.m ?? 0\n\t\tif (max === null || max === 0 || count === max) continue\n\t\tconst present = await adapter.query<{ sequence_number: number }>(\n\t\t\t`SELECT DISTINCT sequence_number FROM (${union}) ORDER BY sequence_number ASC`,\n\t\t\tparams,\n\t\t)\n\t\tlet expected = 1\n\t\tfor (const { sequence_number: seq } of present) {\n\t\t\tif (seq > expected) gaps.push({ nodeId, from: expected, to: seq - 1 })\n\t\t\texpected = Math.max(expected, seq + 1)\n\t\t}\n\t}\n\treturn gaps\n}\n\nasync function loadCompactedAt(adapter: StorageAdapter): Promise<number | null> {\n\tconst rows = await adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tCOMPACTION_BASELINE_META_KEY,\n\t])\n\tconst value = Number(rows[0]?.value)\n\treturn rows[0] && Number.isFinite(value) ? value : null\n}\n\nfunction describeRow(\n\tcollection: string,\n\trow: OperationRow,\n\tproblem: LogRowProblem,\n\tdetail: string,\n): LogIntegrityRow {\n\treturn {\n\t\tcollection,\n\t\toperationId: typeof row.id === 'string' ? row.id : '',\n\t\tnodeId: typeof row.node_id === 'string' ? row.node_id : null,\n\t\tsequenceNumber: Number.isInteger(row.sequence_number) ? row.sequence_number : null,\n\t\tproblem,\n\t\tdetail,\n\t}\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === 'string' && value.length > 0\n}\n\nfunction isJsonObjectOrNull(value: unknown): boolean {\n\tif (value === null || value === undefined) return true\n\tif (typeof value !== 'string') return false\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction isJsonStringArray(value: unknown): boolean {\n\tif (typeof value !== 'string') return false\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value)\n\t\treturn Array.isArray(parsed) && parsed.every((id) => typeof id === 'string')\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction truncate(value: string): string {\n\treturn value.length > 120 ? `${value.slice(0, 117)}...` : value\n}\n\nfunction bytesReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) return { $bytes: Array.from(value) }\n\treturn value\n}\n","import { HybridLogicalClock, KoraError, quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n} from '../fold/record-folder'\nimport { checkOperationRow, recoverTimestamp } from '../log-integrity/log-integrity'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE } from '../store/sequence-repair'\nimport { TERMINAL_REJECTIONS_TABLE, type TerminalRejection } from '../sync/local-sync-records'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport type { BackupManifest, BackupOptions, RestoreOptions, RestoreResult } from './types'\n\n// ── Format ──────────────────────────────────────────────────────────────────\n//\n// A backup is a sequence of sections `[u32 nameLen][u32 contentLen][name][content]`:\n//\n// manifest JSON BackupManifest (first section)\n// version_vector JSON { nodeId: maxSequence } of the exporting database\n// operations NDJSON, one canonical Operation per line (collection, data,\n// previousData, HLC timestamp object, atomicOps, transactionId,\n// mutationName, fieldVersions), in HLC order. Includes\n// operations kept only in the sequence-conflicts table.\n// terminal_rejections JSON TerminalRejection[] (operations the server refused for good)\n// fold_base NDJSON { collection, recordId, state }: per-record fold states of\n// compacted operations (W7, RT-66); a restore keeps them\n// fold_snapshot NDJSON { collection, recordId, state }: per-record row snapshots\n// (approximate bases, RT-68)\n// compacted_through JSON { nodeId: sequence }: per-node prefix folded into the bases\n// records:<name> NDJSON raw rows of the collection, tombstones included, bytes\n// tagged as { \"$bytes\": \"<base64>\" }\n// checksum SHA-256 hex over every section between manifest and checksum\n//\n// Version 2 (STORE-5) carries no `_kora_meta`: a device's identity (node id, node\n// tokens) and sync state never travel in a backup. Version 1 files are refused with\n// BACKUP_FORMAT_OUTDATED; {@link convertBackupV1} converts them.\n\n/** Current backup format version. */\nexport const BACKUP_VERSION = 2\n\n/** A backup file this release cannot restore as-is. */\nexport class BackupFormatError extends KoraError {\n\tconstructor(message: string, code: string, context?: Record<string, unknown>) {\n\t\tsuper(message, code, context)\n\t\tthis.name = 'BackupFormatError'\n\t}\n}\n\nfunction encodeSection(name: string, content: Uint8Array): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(name)\n\tconst result = new Uint8Array(8 + nameBytes.length + content.length)\n\tconst dv = new DataView(result.buffer)\n\tdv.setUint32(0, nameBytes.length, true)\n\tdv.setUint32(4, content.length, true)\n\tresult.set(nameBytes, 8)\n\tresult.set(content, 8 + nameBytes.length)\n\treturn result\n}\n\nfunction encodeJsonSection(name: string, data: unknown): Uint8Array {\n\treturn encodeSection(name, new TextEncoder().encode(JSON.stringify(data, bytesReplacer)))\n}\n\nfunction encodeNdjsonSection(name: string, items: unknown[]): Uint8Array {\n\tconst lines = items.map((item) => JSON.stringify(item, bytesReplacer)).join('\\n')\n\treturn encodeSection(name, new TextEncoder().encode(items.length > 0 ? `${lines}\\n` : ''))\n}\n\ninterface Section {\n\tname: string\n\tcontent: Uint8Array\n}\n\nfunction parseSections(data: Uint8Array): Section[] {\n\tconst sections: Section[] = []\n\tconst dv = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\tlet offset = 0\n\twhile (offset + 8 <= data.byteLength) {\n\t\tconst nameLen = dv.getUint32(offset, true)\n\t\tconst contentLen = dv.getUint32(offset + 4, true)\n\t\toffset += 8\n\t\tif (offset + nameLen + contentLen > data.byteLength) break\n\t\tconst name = new TextDecoder().decode(data.slice(offset, offset + nameLen))\n\t\toffset += nameLen\n\t\tsections.push({ name, content: data.slice(offset, offset + contentLen) })\n\t\toffset += contentLen\n\t}\n\treturn sections\n}\n\nfunction findSection(sections: Section[], name: string): Uint8Array | null {\n\treturn sections.find((section) => section.name === name)?.content ?? null\n}\n\nfunction parseJsonSection<T>(sections: Section[], name: string): T | null {\n\tconst content = findSection(sections, name)\n\tif (!content) return null\n\treturn JSON.parse(new TextDecoder().decode(content), bytesReviver) as T\n}\n\nfunction parseNdjson<T>(content: Uint8Array | null): T[] {\n\tif (!content) return []\n\treturn new TextDecoder()\n\t\t.decode(content)\n\t\t.split('\\n')\n\t\t.filter((line) => line.trim().length > 0)\n\t\t.map((line) => JSON.parse(line, bytesReviver) as T)\n}\n\nfunction concat(parts: Uint8Array[]): Uint8Array {\n\tconst total = parts.reduce((sum, part) => sum + part.length, 0)\n\tconst result = new Uint8Array(total)\n\tlet pos = 0\n\tfor (const part of parts) {\n\t\tresult.set(part, pos)\n\t\tpos += part.length\n\t}\n\treturn result\n}\n\n// ── Export ──────────────────────────────────────────────────────────────────\n\n/**\n * Export a backup (format version 2) from an opened database.\n *\n * Everything is read inside one transaction, so the backup is a consistent snapshot.\n * Operations are exported in canonical form (exactly what `deserializeOperation` reads\n * back), including tombstones, so a restore rebuilds the same log.\n *\n * @param adapter - The storage adapter\n * @param schema - The schema definition\n * @param nodeId - Node id of the exporting device (informational only; never imported)\n * @param schemaVersion - Schema version\n * @param options - Backup options\n * @returns Backup as a Uint8Array\n */\nexport async function exportBackup(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n\tschemaVersion: number,\n\toptions?: BackupOptions,\n): Promise<Uint8Array> {\n\tconst onProgress = options?.onProgress ?? (() => {})\n\tconst includeRecords = options?.includeRecords ?? true\n\tconst filter = options?.collections\n\tconst collections = Object.keys(schema.collections).filter(\n\t\t(name) => !filter || filter.includes(name),\n\t)\n\n\tconst snapshot: {\n\t\tvector: Record<string, number>\n\t\toperations: Operation[]\n\t\tterminal: TerminalRejection[]\n\t\trecords: Map<string, Array<Record<string, unknown>>>\n\t\tbases: FoldStateRow[]\n\t\tsnapshots: FoldStateRow[]\n\t\tcompactedThrough: Record<string, number>\n\t\tcompacted: boolean\n\t} = {\n\t\tvector: {},\n\t\toperations: [],\n\t\tterminal: [],\n\t\trecords: new Map(),\n\t\tbases: [],\n\t\tsnapshots: [],\n\t\tcompactedThrough: {},\n\t\tcompacted: false,\n\t}\n\n\tonProgress({ phase: 'reading', progress: 0, message: 'Reading the local database' })\n\tawait adapter.transaction(async (tx) => {\n\t\tconst vector = await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tfor (const row of vector) snapshot.vector[row.node_id] = row.sequence_number\n\t\tsnapshot.operations = await readOperations(tx, collections)\n\t\tsnapshot.terminal = await readTerminalRejections(tx)\n\t\t// W7 (RT-66): compacted history lives only in the base states; without them a\n\t\t// restore on another device would rebuild records from an incomplete log.\n\t\tsnapshot.bases = await readFoldStateRows(tx, FOLD_BASE_TABLE, collections)\n\t\tsnapshot.snapshots = await readFoldStateRows(tx, FOLD_SNAPSHOT_TABLE, collections)\n\t\tif (await hasTable(tx, COMPACTED_THROUGH_TABLE)) {\n\t\t\tfor (const row of await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t\t`SELECT node_id, sequence_number FROM ${COMPACTED_THROUGH_TABLE}`,\n\t\t\t)) {\n\t\t\t\tsnapshot.compactedThrough[row.node_id] = row.sequence_number\n\t\t\t}\n\t\t}\n\t\tsnapshot.compacted =\n\t\t\tsnapshot.bases.length > 0 ||\n\t\t\tObject.keys(snapshot.compactedThrough).length > 0 ||\n\t\t\t(\n\t\t\t\tawait tx.query<{ value: string }>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\t\t])\n\t\t\t).length > 0\n\t\tif (includeRecords) {\n\t\t\tfor (const collection of collections) {\n\t\t\t\tsnapshot.records.set(\n\t\t\t\t\tcollection,\n\t\t\t\t\tawait tx.query<Record<string, unknown>>(`SELECT * FROM ${quoteIdent(collection)}`),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t})\n\tonProgress({ phase: 'reading', progress: 0.7, message: 'Encoding' })\n\n\tconst content: Uint8Array[] = [\n\t\tencodeJsonSection('version_vector', snapshot.vector),\n\t\tencodeNdjsonSection('operations', snapshot.operations),\n\t\tencodeJsonSection('terminal_rejections', snapshot.terminal),\n\t\tencodeNdjsonSection('fold_base', snapshot.bases),\n\t\tencodeNdjsonSection('fold_snapshot', snapshot.snapshots),\n\t\tencodeJsonSection('compacted_through', snapshot.compactedThrough),\n\t]\n\tfor (const [collection, rows] of snapshot.records) {\n\t\tif (rows.length > 0) content.push(encodeNdjsonSection(`records:${collection}`, rows))\n\t}\n\tconst body = concat(content)\n\tconst checksum = await computeSha256(body)\n\tonProgress({ phase: 'writing', progress: 1, message: 'Finalizing' })\n\n\tconst manifest: BackupManifest = {\n\t\tversion: BACKUP_VERSION,\n\t\tcreatedAt: Date.now(),\n\t\tnodeId,\n\t\tschemaVersion,\n\t\toperationCount: snapshot.operations.length,\n\t\tcollections,\n\t\tincludesRecords: includeRecords,\n\t\tincludesTombstones: true,\n\t\tincludesFoldState: true,\n\t\tcompacted: snapshot.compacted,\n\t\tchecksum,\n\t}\n\treturn concat([\n\t\tencodeJsonSection('manifest', manifest),\n\t\tbody,\n\t\tencodeSection('checksum', new TextEncoder().encode(checksum)),\n\t])\n}\n\n/** Operations of `collections` in canonical form and HLC order (causal order). */\nasync function readOperations(tx: Transaction, collections: string[]): Promise<Operation[]> {\n\tconst operations: Operation[] = []\n\tconst seen = new Set<string>()\n\tconst retained = await hasTable(tx, SEQ_CONFLICTS_TABLE)\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} ORDER BY sequence_number ASC`,\n\t\t)\n\t\t// Other nodes' operations kept only in the sequence-conflicts table still belong\n\t\t// to the log (record folds and dedup use them).\n\t\tif (retained) {\n\t\t\trows.push(\n\t\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND reemitted_as IS NULL`,\n\t\t\t\t\t[collection],\n\t\t\t\t)),\n\t\t\t)\n\t\t}\n\t\tfor (const row of rows) {\n\t\t\tif (seen.has(row.id)) continue\n\t\t\tseen.add(row.id)\n\t\t\toperations.push(deserializeOperationWithCollection(row, collection))\n\t\t}\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\treturn operations\n}\n\n/** One per-record fold state row (`_kora_fold_base` / `_kora_fold_snapshot`) in a backup. */\nexport interface FoldStateRow {\n\tcollection: string\n\trecordId: string\n\t/** The serialized `FoldState`, as stored. */\n\tstate: string\n}\n\nasync function readFoldStateRows(\n\ttx: Transaction,\n\ttable: string,\n\tcollections: string[],\n): Promise<FoldStateRow[]> {\n\tif (!(await hasTable(tx, table))) return []\n\tconst out: FoldStateRow[] = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ record_id: string; state: string }>(\n\t\t\t`SELECT record_id, state FROM ${table} WHERE collection = ? ORDER BY record_id`,\n\t\t\t[collection],\n\t\t)\n\t\tfor (const row of rows) out.push({ collection, recordId: row.record_id, state: row.state })\n\t}\n\treturn out\n}\n\nasync function readTerminalRejections(tx: Transaction): Promise<TerminalRejection[]> {\n\tif (!(await hasTable(tx, TERMINAL_REJECTIONS_TABLE))) return []\n\tconst rows = await tx.query<{\n\t\toperation_id: string\n\t\tnode_id: string | null\n\t\tsequence_number: number | null\n\t\tcode: string\n\t\trejected_at: number\n\t}>(\n\t\t`SELECT operation_id, node_id, sequence_number, code, rejected_at FROM ${TERMINAL_REJECTIONS_TABLE} ORDER BY operation_id`,\n\t)\n\treturn rows.map((row) => ({\n\t\toperationId: row.operation_id,\n\t\tnodeId: row.node_id,\n\t\tsequenceNumber: row.sequence_number,\n\t\tcode: row.code,\n\t\trejectedAt: row.rejected_at,\n\t}))\n}\n\nasync function hasTable(tx: Transaction, name: string): Promise<boolean> {\n\tconst rows = await tx.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[name],\n\t)\n\treturn rows.length > 0\n}\n\n// ── Parse ───────────────────────────────────────────────────────────────────\n\n/** A verified, parsed version-2 backup. */\nexport interface ParsedBackup {\n\tmanifest: BackupManifest\n\t/** Canonical operations of the requested collections, in HLC order. */\n\toperations: Operation[]\n\t/** Version vector of the exporting database. */\n\tversionVector: Map<string, number>\n\tterminalRejections: TerminalRejection[]\n\t/** Raw rows per collection (present only when the manifest includes records). */\n\trecords: Map<string, Array<Record<string, unknown>>>\n\t/** Per-record compacted base states of the requested collections (RT-66). */\n\tfoldBases: FoldStateRow[]\n\t/** Per-record row snapshots of the requested collections (RT-68). */\n\tfoldSnapshots: FoldStateRow[]\n\t/** Per node, the sequence prefix compacted into the bases. */\n\tcompactedThrough: Map<string, number>\n}\n\n/**\n * Read backup manifest without loading the entire backup.\n *\n * @param data - The raw backup data\n * @returns The backup manifest\n */\nexport function readBackupManifest(data: Uint8Array): BackupManifest {\n\tconst manifest = parseJsonSection<BackupManifest>(parseSections(data), 'manifest')\n\tif (!manifest) {\n\t\tthrow new BackupFormatError('Invalid backup: manifest section not found', 'BACKUP_INVALID')\n\t}\n\treturn manifest\n}\n\n/**\n * Validate the backup checksum.\n *\n * @param data - The raw backup data\n * @returns True if the checksum is valid\n */\nexport async function verifyBackupChecksum(data: Uint8Array): Promise<boolean> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest?.checksum) return false\n\tconst body = concat(\n\t\tsections\n\t\t\t.filter((s) => s.name !== 'manifest' && s.name !== 'checksum')\n\t\t\t.map((s) => encodeSection(s.name, s.content)),\n\t)\n\treturn (await computeSha256(body)) === manifest.checksum\n}\n\n/**\n * Parse and verify a backup: format version, checksum, and every operation must be\n * canonical (it round-trips through the operation serializer). Throws\n * {@link BackupFormatError}; nothing is written.\n *\n * @param data - The raw backup data\n * @param options - `collections` keeps only those collections\n */\nexport async function parseBackup(\n\tdata: Uint8Array,\n\toptions?: { collections?: string[] },\n): Promise<ParsedBackup> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest) {\n\t\tthrow new BackupFormatError('Invalid backup: manifest section not found', 'BACKUP_INVALID')\n\t}\n\tif (manifest.version === 1) {\n\t\tthrow new BackupFormatError(\n\t\t\t'This backup was written by Kora 1.0.0-beta.12 or earlier (format version 1), whose restore corrupted operation timestamps and copied the exporting device identity. Convert it first: `restoreBackup`/`importBackup(await convertBackupV1(data))`.',\n\t\t\t'BACKUP_FORMAT_OUTDATED',\n\t\t\t{ version: 1, fix: 'Call convertBackupV1(data) and import the result.' },\n\t\t)\n\t}\n\tif (manifest.version !== BACKUP_VERSION) {\n\t\tthrow new BackupFormatError(\n\t\t\t`Unsupported backup version: ${String(manifest.version)} (this release reads version ${BACKUP_VERSION}).`,\n\t\t\t'BACKUP_VERSION_UNSUPPORTED',\n\t\t\t{ version: manifest.version },\n\t\t)\n\t}\n\tif (!(await verifyBackupChecksum(data))) {\n\t\tthrow new BackupFormatError(\n\t\t\t'Backup checksum mismatch: data may be corrupted',\n\t\t\t'BACKUP_CHECKSUM_MISMATCH',\n\t\t)\n\t}\n\n\tconst keep = (collection: string): boolean =>\n\t\t!options?.collections || options.collections.includes(collection)\n\tconst operations: Operation[] = []\n\tfor (const raw of parseNdjson<Operation>(findSection(sections, 'operations'))) {\n\t\tif (!keep(raw.collection)) continue\n\t\toperations.push(canonicalOperation(raw))\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst vector = new Map<string, number>()\n\tfor (const [nodeId, seq] of Object.entries(\n\t\tparseJsonSection<Record<string, number>>(sections, 'version_vector') ?? {},\n\t)) {\n\t\tif (Number.isInteger(seq) && seq > 0) vector.set(nodeId, seq)\n\t}\n\n\tconst records = new Map<string, Array<Record<string, unknown>>>()\n\tif (manifest.includesRecords) {\n\t\tfor (const collection of manifest.collections) {\n\t\t\tif (!keep(collection)) continue\n\t\t\trecords.set(\n\t\t\t\tcollection,\n\t\t\t\tparseNdjson<Record<string, unknown>>(findSection(sections, `records:${collection}`)),\n\t\t\t)\n\t\t}\n\t}\n\n\tconst foldRows = (name: string): FoldStateRow[] =>\n\t\tparseNdjson<FoldStateRow>(findSection(sections, name)).filter(\n\t\t\t(row) =>\n\t\t\t\ttypeof row?.collection === 'string' &&\n\t\t\t\ttypeof row.recordId === 'string' &&\n\t\t\t\ttypeof row.state === 'string' &&\n\t\t\t\tkeep(row.collection),\n\t\t)\n\tconst compactedThrough = new Map<string, number>()\n\tfor (const [nodeId, seq] of Object.entries(\n\t\tparseJsonSection<Record<string, number>>(sections, 'compacted_through') ?? {},\n\t)) {\n\t\tif (Number.isInteger(seq) && seq > 0) compactedThrough.set(nodeId, seq)\n\t}\n\n\treturn {\n\t\tmanifest,\n\t\toperations,\n\t\tversionVector: vector,\n\t\tterminalRejections:\n\t\t\tparseJsonSection<TerminalRejection[]>(sections, 'terminal_rejections') ?? [],\n\t\trecords,\n\t\tfoldBases: foldRows('fold_base'),\n\t\tfoldSnapshots: foldRows('fold_snapshot'),\n\t\tcompactedThrough,\n\t}\n}\n\n/** Re-read an exported operation through the log serializer; refuse a damaged one. */\nfunction canonicalOperation(raw: Operation): Operation {\n\tlet row: OperationRow\n\ttry {\n\t\trow = serializeOperation(raw)\n\t} catch (error) {\n\t\tthrow new BackupFormatError(\n\t\t\t`Backup operation ${String(raw?.id)} is not a valid operation: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationId: raw?.id },\n\t\t)\n\t}\n\tconst verdict = checkOperationRow(row)\n\tif (verdict.kind !== 'ok' || typeof raw.collection !== 'string' || raw.collection === '') {\n\t\tthrow new BackupFormatError(\n\t\t\t`Backup operation ${String(raw.id)} is not canonical (${verdict.kind === 'ok' ? 'no collection' : verdict.problem}).`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationId: raw.id },\n\t\t)\n\t}\n\treturn deserializeOperationWithCollection(row, raw.collection)\n}\n\n// ── Version 1 conversion ────────────────────────────────────────────────────\n\n/** Options for {@link convertBackupV1}. */\nexport interface ConvertBackupV1Options {\n\t/**\n\t * Drop operations whose timestamp cannot be recovered instead of refusing the file.\n\t * Default false.\n\t */\n\tdropUnrecoverable?: boolean\n}\n\n/**\n * Convert a version-1 backup (Kora 1.0.0-beta.12 and earlier) to version 2.\n *\n * - Operations: a v1 file exported from a database that a v1 restore had damaged holds\n * misread timestamps (`wallTime: null`); they are recovered from the misread values\n * (the same rule as the log-integrity scan). An unrecoverable one refuses the file\n * unless `dropUnrecoverable` is set.\n * - The `meta` section (the exporting device's node id, node tokens, sync state) is\n * dropped: it must never be imported into another database.\n * - Record rows are kept; v1 exported live rows only, so the manifest records\n * `includesTombstones: false`. Bytes that v1 serialized as `{\"0\":..,\"1\":..}` objects\n * are decoded on restore.\n *\n * @throws {BackupFormatError} When the input is not a valid version-1 backup\n */\nexport async function convertBackupV1(\n\tdata: Uint8Array,\n\toptions?: ConvertBackupV1Options,\n): Promise<Uint8Array> {\n\tconst sections = parseSections(data)\n\tconst manifest = parseJsonSection<BackupManifest>(sections, 'manifest')\n\tif (!manifest || manifest.version !== 1) {\n\t\tthrow new BackupFormatError('convertBackupV1 expects a version-1 backup.', 'BACKUP_INVALID', {\n\t\t\tversion: manifest?.version,\n\t\t})\n\t}\n\tif (!(await verifyBackupChecksum(data))) {\n\t\tthrow new BackupFormatError(\n\t\t\t'Backup checksum mismatch: data may be corrupted',\n\t\t\t'BACKUP_CHECKSUM_MISMATCH',\n\t\t)\n\t}\n\tconst operations: Operation[] = []\n\tconst dropped: string[] = []\n\tfor (const raw of parseNdjson<Operation>(findSection(sections, 'operations'))) {\n\t\tconst fixed = recoverV1Operation(raw)\n\t\tif (fixed) operations.push(fixed)\n\t\telse dropped.push(String(raw?.id))\n\t}\n\tif (dropped.length > 0 && !options?.dropUnrecoverable) {\n\t\tthrow new BackupFormatError(\n\t\t\t`${dropped.length} operation(s) in this version-1 backup have unrecoverable timestamps (first: ${dropped[0]}). Pass { dropUnrecoverable: true } to convert without them.`,\n\t\t\t'BACKUP_OPERATION_INVALID',\n\t\t\t{ operationIds: dropped.slice(0, 20) },\n\t\t)\n\t}\n\toperations.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst content: Uint8Array[] = [\n\t\tencodeJsonSection(\n\t\t\t'version_vector',\n\t\t\tparseJsonSection<Record<string, number>>(sections, 'version_vector') ?? {},\n\t\t),\n\t\tencodeNdjsonSection('operations', operations),\n\t\tencodeJsonSection('terminal_rejections', []),\n\t]\n\tfor (const section of sections) {\n\t\tif (section.name.startsWith('records:')) {\n\t\t\tconst rows = parseNdjson<Record<string, unknown>>(section.content).map(decodeV1Bytes)\n\t\t\tcontent.push(encodeNdjsonSection(section.name, rows))\n\t\t}\n\t}\n\tconst body = concat(content)\n\tconst checksum = await computeSha256(body)\n\tconst converted: BackupManifest = {\n\t\tversion: BACKUP_VERSION,\n\t\tcreatedAt: manifest.createdAt,\n\t\tnodeId: manifest.nodeId,\n\t\tschemaVersion: manifest.schemaVersion,\n\t\toperationCount: operations.length,\n\t\tcollections: manifest.collections,\n\t\tincludesRecords: manifest.includesRecords,\n\t\tincludesTombstones: false,\n\t\tchecksum,\n\t\tconvertedFrom: 1,\n\t}\n\treturn concat([\n\t\tencodeJsonSection('manifest', converted),\n\t\tbody,\n\t\tencodeSection('checksum', new TextEncoder().encode(checksum)),\n\t])\n}\n\nfunction recoverV1Operation(raw: Operation): Operation | null {\n\tif (!raw || typeof raw !== 'object' || typeof raw.id !== 'string') return null\n\tconst ts = raw.timestamp as unknown\n\tlet timestamp = ts as Operation['timestamp']\n\tconst valid =\n\t\tts !== null &&\n\t\ttypeof ts === 'object' &&\n\t\tNumber.isInteger((ts as { wallTime: unknown }).wallTime) &&\n\t\tNumber.isInteger((ts as { logical: unknown }).logical)\n\tif (!valid) {\n\t\tconst recovered = recoverTimestamp(JSON.stringify(ts))\n\t\tif (!recovered) return null\n\t\ttimestamp = HybridLogicalClock.deserialize(recovered)\n\t}\n\ttry {\n\t\treturn canonicalOperation({ ...raw, timestamp })\n\t} catch {\n\t\treturn null\n\t}\n}\n\n/** v1 wrote Uint8Array columns through JSON.stringify: `{\"0\":1,\"1\":2}`. */\nfunction decodeV1Bytes(row: Record<string, unknown>): Record<string, unknown> {\n\tconst out: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(row)) {\n\t\tout[key] = looksLikeSerializedBytes(value) ? toBytes(value as Record<string, number>) : value\n\t}\n\treturn out\n}\n\nfunction looksLikeSerializedBytes(value: unknown): boolean {\n\tif (value === null || typeof value !== 'object' || Array.isArray(value)) return false\n\tconst entries = Object.entries(value as Record<string, unknown>)\n\tif (entries.length === 0) return false\n\treturn entries.every(\n\t\t([key, byte], index) =>\n\t\t\tkey === String(index) &&\n\t\t\tNumber.isInteger(byte) &&\n\t\t\t(byte as number) >= 0 &&\n\t\t\t(byte as number) < 256,\n\t)\n}\n\nfunction toBytes(value: Record<string, number>): Uint8Array {\n\tconst length = Object.keys(value).length\n\tconst bytes = new Uint8Array(length)\n\tfor (let i = 0; i < length; i++) bytes[i] = value[String(i)] ?? 0\n\treturn bytes\n}\n\n// ── Low-level restore (deprecated entry point) ─────────────────────────────\n\n/**\n * Restore a backup into the database behind `adapter`.\n *\n * @deprecated Use `store.importBackup()` / `app.importBackup()`: restoring needs the\n * store (the device's identity, version vector, clock and live queries). This entry\n * point opens a temporary `Store` on `adapter`, imports, and CLOSES the adapter.\n *\n * @param adapter - A storage adapter no store is using\n * @param schema - The schema definition\n * @param data - The backup data\n * @param options - Restore options\n */\nexport async function restoreBackup(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tdata: Uint8Array,\n\toptions?: RestoreOptions,\n): Promise<RestoreResult> {\n\tconst { Store } = await import('../store/store')\n\tconst store = new Store({ schema, adapter })\n\tawait store.open()\n\ttry {\n\t\treturn await store.importBackup(data, options)\n\t} finally {\n\t\tawait store.close()\n\t}\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction bytesReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) return { $bytes: toBase64(value) }\n\treturn value\n}\n\nfunction bytesReviver(_key: string, value: unknown): unknown {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\t!Array.isArray(value) &&\n\t\tObject.keys(value).length === 1 &&\n\t\ttypeof (value as { $bytes?: unknown }).$bytes === 'string'\n\t) {\n\t\treturn fromBase64((value as { $bytes: string }).$bytes)\n\t}\n\treturn value\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n\tlet binary = ''\n\tconst CHUNK = 0x8000\n\tfor (let i = 0; i < bytes.length; i += CHUNK) {\n\t\tbinary += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n\t}\n\treturn btoa(binary)\n}\n\nfunction fromBase64(text: string): Uint8Array {\n\tconst binary = atob(text)\n\tconst bytes = new Uint8Array(binary.length)\n\tfor (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n\treturn bytes\n}\n\nasync function computeSha256(data: Uint8Array): Promise<string> {\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', new Uint8Array(data))\n\treturn Array.from(new Uint8Array(hashBuffer))\n\t\t.map((b) => b.toString(16).padStart(2, '0'))\n\t\t.join('')\n}\n","import type {\n\tCausalTracker,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { RecordFolder } from '../fold/record-folder'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport type { Transaction } from '../types'\n\n/**\n * Called inside the write transaction for every local delete, after the delete\n * operation is built and before referential side effects run. Lets the unified\n * apply pipeline run its referential checks (and emit their traces) against the\n * rows the transaction sees. Throwing aborts the whole write.\n */\nexport type LocalDeleteHook = (operation: Operation, tx: Transaction) => Promise<void>\n\n/**\n * Everything the single local write path needs to build and persist an\n * operation inside a storage transaction. One environment serves single-record\n * writes, `app.transaction` commits and referential cascades, so every local\n * operation is built the same way (W6).\n */\nexport interface WriteEnv {\n\treadonly schema: SchemaDefinition\n\treadonly clock: HybridLogicalClock\n\treadonly nodeId: string\n\treadonly relationEnforcer: RelationEnforcer | null\n\treadonly secretKeyProvider?: SecretKeyProvider\n\t/** Shared by every operation of an `app.transaction` / `app.mutation` commit. */\n\treadonly transactionId?: string\n\t/** Human-readable mutation name propagated to every operation (DevTools). */\n\treadonly mutationName?: string\n\t/** See {@link LocalDeleteHook}. */\n\treadonly beforeLocalDelete?: LocalDeleteHook\n\t/**\n\t * The W7 record fold. When set, a local write appends its operation and then\n\t * merges it into the record's fold state, which re-materializes the row (the\n\t * same path remote operations take). Absent only under\n\t * `experimental.legacyMerge` (and while a pre-W7 database is migrated, before its\n\t * re-materialization): the row is then written directly, as in beta.12.\n\t */\n\treadonly fold?: RecordFolder\n\t/**\n\t * Largest operation a local write may produce (RT-86), the server's\n\t * `maxOperationBytes`. Default `DEFAULT_MAX_OPERATION_BYTES` (256 KiB).\n\t */\n\treadonly maxOperationBytes?: number\n\t/**\n\t * Throws when local writes are not allowed right now: the store's pinned node\n\t * belongs to another user than the one signed in (F9). Called before every local\n\t * operation is built.\n\t */\n\treadonly assertLocalWriteAllowed?: () => void\n}\n\n/**\n * Causal bookkeeping for the operations built inside ONE storage transaction.\n *\n * Dependencies are computed from the committed causal heads (the shared\n * {@link CausalTracker}) overlaid with the operations already built in this\n * transaction. Heads are published to the shared tracker only after the\n * transaction commits, so a rolled-back write never leaves a dependency on an\n * operation that does not exist.\n */\nexport class CausalScope {\n\tprivate readonly lastByCollection = new Map<string, string>()\n\tprivate lastInScope: string | null = null\n\tprivate readonly recorded: Array<{ collection: string; id: string }> = []\n\n\tconstructor(\n\t\tprivate readonly tracker: CausalTracker | null,\n\t\t/** When true, every operation also depends on the previous one in this scope. */\n\t\tprivate readonly chainOperations: boolean,\n\t) {}\n\n\t/**\n\t * Direct causal parents for the next operation in `collection`.\n\t *\n\t * @param collection - Collection of the operation being built\n\t * @param extra - Explicit parents (e.g. the delete that caused a cascade)\n\t */\n\tdepsFor(collection: string, extra: readonly string[] = []): string[] {\n\t\tconst deps: string[] = []\n\t\tconst add = (id: string | undefined | null): void => {\n\t\t\tif (id && !deps.includes(id)) deps.push(id)\n\t\t}\n\t\tfor (const id of extra) add(id)\n\t\tconst local = this.lastByCollection.get(collection)\n\t\tif (local !== undefined) {\n\t\t\tadd(local)\n\t\t} else {\n\t\t\tfor (const id of this.tracker?.nextCausalDeps(collection, false) ?? []) add(id)\n\t\t}\n\t\tif (this.chainOperations) add(this.lastInScope)\n\t\treturn deps\n\t}\n\n\t/** Record an operation built in this scope. */\n\trecord(collection: string, operationId: string): void {\n\t\tthis.lastByCollection.set(collection, operationId)\n\t\tthis.lastInScope = operationId\n\t\tthis.recorded.push({ collection, id: operationId })\n\t}\n\n\t/** Publish this scope's heads to the shared tracker. Call only after commit. */\n\tpublish(): void {\n\t\tfor (const { collection, id } of this.recorded) {\n\t\t\tthis.tracker?.afterOperation(collection, id, false)\n\t\t}\n\t}\n}\n\n/**\n * The sequence-number block of ONE write transaction.\n *\n * The first number is reserved with one `UPSERT ... RETURNING` on\n * `_kora_version_vector`, inside the transaction; later numbers continue the block\n * in memory, and {@link SequenceBlock.close} persists the block's end with one\n * write before the transaction commits. Write transactions are serialized and no\n * code path allocates numbers outside one, so the block is contiguous and never\n * shared; the UNIQUE `(node_id, sequence_number)` index on every op table is the\n * backstop. A rollback discards the reservation with everything else.\n */\nexport class SequenceBlock {\n\tprivate last: number | null = null\n\tprivate persisted = 0\n\n\tconstructor(\n\t\tprivate readonly tx: Transaction,\n\t\tprivate readonly nodeId: string,\n\t) {}\n\n\t/** The next number of the block. */\n\tasync take(): Promise<number> {\n\t\tif (this.last === null) {\n\t\t\tconst rows = await this.tx.query<{ sequence_number: number }>(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, 1)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = sequence_number + 1\n RETURNING sequence_number`,\n\t\t\t\t[this.nodeId],\n\t\t\t)\n\t\t\tconst first = rows[0]?.sequence_number\n\t\t\tif (first === undefined) {\n\t\t\t\tthrow new KoraError(\n\t\t\t\t\t`Failed to reserve a sequence number for node \"${this.nodeId}\"`,\n\t\t\t\t\t'SEQUENCE_RESERVATION_FAILED',\n\t\t\t\t\t{ nodeId: this.nodeId },\n\t\t\t\t)\n\t\t\t}\n\t\t\tthis.last = first\n\t\t\tthis.persisted = first\n\t\t\treturn first\n\t\t}\n\t\tthis.last += 1\n\t\treturn this.last\n\t}\n\n\t/** Persist the end of the block. Must run inside the transaction, before commit. */\n\tasync close(): Promise<void> {\n\t\tif (this.last === null || this.last === this.persisted) return\n\t\tawait this.tx.execute(\n\t\t\t'UPDATE _kora_version_vector SET sequence_number = MAX(sequence_number, ?) WHERE node_id = ?',\n\t\t\t[this.last, this.nodeId],\n\t\t)\n\t\tthis.persisted = this.last\n\t}\n}\n\n/**\n * The per-transaction state of a local write: the transaction handle, its\n * sequence block and its causal scope. Every operation built in one transaction\n * takes the next number of the same contiguous block.\n */\nexport interface WriteScope {\n\treadonly tx: Transaction\n\treadonly sequence: SequenceBlock\n\treadonly causal: CausalScope\n}\n\n/**\n * Run `write` with a fresh {@link WriteScope} on `tx`, then close the sequence\n * block (still inside the transaction).\n */\nexport async function withWriteScope<T>(\n\ttx: Transaction,\n\tnodeId: string,\n\tcausal: CausalScope,\n\twrite: (scope: WriteScope) => Promise<T>,\n): Promise<T> {\n\tconst scope: WriteScope = { tx, sequence: new SequenceBlock(tx, nodeId), causal }\n\tconst result = await write(scope)\n\tawait scope.sequence.close()\n\treturn result\n}\n\n/**\n * Whether a storage error means the device ran out of space: SQLite's\n * `SQLITE_FULL` (\"database or disk is full\") or a browser quota error from OPFS /\n * IndexedDB. The store maps these to a `store:quota-exceeded` event (STORE-15).\n */\nexport function isStorageFullError(error: unknown): boolean {\n\tif (error === null || typeof error !== 'object') return false\n\tconst candidate = error as { name?: unknown; code?: unknown; message?: unknown; cause?: unknown }\n\tif (candidate.name === 'QuotaExceededError') return true\n\tif (candidate.code === 'SQLITE_FULL' || candidate.code === 'QUOTA_EXCEEDED') return true\n\tconst message = typeof candidate.message === 'string' ? candidate.message : ''\n\tif (/SQLITE_FULL|database or disk is full|quota ?exceeded/i.test(message)) return true\n\treturn candidate.cause !== undefined && candidate.cause !== error\n\t\t? isStorageFullError(candidate.cause)\n\t\t: false\n}\n","import type { Operation } from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { LocalMutationContext } from './types'\nimport { CausalScope, type WriteScope, withWriteScope } from './write-context'\nimport type { WriteResult } from './write-ops'\n\n/**\n * Run one local write in its own storage transaction, then publish it.\n *\n * Post-commit work (causal heads, in-memory version vector, subscriptions,\n * `operation:created`) runs only after the transaction commits, so nothing\n * observable ever points at an operation that was rolled back (STORE-15).\n */\nexport async function runLocalWrite(\n\tctx: LocalMutationContext,\n\twrite: (scope: WriteScope) => Promise<WriteResult>,\n): Promise<WriteResult> {\n\tconst causal = new CausalScope(ctx.causalTracker, false)\n\tlet result: WriteResult | undefined\n\ttry {\n\t\tawait ctx.adapter.transaction(async (tx) => {\n\t\t\tresult = await withWriteScope(tx, ctx.nodeId, causal, write)\n\t\t})\n\t} catch (error) {\n\t\tctx.onStorageError?.(error)\n\t\tthrow error\n\t}\n\tif (!result) {\n\t\tthrow new KoraError('Local write transaction completed without a result', 'WRITE_INCOMPLETE', {\n\t\t\tcollection: ctx.collection,\n\t\t})\n\t}\n\tcausal.publish()\n\tpublishOperations(ctx, result)\n\treturn result\n}\n\n/** Notify the store about every operation of a committed write, in creation order. */\nfunction publishOperations(ctx: LocalMutationContext, result: WriteResult): void {\n\tconst ops: Operation[] = []\n\tif (result.operation) ops.push(result.operation)\n\tops.push(...result.sideEffects)\n\tfor (const op of ops) {\n\t\tctx.onMutation(op.collection, op)\n\t}\n}\n","import { EMPTY_ROW_VERSION } from './row-version'\n\n/**\n * Per-field last-writer versions for a materialized row.\n *\n * Each entry maps a field name to a serialized HLC timestamp (the same\n * lexicographically-sortable form used by the row `_version` column). Because\n * the serialized form sorts identically to {@link HybridLogicalClock.compare},\n * per-field last-write-wins is a plain string comparison: the greater string is\n * the newer writer. This makes field-level convergence deterministic and\n * independent of the order operations happen to arrive in.\n */\nexport type FieldVersions = Record<string, string>\n\n/**\n * Parse the `_field_versions` JSON column into a map. Tolerates null, empty,\n * and malformed values by returning an empty map — a row that predates\n * per-field tracking simply has no field versions and falls back to `_version`.\n */\nexport function parseFieldVersions(raw: unknown): FieldVersions {\n\tif (typeof raw !== 'string' || raw.length === 0) {\n\t\treturn {}\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown\n\t\tif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n\t\t\treturn {}\n\t\t}\n\t\tconst result: FieldVersions = {}\n\t\tfor (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tresult[key] = value\n\t\t\t}\n\t\t}\n\t\treturn result\n\t} catch {\n\t\treturn {}\n\t}\n}\n\n/**\n * Serialize a field-version map for storage in the `_field_versions` column.\n */\nexport function serializeFieldVersions(versions: FieldVersions): string {\n\treturn JSON.stringify(versions)\n}\n\n/**\n * Build the initial field-version map for an insert: every supplied field is\n * stamped with the operation's version.\n */\nexport function fieldVersionsForFields(\n\tfieldNames: Iterable<string>,\n\tversion: string,\n): FieldVersions {\n\tconst versions: FieldVersions = {}\n\tfor (const field of fieldNames) {\n\t\tversions[field] = version\n\t}\n\treturn versions\n}\n\n/**\n * The effective stored version for a field: its own tracked version if present,\n * otherwise the row-level `_version` (so rows written before per-field tracking\n * still compare correctly), otherwise the empty sentinel (older than anything).\n */\nexport function effectiveFieldVersion(\n\tcurrent: FieldVersions,\n\tfield: string,\n\trowVersion: string | undefined,\n): string {\n\tconst own = current[field]\n\tif (own !== undefined) {\n\t\treturn own\n\t}\n\treturn rowVersion ?? EMPTY_ROW_VERSION\n}\n\n/**\n * Result of resolving an incoming operation against the current per-field\n * versions of a row.\n */\nexport interface PerFieldLwwResult {\n\t/** Fields the incoming operation wins (strictly newer than the stored version). */\n\twinners: string[]\n\t/** The merged field-version map to persist (winners advanced to `incomingVersion`). */\n\tmerged: FieldVersions\n}\n\n/**\n * Resolve per-field last-write-wins for an incoming operation.\n *\n * For each incoming field, the operation wins only when its version is strictly\n * greater than the field's effective stored version. Ties (identical version,\n * i.e. the same operation re-applied) are losses, keeping the resolution\n * idempotent. The comparison is a total order, so every node resolves the same\n * winner regardless of the order operations arrive.\n *\n * @param current - Parsed `_field_versions` of the target row\n * @param incomingFields - Field names carried by the incoming operation\n * @param incomingVersion - Serialized HLC version of the incoming operation\n * @param rowVersion - The row's `_version` (fallback for untracked fields)\n */\nexport function resolvePerFieldLww(\n\tcurrent: FieldVersions,\n\tincomingFields: Iterable<string>,\n\tincomingVersion: string,\n\trowVersion: string | undefined,\n): PerFieldLwwResult {\n\tconst winners: string[] = []\n\tconst merged: FieldVersions = { ...current }\n\tfor (const field of incomingFields) {\n\t\tconst stored = effectiveFieldVersion(current, field, rowVersion)\n\t\tif (incomingVersion > stored) {\n\t\t\twinners.push(field)\n\t\t\tmerged[field] = incomingVersion\n\t\t}\n\t\t// Losing fields are left untouched: their existing tracked version (or the\n\t\t// row-level `_version` fallback) already reflects the newer writer.\n\t}\n\treturn { winners, merged }\n}\n\n/**\n * Stamp `fields` with `version` on top of a stored `_field_versions` value and\n * return the serialized column. This is the one per-field stamp every local\n * write uses (insert, update, transaction entries, cascades), so every field a\n * device writes carries the HLC of the operation that wrote it.\n *\n * Stamps only move forward: a field already holding a newer version keeps it.\n * The map is keyed by field name with one HLC register per field, the shape the\n * per-field fold (W7) builds on.\n *\n * @param currentRaw - The stored `_field_versions` column (or null for a new row)\n * @param fields - Field names this write sets\n * @param version - The writing operation's serialized HLC version\n */\nexport function stampFieldVersions(\n\tcurrentRaw: unknown,\n\tfields: Iterable<string>,\n\tversion: string,\n): string {\n\tconst versions = parseFieldVersions(currentRaw)\n\tfor (const field of fields) {\n\t\tconst existing = versions[field]\n\t\tif (existing === undefined || existing < version) {\n\t\t\tversions[field] = version\n\t\t}\n\t}\n\treturn serializeFieldVersions(versions)\n}\n","import { KoraError, validateTransition } from '@korajs/core'\nimport type {\n\tCollectionDefinition,\n\tStateMachineConstraint,\n\tStateMachineDefinition,\n} from '@korajs/core'\n\n/**\n * Error thrown when a local mutation attempts an invalid state transition.\n *\n * Contains enough context to debug without reproduction:\n * the collection, record, field, current state, attempted state, and allowed transitions.\n */\nexport class InvalidStateTransitionError extends KoraError {\n\tconstructor(\n\t\tpublic readonly collection: string,\n\t\tpublic readonly recordId: string,\n\t\tpublic readonly field: string,\n\t\tpublic readonly fromState: string,\n\t\tpublic readonly toState: string,\n\t\tpublic readonly allowedStates: string[],\n\t) {\n\t\tsuper(\n\t\t\t`Invalid state transition in collection \"${collection}\": ` +\n\t\t\t\t`cannot transition field \"${field}\" from \"${fromState}\" to \"${toState}\". ` +\n\t\t\t\t`Allowed transitions from \"${fromState}\": ${allowedStates.length > 0 ? allowedStates.join(', ') : '(none -- terminal state)'}`,\n\t\t\t'INVALID_STATE_TRANSITION',\n\t\t\t{ collection, recordId, field, fromState, toState, allowedStates },\n\t\t)\n\t\tthis.name = 'InvalidStateTransitionError'\n\t}\n}\n\n/**\n * Validates a state machine transition for a local mutation (insert or update).\n *\n * For inserts: validates that the initial state (from the data or the default value)\n * is a known state in the state machine.\n *\n * For updates: looks up the current state field value and checks whether\n * the transition to the new value is allowed.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being mutated\n * @param stateMachine - The state machine definition\n * @param currentState - The current value of the state field (null for inserts)\n * @param newState - The new value being set for the state field\n * @returns An object indicating whether the transition is valid, and if not, the allowed states.\n * When `onInvalidTransition` is 'last-valid-state', callers should suppress the field update\n * rather than throwing.\n */\nexport function validateStateTransition(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentState: string | null,\n\tnewState: string,\n): { valid: boolean; allowedStates: string[] } {\n\t// For inserts, any valid enum value is acceptable as the initial state\n\t// (schema validation already ensures the value is a valid enum value)\n\tif (currentState === null) {\n\t\treturn { valid: true, allowedStates: [] }\n\t}\n\n\t// Same-state transitions are always valid (idempotent updates)\n\tif (currentState === newState) {\n\t\treturn { valid: true, allowedStates: stateMachine.transitions[currentState] ?? [] }\n\t}\n\n\tconst constraint: StateMachineConstraint = {\n\t\tfield: stateMachine.field,\n\t\tcollection: collectionName,\n\t\ttransitions: stateMachine.transitions,\n\t}\n\tconst transitionResult = validateTransition(constraint, currentState, newState)\n\tif (transitionResult.valid) {\n\t\treturn { valid: true, allowedStates: transitionResult.allowedTargets }\n\t}\n\n\tconst allowedStates = transitionResult.allowedTargets\n\n\tif (stateMachine.onInvalidTransition === 'reject') {\n\t\tthrow new InvalidStateTransitionError(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\tstateMachine.field,\n\t\t\tcurrentState,\n\t\t\tnewState,\n\t\t\tallowedStates,\n\t\t)\n\t}\n\n\t// 'last-valid-state': return invalid so the caller can suppress the field update\n\treturn { valid: false, allowedStates }\n}\n\n/**\n * Checks whether a collection update data object contains a change to the state machine field,\n * and if so, validates the transition.\n *\n * If the state field is not in the update data, returns the data unchanged.\n * If the transition is invalid and mode is 'last-valid-state', removes the field from the data.\n * If the transition is invalid and mode is 'reject', throws InvalidStateTransitionError.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being updated\n * @param collectionDef - The collection definition from the schema\n * @param currentRecord - The current record data (must include the state field)\n * @param updateData - The partial update data\n * @returns The update data, potentially with the state field removed if invalid and mode is 'last-valid-state'\n */\nexport function validateUpdateStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tcollectionDef: CollectionDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tlet result = updateData\n\tconst stateMachine = collectionDef.stateMachine\n\tif (stateMachine !== undefined) {\n\t\tresult = applyStateMachine(collectionName, recordId, stateMachine, currentRecord, result)\n\t}\n\t// Field-level `t.enum(...).transitions()` maps are state machines too, in the\n\t// default 'reject' mode (NEW-STORE-3). A collection-level machine on the same\n\t// field takes precedence.\n\tfor (const [field, descriptor] of Object.entries(collectionDef.fields)) {\n\t\tif (descriptor.kind !== 'enum' || !descriptor.transitions) continue\n\t\tif (stateMachine?.field === field) continue\n\t\tresult = applyStateMachine(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\t{ field, transitions: descriptor.transitions, onInvalidTransition: 'reject' },\n\t\t\tcurrentRecord,\n\t\t\tresult,\n\t\t)\n\t}\n\treturn result\n}\n\nfunction applyStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst stateField = stateMachine.field\n\tif (!(stateField in updateData)) {\n\t\t// State field not being changed -- no validation needed\n\t\treturn updateData\n\t}\n\n\tconst currentState = currentRecord[stateField]\n\tconst newState = updateData[stateField]\n\n\t// Both values must be strings for state machine validation\n\tif (typeof currentState !== 'string' || typeof newState !== 'string') {\n\t\treturn updateData\n\t}\n\n\tconst result = validateStateTransition(\n\t\tcollectionName,\n\t\trecordId,\n\t\tstateMachine,\n\t\tcurrentState,\n\t\tnewState,\n\t)\n\n\tif (result.valid) {\n\t\treturn updateData\n\t}\n\n\t// Mode is 'last-valid-state': silently remove the state field from the update\n\tconst filtered = { ...updateData }\n\tdelete filtered[stateField]\n\n\t// If no fields remain after removing the state field, the update becomes a no-op.\n\t// Return the empty object -- the caller can decide whether to proceed.\n\treturn filtered\n}\n","import type { CollectionDefinition, SecretKeyProvider } from '@korajs/core'\nimport { transformSecretFieldsForWrite } from '@korajs/core'\n\n/**\n * Convert the values a local write is about to persist into their at-rest form.\n *\n * Every local write path (single-record insert/update and the buffered\n * `TransactionContext` used by `app.transaction` / `app.mutation`) MUST route\n * its data through this helper BEFORE the operation is built, so plaintext\n * secrets never reach the operation log, the materialized row, or the wire.\n * Keeping one helper means a new write path cannot forget the transform\n * without also bypassing this function (STORE-4).\n *\n * @param data - Validated (and atomic-op-resolved) field values for the write\n * @param definition - The collection definition, used to find secret fields\n * @param secretKeyProvider - Key provider for `t.secret()` encrypted fields\n * @returns A copy of `data` with secret fields hashed or encrypted\n */\nexport function toAtRestWriteData(\n\tdata: Record<string, unknown>,\n\tdefinition: CollectionDefinition,\n\tsecretKeyProvider: SecretKeyProvider | undefined,\n): Promise<Record<string, unknown>> {\n\treturn transformSecretFieldsForWrite(data, definition, secretKeyProvider)\n}\n","import type { AtomicOp, CollectionDefinition, Operation } from '@korajs/core'\nimport {\n\tDEFAULT_MAX_OPERATION_BYTES,\n\tKoraError,\n\tOperationTooLargeError,\n\tassertResolvedFieldValue,\n\tcreateOperation,\n\tgenerateUUIDv7,\n\tisAtomicOp,\n\tmeasureOperationBytes,\n\tquoteIdent,\n\tresolveAtomicOp,\n\ttoAtomicOp,\n\tvalidateRecord,\n} from '@korajs/core'\nimport { RecordNotFoundError } from '../errors'\nimport { stampFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery, buildSoftDeleteQuery, buildUpdateQuery } from '../query/sql-builder'\nimport { encodeRichtextFieldsForOpData } from '../serialization/op-data-encoding'\nimport {\n\tdeserializeRecord,\n\tserializeOperation,\n\tserializeRecord,\n\ttoRichtextReadShape,\n} from '../serialization/serializer'\nimport { validateUpdateStateMachine } from '../state-machine/state-validator'\nimport type { CollectionRecord, RawCollectionRow } from '../types'\nimport { toAtRestWriteData } from './secret-write'\nimport type { WriteEnv, WriteScope } from './write-context'\n\n/*\n * THE local write path (W6). Every local operation — a single-record write, each\n * entry of an `app.transaction` / `app.mutation` commit, and every referential\n * cascade — is built and persisted by the functions in this file, inside the\n * storage transaction that commits it:\n *\n * 1. the current row is read through the transaction handle, so validation\n * (existence, state machine) and atomic ops resolve against committed state;\n * 2. the sequence number comes from the transaction's SequenceBlock (reserved\n * with UPSERT ... RETURNING on `_kora_version_vector` inside the transaction,\n * end persisted before commit); transactions are serialized, so the numbers of\n * one commit form one contiguous block and two commits can never share one;\n * 3. the operation is built only AFTER its sequence number is reserved, and is\n * never re-stamped (protocol v2 hashes the sequence number into the id);\n * 4. the row is written with per-field version stamps and the operation row is\n * appended, in the same transaction.\n */\n\n/** An insert whose values are validated and in their at-rest form. */\nexport interface PreparedInsert {\n\treadonly collection: string\n\treadonly recordId: string\n\t/** Record-shaped, at-rest values (secret fields hashed / encrypted). */\n\treadonly data: Record<string, unknown>\n}\n\n/**\n * Validate insert data, fill auto fields and transform secrets. Pure with\n * respect to storage, so `app.transaction` can do it when the developer calls\n * `insert` (returning the new id immediately) and write it at commit.\n */\nexport async function prepareInsert(\n\tenv: WriteEnv,\n\tcollection: string,\n\tdata: Record<string, unknown>,\n): Promise<PreparedInsert> {\n\tconst definition = requireDefinition(env, collection)\n\tconst validated = validateRecord(collection, definition, data, 'insert')\n\tconst now = Date.now()\n\tfor (const [fieldName, descriptor] of Object.entries(definition.fields)) {\n\t\tif (descriptor.auto && descriptor.kind === 'timestamp') {\n\t\t\tvalidated[fieldName] = now\n\t\t}\n\t}\n\t// Secret fields reach their at-rest form BEFORE the operation is built, so\n\t// plaintext never enters the op log, the row, or the wire (STORE-4).\n\tconst writeData = await toAtRestWriteData(validated, definition, env.secretKeyProvider)\n\treturn { collection, recordId: generateUUIDv7(), data: writeData }\n}\n\n/** Result of writing one local operation. */\nexport interface WriteResult {\n\t/** The operation, or null when the write turned out to be a no-op. */\n\treadonly operation: Operation | null\n\t/** The record as stored after the write. */\n\treadonly record: CollectionRecord\n\t/** Operations created as side effects (referential cascades), in creation order. */\n\treadonly sideEffects: Operation[]\n}\n\n/**\n * Write a prepared insert inside `scope.tx`.\n */\nexport async function writeInsertInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinsert: PreparedInsert,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, insert.collection)\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'insert',\n\t\tcollection: insert.collection,\n\t\trecordId: insert.recordId,\n\t\t// Binary richtext values are tagged as canonical JSON BEFORE hashing, so the\n\t\t// hash input, persisted JSON and wire payload are the identical value.\n\t\tdata: encodeRichtextFieldsForOpData(insert.data, definition.fields),\n\t\tpreviousData: null,\n\t\textraCausalDeps,\n\t})\n\n\tif (env.fold) {\n\t\t// Append, then merge: the row is the materialization of the record's state.\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serialized = serializeRecord(insert.data, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst row: Record<string, unknown> = {\n\t\t\tid: insert.recordId,\n\t\t\t...serialized,\n\t\t\t_created_at: operation.timestamp.wallTime,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t// Every inserted field is stamped with this operation's version, so later\n\t\t\t// per-field LWW compares against a real writer, not the row fallback.\n\t\t\t_field_versions: stampFieldVersions(null, Object.keys(serialized), version),\n\t\t}\n\t\tconst rowInsert = buildInsertQuery(insert.collection, row)\n\t\tawait scope.tx.execute(rowInsert.sql, rowInsert.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: {\n\t\t\tid: insert.recordId,\n\t\t\t// A richtext value written as a string returns as the bytes reads return.\n\t\t\t...toRichtextReadShape(insert.data, definition.fields),\n\t\t\tcreatedAt: operation.timestamp.wallTime,\n\t\t\tupdatedAt: operation.timestamp.wallTime,\n\t\t},\n\t\tsideEffects: [],\n\t}\n}\n\n/**\n * Write a local update inside `scope.tx`.\n *\n * `data` must already be schema-validated (it may contain atomic op descriptors).\n * The state machine, atomic ops and `previousData` are all resolved against the\n * row read through the transaction, so concurrent writers serialize correctly\n * (STORE-9, NEW-STORE-2).\n */\nexport async function writeUpdateInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\tdata: Record<string, unknown>,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst currentRecord = deserializeRecord(currentRow, definition.fields)\n\tconst allowed = validateUpdateStateMachine(collection, id, definition, currentRecord, data)\n\tif (Object.keys(allowed).length === 0) {\n\t\treturn { operation: null, record: currentRecord, sideEffects: [] }\n\t}\n\n\tconst previousData: Record<string, unknown> = {}\n\tconst resolved: Record<string, unknown> = {}\n\tconst atomicOps: Record<string, AtomicOp> = {}\n\tfor (const [key, value] of Object.entries(allowed)) {\n\t\tpreviousData[key] = currentRecord[key]\n\t\tif (isAtomicOp(value)) {\n\t\t\tresolved[key] = resolveAtomicOp(currentRecord[key], value)\n\t\t\t// The resolved value must be in the field's domain like any written value\n\t\t\t// (RT-87): `op.increment(0.5)` on a timestamp, an increment past the largest\n\t\t\t// finite number.\n\t\t\tconst descriptor = definition.fields[key]\n\t\t\tif (descriptor) assertResolvedFieldValue(collection, key, descriptor, resolved[key])\n\t\t\tatomicOps[key] = toAtomicOp(value)\n\t\t} else {\n\t\t\tresolved[key] = value\n\t\t}\n\t}\n\t// previousData already holds the stored (at-rest) values, so only the new\n\t// values need the secret transform.\n\tconst writeData = await toAtRestWriteData(resolved, definition, env.secretKeyProvider)\n\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'update',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: encodeRichtextFieldsForOpData(writeData, definition.fields),\n\t\tpreviousData: encodeRichtextFieldsForOpData(previousData, definition.fields),\n\t\textraCausalDeps,\n\t\t...(Object.keys(atomicOps).length > 0 ? { atomicOps } : {}),\n\t})\n\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serializedChanges = serializeRecord(writeData, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\t// A local edit is the newest writer of every field it touches (the HLC is past\n\t\t// every timestamp this device has seen), so each changed field gets its stamp.\n\t\tconst rowUpdate = buildUpdateQuery(collection, id, {\n\t\t\t...serializedChanges,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t_field_versions: stampFieldVersions(\n\t\t\t\tcurrentRow._field_versions,\n\t\t\t\tObject.keys(serializedChanges),\n\t\t\t\tversion,\n\t\t\t),\n\t\t})\n\t\tawait scope.tx.execute(rowUpdate.sql, rowUpdate.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst updatedRow = await readLiveRow(scope, collection, id)\n\tif (!updatedRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(updatedRow, definition.fields),\n\t\tsideEffects: [],\n\t}\n}\n\n/** Options for {@link writeDeleteInTx}. */\nexport interface WriteDeleteOptions {\n\t/** Skip referential checks and cascades (the caller already applied them). */\n\treadonly skipReferentialEnforcement?: boolean\n\t/** Explicit causal parents (e.g. the delete that caused this cascade). */\n\treadonly extraCausalDeps?: readonly string[]\n}\n\n/**\n * Soft-delete a record inside `scope.tx`, then apply the schema's referential\n * policies (cascade, set-null, restrict) in the same transaction. Cascaded\n * operations are built through this same write path, after the parent, so their\n * sequence numbers follow the parent's in the commit's block (STORE-2).\n */\nexport async function writeDeleteInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\toptions: WriteDeleteOptions = {},\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'delete',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: null,\n\t\tpreviousData: null,\n\t\textraCausalDeps: options.extraCausalDeps ?? [],\n\t})\n\n\tif (!options.skipReferentialEnforcement && env.beforeLocalDelete) {\n\t\tawait env.beforeLocalDelete(operation, scope.tx)\n\t}\n\n\t// The row is tombstoned BEFORE side effects run, so a reference cycle\n\t// (self-referencing or mutually-referencing records) cannot cascade back\n\t// into this record.\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst softDelete = buildSoftDeleteQuery(collection, id, operation.timestamp.wallTime, version)\n\t\tawait scope.tx.execute(softDelete.sql, softDelete.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst sideEffects: Operation[] = []\n\tif (!options.skipReferentialEnforcement && env.relationEnforcer) {\n\t\tconst result = await env.relationEnforcer.enforceDelete(\n\t\t\tcollection,\n\t\t\tid,\n\t\t\tscope,\n\t\t\tenv,\n\t\t\toperation.id,\n\t\t)\n\t\tsideEffects.push(...result.operations)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(currentRow, definition.fields),\n\t\tsideEffects,\n\t}\n}\n\ninterface LocalOperationInput {\n\ttype: Operation['type']\n\tcollection: string\n\trecordId: string\n\tdata: Record<string, unknown> | null\n\tpreviousData: Record<string, unknown> | null\n\textraCausalDeps: readonly string[]\n\tatomicOps?: Record<string, AtomicOp>\n}\n\n/**\n * Reserve the next sequence number through the transaction, THEN build the\n * operation. The order matters: the operation is final the moment it exists.\n */\nasync function buildLocalOperation(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinput: LocalOperationInput,\n): Promise<Operation> {\n\tenv.assertLocalWriteAllowed?.()\n\tconst sequenceNumber = await scope.sequence.take()\n\tconst causalDeps = scope.causal.depsFor(input.collection, input.extraCausalDeps)\n\tconst operation = await createOperation(\n\t\t{\n\t\t\tnodeId: env.nodeId,\n\t\t\ttype: input.type,\n\t\t\tcollection: input.collection,\n\t\t\trecordId: input.recordId,\n\t\t\tdata: input.data,\n\t\t\tpreviousData: input.previousData,\n\t\t\tsequenceNumber,\n\t\t\tcausalDeps,\n\t\t\tschemaVersion: env.schema.version,\n\t\t\t...(input.atomicOps !== undefined ? { atomicOps: input.atomicOps } : {}),\n\t\t\t...(env.transactionId !== undefined ? { transactionId: env.transactionId } : {}),\n\t\t\t...(env.mutationName !== undefined ? { mutationName: env.mutationName } : {}),\n\t\t},\n\t\tenv.clock,\n\t)\n\t// Every operation must fit the server's maxOperationBytes (RT-86): refused here, in\n\t// the write's transaction (nothing is written), rather than accepted and then refused\n\t// by the server.\n\tconst maxBytes = env.maxOperationBytes ?? DEFAULT_MAX_OPERATION_BYTES\n\tconst bytes = measureOperationBytes(operation)\n\tif (bytes > maxBytes) {\n\t\tthrow new OperationTooLargeError(input.collection, input.recordId, bytes, maxBytes)\n\t}\n\tscope.causal.record(input.collection, operation.id)\n\treturn operation\n}\n\nasync function appendOperationRow(scope: WriteScope, operation: Operation): Promise<void> {\n\tconst opInsert = buildInsertQuery(\n\t\t`_kora_ops_${operation.collection}`,\n\t\tserializeOperation(operation) as unknown as Record<string, unknown>,\n\t)\n\tawait scope.tx.execute(opInsert.sql, opInsert.params)\n}\n\nasync function readLiveRow(\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n): Promise<RawCollectionRow | undefined> {\n\tconst rows = await scope.tx.query<RawCollectionRow>(\n\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ? AND _deleted = 0`,\n\t\t[id],\n\t)\n\treturn rows[0]\n}\n\nfunction requireDefinition(env: WriteEnv, collection: string): CollectionDefinition {\n\tconst definition = env.schema.collections[collection]\n\tif (!definition) {\n\t\tthrow new KoraError(\n\t\t\t`Unknown collection \"${collection}\". Available: ${Object.keys(env.schema.collections).join(', ')}`,\n\t\t\t'UNKNOWN_COLLECTION',\n\t\t\t{ collection },\n\t\t)\n\t}\n\treturn definition\n}\n","import type { Operation } from '@korajs/core'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeDeleteInTx } from './write-ops'\n\nexport interface ExecuteDeleteOptions {\n\t/** When true, skip referential checks and cascades (caller already enforced them). */\n\tskipReferentialEnforcement?: boolean\n}\n\n/**\n * Soft-delete a record and persist the operation log entry atomically, together\n * with any referential side effects (cascades / set-null), in one transaction.\n * Returns the primary delete operation followed by the side-effect operations.\n */\nexport async function executeDelete(\n\tctx: LocalMutationContext,\n\tid: string,\n\toptions?: ExecuteDeleteOptions,\n): Promise<Operation[]> {\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteDeleteInTx(ctx, scope, ctx.collection, id, {\n\t\t\tskipReferentialEnforcement: options?.skipReferentialEnforcement ?? false,\n\t\t\textraCausalDeps: ctx.extraCausalDeps ?? [],\n\t\t}),\n\t)\n\treturn result.operation ? [result.operation, ...result.sideEffects] : result.sideEffects\n}\n","import type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { prepareInsert, writeInsertInTx } from './write-ops'\n\n/**\n * Insert a record and persist its operation, atomically, through the single\n * local write path (sequence reserved and operation built inside the write\n * transaction).\n */\nexport async function executeInsert(\n\tctx: LocalMutationContext,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst prepared = await prepareInsert(ctx, ctx.collection, data)\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteInsertInTx(ctx, scope, prepared, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n","import { validateRecord } from '@korajs/core'\nimport type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeUpdateInTx } from './write-ops'\n\n/**\n * Update a record and persist its operation, atomically. The row read, the\n * state-machine check and atomic-op resolution all happen inside the write\n * transaction, so concurrent increments compose (STORE-9).\n */\nexport async function executeUpdate(\n\tctx: LocalMutationContext,\n\tid: string,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst validated = validateRecord(ctx.collection, ctx.definition, data, 'update')\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteUpdateInTx(ctx, scope, ctx.collection, id, validated, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n","import type {\n\tCausalTracker,\n\tCollectionDefinition,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport type { RecordFolder } from '../fold/record-folder'\nimport { executeDelete } from '../mutations/execute-delete'\nimport { executeInsert } from '../mutations/execute-insert'\nimport { executeUpdate } from '../mutations/execute-update'\nimport type { LocalMutationContext } from '../mutations/types'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport { deserializeRecord } from '../serialization/serializer'\nimport type {\n\tCollectionRecord,\n\tLocalMutationHandler,\n\tRawCollectionRow,\n\tStorageAdapter,\n} from '../types'\n\n/**\n * Callback invoked after a mutation so the Store can notify subscriptions.\n */\nexport type MutationCallback = (collection: string, operation: Operation) => void\n\n/**\n * Collection provides CRUD operations on a single schema collection.\n * Delegates to {@link LocalMutationHandler} when configured (unified apply pipeline),\n * otherwise uses shared mutation executors directly.\n */\nexport class Collection {\n\tconstructor(\n\t\tprivate readonly name: string,\n\t\tprivate readonly definition: CollectionDefinition,\n\t\tprivate readonly schema: SchemaDefinition,\n\t\tprivate readonly adapter: StorageAdapter,\n\t\tprivate clock: HybridLogicalClock,\n\t\tprivate nodeId: string,\n\t\tprivate readonly onMutation: MutationCallback,\n\t\tprivate relationEnforcer: RelationEnforcer | null,\n\t\tprivate mutationHandler: LocalMutationHandler | null,\n\t\tprivate causalTracker: CausalTracker | null,\n\t\tprivate readonly secretKeyProvider?: SecretKeyProvider,\n\t\tprivate readonly onStorageError?: (error: unknown) => void,\n\t\tprivate readonly fold?: () => RecordFolder | undefined,\n\t\tprivate readonly maxOperationBytes?: number,\n\t\tprivate readonly assertLocalWriteAllowed?: () => void,\n\t) {}\n\n\t/**\n\t * Point this collection at the store's new device identity after a node-id\n\t * rotation (RT-21). Internal: called by the owning Store only.\n\t *\n\t * @internal\n\t */\n\trebindNode(\n\t\tclock: HybridLogicalClock,\n\t\tnodeId: string,\n\t\trelationEnforcer: RelationEnforcer | null,\n\t\tcausalTracker: CausalTracker | null,\n\t): void {\n\t\tthis.clock = clock\n\t\tthis.nodeId = nodeId\n\t\tthis.relationEnforcer = relationEnforcer\n\t\tthis.causalTracker = causalTracker\n\t}\n\n\tprivate mutationContext(): LocalMutationContext {\n\t\tconst fold = this.fold?.()\n\t\treturn {\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tcollection: this.name,\n\t\t\tdefinition: this.definition,\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\tonMutation: this.onMutation,\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(this.onStorageError ? { onStorageError: this.onStorageError } : {}),\n\t\t\t...(this.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t\t...(this.assertLocalWriteAllowed\n\t\t\t\t? { assertLocalWriteAllowed: this.assertLocalWriteAllowed }\n\t\t\t\t: {}),\n\t\t}\n\t}\n\n\tasync insert(data: Record<string, unknown>): Promise<CollectionRecord> {\n\t\tif (this.mutationHandler) {\n\t\t\treturn this.mutationHandler.insert(this.name, data)\n\t\t}\n\t\treturn executeInsert(this.mutationContext(), data)\n\t}\n\n\tasync findById(id: string): Promise<CollectionRecord | null> {\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(this.name)} WHERE id = ? AND _deleted = 0`,\n\t\t\t[id],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) return null\n\t\treturn deserializeRecord(row, this.definition.fields)\n\t}\n\n\tasync update(id: string, data: Record<string, unknown>): Promise<CollectionRecord> {\n\t\tif (this.mutationHandler) {\n\t\t\treturn this.mutationHandler.update(this.name, id, data)\n\t\t}\n\t\treturn executeUpdate(this.mutationContext(), id, data)\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tif (this.mutationHandler) {\n\t\t\tawait this.mutationHandler.delete(this.name, id)\n\t\t\treturn\n\t\t}\n\t\tawait executeDelete(this.mutationContext(), id)\n\t}\n\n\tgetName(): string {\n\t\treturn this.name\n\t}\n\n\tgetDefinition(): CollectionDefinition {\n\t\treturn this.definition\n\t}\n\n\t/** Replace the mutation handler (e.g. after ApplyPipeline is wired in createApp). */\n\tsetMutationHandler(handler: LocalMutationHandler | null): void {\n\t\tthis.mutationHandler = handler\n\t}\n}\n","import {\n\ttype FoldState,\n\tHybridLogicalClock,\n\ttype Operation,\n\ttype SchemaDefinition,\n\ttype VersionVector,\n\tcreateFoldState,\n\tcreateVersionVector,\n\tmergeOp,\n\tquoteIdent,\n} from '@korajs/core'\nimport { computeAckCompactionWatermark } from '../compaction/compact-operation-log'\nimport type { CompactionResult, CompactionStrategy } from '../compaction/types'\nimport { COMPACTION_BASELINE_META_KEY } from '../compaction/types'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE } from '../store/sequence-repair'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport { COMPACTED_THROUGH_TABLE, type RecordFolder } from './record-folder'\n\n/**\n * Whether compaction must keep this operation in the log. The fold state alone is\n * enough to merge later operations, but the plan keeps the operations whose effect\n * cannot be rebuilt from a row snapshot should a future fold-state version need to\n * re-fold from the log: deletes (the tombstone register), atomic intents and writes\n * to custom-resolver fields.\n */\nfunction mustKeep(op: Operation, schema: SchemaDefinition): boolean {\n\tif (op.type === 'delete') return true\n\tif (op.atomicOps !== undefined && Object.keys(op.atomicOps).length > 0) return true\n\tconst resolvers = schema.collections[op.collection]?.resolvers ?? {}\n\treturn Object.keys(op.data ?? {}).some((field) => resolvers[field] !== undefined)\n}\n\n/**\n * Per node, the largest sequence k <= the server's acknowledged sequence such that\n * this database holds every operation 1..k (in some collection's log or the\n * retained sequence conflicts). Only such a prefix can be declared compacted:\n * an operation of that node at or below it is then known to be a duplicate.\n */\nasync function contiguousPrefixes(\n\ttx: Transaction,\n\tschema: SchemaDefinition,\n\tacked: VersionVector,\n): Promise<VersionVector> {\n\tconst out = createVersionVector()\n\tfor (const [nodeId, ackedSeq] of acked) {\n\t\tif (ackedSeq <= 0) continue\n\t\tconst seqs = new Set<number>()\n\t\tfor (const collection of Object.keys(schema.collections)) {\n\t\t\tconst rows = await tx.query<{ sequence_number: number }>(\n\t\t\t\t`SELECT sequence_number FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND sequence_number <= ?`,\n\t\t\t\t[nodeId, ackedSeq],\n\t\t\t)\n\t\t\tfor (const row of rows) seqs.add(row.sequence_number)\n\t\t}\n\t\tconst conflicts = await tx.query<{ sequence_number: number }>(\n\t\t\t`SELECT sequence_number FROM ${SEQ_CONFLICTS_TABLE} WHERE node_id = ? AND sequence_number <= ?`,\n\t\t\t[nodeId, ackedSeq],\n\t\t)\n\t\tfor (const row of conflicts) seqs.add(row.sequence_number)\n\t\tconst through = await tx.query<{ sequence_number: number }>(\n\t\t\t`SELECT sequence_number FROM ${COMPACTED_THROUGH_TABLE} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tlet k = through[0]?.sequence_number ?? 0\n\t\twhile (k < ackedSeq && seqs.has(k + 1)) k += 1\n\t\tif (k > 0) out.set(nodeId, k)\n\t}\n\treturn out\n}\n\n/**\n * Compaction under the W7 fold (STORE-14). For every node, operations within the\n * contiguous prefix the server acknowledged (and older than the age cutoff, for\n * `after-days`) are folded per record into the record's base state, then removed\n * from the log. The record's live fold state is unchanged (it already holds them):\n * `state = join(base, fold(log))` holds before and after.\n *\n * Operations the server terminally rejected are never folded into a base.\n */\nexport async function compactFoldedLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tfolder: RecordFolder,\n\tstrategy: CompactionStrategy,\n\tserverVector: VersionVector,\n): Promise<CompactionResult> {\n\tconst acked = computeAckCompactionWatermark(serverVector)\n\tif (acked.size === 0) return { deletedCount: 0, watermark: acked }\n\tconst cutoff =\n\t\tstrategy.mode === 'after-days'\n\t\t\t? HybridLogicalClock.serialize({\n\t\t\t\t\twallTime: Date.now() - strategy.days * 24 * 60 * 60 * 1000,\n\t\t\t\t\tlogical: 0,\n\t\t\t\t\tnodeId: '',\n\t\t\t\t}).slice(0, 15)\n\t\t\t: null\n\n\tlet deletedCount = 0\n\tlet watermark = createVersionVector()\n\tawait adapter.transaction(async (tx) => {\n\t\twatermark = await contiguousPrefixes(tx, schema, acked)\n\t\tfor (const collection of Object.keys(schema.collections)) {\n\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\tconst byRecord = new Map<string, Operation[]>()\n\t\t\tfor (const [nodeId, maxSeq] of watermark) {\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${table} WHERE node_id = ? AND sequence_number <= ?${cutoff !== null ? ' AND SUBSTR(timestamp, 1, 15) < ?' : ''}`,\n\t\t\t\t\tcutoff !== null ? [nodeId, maxSeq, cutoff] : [nodeId, maxSeq],\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst op = deserializeOperationWithCollection(row, collection)\n\t\t\t\t\tif (mustKeep(op, schema)) continue\n\t\t\t\t\tconst list = byRecord.get(op.recordId) ?? []\n\t\t\t\t\tlist.push(op)\n\t\t\t\t\tbyRecord.set(op.recordId, list)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [recordId, ops] of byRecord) {\n\t\t\t\tconst rejected = await folder.loadTerminalRejections(\n\t\t\t\t\ttx,\n\t\t\t\t\tops.map((op) => op.id),\n\t\t\t\t)\n\t\t\t\tlet addition: FoldState = createFoldState(collection, recordId)\n\t\t\t\tlet any = false\n\t\t\t\tfor (const op of ops) {\n\t\t\t\t\tif (rejected.has(op.id)) continue\n\t\t\t\t\taddition = mergeOp(addition, op, schema, folder.options()).state\n\t\t\t\t\tany = true\n\t\t\t\t}\n\t\t\t\tif (any) await folder.joinIntoBase(tx, addition)\n\t\t\t\tfor (let i = 0; i < ops.length; i += 500) {\n\t\t\t\t\tconst chunk = ops.slice(i, i + 500)\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`DELETE FROM ${table} WHERE id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t\t\tchunk.map((op) => op.id),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tdeletedCount += ops.length\n\t\t\t}\n\t\t}\n\t\tfor (const [nodeId, seq] of watermark) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[nodeId, seq],\n\t\t\t)\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tCOMPACTION_BASELINE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\treturn { deletedCount, watermark }\n}\n","import {\n\tcanonicalizeLegacyOperation,\n\tcanonicalizeProvenLegacyClear,\n\tquoteIdent,\n} from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, StorageAdapter } from '../types'\n\n/** `_kora_meta` key: the op log's legacy bodies were made canonical (RT-83, RT-85). */\nexport const LEGACY_BODIES_META_KEY = 'legacy_bodies_canonical'\n\n/** A log row rewritten into its canonical legacy body. */\nexport interface CanonicalizedLegacyBody {\n\tcollection: string\n\trecordId: string\n}\n\n/**\n * Make every genuine beta.12 clear in the operation log explicit, once per database\n * (RT-83, RT-85).\n *\n * beta.12 applied `update(id, { field: undefined })` as a clear, hashed the member as\n * `null`, and logged JSON without it. Every later replica folds a stored body as\n * written (the fold has no legacy rule: a body a schema transform rewrote must never be\n * read as a clear), so the clear is written into the logged body here, where its\n * provenance is known:\n * - this device's own operations that declare no hash version were written by its\n * beta.12 self (beta.13 always declares version 2): a `previousData` key absent from\n * `data` is always such a clear;\n * - any other node's undeclared update is rewritten only when its id PROVES the clear\n * (`canonicalizeProvenLegacyClear`), as on inbound delivery.\n * The restored body has the same id: version 1 hashes `undefined` and `null` alike.\n *\n * @param adapter - The storage adapter\n * @param schema - The schema (collections with a log)\n * @param ownNodeId - This device's node id\n * @returns The rewritten rows' records (to re-fold)\n */\nexport async function canonicalizeLegacyLogBodies(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\townNodeId: string,\n): Promise<CanonicalizedLegacyBody[]> {\n\tconst rewritten: CanonicalizedLegacyBody[] = []\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${table} WHERE type = 'update' AND previous_data IS NOT NULL`,\n\t\t)\n\t\tconst updates: Array<{ id: string; data: string | null }> = []\n\t\tfor (const row of rows) {\n\t\t\tlet op: Operation\n\t\t\ttry {\n\t\t\t\top = deserializeOperationWithCollection(row, collection)\n\t\t\t} catch {\n\t\t\t\t// An unreadable row is the log-integrity scan's business, not this one's.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (op.hashVersion === 2 || canonicalizeLegacyOperation(op) === op) continue\n\t\t\tconst canonical =\n\t\t\t\top.nodeId === ownNodeId\n\t\t\t\t\t? canonicalizeLegacyOperation(op)\n\t\t\t\t\t: await canonicalizeProvenLegacyClear(op)\n\t\t\tif (canonical === op) continue\n\t\t\tupdates.push({ id: op.id, data: serializeOperation(canonical).data })\n\t\t\trewritten.push({ collection, recordId: op.recordId })\n\t\t}\n\t\tif (updates.length === 0) continue\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tfor (const update of updates) {\n\t\t\t\tawait tx.execute(`UPDATE ${table} SET data = ? WHERE id = ?`, [update.data, update.id])\n\t\t\t}\n\t\t})\n\t}\n\treturn rewritten\n}\n","import {\n\ttype FoldState,\n\ttype HLCTimestamp,\n\tHybridLogicalClock,\n\ttype SchemaDefinition,\n\tcreateSnapshotState,\n\tjoinStates,\n\tquoteIdent,\n} from '@korajs/core'\nimport { deserializeRecord } from '../serialization/serializer'\nimport type { RawCollectionRow, StorageAdapter, Transaction } from '../types'\nimport {\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n\tFOLD_STATE_TABLE,\n\tPROVISIONAL_OPS_TABLE,\n\ttype RecordFolder,\n} from './record-folder'\n\n/**\n * How a database is re-materialized on its first open with the W7 fold:\n *\n * - `'log'`: the log is clean (W8 integrity scan): every record is rebuilt with the\n * fold from its operations. This also repairs replicas that diverged under the\n * pairwise merge of beta.12/13.\n * - `'snapshot+log'`: the log is not complete (it was compacted, or has sequence\n * gaps): each existing row becomes the record's row snapshot (its values at\n * their `_field_versions`, exact where a stored fold state still has them), and\n * the remaining operations are folded on top.\n * - `'kept'`: the log has quarantined rows (W8). Only the records that own a\n * quarantined row are kept exactly as they are (their row becomes their snapshot,\n * nothing is rebuilt from their log); every other record is rebuilt as in `'log'`\n * or `'snapshot+log'` (RT-68).\n *\n * Row snapshots are approximate (see `createSnapshotState`); records that fold\n * against one are listed in `_kora_fold_snapshot` until their history is complete\n * again (a scope entry with the server's fold state, or a full resync).\n */\nexport type RematerializationMode = 'log' | 'snapshot+log' | 'kept'\n\n/** Result of {@link rematerializeDatabase}. */\nexport interface RematerializationResult {\n\tmode: RematerializationMode\n\t/** Records whose state was rebuilt. */\n\trecords: number\n\t/** Rows whose visible values changed. */\n\tchangedRows: number\n\t/** Records that now fold against a row snapshot (approximate until settled). */\n\tsnapshots: number\n}\n\n/** Which records to keep as row snapshots (they own quarantined log rows). */\nexport interface KeptRecords {\n\t/** `collection` -> record ids. */\n\trecords: ReadonlyMap<string, ReadonlySet<string>>\n\t/** Collections with a quarantined row whose record id is unknown: kept whole. */\n\tcollections: ReadonlySet<string>\n}\n\nconst BATCH = 200\n\n/**\n * Rebuild every record's fold state and row. Runs once per database (the store\n * records completion in `_kora_meta`), after the W8 log-integrity scan and the\n * schema migrations. One write transaction per batch of records, so a crash\n * resumes from scratch safely (the rebuild is a pure function of the log and rows).\n *\n * @param mode - `'log'` or `'snapshot+log'` for the records that are not kept;\n * `'kept'` is reported when `kept` names any record\n * @param kept - Records owning quarantined log rows (kept as they are)\n * @param collections - Only these collections (default: all)\n */\nexport async function rematerializeDatabase(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tfolder: RecordFolder,\n\tmode: Exclude<RematerializationMode, 'kept'>,\n\tkept: KeptRecords = { records: new Map(), collections: new Set() },\n\tcollections?: readonly string[],\n): Promise<RematerializationResult> {\n\tlet records = 0\n\tlet changedRows = 0\n\tlet snapshots = 0\n\tconst authoritative = folder.getAuthoritativeNodeIds()\n\tfor (const [collection, definition] of Object.entries(schema.collections)) {\n\t\tif (collections && !collections.includes(collection)) continue\n\t\tconst ids = new Set<string>()\n\t\tfor (const row of await adapter.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${quoteIdent(collection)}`,\n\t\t)) {\n\t\t\tids.add(row.id)\n\t\t}\n\t\tfor (const row of await adapter.query<{ record_id: string }>(\n\t\t\t`SELECT DISTINCT record_id FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t)) {\n\t\t\tids.add(row.record_id)\n\t\t}\n\t\tconst keptIds = kept.records.get(collection)\n\t\tconst keepAll = kept.collections.has(collection)\n\t\tconst all = [...ids].sort()\n\t\tfor (let i = 0; i < all.length; i += BATCH) {\n\t\t\tconst batch = all.slice(i, i + BATCH)\n\t\t\tawait adapter.transaction(async (tx) => {\n\t\t\t\tfor (const recordId of batch) {\n\t\t\t\t\trecords += 1\n\t\t\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst row = rows[0]\n\t\t\t\t\tconst before = row ? JSON.stringify(deserializeRecord(row, definition.fields)) : null\n\t\t\t\t\tconst seed = await folder.loadStoredState(tx, collection, recordId)\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t\t\t\t[collection, recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst snapshotOf = (from: RawCollectionRow): FoldState =>\n\t\t\t\t\t\tsnapshotFromRow(from, collection, schema, { seed, authoritative })\n\t\t\t\t\tif (keepAll || keptIds?.has(recordId)) {\n\t\t\t\t\t\tif (row) {\n\t\t\t\t\t\t\t// Owns a quarantined row: never rebuilt from its log; the row stays as\n\t\t\t\t\t\t\t// it is and later operations merge onto it.\n\t\t\t\t\t\t\tconst snapshot = snapshotOf(row)\n\t\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshot)\n\t\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t\t\tconst base = await folder.loadBase(tx, collection, recordId)\n\t\t\t\t\t\t\tawait folder.saveState(tx, base ? joinStates(base, snapshot, schema) : snapshot)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (mode === 'snapshot+log' && row) {\n\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshotOf(row))\n\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t}\n\t\t\t\t\tconst state = await folder.foldFromLog(tx, collection, recordId)\n\t\t\t\t\tif (state === null) {\n\t\t\t\t\t\t// No operation and no base: a row the log never had (cannot happen on a\n\t\t\t\t\t\t// clean log; kept as a snapshot rather than dropped).\n\t\t\t\t\t\tif (row) {\n\t\t\t\t\t\t\tconst snapshot = snapshotOf(row)\n\t\t\t\t\t\t\tawait folder.saveSnapshot(tx, snapshot)\n\t\t\t\t\t\t\tawait folder.saveState(tx, snapshot)\n\t\t\t\t\t\t\tsnapshots += 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tawait folder.saveState(tx, state)\n\t\t\t\t\tawait folder.materializeRow(tx, state, 'all', { clearRetraction: false })\n\t\t\t\t\tconst afterRows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst after = afterRows[0]\n\t\t\t\t\t\t? JSON.stringify(deserializeRecord(afterRows[0], definition.fields))\n\t\t\t\t\t\t: null\n\t\t\t\t\tif (before !== after) changedRows += 1\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\tconst keptAny = kept.collections.size > 0 || [...kept.records.values()].some((s) => s.size > 0)\n\treturn { mode: keptAny ? 'kept' : mode, records, changedRows, snapshots }\n}\n\n/**\n * The base snapshot of a materialized row: its values at their `_field_versions`\n * (rows from before per-field versions fall back to `_version`, then `_updated_at`).\n * With a `seed` (the record's stored fold state), every field it still holds in\n * the current plan's kind is taken from it exactly (RT-68).\n */\nexport function snapshotFromRow(\n\trow: RawCollectionRow,\n\tcollection: string,\n\tschema: SchemaDefinition,\n\toptions: { seed?: FoldState | null; authoritative?: ReadonlySet<string> } = {},\n): FoldState {\n\tconst definition = schema.collections[collection]\n\tconst record = definition ? deserializeRecord(row, definition.fields) : { id: row.id }\n\tconst { id: _id, createdAt: _c, updatedAt: _u, ...values } = record as Record<string, unknown>\n\tconst latest = rowVersion(row)\n\tconst fieldVersions: Record<string, HLCTimestamp> = {}\n\tconst raw = typeof row._field_versions === 'string' ? row._field_versions : '{}'\n\ttry {\n\t\tfor (const [field, version] of Object.entries(JSON.parse(raw) as Record<string, unknown>)) {\n\t\t\tif (typeof version === 'string' && version.length > 0) {\n\t\t\t\tfieldVersions[field] = HybridLogicalClock.deserialize(version)\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Malformed versions: every field falls back to the row version.\n\t}\n\tconst createdAt = typeof row._created_at === 'number' ? row._created_at : latest.wallTime\n\treturn createSnapshotState(\n\t\t{\n\t\t\tcollection,\n\t\t\trecordId: row.id,\n\t\t\tvalues,\n\t\t\tfieldVersions,\n\t\t\tcreated: { wallTime: createdAt, logical: 0, nodeId: '' },\n\t\t\tlatest,\n\t\t\tdeleted: row._deleted === 1,\n\t\t},\n\t\tschema,\n\t\t{\n\t\t\t...(options.seed ? { seed: options.seed } : {}),\n\t\t\t...(options.authoritative ? { authoritativeNodeIds: options.authoritative } : {}),\n\t\t},\n\t)\n}\n\nfunction rowVersion(row: RawCollectionRow): HLCTimestamp {\n\tif (typeof row._version === 'string' && row._version.length > 0) {\n\t\ttry {\n\t\t\treturn HybridLogicalClock.deserialize(row._version)\n\t\t} catch {\n\t\t\t// fall through\n\t\t}\n\t}\n\tconst wall = typeof row._updated_at === 'number' ? row._updated_at : 0\n\treturn { wallTime: wall, logical: 0, nodeId: '' }\n}\n\n/** Remove every fold state, base, row snapshot and provisional effect (mode switch). */\nexport async function clearFoldTables(tx: Transaction): Promise<void> {\n\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${FOLD_BASE_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE}`)\n\tawait tx.execute(`DELETE FROM ${PROVISIONAL_OPS_TABLE}`)\n}\n","import { KoraError, migrationStepsToSQL, quoteIdent, validateRecord } from '@korajs/core'\nimport type { CausalTracker, MigrationStep, Operation, SchemaDefinition } from '@korajs/core'\nimport {\n\tCausalScope,\n\ttype WriteEnv,\n\ttype WriteScope,\n\twithWriteScope,\n} from '../mutations/write-context'\nimport { writeUpdateInTx } from '../mutations/write-ops'\nimport { deserializeRecord, serializeRecord } from '../serialization/serializer'\nimport type { MetaRow, RawCollectionRow, StorageAdapter, Transaction } from '../types'\n\ntype BackfillStep = Extract<MigrationStep, { type: 'backfill' }>\n\n/** Keys every record carries besides its schema fields. */\nconst RECORD_KEYS: ReadonlySet<string> = new Set(['id', 'createdAt', 'updatedAt'])\n\n/** Everything the migration runner needs from the store. */\nexport interface MigrationRunContext {\n\treadonly adapter: StorageAdapter\n\treadonly schema: SchemaDefinition\n\t/** Write environment of the store's current node (clock, node id, secrets). */\n\treadonly env: Omit<WriteEnv, 'mutationName' | 'transactionId'>\n\treadonly causalTracker: CausalTracker | null\n\t/** Called after each version commits, once per operation its backfills wrote. */\n\treadonly onOperation: (operation: Operation) => void\n}\n\n/**\n * Bring the local database from its stored schema version to `schema.version`\n * (STORE-13, NEW-STORE-1).\n *\n * Each version runs in ONE transaction: its structural DDL, its backfills and the\n * `schema_version` write. A failure (a throwing transform, a crash) leaves no partial\n * effect, so a retry never applies a non-idempotent backfill twice.\n *\n * Backfill transforms receive the deserialized record (booleans, arrays, objects as the\n * app reads them). Every changed record is written through the single local write path\n * as an update operation with mutation name `migration:v<N>`, so the backfilled values\n * sync to the server and other devices; a step declared `localOnly` rewrites the rows\n * only. Fields the transform returns unchanged are not written.\n *\n * @returns The operations the backfills wrote, in commit order\n */\nexport async function runSchemaMigrations(ctx: MigrationRunContext): Promise<Operation[]> {\n\tconst stored = await readStoredSchemaVersion(ctx.adapter)\n\tconst target = ctx.schema.version\n\tif (stored >= target) {\n\t\tif (stored === 0) await writeSchemaVersion(ctx.adapter, target)\n\t\treturn []\n\t}\n\n\tconst written: Operation[] = []\n\tconst migrations = ctx.schema.migrations ?? {}\n\tfor (let version = stored + 1; version <= target; version++) {\n\t\tconst migration = migrations[version]\n\t\tconst steps = migration?.steps ?? []\n\t\tconst committed: Operation[] = []\n\t\tconst causal = new CausalScope(ctx.causalTracker, false)\n\t\tawait ctx.adapter.transaction(async (tx) => {\n\t\t\tfor (const step of steps) {\n\t\t\t\tif (step.type === 'renameField') {\n\t\t\t\t\tawait renameColumn(tx, step.collection, step.from, step.to)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor (const sql of migrationStepsToSQL([step])) {\n\t\t\t\t\tawait executeStructural(tx, sql)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst backfills = steps.filter((step): step is BackfillStep => step.type === 'backfill')\n\t\t\tif (backfills.length > 0) {\n\t\t\t\tconst env: WriteEnv = { ...ctx.env, mutationName: `migration:v${version}` }\n\t\t\t\tawait withWriteScope(tx, ctx.env.nodeId, causal, async (scope) => {\n\t\t\t\t\tfor (const step of backfills) {\n\t\t\t\t\t\tcommitted.push(...(await runBackfill(ctx.schema, env, scope, version, step)))\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\tawait tx.execute(\n\t\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('schema_version', ?)\",\n\t\t\t\t[String(version)],\n\t\t\t)\n\t\t})\n\t\tcausal.publish()\n\t\tfor (const operation of committed) ctx.onOperation(operation)\n\t\twritten.push(...committed)\n\t}\n\treturn written\n}\n\n/**\n * Structural DDL, tolerating \"duplicate column name\": the adapter's open already ran the\n * current schema's DDL, which adds the target schema's columns (`--kora:safe-alter`).\n * Inside a transaction a failed statement rolls back only itself.\n */\nasync function executeStructural(tx: Transaction, sql: string): Promise<void> {\n\ttry {\n\t\tawait tx.execute(sql)\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\tif (!message.includes('duplicate column name')) throw error\n\t}\n}\n\n/**\n * A `renameField` step. The adapter's open has already run the target schema's DDL, whose\n * `--kora:safe-alter` adds the renamed field's column (empty, or holding its default) and\n * creates the target schema's indexes on it; a plain `RENAME COLUMN` would then fail\n * \"duplicate column name\" and leave the values in the old column. The pre-added column is\n * dropped first (with the indexes on it, recreated afterwards), so the rename keeps the\n * values and the source column's constraints. Runs inside the version's transaction.\n */\nasync function renameColumn(\n\ttx: Transaction,\n\tcollection: string,\n\tfrom: string,\n\tto: string,\n): Promise<void> {\n\tconst table = quoteIdent(collection)\n\tconst columns = await tx.query<{ name: string }>(\n\t\t`SELECT name FROM pragma_table_info(${sqlText(collection)})`,\n\t)\n\tconst names = new Set(columns.map((column) => column.name))\n\t// A database created at (or past) this version: the open's DDL already made `to` and\n\t// there is no `from` to carry over (a fresh install of a schema whose history has\n\t// renames). Nothing to rename.\n\tif (!names.has(from) && names.has(to)) return\n\tif (names.has(from) && names.has(to)) {\n\t\tconst indexes = await tx.query<{ name: string; sql: string }>(\n\t\t\t`SELECT m.name AS name, m.sql AS sql FROM sqlite_master m WHERE m.type = 'index' AND m.tbl_name = ${sqlText(collection)} AND m.sql IS NOT NULL AND EXISTS (SELECT 1 FROM pragma_index_info(m.name) i WHERE i.name = ${sqlText(to)})`,\n\t\t)\n\t\tfor (const index of indexes) await tx.execute(`DROP INDEX ${quoteIdent(index.name)}`)\n\t\tawait tx.execute(`ALTER TABLE ${table} DROP COLUMN ${quoteIdent(to)}`)\n\t\tawait tx.execute(`ALTER TABLE ${table} RENAME COLUMN ${quoteIdent(from)} TO ${quoteIdent(to)}`)\n\t\tfor (const index of indexes) {\n\t\t\tawait tx.execute(index.sql.replace(/^CREATE INDEX /i, 'CREATE INDEX IF NOT EXISTS '))\n\t\t}\n\t\treturn\n\t}\n\tawait executeStructural(\n\t\ttx,\n\t\t`ALTER TABLE ${table} RENAME COLUMN ${quoteIdent(from)} TO ${quoteIdent(to)}`,\n\t)\n}\n\nfunction sqlText(value: string): string {\n\treturn `'${value.replaceAll(\"'\", \"''\")}'`\n}\n\nasync function runBackfill(\n\tschema: SchemaDefinition,\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tversion: number,\n\tstep: BackfillStep,\n): Promise<Operation[]> {\n\tconst definition = schema.collections[step.collection]\n\tif (!definition) {\n\t\tthrow new KoraError(\n\t\t\t`Migration v${version} backfills unknown collection \"${step.collection}\".`,\n\t\t\t'MIGRATION_UNKNOWN_COLLECTION',\n\t\t\t{ version, collection: step.collection },\n\t\t)\n\t}\n\tconst rows = await scope.tx.query<RawCollectionRow>(\n\t\t`SELECT * FROM ${quoteIdent(step.collection)} WHERE _deleted = 0 ORDER BY id`,\n\t)\n\tconst operations: Operation[] = []\n\tfor (const row of rows) {\n\t\tconst record = deserializeRecord(row, definition.fields)\n\t\tconst updates = step.transform({ ...record })\n\t\tif (updates === null || typeof updates !== 'object') continue\n\t\tconst changes: Record<string, unknown> = {}\n\t\tfor (const [field, value] of Object.entries(updates)) {\n\t\t\t// `{ ...record, x }` restates the record's own keys: unchanged ones are ignored.\n\t\t\tif (RECORD_KEYS.has(field) && sameValue(record[field], value)) continue\n\t\t\tif (!(field in definition.fields)) {\n\t\t\t\tthrow new KoraError(\n\t\t\t\t\t`Migration v${version} backfill of \"${step.collection}\" returned unknown field \"${field}\".`,\n\t\t\t\t\t'MIGRATION_UNKNOWN_FIELD',\n\t\t\t\t\t{ version, collection: step.collection, field, fix: 'Return only schema fields.' },\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!sameValue(record[field], value)) changes[field] = value\n\t\t}\n\t\tif (Object.keys(changes).length === 0) continue\n\n\t\tif (step.localOnly) {\n\t\t\tconst serialized = serializeRecord(changes, definition.fields)\n\t\t\tconst columns = Object.keys(serialized)\n\t\t\tawait scope.tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(step.collection)} SET ${columns.map((c) => `${quoteIdent(c)} = ?`).join(', ')} WHERE id = ?`,\n\t\t\t\t[...columns.map((c) => serialized[c]), row.id],\n\t\t\t)\n\t\t\tcontinue\n\t\t}\n\t\tconst validated = validateRecord(step.collection, definition, changes, 'update')\n\t\tconst result = await writeUpdateInTx(env, scope, step.collection, row.id, validated)\n\t\tif (result.operation) operations.push(result.operation)\n\t}\n\treturn operations\n}\n\n/** Structural equality for record values (JSON-shaped; bytes compared bytewise). */\nfunction sameValue(a: unknown, b: unknown): boolean {\n\tif (Object.is(a, b)) return true\n\tif (a instanceof Uint8Array || b instanceof Uint8Array) {\n\t\tif (!(a instanceof Uint8Array) || !(b instanceof Uint8Array) || a.length !== b.length) {\n\t\t\treturn false\n\t\t}\n\t\treturn a.every((byte, index) => byte === b[index])\n\t}\n\tif (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {\n\t\t// A missing value and null are the same stored value.\n\t\treturn (a ?? null) === (b ?? null)\n\t}\n\tif (Array.isArray(a) !== Array.isArray(b)) return false\n\tconst keysA = Object.keys(a)\n\tconst keysB = Object.keys(b)\n\tif (keysA.length !== keysB.length) return false\n\treturn keysA.every((key) =>\n\t\tsameValue((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]),\n\t)\n}\n\nasync function readStoredSchemaVersion(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<MetaRow>(\n\t\t\"SELECT value FROM _kora_meta WHERE key = 'schema_version'\",\n\t)\n\treturn rows[0] ? Number(rows[0].value) : 0\n}\n\nasync function writeSchemaVersion(adapter: StorageAdapter, version: number): Promise<void> {\n\tawait adapter.execute(\n\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('schema_version', ?)\",\n\t\t[String(version)],\n\t)\n}\n","/**\n * The schema-version ceiling (RT-109): a build never runs against a database a newer\n * build already migrated.\n *\n * `generateFullDDL` emits `--kora:schema-ceiling <version>` right after `_kora_meta`, before\n * any other DDL. It is a SQL comment; Kora's DDL executors (the native adapter, the SQLite\n * WASM worker, the test bridge) stop there with {@link schemaAheadMessage} when the\n * database's stored schema version is newer, so not even this build's additive DDL touches\n * it. The store then maps the failure to `SchemaVersionAheadError` and checks again after\n * every open (adapters that restore data after their DDL, such as the IndexedDB fallback).\n *\n * No imports: the SQLite WASM worker bundles this file.\n */\n\nconst DIRECTIVE = /^--kora:schema-ceiling (\\d+)$/\nconst AHEAD = /KORA_SCHEMA_VERSION_AHEAD stored=(\\d+) code=(\\d+)/\n\n/** The version a `--kora:schema-ceiling <version>` DDL statement names, or null. */\nexport function parseSchemaCeiling(sql: string): number | null {\n\tconst match = DIRECTIVE.exec(sql.trim())\n\treturn match ? Number(match[1]) : null\n}\n\n/** The stored version from a `_kora_meta` row read, or 0 when none is stored. */\nexport function storedSchemaVersion(rows: ReadonlyArray<{ value: unknown }>): number {\n\tconst value = Number(rows[0]?.value ?? 0)\n\treturn Number.isFinite(value) ? value : 0\n}\n\n/** The message a DDL executor throws when the database is ahead (parsed back by the store). */\nexport function schemaAheadMessage(stored: number, code: number): string {\n\treturn `KORA_SCHEMA_VERSION_AHEAD stored=${stored} code=${code}: the database was migrated by a newer build (schema version ${stored}); this build's schema version is ${code}.`\n}\n\n/** The versions in an error raised by {@link schemaAheadMessage}, wherever it was wrapped. */\nexport function parseSchemaAhead(error: unknown): { stored: number; code: number } | null {\n\tconst seen = new Set<unknown>()\n\tlet current: unknown = error\n\twhile (current !== null && current !== undefined && !seen.has(current)) {\n\t\tseen.add(current)\n\t\tconst text =\n\t\t\tcurrent instanceof Error ? current.message : typeof current === 'string' ? current : ''\n\t\tconst match = AHEAD.exec(text)\n\t\tif (match) return { stored: Number(match[1]), code: Number(match[2]) }\n\t\tcurrent = current instanceof Error ? (current as { cause?: unknown }).cause : null\n\t}\n\treturn null\n}\n\n/** Query the stored schema version through a synchronous runner (DDL executors). */\nexport const STORED_SCHEMA_VERSION_SQL = \"SELECT value FROM _kora_meta WHERE key = 'schema_version'\"\n","import type { FieldDescriptor, FieldKind } from '@korajs/core'\nimport type { CollectionRecord } from '../types'\n\n/** Compares two query result sets; true means subscribers need not be notified. */\nexport type ResultsEqual = (\n\tprev: readonly CollectionRecord[],\n\tnext: readonly CollectionRecord[],\n) => boolean\n\ntype ValueEqual = (a: unknown, b: unknown) => boolean\n\n/**\n * Structural equality for any value a deserialized record can hold: primitives\n * (with `Object.is`, so NaN equals NaN), arrays, byte views (richtext and blob\n * state), Dates and plain objects (own enumerable keys, order-insensitive).\n *\n * Deserialization builds fresh arrays and objects on every query run, so a\n * reference comparison reports every structured field as changed (STORE-12) and\n * every subscriber re-renders on every unrelated write to the collection.\n */\nexport function structurallyEqual(a: unknown, b: unknown): boolean {\n\tif (Object.is(a, b)) return true\n\tif (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n\n\tif (ArrayBuffer.isView(a) || ArrayBuffer.isView(b)) {\n\t\tif (!ArrayBuffer.isView(a) || !ArrayBuffer.isView(b)) return false\n\t\treturn bytesEqual(a, b)\n\t}\n\tif (Array.isArray(a) || Array.isArray(b)) {\n\t\tif (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tif (!structurallyEqual(a[i], b[i])) return false\n\t\t}\n\t\treturn true\n\t}\n\tif (a instanceof Date || b instanceof Date) {\n\t\treturn a instanceof Date && b instanceof Date && Object.is(a.getTime(), b.getTime())\n\t}\n\n\tconst objA = a as Record<string, unknown>\n\tconst objB = b as Record<string, unknown>\n\tconst keysA = Object.keys(objA)\n\tif (keysA.length !== Object.keys(objB).length) return false\n\tfor (const key of keysA) {\n\t\tif (!Object.hasOwn(objB, key)) return false\n\t\tif (!structurallyEqual(objA[key], objB[key])) return false\n\t}\n\treturn true\n}\n\nfunction bytesEqual(a: ArrayBufferView, b: ArrayBufferView): boolean {\n\tif (a.byteLength !== b.byteLength) return false\n\tconst x = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n\tconst y = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)\n\tfor (let i = 0; i < x.length; i++) {\n\t\tif (x[i] !== y[i]) return false\n\t}\n\treturn true\n}\n\nfunction scalarEqual(a: unknown, b: unknown): boolean {\n\treturn Object.is(a, b)\n}\n\n/**\n * The comparator for one field kind. Scalars deserialize to primitives, so\n * identity is exact for them; structured kinds deserialize to fresh containers\n * and need a structural comparison.\n */\nfunction equalityForKind(kind: FieldKind): ValueEqual {\n\tswitch (kind) {\n\t\tcase 'string':\n\t\tcase 'number':\n\t\tcase 'boolean':\n\t\tcase 'timestamp':\n\t\tcase 'enum':\n\t\t\treturn scalarEqual\n\t\tcase 'array':\n\t\tcase 'object':\n\t\tcase 'json':\n\t\tcase 'blob':\n\t\tcase 'richtext':\n\t\tcase 'secret':\n\t\t\treturn structurallyEqual\n\t\tdefault:\n\t\t\treturn structurallyEqual\n\t}\n}\n\n/**\n * Build the result-set comparator for a collection's records: per schema field,\n * the comparator for its kind; for every other key (id, createdAt, updatedAt and\n * included relations) a structural comparison.\n *\n * @param fields - The collection's field descriptors\n * @returns A comparator that is true when both result sets hold the same records,\n * in the same order, with structurally equal values\n */\nexport function createResultsEqual(fields: Record<string, FieldDescriptor>): ResultsEqual {\n\tconst perField = new Map<string, ValueEqual>()\n\tfor (const [name, descriptor] of Object.entries(fields)) {\n\t\tperField.set(name, equalityForKind(descriptor.kind))\n\t}\n\n\tconst recordEqual = (a: CollectionRecord, b: CollectionRecord): boolean => {\n\t\tconst recA = a as Record<string, unknown>\n\t\tconst recB = b as Record<string, unknown>\n\t\tconst keysA = Object.keys(recA)\n\t\tif (keysA.length !== Object.keys(recB).length) return false\n\t\tfor (const key of keysA) {\n\t\t\tif (!Object.hasOwn(recB, key)) return false\n\t\t\tconst eq = perField.get(key) ?? structurallyEqual\n\t\t\tif (!eq(recA[key], recB[key])) return false\n\t\t}\n\t\treturn true\n\t}\n\n\treturn (prev, next) => {\n\t\tif (prev === next) return true\n\t\tif (prev.length !== next.length) return false\n\t\t// Cheap pass first: a different id at any position means the set changed.\n\t\tfor (let i = 0; i < prev.length; i++) {\n\t\t\tif (prev[i]?.id !== next[i]?.id) return false\n\t\t}\n\t\tfor (let i = 0; i < prev.length; i++) {\n\t\t\tconst a = prev[i]\n\t\t\tconst b = next[i]\n\t\t\tif (a === undefined || b === undefined) return a === b\n\t\t\tif (!recordEqual(a, b)) return false\n\t\t}\n\t\treturn true\n\t}\n}\n\n/**\n * Comparator used when the collection's schema is unknown (a subscription\n * registered directly on the manager): structural comparison of every value.\n */\nexport const defaultResultsEqual: ResultsEqual = createResultsEqual({})\n","/**\n * Minimal pluralization/singularization utilities for relation name resolution.\n * Handles common English patterns — not meant to be exhaustive.\n */\n\nfunction isVowel(char: string | undefined): boolean {\n\tif (!char) return false\n\treturn 'aeiouAEIOU'.includes(char)\n}\n\n/**\n * Pluralize a word using common English rules.\n *\n * @example\n * ```\n * pluralize('project') // 'projects'\n * pluralize('category') // 'categories'\n * pluralize('match') // 'matches'\n * ```\n */\nexport function pluralize(word: string): string {\n\tif (word.endsWith('s')) return word\n\tif (word.endsWith('y') && !isVowel(word[word.length - 2])) {\n\t\treturn `${word.slice(0, -1)}ies`\n\t}\n\tif (word.endsWith('sh') || word.endsWith('ch') || word.endsWith('x') || word.endsWith('z')) {\n\t\treturn `${word}es`\n\t}\n\treturn `${word}s`\n}\n\n/**\n * Singularize a word using common English rules.\n *\n * @example\n * ```\n * singularize('projects') // 'project'\n * singularize('categories') // 'category'\n * singularize('matches') // 'match'\n * ```\n */\nexport function singularize(word: string): string {\n\tif (word.endsWith('ies') && !isVowel(word[word.length - 4])) {\n\t\treturn `${word.slice(0, -3)}y`\n\t}\n\tif (\n\t\tword.endsWith('shes') ||\n\t\tword.endsWith('ches') ||\n\t\tword.endsWith('xes') ||\n\t\tword.endsWith('zes')\n\t) {\n\t\treturn word.slice(0, -2)\n\t}\n\tif (word.endsWith('ses')) {\n\t\treturn word.slice(0, -2)\n\t}\n\tif (word.endsWith('s') && !word.endsWith('ss')) {\n\t\treturn word.slice(0, -1)\n\t}\n\treturn word\n}\n","import { QueryError } from '../errors'\nimport type { QueryDescriptor, WhereClause } from '../types'\n\n/**\n * Normalise a `where` clause to its canonical form (RT-102). This is the ONE place that\n * decides what a where value means, so the SQL the store runs, the descriptor and the\n * query key (store cache, React/Vue/Svelte bindings) always agree:\n *\n * - `undefined` means \"no condition\": `where({ projectId: undefined })` is `where({})`\n * (the usual \"nothing selected yet\" pattern), and an operator whose operand is\n * `undefined` (`{ $gt: undefined }`) is dropped; a field left with no operator is\n * dropped. A later `.where({ x: undefined })` therefore does not remove an earlier\n * condition on `x`.\n * - `null` means SQL `IS NULL` (`$ne: null` means `IS NOT NULL`).\n * - Non-finite numbers (`NaN`, `Infinity`) have no stored representation: refused.\n * - `undefined` inside a `$in` list is refused (ambiguous: no condition cannot be one\n * element of a list).\n *\n * @param where - The clause as the developer wrote it\n * @returns A new clause with the rules above applied\n * @throws {QueryError} For a non-finite number or an `undefined` `$in` element\n */\nexport function normalizeWhere(where: WhereClause): WhereClause {\n\tconst out: WhereClause = {}\n\tfor (const [field, value] of Object.entries(where)) {\n\t\tif (value === undefined) continue\n\t\tif (isOperatorObject(value)) {\n\t\t\tconst operators: Record<string, unknown> = {}\n\t\t\tfor (const [operator, operand] of Object.entries(value)) {\n\t\t\t\tif (operand === undefined) continue\n\t\t\t\toperators[operator] = normalizeOperand(field, operator, operand)\n\t\t\t}\n\t\t\tif (Object.keys(operators).length === 0) continue\n\t\t\tout[field] = operators\n\t\t\tcontinue\n\t\t}\n\t\tout[field] = normalizeOperand(field, '$eq', value)\n\t}\n\treturn out\n}\n\nfunction normalizeOperand(field: string, operator: string, operand: unknown): unknown {\n\tif (Array.isArray(operand)) {\n\t\treturn operand.map((item) => {\n\t\t\tif (item === undefined) {\n\t\t\t\tthrow new QueryError(\n\t\t\t\t\t`Invalid ${operator} list for field \"${field}\": it contains undefined. Remove the undefined element, or use null to match missing values.`,\n\t\t\t\t\t{ field, operator },\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn assertFinite(field, operator, item)\n\t\t})\n\t}\n\treturn assertFinite(field, operator, operand)\n}\n\nfunction assertFinite(field: string, operator: string, value: unknown): unknown {\n\tif (typeof value === 'number' && !Number.isFinite(value)) {\n\t\tthrow new QueryError(\n\t\t\t`Invalid value for field \"${field}\" (${operator}): ${String(value)} is not a finite number and cannot match a stored value.`,\n\t\t\t{ field, operator, value: String(value) },\n\t\t)\n\t}\n\treturn value\n}\n\nfunction isOperatorObject(value: unknown): value is Record<string, unknown> {\n\tif (value === null || typeof value !== 'object' || Array.isArray(value)) return false\n\tif (value instanceof Date || ArrayBuffer.isView(value)) return false\n\treturn true\n}\n\n/**\n * The canonical identity of a query: equal keys if and only if the descriptors run the\n * same query (RT-102). Used by the store's query-store cache and by every framework\n * binding to decide when to share a store or re-subscribe.\n *\n * Unlike `JSON.stringify`, nothing is dropped or conflated: `where` keys are sorted\n * (their order does not change the query), `undefined` is dropped exactly as\n * {@link normalizeWhere} drops it, and `NaN`, `Date` and byte values keep distinct,\n * typed encodings.\n *\n * @param descriptor - The query descriptor (`queryBuilder.getDescriptor()`)\n * @returns A string key\n */\nexport function queryKey(descriptor: QueryDescriptor): string {\n\treturn canonical({\n\t\tcollection: descriptor.collection,\n\t\twhere: normalizeWhere(descriptor.where),\n\t\torderBy: descriptor.orderBy.map((clause) => [clause.field, clause.direction]),\n\t\tlimit: descriptor.limit,\n\t\toffset: descriptor.offset,\n\t\tinclude: descriptor.include,\n\t})\n}\n\nfunction canonical(value: unknown): string {\n\tif (value === undefined) return 'u'\n\tif (value === null) return 'n'\n\tswitch (typeof value) {\n\t\tcase 'string':\n\t\t\treturn JSON.stringify(value)\n\t\tcase 'number':\n\t\t\t// Distinguishes NaN, Infinity and -0 (never equal to another stored number).\n\t\t\treturn Object.is(value, -0) ? 'num:-0' : `num:${String(value)}`\n\t\tcase 'boolean':\n\t\t\treturn value ? 'true' : 'false'\n\t\tcase 'bigint':\n\t\t\treturn `big:${value.toString()}`\n\t\tdefault:\n\t\t\tbreak\n\t}\n\tif (value instanceof Date) return `date:${value.getTime()}`\n\tif (ArrayBuffer.isView(value)) {\n\t\tconst bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\n\t\treturn `bytes:${Array.from(bytes).join(',')}`\n\t}\n\tif (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`\n\tif (typeof value === 'object') {\n\t\tconst entries = Object.entries(value as Record<string, unknown>)\n\t\t\t.filter(([, item]) => item !== undefined)\n\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\treturn `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(',')}}`\n\t}\n\treturn `?:${typeof value}`\n}\n","import type { CollectionDefinition, SchemaDefinition } from '@korajs/core'\nimport { encodeStoredText, quoteIdent } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport { deserializeRecord } from '../serialization/serializer'\nimport { type ResultsEqual, createResultsEqual } from '../subscription/result-equality'\nimport type { SubscriptionManager } from '../subscription/subscription-manager'\nimport type {\n\tCollectionRecord,\n\tOrderByDirection,\n\tQueryDescriptor,\n\tRawCollectionRow,\n\tStorageAdapter,\n\tSubscribeOptions,\n\tSubscriptionCallback,\n\tWhereClause,\n} from '../types'\nimport { pluralize, singularize } from './pluralize'\nimport { normalizeWhere } from './query-key'\nimport { buildCountQuery, buildSelectQuery } from './sql-builder'\n\nconst RESULTS_EQUAL_CACHE = new WeakMap<CollectionDefinition, ResultsEqual>()\n\n/**\n * Fluent query builder for constructing and executing collection queries.\n * Supports where, orderBy, limit, offset, include, exec, count, and subscribe.\n *\n * The generic parameter `T` defaults to `CollectionRecord` for backward compatibility\n * but can be narrowed to a specific record type for full type inference.\n *\n * @example\n * ```typescript\n * const todos = await app.todos\n * .where({ completed: false })\n * .orderBy('createdAt', 'desc')\n * .limit(10)\n * .exec()\n * ```\n */\nexport class QueryBuilder<T = CollectionRecord> {\n\tprivate descriptor: QueryDescriptor\n\n\tconstructor(\n\t\tprivate readonly collectionName: string,\n\t\tprivate readonly definition: CollectionDefinition,\n\t\tprivate readonly adapter: StorageAdapter,\n\t\tprivate readonly subscriptionManager: SubscriptionManager,\n\t\tinitialWhere: WhereClause = {},\n\t\tprivate readonly schema?: SchemaDefinition,\n\t) {\n\t\tthis.descriptor = {\n\t\t\tcollection: collectionName,\n\t\t\twhere: normalizeWhere(initialWhere),\n\t\t\torderBy: [],\n\t\t}\n\t}\n\n\t/**\n\t * Add WHERE conditions (AND semantics, merged with existing conditions).\n\t *\n\t * A field whose value is `undefined` adds no condition (it does not remove an\n\t * earlier one); `null` matches missing values (`IS NULL`). Non-finite numbers are\n\t * refused. See {@link normalizeWhere} (RT-102).\n\t */\n\twhere(conditions: WhereClause): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\twhere: { ...clone.descriptor.where, ...normalizeWhere(conditions) },\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Add ORDER BY clause.\n\t */\n\torderBy(field: string, direction: OrderByDirection = 'asc'): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\torderBy: [...clone.descriptor.orderBy, { field, direction }],\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Set result limit.\n\t */\n\tlimit(n: number): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = { ...clone.descriptor, limit: n }\n\t\treturn clone\n\t}\n\n\t/**\n\t * Set result offset.\n\t */\n\toffset(n: number): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tclone.descriptor = { ...clone.descriptor, offset: n }\n\t\treturn clone\n\t}\n\n\t/**\n\t * Include related records in the query results.\n\t * Follows relations defined in the schema to batch-fetch related data.\n\t *\n\t * @param targets - Relation target names (collection names or relation names)\n\t * @returns A new QueryBuilder with include targets added\n\t *\n\t * @example\n\t * ```typescript\n\t * const todosWithProject = await app.todos\n\t * .where({ completed: false })\n\t * .include('project')\n\t * .exec()\n\t * ```\n\t */\n\tinclude(...targets: string[]): QueryBuilder<T> {\n\t\tconst clone = this.clone()\n\t\tconst existing = clone.descriptor.include ?? []\n\t\tclone.descriptor = {\n\t\t\t...clone.descriptor,\n\t\t\tinclude: [...existing, ...targets],\n\t\t}\n\t\treturn clone\n\t}\n\n\t/**\n\t * Execute the query and return results.\n\t */\n\tasync exec(): Promise<T[]> {\n\t\tconst { sql, params } = buildSelectQuery(this.descriptor, this.definition.fields)\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(sql, params)\n\t\tconst records = rows.map((row) => deserializeRecord(row, this.definition.fields))\n\n\t\t// Resolve includes if any\n\t\tif (this.descriptor.include && this.descriptor.include.length > 0 && this.schema) {\n\t\t\tawait this.resolveIncludes(records)\n\t\t}\n\n\t\treturn records as T[]\n\t}\n\n\t/**\n\t * Execute a COUNT query and return the count.\n\t */\n\tasync count(): Promise<number> {\n\t\tconst { sql, params } = buildCountQuery(this.descriptor, this.definition.fields)\n\t\tconst rows = await this.adapter.query<{ count: number }>(sql, params)\n\t\treturn rows[0]?.count ?? 0\n\t}\n\n\t/**\n\t * Subscribe to query results. Callback is called immediately with current results,\n\t * then again whenever the results change due to mutations.\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tsubscribe(callback: SubscriptionCallback<T>, options?: SubscribeOptions): () => void {\n\t\tconst executeFn = () => this.exec()\n\n\t\t// Resolve includeCollections for subscription tracking\n\t\tconst descriptorCopy = { ...this.descriptor }\n\t\tif (descriptorCopy.include && descriptorCopy.include.length > 0 && this.schema) {\n\t\t\tdescriptorCopy.includeCollections = this.resolveIncludeCollections(descriptorCopy.include)\n\t\t}\n\n\t\t// Use registerAndFetch to execute immediately, set lastResults,\n\t\t// and call callback — ensuring subsequent flushes diff correctly.\n\t\treturn this.subscriptionManager.registerAndFetch(\n\t\t\tdescriptorCopy,\n\t\t\tcallback as SubscriptionCallback<CollectionRecord>,\n\t\t\texecuteFn as () => Promise<CollectionRecord[]>,\n\t\t\t{ onError: options?.onError, resultsEqual: this.getResultsEqual() },\n\t\t)\n\t}\n\n\t/** Comparator built once per collection definition and shared by its queries. */\n\tprivate getResultsEqual(): ResultsEqual {\n\t\tlet cached = RESULTS_EQUAL_CACHE.get(this.definition)\n\t\tif (!cached) {\n\t\t\tcached = createResultsEqual(this.definition.fields)\n\t\t\tRESULTS_EQUAL_CACHE.set(this.definition, cached)\n\t\t}\n\t\treturn cached\n\t}\n\n\t/** Get the internal descriptor (for testing/debugging) */\n\tgetDescriptor(): QueryDescriptor {\n\t\treturn { ...this.descriptor }\n\t}\n\n\tprivate clone(): QueryBuilder<T> {\n\t\tconst qb = new QueryBuilder<T>(\n\t\t\tthis.collectionName,\n\t\t\tthis.definition,\n\t\t\tthis.adapter,\n\t\t\tthis.subscriptionManager,\n\t\t\t{},\n\t\t\tthis.schema,\n\t\t)\n\t\tqb.descriptor = {\n\t\t\t...this.descriptor,\n\t\t\twhere: { ...this.descriptor.where },\n\t\t\torderBy: [...this.descriptor.orderBy],\n\t\t\tinclude: this.descriptor.include ? [...this.descriptor.include] : undefined,\n\t\t\tincludeCollections: this.descriptor.includeCollections\n\t\t\t\t? [...this.descriptor.includeCollections]\n\t\t\t\t: undefined,\n\t\t}\n\t\treturn qb\n\t}\n\n\t/**\n\t * Resolve include targets to their actual collection names for subscription tracking.\n\t */\n\tprivate resolveIncludeCollections(targets: string[]): string[] {\n\t\tif (!this.schema) return []\n\t\tconst collections: string[] = []\n\n\t\tfor (const target of targets) {\n\t\t\tconst relation = this.findRelation(target)\n\t\t\tif (relation) {\n\t\t\t\t// For many-to-one: the related collection is `relation.to`\n\t\t\t\t// For one-to-many: the related collection is `relation.from`\n\t\t\t\tif (relation.from === this.collectionName) {\n\t\t\t\t\tcollections.push(relation.to)\n\t\t\t\t} else {\n\t\t\t\t\tcollections.push(relation.from)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn collections\n\t}\n\n\t/**\n\t * Resolve includes after primary query, batch-fetching related records.\n\t */\n\tprivate async resolveIncludes(records: CollectionRecord[]): Promise<void> {\n\t\tif (!this.schema || !this.descriptor.include || records.length === 0) return\n\n\t\tfor (const target of this.descriptor.include) {\n\t\t\tconst relation = this.findRelation(target)\n\t\t\tif (!relation) {\n\t\t\t\tthrow new QueryError(\n\t\t\t\t\t`No relation found for include target \"${target}\" on collection \"${this.collectionName}\". ` +\n\t\t\t\t\t\t`Check that a relation is defined in your schema that connects \"${this.collectionName}\" to \"${target}\".`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (relation.from === this.collectionName) {\n\t\t\t\t// Many-to-one or one-to-one: primary has FK → fetch parent records\n\t\t\t\tawait this.resolveManyToOneInclude(records, relation, target)\n\t\t\t} else {\n\t\t\t\t// One-to-many: related collection has FK → fetch children\n\t\t\t\tawait this.resolveOneToManyInclude(records, relation, target)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Many-to-one: collect FK values from primary results, batch-fetch related, attach as singular.\n\t */\n\tprivate async resolveManyToOneInclude(\n\t\trecords: CollectionRecord[],\n\t\trelation: { from: string; to: string; field: string },\n\t\ttarget: string,\n\t): Promise<void> {\n\t\tconst fkField = relation.field\n\t\tconst fkValues = records\n\t\t\t.map((r) => r[fkField])\n\t\t\t.filter((v): v is string => v !== null && v !== undefined && typeof v === 'string')\n\n\t\tif (fkValues.length === 0) {\n\t\t\t// All null FKs — set property to null on all records\n\t\t\tconst propName = singularize(target)\n\t\t\tfor (const record of records) {\n\t\t\t\t;(record as Record<string, unknown>)[propName] = null\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst uniqueFks = [...new Set(fkValues)]\n\t\tconst relatedCollection = relation.to\n\t\tconst relatedDef = this.schema?.collections[relatedCollection]\n\t\tif (!relatedDef) return\n\n\t\t// Batch fetch: SELECT * FROM <to> WHERE id IN (...) AND _deleted = 0\n\t\tconst placeholders = uniqueFks.map(() => '?').join(', ')\n\t\tconst sql = `SELECT * FROM ${quoteIdent(relatedCollection)} WHERE id IN (${placeholders}) AND _deleted = 0`\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(sql, uniqueFks)\n\t\tconst relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields))\n\n\t\t// Build lookup\n\t\tconst lookup = new Map<string, CollectionRecord>()\n\t\tfor (const r of relatedRecords) {\n\t\t\tlookup.set(r.id, r)\n\t\t}\n\n\t\t// Attach as singular property\n\t\tconst propName = singularize(target)\n\t\tfor (const record of records) {\n\t\t\tconst fk = record[fkField] as string | null\n\t\t\t;(record as Record<string, unknown>)[propName] = fk ? (lookup.get(fk) ?? null) : null\n\t\t}\n\t}\n\n\t/**\n\t * One-to-many: collect primary IDs, batch-fetch children, attach as array.\n\t */\n\tprivate async resolveOneToManyInclude(\n\t\trecords: CollectionRecord[],\n\t\trelation: { from: string; to: string; field: string },\n\t\ttarget: string,\n\t): Promise<void> {\n\t\tconst primaryIds = records.map((r) => r.id)\n\t\tconst relatedCollection = relation.from\n\t\tconst relatedDef = this.schema?.collections[relatedCollection]\n\t\tif (!relatedDef) return\n\n\t\tconst fkField = relation.field\n\t\tconst placeholders = primaryIds.map(() => '?').join(', ')\n\t\tconst sql = `SELECT * FROM ${quoteIdent(relatedCollection)} WHERE ${quoteIdent(fkField)} IN (${placeholders}) AND _deleted = 0`\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\tsql,\n\t\t\tprimaryIds.map((id) => encodeStoredText(id)),\n\t\t)\n\t\tconst relatedRecords = rows.map((row) => deserializeRecord(row, relatedDef.fields))\n\n\t\t// Group by FK\n\t\tconst grouped = new Map<string, CollectionRecord[]>()\n\t\tfor (const r of relatedRecords) {\n\t\t\tconst fk = r[fkField] as string\n\t\t\tif (!grouped.has(fk)) {\n\t\t\t\tgrouped.set(fk, [])\n\t\t\t}\n\t\t\tgrouped.get(fk)?.push(r)\n\t\t}\n\n\t\t// Attach as array property\n\t\tconst propName = pluralize(target)\n\t\tfor (const record of records) {\n\t\t\t;(record as Record<string, unknown>)[propName] = grouped.get(record.id) ?? []\n\t\t}\n\t}\n\n\t/**\n\t * Find a relation definition matching the include target.\n\t * Searches by relation name, target collection name, and singularized/pluralized variants.\n\t */\n\tprivate findRelation(\n\t\ttarget: string,\n\t): { from: string; to: string; field: string; type: string } | null {\n\t\tif (!this.schema) return null\n\n\t\tfor (const [_name, rel] of Object.entries(this.schema.relations)) {\n\t\t\t// Direct match: target is the related collection name\n\t\t\tif (rel.from === this.collectionName && rel.to === target) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === target) return rel\n\n\t\t\t// Singularized match: \"project\" matches relation to \"projects\"\n\t\t\tif (rel.from === this.collectionName && rel.to === pluralize(target)) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === pluralize(target)) return rel\n\n\t\t\t// Pluralized match: \"todos\" matches relation from \"todos\"\n\t\t\tif (rel.from === this.collectionName && rel.to === singularize(target)) return rel\n\t\t\tif (rel.to === this.collectionName && rel.from === singularize(target)) return rel\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import type { OnDeleteAction, RelationDefinition, SchemaDefinition } from '@korajs/core'\n\n/**\n * A resolved relation reference: describes a relation that points TO a given collection.\n * When a record in `targetCollection` is deleted, we must handle records in\n * `sourceCollection` that reference it via `foreignKeyField`.\n */\nexport interface IncomingRelation {\n\t/** Name of the relation in the schema */\n\trelationName: string\n\t/** Collection that holds the foreign key (the \"from\" side) */\n\tsourceCollection: string\n\t/** Field in the source collection that references the target */\n\tforeignKeyField: string\n\t/** What to do when the referenced record is deleted */\n\tonDelete: OnDeleteAction\n\t/** The full relation definition */\n\trelation: RelationDefinition\n}\n\n/**\n * Builds an efficient lookup from target collection to all relations that reference it.\n *\n * Given a schema with relations like:\n * ```\n * todoBelongsToProject: { from: 'todos', to: 'projects', field: 'projectId', onDelete: 'cascade' }\n * ```\n *\n * The lookup for 'projects' would return:\n * ```\n * [{ sourceCollection: 'todos', foreignKeyField: 'projectId', onDelete: 'cascade', ... }]\n * ```\n *\n * This enables O(1) lookup when deleting a record to find all dependent relations.\n *\n * @param schema - The full schema definition containing relations\n * @returns A map from target collection name to its incoming relations\n */\nexport function buildRelationLookup(schema: SchemaDefinition): Map<string, IncomingRelation[]> {\n\tconst lookup = new Map<string, IncomingRelation[]>()\n\n\tfor (const [relationName, relation] of Object.entries(schema.relations)) {\n\t\tconst targetCollection = relation.to\n\t\tconst existing = lookup.get(targetCollection) ?? []\n\t\texisting.push({\n\t\t\trelationName,\n\t\t\tsourceCollection: relation.from,\n\t\t\tforeignKeyField: relation.field,\n\t\t\tonDelete: relation.onDelete,\n\t\t\trelation,\n\t\t})\n\t\tlookup.set(targetCollection, existing)\n\t}\n\n\treturn lookup\n}\n\n/**\n * Get all incoming relations for a given collection.\n * Returns an empty array if no relations reference the collection.\n *\n * @param lookup - The pre-built relation lookup map\n * @param collection - The target collection name\n * @returns Array of incoming relations\n */\nexport function getIncomingRelations(\n\tlookup: Map<string, IncomingRelation[]>,\n\tcollection: string,\n): IncomingRelation[] {\n\treturn lookup.get(collection) ?? []\n}\n","import type { Operation, SchemaDefinition } from '@korajs/core'\nimport { KoraError, encodeStoredText, quoteIdent } from '@korajs/core'\nimport type { WriteEnv, WriteScope } from '../mutations/write-context'\nimport { writeDeleteInTx, writeUpdateInTx } from '../mutations/write-ops'\nimport type { Transaction } from '../types'\nimport type { IncomingRelation } from './relation-lookup'\nimport { buildRelationLookup, getIncomingRelations } from './relation-lookup'\n\n/**\n * Error thrown when a delete is refused due to a 'restrict' referential integrity policy.\n * The error includes context about which relation caused the restriction and\n * how many referencing records exist.\n */\nexport class ReferentialIntegrityError extends KoraError {\n\tconstructor(\n\t\tcollection: string,\n\t\trecordId: string,\n\t\treferencingCollection: string,\n\t\trelationName: string,\n\t\treferencingCount: number,\n\t) {\n\t\tsuper(\n\t\t\t`Cannot delete record \"${recordId}\" from \"${collection}\": ${referencingCount} record(s) in \"${referencingCollection}\" reference it via relation \"${relationName}\" with onDelete: 'restrict'. Delete or reassign the referencing records first.`,\n\t\t\t'REFERENTIAL_INTEGRITY',\n\t\t\t{\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t\treferencingCollection,\n\t\t\t\trelationName,\n\t\t\t\treferencingCount,\n\t\t\t},\n\t\t)\n\t\tthis.name = 'ReferentialIntegrityError'\n\t}\n}\n\n/**\n * Configuration for the RelationEnforcer.\n */\nexport interface RelationEnforcerConfig {\n\tschema: SchemaDefinition\n}\n\n/**\n * Result of enforcing referential integrity on a delete operation.\n * Contains all additional operations that were created as side effects\n * (cascaded deletes and set-null updates).\n */\nexport interface EnforcementResult {\n\t/** Additional operations created by cascading deletes and set-null updates */\n\toperations: Operation[]\n}\n\n/**\n * Enforces referential integrity constraints during local delete operations.\n *\n * When a record is deleted, this enforcer checks all relations that reference\n * the deleted record's collection and applies the appropriate onDelete policy:\n *\n * - **cascade**: Recursively deletes all referencing records\n * - **set-null**: Sets the foreign key to null on all referencing records\n * - **restrict**: Throws a ReferentialIntegrityError if any references exist\n * - **no-action**: Does nothing (the foreign key is left dangling)\n *\n * The enforcer runs inside the delete's write transaction and writes every side\n * effect through the single local write path (`writeDeleteInTx` /\n * `writeUpdateInTx`), so cascaded operations reserve their sequence numbers in\n * the same contiguous block as the parent and carry per-field version stamps\n * (STORE-2, STORE-3). Every generated operation depends causally on the delete\n * that caused it.\n *\n * @example\n * ```typescript\n * const enforcer = new RelationEnforcer({ schema })\n * // inside a write transaction, after building the parent delete operation:\n * const result = await enforcer.enforceDelete('projects', 'proj-1', scope, env, deleteOp.id)\n * // result.operations contains any cascaded delete/update ops\n * ```\n */\nexport class RelationEnforcer {\n\tprivate readonly lookup: Map<string, IncomingRelation[]>\n\n\tconstructor(config: RelationEnforcerConfig) {\n\t\tthis.lookup = buildRelationLookup(config.schema)\n\t}\n\n\t/**\n\t * Enforce referential integrity for a record being deleted.\n\t *\n\t * @param collection - The collection the deleted record belongs to\n\t * @param recordId - The ID of the deleted record\n\t * @param scope - The active write scope (transaction + causal scope)\n\t * @param env - The write environment of the delete\n\t * @param parentOpId - Id of the delete operation; every side effect depends on it\n\t * @returns All additional operations created as side effects\n\t * @throws {ReferentialIntegrityError} If a 'restrict' policy is violated\n\t */\n\tasync enforceDelete(\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<EnforcementResult> {\n\t\tconst incomingRelations = getIncomingRelations(this.lookup, collection)\n\t\tif (incomingRelations.length === 0) {\n\t\t\treturn { operations: [] }\n\t\t}\n\n\t\tconst allOperations: Operation[] = []\n\n\t\t// Process relations in a deterministic order (sorted by relation name)\n\t\t// to ensure identical results regardless of Map iteration order.\n\t\tconst sortedRelations = [...incomingRelations].sort((a, b) =>\n\t\t\ta.relationName.localeCompare(b.relationName),\n\t\t)\n\n\t\tfor (const incoming of sortedRelations) {\n\t\t\tconst ops = await this.enforceRelation(incoming, recordId, scope, env, parentOpId)\n\t\t\tallOperations.push(...ops)\n\t\t}\n\n\t\treturn { operations: allOperations }\n\t}\n\n\t/**\n\t * Enforce a single relation's onDelete policy.\n\t */\n\tprivate async enforceRelation(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tswitch (incoming.onDelete) {\n\t\t\tcase 'cascade':\n\t\t\t\treturn this.enforceCascade(incoming, deletedRecordId, scope, env, parentOpId)\n\t\t\tcase 'set-null':\n\t\t\t\treturn this.enforceSetNull(incoming, deletedRecordId, scope, env, parentOpId)\n\t\t\tcase 'restrict':\n\t\t\t\treturn this.enforceRestrict(incoming, deletedRecordId, scope.tx)\n\t\t\tcase 'no-action':\n\t\t\t\treturn []\n\t\t}\n\t}\n\n\t/**\n\t * Cascade: delete every live record that references the deleted record. Each\n\t * cascaded delete runs the full delete path, so it recurses into its own\n\t * referencing records.\n\t */\n\tprivate async enforceCascade(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tconst referencingIds = await this.findReferencing(incoming, deletedRecordId, scope.tx)\n\t\tconst operations: Operation[] = []\n\t\tfor (const id of referencingIds) {\n\t\t\tconst result = await writeDeleteInTx(env, scope, incoming.sourceCollection, id, {\n\t\t\t\textraCausalDeps: [parentOpId],\n\t\t\t})\n\t\t\tif (result.operation) operations.push(result.operation)\n\t\t\toperations.push(...result.sideEffects)\n\t\t}\n\t\treturn operations\n\t}\n\n\t/**\n\t * Set-null: set the foreign key to null on every live referencing record.\n\t */\n\tprivate async enforceSetNull(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\tscope: WriteScope,\n\t\tenv: WriteEnv,\n\t\tparentOpId: string,\n\t): Promise<Operation[]> {\n\t\tconst referencingIds = await this.findReferencing(incoming, deletedRecordId, scope.tx)\n\t\tconst operations: Operation[] = []\n\t\tfor (const id of referencingIds) {\n\t\t\tconst result = await writeUpdateInTx(\n\t\t\t\tenv,\n\t\t\t\tscope,\n\t\t\t\tincoming.sourceCollection,\n\t\t\t\tid,\n\t\t\t\t{ [incoming.foreignKeyField]: null },\n\t\t\t\t[parentOpId],\n\t\t\t)\n\t\t\tif (result.operation) operations.push(result.operation)\n\t\t}\n\t\treturn operations\n\t}\n\n\t/**\n\t * Restrict: refuse the delete if any referencing records exist.\n\t */\n\tprivate async enforceRestrict(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\ttx: Transaction,\n\t): Promise<Operation[]> {\n\t\tconst { sourceCollection, foreignKeyField, relationName } = incoming\n\n\t\tconst countRows = await tx.query<{ cnt: number }>(\n\t\t\t`SELECT COUNT(*) as cnt FROM ${quoteIdent(sourceCollection)} WHERE ${quoteIdent(foreignKeyField)} = ? AND _deleted = 0`,\n\t\t\t// The foreign key column holds the stored-text form (RT-65).\n\t\t\t[encodeStoredText(deletedRecordId)],\n\t\t)\n\t\tconst count = countRows[0]?.cnt ?? 0\n\n\t\tif (count > 0) {\n\t\t\tthrow new ReferentialIntegrityError(\n\t\t\t\tincoming.relation.to,\n\t\t\t\tdeletedRecordId,\n\t\t\t\tsourceCollection,\n\t\t\t\trelationName,\n\t\t\t\tcount,\n\t\t\t)\n\t\t}\n\n\t\treturn []\n\t}\n\n\t/** Ids of live records referencing `deletedRecordId`, in id order (deterministic). */\n\tprivate async findReferencing(\n\t\tincoming: IncomingRelation,\n\t\tdeletedRecordId: string,\n\t\ttx: Transaction,\n\t): Promise<string[]> {\n\t\tconst rows = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${quoteIdent(incoming.sourceCollection)} WHERE ${quoteIdent(incoming.foreignKeyField)} = ? AND _deleted = 0 ORDER BY id`,\n\t\t\t// The foreign key column holds the stored-text form (RT-65).\n\t\t\t[encodeStoredText(deletedRecordId)],\n\t\t)\n\t\treturn rows.map((row) => row.id)\n\t}\n\n\t/**\n\t * Get the relation lookup map for external use (e.g., by the merge engine).\n\t */\n\tgetRelationLookup(): Map<string, IncomingRelation[]> {\n\t\treturn this.lookup\n\t}\n}\n","import {\n\tHybridLogicalClock,\n\tOperationError,\n\tfoldRecord,\n\tisFoldStateLive,\n\tmaterialize,\n} from '@korajs/core'\nimport type {\n\tCollectionDefinition,\n\tOperation,\n\tOperationTransform,\n\tSchemaDefinition,\n} from '@korajs/core'\nimport { topologicalSort } from '@korajs/core/internal'\nimport { mergeYjsUpdates } from '../fold/record-folder'\nimport { decodeRichtextFieldsFromOpData } from '../serialization/op-data-encoding'\nimport type { CollectionRecord } from '../types'\n\n/**\n * In-memory materialized state at a causal cut in the operation log.\n * Read-only — does not mutate the live store.\n */\nexport interface ReplaySnapshot {\n\t/** The operation whose causal past was replayed (inclusive). */\n\ttargetOperation: Operation\n\t/** Operations applied in causal order (ancestors + target). */\n\toperationsApplied: Operation[]\n\t/** Non-deleted records per collection after replay. */\n\tcollections: Record<string, CollectionRecord[]>\n\t/** Look up a single record at the replay cut. Returns null if deleted or missing. */\n\tfindRecord(collection: string, recordId: string): CollectionRecord | null\n}\n\ninterface MutableReplayRecord {\n\tid: string\n\tfields: Record<string, unknown>\n\tdeleted: boolean\n\tcreatedAt: number\n\tupdatedAt: number\n}\n\ntype ReplayMemoryState = Map<string, Map<string, MutableReplayRecord>>\n\n/**\n * Collect the target operation and all causal ancestors present in `allOps`.\n *\n * @param aliases - Old operation id -> the id it was re-emitted under (a renumbered\n * version-2 operation, `_kora_seq_conflicts.reemitted_as`). A dependent the server\n * already stored keeps naming the old id; the alias resolves it.\n */\nexport function collectCausalClosure(\n\tallOps: Operation[],\n\ttargetOperationId: string,\n\taliases: ReadonlyMap<string, string> = new Map(),\n): Operation[] {\n\tconst opMap = new Map<string, Operation>()\n\tfor (const op of allOps) {\n\t\topMap.set(op.id, op)\n\t}\n\n\tconst target = opMap.get(targetOperationId)\n\tif (!target) {\n\t\tthrow new OperationError(\n\t\t\t`Operation \"${targetOperationId}\" not found in the local operation log`,\n\t\t\t{\n\t\t\t\toperationId: targetOperationId,\n\t\t\t},\n\t\t)\n\t}\n\n\tconst included = new Set<string>()\n\tconst stack: string[] = [targetOperationId]\n\n\twhile (stack.length > 0) {\n\t\tconst id = stack.pop()\n\t\tif (id === undefined || included.has(id)) {\n\t\t\tcontinue\n\t\t}\n\t\tincluded.add(id)\n\t\tconst op = opMap.get(id)\n\t\tif (!op) {\n\t\t\tcontinue\n\t\t}\n\t\tfor (const dep of op.causalDeps) {\n\t\t\tlet depId = dep\n\t\t\t// Follow re-emissions (a renumbered op may itself have been renumbered again).\n\t\t\tfor (let hops = 0; !opMap.has(depId) && aliases.has(depId) && hops < 8; hops++) {\n\t\t\t\tdepId = aliases.get(depId) ?? depId\n\t\t\t}\n\t\t\tif (opMap.has(depId)) {\n\t\t\t\tstack.push(depId)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst subset = allOps.filter((op) => included.has(op.id))\n\treturn topologicalSort(subset)\n}\n\n/**\n * Replay a causal subset of operations into an in-memory materialized snapshot.\n * Does not use the merge engine — concurrent ops outside the causal cut are excluded.\n */\nexport function buildReplaySnapshot(\n\tschema: SchemaDefinition,\n\tallOps: Operation[],\n\ttargetOperationId: string,\n\taliases: ReadonlyMap<string, string> = new Map(),\n\ttransforms: readonly OperationTransform[] = [],\n): ReplaySnapshot {\n\tconst operationsApplied = collectCausalClosure(allOps, targetOperationId, aliases)\n\tconst targetOperation = operationsApplied.find((op) => op.id === targetOperationId)\n\tif (!targetOperation) {\n\t\tthrow new OperationError(`Operation \"${targetOperationId}\" not found after causal sort`, {\n\t\t\toperationId: targetOperationId,\n\t\t})\n\t}\n\n\tconst memory = foldIntoMemory(operationsApplied, schema, transforms)\n\n\tconst collections = materializeCollections(schema, memory)\n\n\treturn {\n\t\ttargetOperation,\n\t\toperationsApplied,\n\t\tcollections,\n\t\tfindRecord(collection: string, recordId: string): CollectionRecord | null {\n\t\t\tconst colMap = memory.get(collection)\n\t\t\tconst record = colMap?.get(recordId)\n\t\t\tif (!record || record.deleted) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst definition = schema.collections[collection]\n\t\t\tif (!definition) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn toCollectionRecord(record, definition)\n\t\t},\n\t}\n}\n\n/**\n * Fold every record of the causal cut with the W7 fold, exactly as the live store\n * materializes it (the cut may hold concurrent branches: the fold, not the\n * application order, decides).\n */\nfunction foldIntoMemory(\n\tops: readonly Operation[],\n\tschema: SchemaDefinition,\n\ttransforms: readonly OperationTransform[],\n): ReplayMemoryState {\n\tconst byRecord = new Map<string, Operation[]>()\n\tfor (const op of ops) {\n\t\tif (!schema.collections[op.collection]) continue\n\t\tconst key = `${op.collection}\\u0000${op.recordId}`\n\t\tconst list = byRecord.get(key) ?? []\n\t\tlist.push(op)\n\t\tbyRecord.set(key, list)\n\t}\n\tconst state: ReplayMemoryState = new Map()\n\tfor (const recordOps of byRecord.values()) {\n\t\tconst first = recordOps[0] as Operation\n\t\tconst definition = schema.collections[first.collection] as CollectionDefinition\n\t\t// The live store folds with the schema transforms (RT-84): so does time travel.\n\t\tconst folded = foldRecord(recordOps, schema, {\n\t\t\trichtext: mergeYjsUpdates,\n\t\t\t...(transforms.length > 0 ? { transforms } : {}),\n\t\t}).state\n\t\tif (folded === null || folded.cr === null || folded.u === null) continue\n\t\tconst values = materialize({ ...folded, d: null }, { richtext: mergeYjsUpdates }) ?? {}\n\t\tlet colMap = state.get(first.collection)\n\t\tif (!colMap) {\n\t\t\tcolMap = new Map()\n\t\t\tstate.set(first.collection, colMap)\n\t\t}\n\t\tcolMap.set(first.recordId, {\n\t\t\tid: first.recordId,\n\t\t\t// The fold materializes op-data form (tagged binary); snapshots expose\n\t\t\t// record-shaped values (Uint8Array / string).\n\t\t\tfields: decodeRichtextFieldsFromOpData(values, definition.fields),\n\t\t\tdeleted: !isFoldStateLive(folded),\n\t\t\tcreatedAt: HybridLogicalClock.deserialize(folded.cr.t).wallTime,\n\t\t\tupdatedAt: HybridLogicalClock.deserialize(folded.u.t).wallTime,\n\t\t})\n\t}\n\treturn state\n}\n\nfunction materializeCollections(\n\tschema: SchemaDefinition,\n\tmemory: ReplayMemoryState,\n): Record<string, CollectionRecord[]> {\n\tconst collections: Record<string, CollectionRecord[]> = {}\n\n\tfor (const [collectionName, definition] of Object.entries(schema.collections)) {\n\t\tconst colMap = memory.get(collectionName)\n\t\tconst records: CollectionRecord[] = []\n\t\tif (colMap) {\n\t\t\tfor (const record of colMap.values()) {\n\t\t\t\tif (!record.deleted) {\n\t\t\t\t\trecords.push(toCollectionRecord(record, definition))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcollections[collectionName] = records\n\t}\n\n\treturn collections\n}\n\nfunction toCollectionRecord(\n\trecord: MutableReplayRecord,\n\tdefinition: CollectionDefinition,\n): CollectionRecord {\n\tconst result: CollectionRecord = {\n\t\tid: record.id,\n\t\tcreatedAt: record.createdAt,\n\t\tupdatedAt: record.updatedAt,\n\t}\n\tfor (const [fieldName] of Object.entries(definition.fields)) {\n\t\tif (fieldName in record.fields) {\n\t\t\tresult[fieldName] = record.fields[fieldName]\n\t\t}\n\t}\n\treturn result\n}\n","import type { SequenceConfig } from '@korajs/core'\nimport { defaultSequenceFormat, formatSequenceValue } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\n\ninterface SequenceRow {\n\tcounter: number\n}\n\n/**\n * Manages offline-safe sequences backed by a `_kora_sequences` table.\n *\n * Each sequence counter is scoped by (name, scope, nodeId), ensuring\n * that different devices never collide. The counter is atomically\n * incremented within a database transaction.\n *\n * @example\n * ```typescript\n * const mgr = new SequenceManager(adapter, 'node-abc')\n *\n * const receipt = await mgr.next('receipt', {\n * scope: 'store-1',\n * format: 'S-{date}-{node4}-{seq}',\n * })\n * // → \"S-20260508-node-0001\"\n * ```\n */\nexport class SequenceManager {\n\tprivate readonly adapter: StorageAdapter\n\tprivate readonly nodeId: string\n\n\tconstructor(adapter: StorageAdapter, nodeId: string) {\n\t\tthis.adapter = adapter\n\t\tthis.nodeId = nodeId\n\t}\n\n\t/**\n\t * Get the next value in a sequence, atomically incrementing the counter.\n\t *\n\t * @param name - The sequence name (e.g., 'receipt', 'invoice')\n\t * @param config - Optional configuration for scope, format, and starting value\n\t * @returns The formatted sequence value\n\t */\n\tasync next(name: string, config?: SequenceConfig): Promise<string> {\n\t\tconst scope = config?.scope ?? ''\n\t\tconst startAt = config?.startAt ?? 1\n\t\tconst format = config?.format ?? defaultSequenceFormat(name)\n\n\t\tlet counter = 0\n\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t// Try to read the current counter\n\t\t\tconst rows = await tx.query<SequenceRow>(\n\t\t\t\t'SELECT counter FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t\t[name, scope, this.nodeId],\n\t\t\t)\n\n\t\t\tif (rows.length > 0) {\n\t\t\t\tconst row = rows[0] as SequenceRow\n\t\t\t\tcounter = row.counter + 1\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'UPDATE _kora_sequences SET counter = ? WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t\t\t[counter, name, scope, this.nodeId],\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\t// First use — initialize with startAt\n\t\t\t\tcounter = startAt\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'INSERT INTO _kora_sequences (name, scope, node_id, counter) VALUES (?, ?, ?, ?)',\n\t\t\t\t\t[name, scope, this.nodeId, counter],\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn formatSequenceValue(format, counter, this.nodeId)\n\t}\n\n\t/**\n\t * Get the current counter value without incrementing.\n\t *\n\t * @param name - The sequence name\n\t * @param config - Optional scope\n\t * @returns The current counter value, or 0 if the sequence has never been used\n\t */\n\tasync current(name: string, config?: { scope?: string }): Promise<number> {\n\t\tconst scope = config?.scope ?? ''\n\n\t\tconst rows = await this.adapter.query<SequenceRow>(\n\t\t\t'SELECT counter FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t[name, scope, this.nodeId],\n\t\t)\n\n\t\tif (rows.length > 0) {\n\t\t\treturn (rows[0] as SequenceRow).counter\n\t\t}\n\t\treturn 0\n\t}\n\n\t/**\n\t * Reset a sequence counter.\n\t *\n\t * @param name - The sequence name\n\t * @param config - Optional scope and target value\n\t */\n\tasync reset(name: string, config?: { scope?: string; to?: number }): Promise<void> {\n\t\tconst scope = config?.scope ?? ''\n\t\tconst to = config?.to ?? 0\n\n\t\tawait this.adapter.execute(\n\t\t\t'DELETE FROM _kora_sequences WHERE name = ? AND scope = ? AND node_id = ?',\n\t\t\t[name, scope, this.nodeId],\n\t\t)\n\n\t\tif (to > 0) {\n\t\t\tawait this.adapter.execute(\n\t\t\t\t'INSERT INTO _kora_sequences (name, scope, node_id, counter) VALUES (?, ?, ?, ?)',\n\t\t\t\t[name, scope, this.nodeId, to],\n\t\t\t)\n\t\t}\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\nimport { isRawTextKind } from './serializer'\n\n/** `_kora_meta` key: raw-string columns hold the stored-text codec's form (RT-65). */\nexport const STORED_TEXT_CODEC_META_KEY = 'stored_text_codec'\n\n/** Version of the codec the rows are written with. */\nconst STORED_TEXT_CODEC_VERSION = '1'\n\n/**\n * Once per database: re-encode the U+FFFF of rows written before the stored-text codec\n * (RT-65) so the decoder returns them unchanged. A row written before the codec holds\n * the raw string; the only code unit whose meaning changes under the decoder is the\n * escape introducer U+FFFF (`U+FFFF` -> `U+FFFF F`). NUL needs no rewrite (better-sqlite3\n * stored it as is), and a lone surrogate a pre-codec row held was already replaced by\n * U+FFFD when it was bound, so nothing is left to recover.\n *\n * Every collection table of the schema that exists is rewritten, for the columns of its\n * raw-string fields that exist. One transaction; the meta key makes it idempotent.\n *\n * @param adapter - An open storage adapter\n * @param schema - The schema whose collection tables to migrate\n */\nexport async function ensureStoredTextCodec(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<void> {\n\tconst rows = await adapter.query<{ value: string }>(\n\t\t'SELECT value FROM _kora_meta WHERE key = ?',\n\t\t[STORED_TEXT_CODEC_META_KEY],\n\t)\n\tif (rows[0]?.value === STORED_TEXT_CODEC_VERSION) return\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const [name, collection] of Object.entries(schema.collections)) {\n\t\t\tconst columns = new Set(\n\t\t\t\t(await tx.query<{ name: string }>(`PRAGMA table_info(${quoteIdent(name)})`)).map(\n\t\t\t\t\t(column) => column.name,\n\t\t\t\t),\n\t\t\t)\n\t\t\tif (columns.size === 0) continue\n\t\t\tfor (const [field, descriptor] of Object.entries(collection.fields)) {\n\t\t\t\tif (!isRawTextKind(descriptor.kind) || !columns.has(field)) continue\n\t\t\t\tconst column = quoteIdent(field)\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(name)} SET ${column} = replace(${column}, char(65535), char(65535) || 'F') WHERE instr(${column}, char(65535)) > 0`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tSTORED_TEXT_CODEC_META_KEY,\n\t\t\tSTORED_TEXT_CODEC_VERSION,\n\t\t])\n\t})\n}\n","/**\n * Bloom filter for fast subscription dependency pre-checking.\n *\n * When the SubscriptionManager has many active subscriptions, checking whether a\n * mutation might affect any subscription requires scanning all subscriptions.\n * This bloom filter provides a fast O(k) pre-check: if the filter says \"definitely\n * not present\", we can skip the subscription entirely. If it says \"maybe present\",\n * we fall through to the precise collection/field matching.\n *\n * Uses FNV-1a for hashing and Kirsch-Mitzenmacker double hashing to derive k\n * hash functions from two base hashes.\n */\n\n// FNV-1a constants for 32-bit hashes\nconst FNV_OFFSET_BASIS = 0x811c9dc5\nconst FNV_PRIME = 0x01000193\n\n/**\n * Compute FNV-1a 32-bit hash of a string.\n *\n * FNV-1a is a non-cryptographic hash function optimized for speed and distribution.\n * It processes one byte at a time: XOR then multiply, which gives better avalanche\n * behavior than the original FNV-1 (multiply then XOR).\n *\n * @param input - The string to hash\n * @returns A 32-bit unsigned integer hash\n */\nexport function fnv1a32(input: string): number {\n\tlet hash = FNV_OFFSET_BASIS\n\tfor (let i = 0; i < input.length; i++) {\n\t\thash ^= input.charCodeAt(i)\n\t\t// Math.imul gives true 32-bit integer multiplication without overflow issues\n\t\thash = Math.imul(hash, FNV_PRIME)\n\t}\n\t// Ensure unsigned 32-bit result\n\treturn hash >>> 0\n}\n\n/**\n * Calculate the optimal number of bits for a bloom filter.\n *\n * Formula: m = -(n * ln(p)) / (ln(2)^2)\n * Rounded up to the nearest multiple of 32 for Uint32Array alignment.\n *\n * @param expectedItems - Expected number of items to insert\n * @param falsePositiveRate - Desired false positive rate (0-1)\n * @returns Number of bits, rounded to nearest 32-bit multiple (minimum 32)\n */\nexport function optimalBitCount(expectedItems: number, falsePositiveRate: number): number {\n\tif (expectedItems <= 0) return 32\n\tif (falsePositiveRate <= 0 || falsePositiveRate >= 1) return 32\n\n\tconst ln2Squared = Math.LN2 * Math.LN2\n\tconst rawBits = -(expectedItems * Math.log(falsePositiveRate)) / ln2Squared\n\n\t// Round up to nearest 32-bit multiple for Uint32Array alignment\n\tconst aligned = Math.ceil(rawBits / 32) * 32\n\treturn Math.max(32, aligned)\n}\n\n/**\n * Calculate the optimal number of hash functions for a bloom filter.\n *\n * Formula: k = (m/n) * ln(2)\n * Clamped to [1, 30] to avoid degenerate cases.\n *\n * @param bitCount - Total number of bits in the filter\n * @param expectedItems - Expected number of items to insert\n * @returns Number of hash functions, clamped to [1, 30]\n */\nexport function optimalHashCount(bitCount: number, expectedItems: number): number {\n\tif (expectedItems <= 0) return 1\n\tconst raw = (bitCount / expectedItems) * Math.LN2\n\treturn Math.max(1, Math.min(30, Math.round(raw)))\n}\n\n/**\n * Bloom filter for subscription dependency tracking.\n *\n * Each subscription adds its watched collection (and optionally fields) to the\n * filter. When a mutation arrives, we check \"collection\" and \"collection:field\"\n * keys against the filter. A negative result means no subscription cares about\n * this mutation, so we can skip the expensive per-subscription scan.\n *\n * @example\n * ```typescript\n * const filter = new SubscriptionBloomFilter(100, 0.01)\n * filter.add('todos')\n * filter.add('todos', 'completed')\n *\n * filter.mightContain('todos') // true (definitely added)\n * filter.mightContain('projects') // false (definitely not added)\n * filter.mightContain('todos', 'completed') // true (definitely added)\n * ```\n */\nexport class SubscriptionBloomFilter {\n\tprivate bits: Uint32Array\n\tprivate readonly bitCount: number\n\tprivate readonly hashCount: number\n\tprivate itemCount = 0\n\n\tconstructor(expectedItems: number, falsePositiveRate = 0.01) {\n\t\tthis.bitCount = optimalBitCount(expectedItems, falsePositiveRate)\n\t\tthis.hashCount = optimalHashCount(this.bitCount, expectedItems)\n\t\tthis.bits = new Uint32Array(this.bitCount / 32)\n\t}\n\n\t/**\n\t * Add a collection (and optional field) to the bloom filter.\n\t *\n\t * @param collection - Collection name (e.g., \"todos\")\n\t * @param field - Optional field name (e.g., \"completed\")\n\t */\n\tadd(collection: string, field?: string): void {\n\t\tconst key = field !== undefined ? `${collection}:${field}` : collection\n\t\tconst positions = this.getPositions(key)\n\t\tfor (const pos of positions) {\n\t\t\tconst wordIndex = pos >>> 5 // equivalent to Math.floor(pos / 32)\n\t\t\tconst bitIndex = pos & 31 // equivalent to pos % 32\n\t\t\tconst current = this.bits[wordIndex] ?? 0\n\t\t\tthis.bits[wordIndex] = current | (1 << bitIndex)\n\t\t}\n\t\tthis.itemCount++\n\t}\n\n\t/**\n\t * Check if a collection (and optional field) might be in the filter.\n\t *\n\t * A return value of `false` means the item is DEFINITELY NOT in the filter.\n\t * A return value of `true` means the item MIGHT be in the filter (possible false positive).\n\t *\n\t * @param collection - Collection name to check\n\t * @param field - Optional field name to check\n\t * @returns false = definitely absent, true = possibly present\n\t */\n\tmightContain(collection: string, field?: string): boolean {\n\t\tconst key = field !== undefined ? `${collection}:${field}` : collection\n\t\tconst positions = this.getPositions(key)\n\t\tfor (const pos of positions) {\n\t\t\tconst wordIndex = pos >>> 5\n\t\t\tconst bitIndex = pos & 31\n\t\t\tif (((this.bits[wordIndex] ?? 0) & (1 << bitIndex)) === 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\n\t/**\n\t * Reset the bloom filter, clearing all bits and the item count.\n\t */\n\tclear(): void {\n\t\tthis.bits.fill(0)\n\t\tthis.itemCount = 0\n\t}\n\n\t/**\n\t * Estimate the current false positive rate based on the number of items inserted.\n\t *\n\t * Formula: (1 - e^(-kn/m))^k\n\t * where k = hash count, n = item count, m = bit count.\n\t *\n\t * @returns Estimated false positive rate as a number between 0 and 1\n\t */\n\testimatedFalsePositiveRate(): number {\n\t\tif (this.itemCount === 0) return 0\n\t\tconst exponent = -(this.hashCount * this.itemCount) / this.bitCount\n\t\treturn (1 - Math.exp(exponent)) ** this.hashCount\n\t}\n\n\t/**\n\t * @returns The number of items that have been added to the filter\n\t */\n\tgetItemCount(): number {\n\t\treturn this.itemCount\n\t}\n\n\t/**\n\t * @returns The total number of bits in the filter\n\t */\n\tgetBitCount(): number {\n\t\treturn this.bitCount\n\t}\n\n\t/**\n\t * @returns The number of hash functions used\n\t */\n\tgetHashCount(): number {\n\t\treturn this.hashCount\n\t}\n\n\t/**\n\t * Count the number of bits currently set to 1.\n\t * Uses Brian Kernighan's algorithm: each iteration clears the lowest set bit,\n\t * so the loop runs exactly as many times as there are set bits.\n\t *\n\t * @returns Number of bits set to 1\n\t */\n\tgetSetBitCount(): number {\n\t\tlet count = 0\n\t\tfor (let i = 0; i < this.bits.length; i++) {\n\t\t\tlet word = this.bits[i] ?? 0\n\t\t\twhile (word !== 0) {\n\t\t\t\t// Clear the lowest set bit: n & (n - 1) removes the rightmost 1-bit\n\t\t\t\tword &= word - 1\n\t\t\t\tcount++\n\t\t\t}\n\t\t}\n\t\treturn count\n\t}\n\n\t/**\n\t * Compute k bit positions for a given key using Kirsch-Mitzenmacker double hashing.\n\t *\n\t * Instead of computing k independent hash functions, we compute two base hashes\n\t * (h1 and h2) and derive the rest as: h_i = (h1 + i * h2) mod m.\n\t * This technique is proven to have the same asymptotic false positive rate as\n\t * k independent hash functions.\n\t *\n\t * We derive h1 and h2 from a single FNV-1a hash by splitting and mixing:\n\t * h1 = fnv1a(key), h2 = fnv1a(key + \"\\0salt\") to ensure independence.\n\t */\n\tprivate getPositions(key: string): number[] {\n\t\tconst h1 = fnv1a32(key)\n\t\t// Use a null-byte separator + salt suffix to derive a second independent hash\n\t\tconst h2 = fnv1a32(`${key}\\0bloom`)\n\n\t\tconst positions = new Array<number>(this.hashCount)\n\t\tfor (let i = 0; i < this.hashCount; i++) {\n\t\t\t// Combine h1 and h2 with Kirsch-Mitzenmacker technique\n\t\t\tpositions[i] = ((h1 + Math.imul(i, h2)) >>> 0) % this.bitCount\n\t\t}\n\t\treturn positions\n\t}\n}\n","import type { Operation } from '@korajs/core'\nimport { QueryError } from '../errors'\nimport type {\n\tCollectionRecord,\n\tQueryDescriptor,\n\tQueryErrorPhase,\n\tQuerySubscriptionError,\n\tSubscribeOptions,\n\tSubscription,\n\tSubscriptionCallback,\n} from '../types'\nimport { SubscriptionBloomFilter } from './bloom-filter'\nimport { type ResultsEqual, defaultResultsEqual } from './result-equality'\n\n/**\n * Per-subscription options accepted by `register` / `registerAndFetch`.\n */\nexport interface RegisterOptions extends SubscribeOptions {\n\t/** Result-set comparator; defaults to structural comparison of every value. */\n\tresultsEqual?: ResultsEqual\n}\n\nlet nextSubId = 0\n\n/**\n * Default threshold for activating bloom filter-based dependency tracking.\n * Below this count, linear scanning is faster due to bloom filter rebuild overhead.\n */\nconst DEFAULT_BLOOM_THRESHOLD = 100\n\n/**\n * Default expected items for bloom filter sizing.\n * Sized to handle typical subscription dependency counts with headroom.\n */\nconst DEFAULT_BLOOM_EXPECTED_ITEMS = 500\n\n/**\n * Default false positive rate for bloom filter.\n * 1% provides a good balance between filter size and accuracy.\n */\nconst DEFAULT_BLOOM_FALSE_POSITIVE_RATE = 0.01\n\n/**\n * Configuration options for the SubscriptionManager.\n */\nexport interface SubscriptionManagerOptions {\n\t/**\n\t * Minimum number of subscriptions before activating bloom filter.\n\t * Below this threshold, linear scanning is used (bloom filter overhead not worth it).\n\t * @default 100\n\t */\n\tbloomThreshold?: number\n\n\t/**\n\t * Expected number of unique collection+field dependencies for bloom filter sizing.\n\t * @default 500\n\t */\n\tbloomExpectedItems?: number\n\n\t/**\n\t * Target false positive rate for the bloom filter.\n\t * Lower values require more memory but reduce unnecessary precise checks.\n\t * @default 0.01\n\t */\n\tbloomFalsePositiveRate?: number\n\n\t/** Called when a query subscription is registered (e.g. to register sync query subsets). */\n\tonQuerySubscribed?: (descriptor: QueryDescriptor) => () => void\n\n\t/**\n\t * Called for every subscription failure (the store emits `query:error`), in\n\t * addition to the subscriber's own `onError`.\n\t */\n\tonQueryError?: (failure: QuerySubscriptionError) => void\n}\n\n/**\n * A committed change to the rows of one collection that can affect query results\n * (RT-98). Every invalidation the store makes produces one: local writes and remote\n * applies (with the operation), and changes made without a new operation (rejection\n * re-folds, scope retraction, cascade settling, rematerialization, backup restore,\n * held/discarded writes).\n */\nexport interface RecordsChange {\n\t/** Collection whose rows changed */\n\treadonly collection: string\n\t/** Changed record ids, or null when unknown (treat the whole collection as changed) */\n\treadonly ids: readonly string[] | null\n\t/** The operation that caused the change, when there is one */\n\treadonly operation?: Operation\n}\n\n/** Listener for {@link RecordsChange}s made by this runtime (not those relayed from peers). */\nexport type RecordsChangeListener = (change: RecordsChange) => void\n\n/**\n * Performance statistics for monitoring subscription checking efficiency.\n */\nexport interface SubscriptionStats {\n\t/** Total number of mutation notifications processed */\n\ttotalChecks: number\n\t/** Number of times bloom filter said \"maybe\" (proceeded to precise check) */\n\tbloomFilterHits: number\n\t/** Number of times bloom filter said \"definitely not\" (skipped all subscriptions) */\n\tbloomFilterMisses: number\n\t/** Number of times bloom filter said \"maybe\" but precise check found no match */\n\tfalsePositives: number\n\t/** Average time per check in milliseconds */\n\taverageCheckTimeMs: number\n\t/** Whether bloom filter is currently active */\n\tbloomFilterActive: boolean\n\t/** Current subscription count */\n\tsubscriptionCount: number\n}\n\n/**\n * Manages reactive subscriptions with two-level dependency checking.\n *\n * When a mutation occurs on a collection, affected subscriptions are re-evaluated\n * in a microtask batch and callbacks are invoked only if results actually changed.\n *\n * For large subscription counts (>= bloomThreshold), a bloom filter provides O(k)\n * pre-filtering to avoid scanning all subscriptions on every mutation:\n *\n * Level 1 (Bloom filter): Fast O(k) check -- does this mutation potentially affect\n * any subscription? If NO: skip all subscriptions (guaranteed correct).\n * If MAYBE: proceed to Level 2.\n *\n * Level 2 (Precise check): Only evaluate subscriptions that match the mutated\n * collection, including included (related) collection tracking.\n */\nexport class SubscriptionManager {\n\tprivate subscriptions = new Map<string, Subscription>()\n\tprivate pendingCollections = new Set<string>()\n\tprivate flushScheduled = false\n\tprivate readonly onQuerySubscribed?: (descriptor: QueryDescriptor) => () => void\n\tprivate readonly onQueryError?: (failure: QuerySubscriptionError) => void\n\tprivate readonly changeListeners = new Set<RecordsChangeListener>()\n\t/**\n\t * Collections changed before the first change listener attached (a store's open:\n\t * rematerialization, migration backfills). Replayed to that listener, so other tabs\n\t * hear about changes made while this tab was still opening. Bounded by the schema.\n\t */\n\tprivate unheardCollections: Set<string> | null = new Set()\n\n\t// Bloom filter state\n\tprivate bloomFilter: SubscriptionBloomFilter | null = null\n\tprivate bloomDirty = false\n\tprivate readonly bloomThreshold: number\n\tprivate readonly bloomExpectedItems: number\n\tprivate readonly bloomFalsePositiveRate: number\n\n\t// Performance stats\n\tprivate totalChecks = 0\n\tprivate bloomFilterHits = 0\n\tprivate bloomFilterMisses = 0\n\tprivate falsePositives = 0\n\tprivate totalCheckTimeMs = 0\n\n\tconstructor(options?: SubscriptionManagerOptions) {\n\t\tthis.bloomThreshold = options?.bloomThreshold ?? DEFAULT_BLOOM_THRESHOLD\n\t\tthis.bloomExpectedItems = options?.bloomExpectedItems ?? DEFAULT_BLOOM_EXPECTED_ITEMS\n\t\tthis.bloomFalsePositiveRate =\n\t\t\toptions?.bloomFalsePositiveRate ?? DEFAULT_BLOOM_FALSE_POSITIVE_RATE\n\t\tthis.onQuerySubscribed = options?.onQuerySubscribed\n\t\tthis.onQueryError = options?.onQueryError\n\t}\n\n\t/**\n\t * Register a new subscription.\n\t *\n\t * @param descriptor - The query descriptor defining what this subscription watches\n\t * @param callback - Called with results whenever they change\n\t * @param executeFn - Function to re-execute the query and get current results\n\t * @returns An unsubscribe function\n\t */\n\tregister(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions?: RegisterOptions,\n\t): () => void {\n\t\t// No initial run: the empty baseline counts as delivered, so a flush only\n\t\t// notifies when the results differ from it.\n\t\tconst subscription = this.createSubscription(descriptor, callback, executeFn, options)\n\t\tsubscription.delivered = true\n\t\treturn this.track(subscription)\n\t}\n\n\t/**\n\t * Register a subscription and immediately execute the query.\n\t * The initial results are stored as lastResults so subsequent flushes\n\t * correctly diff against the initial state. A failing initial run is reported\n\t * through `options.onError` and the `query:error` hook, never as an unhandled\n\t * rejection (STORE-12).\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tregisterAndFetch(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions?: RegisterOptions,\n\t): () => void {\n\t\tconst subscription = this.createSubscription(descriptor, callback, executeFn, options)\n\t\tconst unsubscribe = this.track(subscription)\n\t\tvoid this.run(subscription)\n\t\treturn unsubscribe\n\t}\n\n\tprivate createSubscription(\n\t\tdescriptor: QueryDescriptor,\n\t\tcallback: SubscriptionCallback<CollectionRecord>,\n\t\texecuteFn: () => Promise<CollectionRecord[]>,\n\t\toptions: RegisterOptions | undefined,\n\t): Subscription {\n\t\treturn {\n\t\t\tid: `sub_${++nextSubId}`,\n\t\t\tdescriptor,\n\t\t\tcallback,\n\t\t\texecuteFn,\n\t\t\tlastResults: [],\n\t\t\tresultsEqual: options?.resultsEqual ?? defaultResultsEqual,\n\t\t\tonError: options?.onError,\n\t\t\trunsStarted: 0,\n\t\t\tlastAppliedRun: 0,\n\t\t\terrored: false,\n\t\t\tdelivered: false,\n\t\t}\n\t}\n\n\tprivate track(subscription: Subscription): () => void {\n\t\tconst id = subscription.id\n\t\tthis.subscriptions.set(id, subscription)\n\n\t\t// Mark bloom filter as needing rebuild since dependencies changed\n\t\tthis.bloomDirty = true\n\n\t\tconst externalCleanup = this.onQuerySubscribed?.(subscription.descriptor)\n\n\t\treturn () => {\n\t\t\tif (!this.subscriptions.delete(id)) return\n\t\t\tthis.bloomDirty = true\n\t\t\texternalCleanup?.()\n\t\t}\n\t}\n\n\t/**\n\t * Run a subscription's query and deliver the result when it changed. Never\n\t * throws: failures go to the error channel. Runs are numbered so a slow,\n\t * older run never overwrites the result of a newer one.\n\t */\n\tprivate async run(sub: Subscription): Promise<void> {\n\t\tconst runNumber = (sub.runsStarted ?? 0) + 1\n\t\tsub.runsStarted = runNumber\n\t\tlet results: CollectionRecord[]\n\t\ttry {\n\t\t\tresults = await sub.executeFn()\n\t\t} catch (error) {\n\t\t\tif (!this.isCurrent(sub, runNumber)) return\n\t\t\tsub.lastAppliedRun = runNumber\n\t\t\tsub.errored = true\n\t\t\tthis.reportError(sub, error, sub.delivered ? 'refresh' : 'initial')\n\t\t\treturn\n\t\t}\n\t\tif (!this.isCurrent(sub, runNumber)) return\n\t\tsub.lastAppliedRun = runNumber\n\n\t\t// After a failure, the next success is always delivered (even when equal to\n\t\t// the last results) so bindings can leave their error state.\n\t\tconst equal = sub.resultsEqual ?? defaultResultsEqual\n\t\tif (sub.delivered && !sub.errored && equal(sub.lastResults, results)) return\n\n\t\tsub.lastResults = results\n\t\tsub.delivered = true\n\t\tsub.errored = false\n\t\ttry {\n\t\t\tsub.callback(results)\n\t\t} catch (error) {\n\t\t\tthis.reportError(sub, error, 'callback')\n\t\t}\n\t}\n\n\tprivate isCurrent(sub: Subscription, runNumber: number): boolean {\n\t\treturn this.subscriptions.get(sub.id) === sub && runNumber > (sub.lastAppliedRun ?? 0)\n\t}\n\n\tprivate reportError(sub: Subscription, thrown: unknown, phase: QueryErrorPhase): void {\n\t\tconst error =\n\t\t\tthrown instanceof Error\n\t\t\t\t? thrown\n\t\t\t\t: new QueryError(`Query subscription failed: ${String(thrown)}`, {\n\t\t\t\t\t\tcollection: sub.descriptor.collection,\n\t\t\t\t\t})\n\t\tconst failure: QuerySubscriptionError = {\n\t\t\terror,\n\t\t\tphase,\n\t\t\tcollection: sub.descriptor.collection,\n\t\t\tqueryId: sub.id,\n\t\t}\n\t\ttry {\n\t\t\tthis.onQueryError?.(failure)\n\t\t} catch (hookError) {\n\t\t\tconsole.error('[kora] query:error listener threw', hookError)\n\t\t}\n\t\tif (sub.onError) {\n\t\t\ttry {\n\t\t\t\tsub.onError(failure)\n\t\t\t} catch (handlerError) {\n\t\t\t\tconsole.error('[kora] subscription onError handler threw', handlerError)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\t// No subscriber handler: log so the failure is never silent.\n\t\tconsole.error(\n\t\t\t`[kora] Query subscription ${sub.id} on \"${sub.descriptor.collection}\" failed (${phase}). Pass subscribe(cb, { onError }) to handle it.`,\n\t\t\terror,\n\t\t)\n\t}\n\n\t/**\n\t * Notify the manager that a mutation occurred on a collection.\n\t * Schedules a microtask flush to batch multiple mutations in the same tick.\n\t */\n\tnotify(collection: string, operation: Operation): void {\n\t\tthis.recordsChanged({ collection, ids: [operation.recordId], operation })\n\t}\n\n\t/**\n\t * Invalidate a collection after a local-view change that has no domain operation\n\t * (a re-fold, a retraction, a restore). Pass the record ids when known.\n\t */\n\tinvalidate(collection: string, ids: readonly string[] | null = null): void {\n\t\tthis.recordsChanged({ collection, ids })\n\t}\n\n\t/**\n\t * The single entry point for a committed change made by this runtime (RT-98): it\n\t * schedules the affected queries and tells every change listener (the cross-tab\n\t * bus), so no invalidation path can reach this tab's queries without reaching the\n\t * other tabs' too.\n\t */\n\trecordsChanged(change: RecordsChange): void {\n\t\tthis.pendingCollections.add(change.collection)\n\t\tthis.scheduleFlush()\n\t\tif (this.unheardCollections) this.unheardCollections.add(change.collection)\n\t\tfor (const listener of this.changeListeners) {\n\t\t\ttry {\n\t\t\t\tlistener(change)\n\t\t\t} catch (error) {\n\t\t\t\t// A failing listener must not stop this tab's queries or other listeners.\n\t\t\t\tconsole.error('[kora] records-change listener failed', error)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Invalidate a collection for a change another runtime made to the shared\n\t * database. Not relayed to change listeners (the peer already broadcast it).\n\t */\n\tinvalidateFromPeer(collection: string): void {\n\t\tthis.pendingCollections.add(collection)\n\t\tthis.scheduleFlush()\n\t}\n\n\t/**\n\t * Listen to every committed change this runtime makes.\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tonRecordsChanged(listener: RecordsChangeListener): () => void {\n\t\tthis.changeListeners.add(listener)\n\t\tconst unheard = this.unheardCollections\n\t\tthis.unheardCollections = null\n\t\tfor (const collection of unheard ?? []) {\n\t\t\ttry {\n\t\t\t\tlistener({ collection, ids: null })\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[kora] records-change listener failed', error)\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tthis.changeListeners.delete(listener)\n\t\t}\n\t}\n\n\t/**\n\t * Immediately flush all pending notifications.\n\t * Useful for testing. In production, flushing happens via microtask.\n\t */\n\tasync flush(): Promise<void> {\n\t\tif (this.pendingCollections.size === 0) return\n\n\t\tconst collections = new Set(this.pendingCollections)\n\t\tthis.pendingCollections.clear()\n\t\tthis.flushScheduled = false\n\n\t\tconst affected = this.findAffectedSubscriptions(collections)\n\n\t\t// Re-execute and diff. run() never throws: failures reach the error channel.\n\t\tfor (const sub of affected) {\n\t\t\tawait this.run(sub)\n\t\t}\n\t}\n\n\t/**\n\t * Remove all subscriptions. Called on store close.\n\t */\n\tclear(): void {\n\t\tthis.subscriptions.clear()\n\t\tthis.pendingCollections.clear()\n\t\tthis.flushScheduled = false\n\t\tthis.bloomFilter = null\n\t\tthis.bloomDirty = false\n\t\tthis.totalChecks = 0\n\t\tthis.bloomFilterHits = 0\n\t\tthis.bloomFilterMisses = 0\n\t\tthis.falsePositives = 0\n\t\tthis.totalCheckTimeMs = 0\n\t}\n\n\t/** Number of active subscriptions (for testing/debugging) */\n\tget size(): number {\n\t\treturn this.subscriptions.size\n\t}\n\n\t/**\n\t * Get performance statistics for monitoring subscription checking efficiency.\n\t * Useful for DevTools integration and performance tuning.\n\t */\n\tgetStats(): SubscriptionStats {\n\t\treturn {\n\t\t\ttotalChecks: this.totalChecks,\n\t\t\tbloomFilterHits: this.bloomFilterHits,\n\t\t\tbloomFilterMisses: this.bloomFilterMisses,\n\t\t\tfalsePositives: this.falsePositives,\n\t\t\taverageCheckTimeMs: this.totalChecks > 0 ? this.totalCheckTimeMs / this.totalChecks : 0,\n\t\t\tbloomFilterActive: this.isBloomActive(),\n\t\t\tsubscriptionCount: this.subscriptions.size,\n\t\t}\n\t}\n\n\t/**\n\t * Check if bloom filter is currently active.\n\t * Active when subscription count meets or exceeds the threshold.\n\t */\n\tisBloomActive(): boolean {\n\t\treturn this.subscriptions.size >= this.bloomThreshold\n\t}\n\n\t/**\n\t * Find subscriptions affected by mutations to the given collections.\n\t * Uses two-level checking when bloom filter is active:\n\t *\n\t * Level 1: Bloom filter pre-check -- if no subscription depends on any\n\t * of the mutated collections, skip everything (O(k) per collection).\n\t *\n\t * Level 2: Precise check -- linear scan of subscriptions, matching\n\t * against the mutated collections.\n\t */\n\tprivate findAffectedSubscriptions(collections: Set<string>): Subscription[] {\n\t\tconst startTime = performance.now()\n\t\tthis.totalChecks++\n\n\t\tconst useBloom = this.isBloomActive()\n\n\t\tif (useBloom) {\n\t\t\t// Rebuild bloom filter if dependencies have changed\n\t\t\tif (this.bloomDirty || this.bloomFilter === null) {\n\t\t\t\tthis.rebuildBloomFilter()\n\t\t\t}\n\n\t\t\tconst filter = this.bloomFilter\n\t\t\tif (filter !== null) {\n\t\t\t\t// Level 1: Bloom filter pre-check\n\t\t\t\tlet anyPossibleMatch = false\n\t\t\t\tfor (const col of collections) {\n\t\t\t\t\tif (filter.mightContain(col)) {\n\t\t\t\t\t\tanyPossibleMatch = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!anyPossibleMatch) {\n\t\t\t\t\t// Bloom filter guarantees no subscription depends on these collections\n\t\t\t\t\tthis.bloomFilterMisses++\n\t\t\t\t\tthis.totalCheckTimeMs += performance.now() - startTime\n\t\t\t\t\treturn []\n\t\t\t\t}\n\n\t\t\t\tthis.bloomFilterHits++\n\t\t\t}\n\t\t}\n\n\t\t// Level 2: Precise check (or only check when bloom is not active)\n\t\tconst affected: Subscription[] = []\n\t\tlet anyPreciseMatch = false\n\n\t\tfor (const sub of this.subscriptions.values()) {\n\t\t\tif (collections.has(sub.descriptor.collection)) {\n\t\t\t\taffected.push(sub)\n\t\t\t\tanyPreciseMatch = true\n\t\t\t} else if (sub.descriptor.includeCollections) {\n\t\t\t\t// Re-evaluate if a mutation affects an included (related) collection\n\t\t\t\tfor (const incCol of sub.descriptor.includeCollections) {\n\t\t\t\t\tif (collections.has(incCol)) {\n\t\t\t\t\t\taffected.push(sub)\n\t\t\t\t\t\tanyPreciseMatch = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Track false positives: bloom said \"maybe\" but precise check found nothing\n\t\tif (useBloom && !anyPreciseMatch) {\n\t\t\tthis.falsePositives++\n\t\t}\n\n\t\tthis.totalCheckTimeMs += performance.now() - startTime\n\t\treturn affected\n\t}\n\n\t/**\n\t * Rebuild the bloom filter from all current subscriptions.\n\t * Adds collection-level dependencies for every subscription, plus\n\t * any included collection dependencies.\n\t */\n\tprivate rebuildBloomFilter(): void {\n\t\tconst filter = new SubscriptionBloomFilter(this.bloomExpectedItems, this.bloomFalsePositiveRate)\n\n\t\tfor (const sub of this.subscriptions.values()) {\n\t\t\t// Add the primary collection dependency\n\t\t\tfilter.add(sub.descriptor.collection)\n\n\t\t\t// Add included (related) collection dependencies\n\t\t\tif (sub.descriptor.includeCollections) {\n\t\t\t\tfor (const incCol of sub.descriptor.includeCollections) {\n\t\t\t\t\tfilter.add(incCol)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.bloomFilter = filter\n\t\tthis.bloomDirty = false\n\t}\n\n\tprivate scheduleFlush(): void {\n\t\tif (this.flushScheduled) return\n\t\tthis.flushScheduled = true\n\t\tqueueMicrotask(() => {\n\t\t\t// flush() cannot reject: run() routes every failure to the error channel.\n\t\t\tvoid this.flush()\n\t\t})\n\t}\n}\n","import { HybridLogicalClock, MAX_LOGICAL, quoteIdent } from '@korajs/core'\nimport type { HLCTimestamp, Operation, SchemaDefinition } from '@korajs/core'\nimport { parseFieldVersions, serializeFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, RawCollectionRow, StorageAdapter } from '../types'\nimport { rehashOperation } from './rehash-operation'\n\n/**\n * Result of re-stamping unsynced operations after a clock correction.\n */\nexport interface ClockRebaseResult {\n\t/** The rewritten operations, in causal order (original HLC total order preserved). */\n\toperations: Operation[]\n\t/** Maps each old (pre-rebase) operation id to its new content-addressed id. */\n\tidMapping: Record<string, string>\n\t/** Number of operations that were re-stamped. */\n\trebasedCount: number\n\t/** Highest timestamp assigned during the rebase, or null when nothing was rebased. */\n\tnewMaxTimestamp: HLCTimestamp | null\n}\n\n/**\n * The serialized logical counter is zero-padded to 5 digits; a logical value\n * needing more digits would break the lexicographic ordering of the stored\n * timestamp / `_version` columns. Overflow spills into wallTime instead.\n * Derived from the clock's own cap so the two can never drift apart.\n */\nconst LOGICAL_COUNTER_LIMIT = MAX_LOGICAL + 1\n\nfunction emptyResult(): ClockRebaseResult {\n\treturn { operations: [], idMapping: {}, rebasedCount: 0, newMaxTimestamp: null }\n}\n\n/**\n * Re-stamp unsynced (never server-acknowledged) operations after a fast device\n * clock was corrected, so sync can resume immediately instead of waiting for\n * real time to catch up with the future timestamps.\n *\n * This is safe for exactly the same reason rewriting unpushed git commits is\n * safe: unacknowledged operations have never been shared, so no other replica\n * can hold a reference to their old ids or timestamps. Acknowledged operations\n * are immutable forever and are never touched here.\n *\n * The relative order of the rebased operations is preserved: they are sorted by\n * their original HLC total order and assigned consecutive logical counters on a\n * single new wall time, chosen to sort after every non-rebased operation in the\n * log (and after corrected \"now\").\n */\nexport async function rebaseUnsyncedOperationsInLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tunsyncedOpIds: string[],\n\tcorrectedNowMs: number,\n): Promise<ClockRebaseResult> {\n\tif (unsyncedOpIds.length === 0) {\n\t\treturn emptyResult()\n\t}\n\tconst rebaseIds = new Set(unsyncedOpIds)\n\n\t// Read phase. A single full scan per collection serves two purposes at once:\n\t// locating the rebased rows and finding the max timestamp of everything else.\n\t// This avoids SQL IN-list size limits and keeps the logic trivially correct\n\t// (correctness over performance; the op log is compacted periodically anyway).\n\tconst rebased: Operation[] = []\n\t// Serialized HLC strings sort lexicographically in the same order as\n\t// HybridLogicalClock.compare, so a plain string max is a timestamp max.\n\tlet maxOtherSerializedTs: string | null = null\n\n\tfor (const collectionName of Object.keys(schema.collections)) {\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)}`,\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tif (rebaseIds.has(row.id)) {\n\t\t\t\trebased.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t} else if (maxOtherSerializedTs === null || row.timestamp > maxOtherSerializedTs) {\n\t\t\t\tmaxOtherSerializedTs = row.timestamp\n\t\t\t}\n\t\t}\n\t}\n\n\tif (rebased.length === 0) {\n\t\treturn emptyResult()\n\t}\n\n\t// The new wall time must sort after both corrected real time and every\n\t// operation that stays in the log, or the rebased ops could lose LWW\n\t// conflicts they previously won locally (silent data reordering).\n\tconst maxOtherWallTime =\n\t\tmaxOtherSerializedTs === null\n\t\t\t? Number.NEGATIVE_INFINITY\n\t\t\t: HybridLogicalClock.deserialize(maxOtherSerializedTs).wallTime\n\tconst baseWallTime = Math.max(correctedNowMs, maxOtherWallTime + 1)\n\n\t// Preserve the ORIGINAL total order so causal relationships (dep before\n\t// dependent) survive the re-stamp.\n\trebased.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\tconst newTimestamps: HLCTimestamp[] = rebased.map((op, i) => ({\n\t\t// Spill into wallTime past the 5-digit logical serialization limit so the\n\t\t// serialized order stays correct even for enormous offline queues.\n\t\twallTime: baseWallTime + Math.floor(i / LOGICAL_COUNTER_LIMIT),\n\t\tlogical: i % LOGICAL_COUNTER_LIMIT,\n\t\tnodeId: op.nodeId,\n\t}))\n\n\t// Recompute content-addressed ids in the original (causal) order. A version-2 id\n\t// (protocol v2, CORE-1) covers causalDeps, so each dependency's new id must be known\n\t// before its dependents are hashed: deps among the rebased set are remapped first.\n\t// Deps on non-rebased (already acknowledged or foreign) operations keep their ids.\n\t// Each operation keeps its own hash version: a version-1 operation (written before\n\t// beta.13) is re-hashed with version 1. The deserialized `data` has the embedded\n\t// metadata keys already stripped, matching exactly what the creation path hashed.\n\tconst idMapping: Record<string, string> = {}\n\tconst newOperations: Operation[] = []\n\tfor (let i = 0; i < rebased.length; i++) {\n\t\tconst op = rebased[i]\n\t\tconst ts = newTimestamps[i]\n\t\tif (!op || !ts) {\n\t\t\tcontinue\n\t\t}\n\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\tconst newId = await rehashOperation({ ...op, timestamp: ts, causalDeps })\n\t\tidMapping[op.id] = newId\n\t\tnewOperations.push({ ...op, id: newId, timestamp: ts, causalDeps })\n\t}\n\n\t// Write phase: one transaction so a crash can never leave the log with a\n\t// mix of old and new stamps (which would corrupt causal deps).\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (let i = 0; i < rebased.length; i++) {\n\t\t\tconst oldOp = rebased[i]\n\t\t\tconst newOp = newOperations[i]\n\t\t\tif (!oldOp || !newOp) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst opsTable = `_kora_ops_${oldOp.collection}`\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(opsTable)} WHERE id = ?`, [oldOp.id])\n\t\t\tconst opInsert = buildInsertQuery(\n\t\t\t\topsTable,\n\t\t\t\tserializeOperation(newOp) as unknown as Record<string, unknown>,\n\t\t\t)\n\t\t\tawait tx.execute(opInsert.sql, opInsert.params)\n\n\t\t\t// Only touch materialized rows whose current version stamp came from\n\t\t\t// this exact operation — a row last written by a different (newer,\n\t\t\t// non-rebased) op must keep its version, or LWW guards would lie.\n\t\t\tconst oldVersion = serializeRowVersion(oldOp.timestamp)\n\t\t\tconst newVersion = serializeRowVersion(newOp.timestamp)\n\t\t\tawait tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _version = ?, _updated_at = ? WHERE id = ? AND _version = ?`,\n\t\t\t\t[newVersion, newOp.timestamp.wallTime, oldOp.recordId, oldVersion],\n\t\t\t)\n\n\t\t\t// Per-field versions stamped by this operation carry the same old (pre-\n\t\t\t// rebase) version string, so re-stamp them too — otherwise field-level\n\t\t\t// LWW would keep comparing against the uncorrected timestamp forever.\n\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t`SELECT _field_versions FROM ${quoteIdent(oldOp.collection)} WHERE id = ?`,\n\t\t\t\t[oldOp.recordId],\n\t\t\t)\n\t\t\tconst fieldVersions = parseFieldVersions(rows[0]?._field_versions)\n\t\t\tlet changed = false\n\t\t\tfor (const [field, version] of Object.entries(fieldVersions)) {\n\t\t\t\tif (version === oldVersion) {\n\t\t\t\t\tfieldVersions[field] = newVersion\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (changed) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,\n\t\t\t\t\t[serializeFieldVersions(fieldVersions), oldOp.recordId],\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// The insert op also stamped `_created_at` (the developer-visible\n\t\t\t// `createdAt`). Replicas materialize it from the rebased op's corrected\n\t\t\t// wallTime, so the originating device must re-stamp its own row too or\n\t\t\t// `createdAt` diverges forever after a clock rebase. Match on the old\n\t\t\t// (pre-rebase) created time so only rows this op created are touched.\n\t\t\tif (oldOp.type === 'insert') {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _created_at = ? WHERE id = ? AND _created_at = ?`,\n\t\t\t\t\t[newOp.timestamp.wallTime, oldOp.recordId, oldOp.timestamp.wallTime],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\t// sequenceNumbers are intentionally unchanged, so `_kora_version_vector`\n\t\t// needs no update: the version vector tracks sequences, not timestamps.\n\t})\n\n\tconst newMaxTimestamp = newTimestamps[newTimestamps.length - 1] ?? null\n\n\treturn {\n\t\toperations: newOperations,\n\t\tidMapping,\n\t\trebasedCount: newOperations.length,\n\t\tnewMaxTimestamp,\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport { parseFieldVersions, serializeFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, RawCollectionRow, StorageAdapter } from '../types'\nimport { rehashOperation } from './rehash-operation'\nimport { NODE_TOKEN_META_KEY } from './sync-state'\n\n/** Result of {@link rotateUnsyncedOperationsInLog}. */\nexport interface NodeRotationResult {\n\t/** The node id the device uses from now on. */\n\tnodeId: string\n\t/** The rewritten operations under the new node id, in their original causal order. */\n\toperations: Operation[]\n\t/** Maps each old operation id to its new content-addressed id. */\n\tidMapping: Record<string, string>\n}\n\n/**\n * Move a device's never-acknowledged operations to a fresh node id (RT-21).\n *\n * The server refused this device's node id (`NODE_ID_CLAIMED`: another device holds\n * it, typically because the node token issued at the first claim was lost). The\n * device keeps its data by re-authoring its unsynced operations under a new node id:\n * same type, record, data and HLC wall time / counter, but the new node id in both\n * `nodeId` and `timestamp.nodeId`, sequence numbers 1..n in the original order, and\n * recomputed content-addressed ids (causal deps among them remapped). This is safe\n * for the same reason a clock rebase is: unacknowledged operations were never\n * shared, so no replica holds their old ids.\n *\n * Materialized rows are re-stamped so per-field LWW keeps comparing against the\n * rewritten timestamps; the version vector gets the new node's sequence (MAX with the\n * stored value) and the old node's entry is never lowered (W6). Everything, the scan\n * of the rotated operations included, runs in one transaction.\n *\n * @param adapter - The store's adapter\n * @param schema - The store schema (collections to scan)\n * @param unsyncedOpIds - Ids of the old node's operations the server never acknowledged\n * @param oldNodeId - The refused node id\n * @param newNodeId - The fresh node id\n * @param options - `moveDatabaseNode: false` re-authors another local node's operations\n * without moving the database's own node id or node token (default true)\n */\nexport async function rotateUnsyncedOperationsInLog(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tunsyncedOpIds: string[],\n\toldNodeId: string,\n\tnewNodeId: string,\n\toptions: { moveDatabaseNode?: boolean } = {},\n): Promise<NodeRotationResult> {\n\tconst moveDatabaseNode = options.moveDatabaseNode !== false\n\tconst rotateIds = new Set(unsyncedOpIds)\n\tconst idMapping: Record<string, string> = {}\n\tconst rewritten: Operation[] = []\n\n\t// One transaction from the scan to the last write (W6): the rotated set is read in\n\t// the transaction that rewrites it, so nothing committed in between is missed.\n\tawait adapter.transaction(async (tx) => {\n\t\tconst rotated: Operation[] = []\n\t\tfor (const collectionName of Object.keys(schema.collections)) {\n\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} WHERE node_id = ?`,\n\t\t\t\t[oldNodeId],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (rotateIds.has(row.id)) {\n\t\t\t\t\trotated.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Original authoring order: sequence numbers are allocated in causal order.\n\t\trotated.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\n\t\tfor (let i = 0; i < rotated.length; i++) {\n\t\t\tconst op = rotated[i]\n\t\t\tif (!op) continue\n\t\t\tconst timestamp = { ...op.timestamp, nodeId: newNodeId }\n\t\t\t// Deps among the rotated set are remapped BEFORE hashing: a version-2 id covers\n\t\t\t// causalDeps, and sequence order is causal order, so every dep is already\n\t\t\t// mapped. Deps on acknowledged operations keep their ids.\n\t\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\t\tconst moved: Operation = {\n\t\t\t\t...op,\n\t\t\t\tnodeId: newNodeId,\n\t\t\t\ttimestamp,\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\tcausalDeps,\n\t\t\t}\n\t\t\tconst id = await rehashOperation(moved)\n\t\t\tidMapping[op.id] = id\n\t\t\trewritten.push({ ...moved, id })\n\t\t}\n\n\t\tfor (let i = 0; i < rotated.length; i++) {\n\t\t\tconst oldOp = rotated[i]\n\t\t\tconst newOp = rewritten[i]\n\t\t\tif (!oldOp || !newOp) continue\n\t\t\tconst opsTable = `_kora_ops_${oldOp.collection}`\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(opsTable)} WHERE id = ?`, [oldOp.id])\n\t\t\tconst insert = buildInsertQuery(\n\t\t\t\topsTable,\n\t\t\t\tserializeOperation(newOp) as unknown as Record<string, unknown>,\n\t\t\t)\n\t\t\tawait tx.execute(insert.sql, insert.params)\n\n\t\t\t// Re-stamp the row and field versions this operation wrote (the version\n\t\t\t// string carries the node id), exactly like a clock rebase.\n\t\t\tconst oldVersion = serializeRowVersion(oldOp.timestamp)\n\t\t\tconst newVersion = serializeRowVersion(newOp.timestamp)\n\t\t\tawait tx.execute(\n\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _version = ? WHERE id = ? AND _version = ?`,\n\t\t\t\t[newVersion, oldOp.recordId, oldVersion],\n\t\t\t)\n\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t`SELECT _field_versions FROM ${quoteIdent(oldOp.collection)} WHERE id = ?`,\n\t\t\t\t[oldOp.recordId],\n\t\t\t)\n\t\t\tconst fieldVersions = parseFieldVersions(rows[0]?._field_versions)\n\t\t\tlet changed = false\n\t\t\tfor (const [field, version] of Object.entries(fieldVersions)) {\n\t\t\t\tif (version === oldVersion) {\n\t\t\t\t\tfieldVersions[field] = newVersion\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (changed) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`UPDATE ${quoteIdent(oldOp.collection)} SET _field_versions = ? WHERE id = ?`,\n\t\t\t\t\t[serializeFieldVersions(fieldVersions), oldOp.recordId],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (moveDatabaseNode) {\n\t\t\tawait tx.execute(\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\", [\n\t\t\t\tnewNodeId,\n\t\t\t])\n\t\t\t// The node token belonged to the refused node id.\n\t\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [NODE_TOKEN_META_KEY])\n\t\t}\n\t\t// The new node's counter covers the rewritten operations: MAX with the stored\n\t\t// value, in this transaction, like every sequence reservation (W6).\n\t\tif (rewritten.length > 0) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[newNodeId, rewritten.length],\n\t\t\t)\n\t\t}\n\t\t// The old node's counter is left as it is, never lowered: a rotated operation\n\t\t// may have reached the server unacknowledged, and a writer still on the old id\n\t\t// (another tab) must not reuse its number for different content. The numbers the\n\t\t// rotated operations held become holes in the old node's log, which upload\n\t\t// tracking treats as resolved.\n\t})\n\n\treturn { nodeId: newNodeId, operations: rewritten, idMapping }\n}\n","import type {\n\tCausalTracker,\n\tCollectionDefinition,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport {\n\tKoraError,\n\tgenerateUUIDv7,\n\tisAtomicOp,\n\tquoteIdent,\n\tresolveAtomicOp,\n\tvalidateRecord,\n} from '@korajs/core'\nimport { RecordNotFoundError } from '../errors'\nimport type { RecordFolder } from '../fold/record-folder'\nimport { toAtRestWriteData } from '../mutations/secret-write'\nimport {\n\tCausalScope,\n\ttype LocalDeleteHook,\n\ttype WriteEnv,\n\twithWriteScope,\n} from '../mutations/write-context'\nimport {\n\ttype PreparedInsert,\n\ttype WriteResult,\n\tprepareInsert,\n\twriteDeleteInTx,\n\twriteInsertInTx,\n\twriteUpdateInTx,\n} from '../mutations/write-ops'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport { deserializeRecord, toRichtextReadShape } from '../serialization/serializer'\nimport { validateUpdateStateMachine } from '../state-machine/state-validator'\nimport type { CollectionRecord, RawCollectionRow, StorageAdapter } from '../types'\n\n/**\n * A buffered mutation. Buffered entries hold the developer's INTENT, not built\n * operations: they are written at commit, inside the commit's storage\n * transaction, through the same single local write path as single-record writes\n * (W6). That is what gives transaction writes in-transaction sequence\n * reservation, per-field version stamps, state-machine validation and atomic ops\n * resolved against the committed row.\n */\ntype BufferedEntry =\n\t| { readonly kind: 'insert'; readonly collection: string; readonly insert: PreparedInsert }\n\t| {\n\t\t\treadonly kind: 'update'\n\t\t\treadonly collection: string\n\t\t\treadonly id: string\n\t\t\t/** Schema-validated update data; may contain atomic op descriptors. */\n\t\t\treadonly data: Record<string, unknown>\n\t }\n\t| { readonly kind: 'delete'; readonly collection: string; readonly id: string }\n\n/**\n * Internal configuration for creating a TransactionContext.\n * Passed from Store to avoid exposing Store internals publicly.\n */\nexport interface TransactionContextConfig {\n\tschema: SchemaDefinition\n\tadapter: StorageAdapter\n\tclock: HybridLogicalClock\n\tnodeId: string\n\trelationEnforcer: RelationEnforcer | null\n\tcausalTracker: CausalTracker | null\n\t/**\n\t * Key provider for `t.secret()` encrypted fields. Transaction writes transform\n\t * secret fields through the same helper as single-record writes (STORE-4).\n\t */\n\tsecretKeyProvider?: SecretKeyProvider\n\t/** Referential hook run for every local delete inside the commit (see {@link LocalDeleteHook}). */\n\tbeforeLocalDelete?: LocalDeleteHook\n\t/** Called when the commit's storage transaction fails, before the error propagates. */\n\tonStorageError?: (error: unknown) => void\n\t/** The W7 record fold (see `WriteEnv.fold`). */\n\tfold?: RecordFolder\n\t/** See `WriteEnv.maxOperationBytes`. */\n\tmaxOperationBytes?: number\n\t/** See `WriteEnv.assertLocalWriteAllowed`. */\n\tassertLocalWriteAllowed?: () => void\n}\n\n/**\n * A collection accessor within a transaction.\n * Operations are buffered and committed atomically when the transaction completes.\n */\nexport interface TransactionCollectionAccessor {\n\tinsert(data: Record<string, unknown>): Promise<CollectionRecord>\n\tupdate(id: string, data: Record<string, unknown>): Promise<CollectionRecord>\n\tdelete(id: string): Promise<void>\n\tfindById(id: string): Promise<CollectionRecord | null>\n}\n\n/**\n * TransactionContext provides atomic multi-collection operations.\n *\n * Mutations are validated and buffered when called (so errors surface at the\n * call site and `insert` returns the new id immediately), then written in a\n * single `StorageAdapter.transaction()` at commit. All operations share the\n * same transactionId (UUID v7) and one contiguous block of sequence numbers.\n *\n * Subscription notifications are deferred until after commit.\n *\n * @example\n * ```typescript\n * const { operations, affectedCollections } = await txContext.commit()\n * // Notify subscriptions after commit\n * for (const op of operations) {\n * subscriptionManager.notify(op.collection, op)\n * }\n * ```\n */\nexport class TransactionContext {\n\tprivate readonly transactionId: string\n\tprivate mutationName: string | undefined\n\tprivate readonly buffer: BufferedEntry[] = []\n\tprivate committed = false\n\tprivate rolledBack = false\n\tprivate readonly config: TransactionContextConfig\n\n\tconstructor(config: TransactionContextConfig) {\n\t\tthis.config = config\n\t\tthis.transactionId = generateUUIDv7()\n\t}\n\n\t/**\n\t * Set a human-readable mutation name for this transaction.\n\t * Propagated to all operations for DevTools display.\n\t */\n\tsetMutationName(name: string): void {\n\t\tthis.mutationName = name\n\t}\n\n\t/**\n\t * Get the mutation name, if set.\n\t */\n\tgetMutationName(): string | undefined {\n\t\treturn this.mutationName\n\t}\n\n\t/**\n\t * Get a collection accessor for buffered operations within this transaction.\n\t */\n\tcollection(name: string): TransactionCollectionAccessor {\n\t\tconst definition = this.config.schema.collections[name]\n\t\tif (!definition) {\n\t\t\tthrow new KoraError(\n\t\t\t\t`Unknown collection \"${name}\". Available: ${Object.keys(this.config.schema.collections).join(', ')}`,\n\t\t\t\t'UNKNOWN_COLLECTION',\n\t\t\t\t{ collection: name },\n\t\t\t)\n\t\t}\n\n\t\treturn {\n\t\t\tinsert: (data: Record<string, unknown>) => this.insert(name, data),\n\t\t\tupdate: (id: string, data: Record<string, unknown>) =>\n\t\t\t\tthis.update(name, definition, id, data),\n\t\t\tdelete: (id: string) => this.deleteRecord(name, definition, id),\n\t\t\tfindById: (id: string) => this.getEffectiveRecord(name, definition, id),\n\t\t}\n\t}\n\n\t/**\n\t * Commit all buffered mutations atomically.\n\t *\n\t * Every entry is written, in call order, inside ONE storage transaction through\n\t * the single local write path: sequence numbers are reserved inside the\n\t * transaction (one contiguous block covering referential side effects too) and\n\t * each operation is built only after its number is reserved.\n\t *\n\t * Returns the list of operations and affected collections for subscription notification.\n\t */\n\tasync commit(): Promise<{ operations: Operation[]; affectedCollections: Set<string> }> {\n\t\tif (this.committed) {\n\t\t\tthrow new KoraError('Transaction already committed.', 'TRANSACTION_COMMITTED', {\n\t\t\t\ttransactionId: this.transactionId,\n\t\t\t})\n\t\t}\n\t\tif (this.rolledBack) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Transaction was rolled back and cannot be committed.',\n\t\t\t\t'TRANSACTION_ROLLED_BACK',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\n\t\tthis.committed = true\n\n\t\tif (this.buffer.length === 0) {\n\t\t\treturn { operations: [], affectedCollections: new Set() }\n\t\t}\n\n\t\tconst env = this.writeEnv()\n\t\tconst causal = new CausalScope(this.config.causalTracker, true)\n\t\tconst operations: Operation[] = []\n\n\t\ttry {\n\t\t\tawait this.config.adapter.transaction(async (tx) => {\n\t\t\t\tawait withWriteScope(tx, env.nodeId, causal, async (scope) => {\n\t\t\t\t\tfor (const entry of this.buffer) {\n\t\t\t\t\t\tlet result: WriteResult\n\t\t\t\t\t\tswitch (entry.kind) {\n\t\t\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\t\t\tresult = await writeInsertInTx(env, scope, entry.insert)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\tcase 'update':\n\t\t\t\t\t\t\t\tresult = await writeUpdateInTx(env, scope, entry.collection, entry.id, entry.data)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\t\t\tresult = await writeDeleteInTx(env, scope, entry.collection, entry.id)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (result.operation) operations.push(result.operation)\n\t\t\t\t\t\toperations.push(...result.sideEffects)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.config.onStorageError?.(error)\n\t\t\tthrow error\n\t\t}\n\n\t\tcausal.publish()\n\t\tconst affectedCollections = new Set(operations.map((op) => op.collection))\n\t\treturn { operations, affectedCollections }\n\t}\n\n\t/**\n\t * Mark the transaction as rolled back. No operations will be committed.\n\t */\n\trollback(): void {\n\t\tthis.rolledBack = true\n\t\tthis.buffer.length = 0\n\t}\n\n\t/**\n\t * Get the transaction ID shared by all operations in this transaction.\n\t */\n\tgetTransactionId(): string {\n\t\treturn this.transactionId\n\t}\n\n\tprivate writeEnv(): WriteEnv {\n\t\treturn {\n\t\t\tschema: this.config.schema,\n\t\t\tclock: this.config.clock,\n\t\t\tnodeId: this.config.nodeId,\n\t\t\trelationEnforcer: this.config.relationEnforcer,\n\t\t\ttransactionId: this.transactionId,\n\t\t\t...(this.config.secretKeyProvider\n\t\t\t\t? { secretKeyProvider: this.config.secretKeyProvider }\n\t\t\t\t: {}),\n\t\t\t...(this.mutationName !== undefined ? { mutationName: this.mutationName } : {}),\n\t\t\t...(this.config.beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: this.config.beforeLocalDelete }\n\t\t\t\t: {}),\n\t\t\t...(this.config.fold ? { fold: this.config.fold } : {}),\n\t\t\t...(this.config.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.config.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t\t...(this.config.assertLocalWriteAllowed\n\t\t\t\t? { assertLocalWriteAllowed: this.config.assertLocalWriteAllowed }\n\t\t\t\t: {}),\n\t\t}\n\t}\n\n\tprivate ensureActive(): void {\n\t\tif (this.committed) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Cannot perform operations on a committed transaction.',\n\t\t\t\t'TRANSACTION_COMMITTED',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\t\tif (this.rolledBack) {\n\t\t\tthrow new KoraError(\n\t\t\t\t'Cannot perform operations on a rolled-back transaction.',\n\t\t\t\t'TRANSACTION_ROLLED_BACK',\n\t\t\t\t{ transactionId: this.transactionId },\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate async insert(\n\t\tcollectionName: string,\n\t\tdata: Record<string, unknown>,\n\t): Promise<CollectionRecord> {\n\t\tthis.ensureActive()\n\t\tconst insert = await prepareInsert(this.writeEnv(), collectionName, data)\n\t\tthis.buffer.push({ kind: 'insert', collection: collectionName, insert })\n\t\tconst now = Date.now()\n\t\t// The returned record carries the at-rest form (secrets hashed/encrypted) and the\n\t\t// read form of richtext (bytes), exactly like a single-record insert.\n\t\tconst fields = this.config.schema.collections[collectionName]?.fields ?? {}\n\t\treturn {\n\t\t\tid: insert.recordId,\n\t\t\t...toRichtextReadShape(insert.data, fields),\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t}\n\t}\n\n\tprivate async update(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t\tdata: Record<string, unknown>,\n\t): Promise<CollectionRecord> {\n\t\tthis.ensureActive()\n\n\t\tconst currentRecord = await this.getEffectiveRecord(collectionName, definition, id)\n\t\tif (!currentRecord) {\n\t\t\tthrow new RecordNotFoundError(collectionName, id)\n\t\t}\n\n\t\tconst validated = validateRecord(collectionName, definition, data, 'update')\n\t\t// Early check so an invalid transition fails at the call site. The commit\n\t\t// re-validates against the row read inside the write transaction, which is\n\t\t// authoritative.\n\t\tconst allowed = validateUpdateStateMachine(\n\t\t\tcollectionName,\n\t\t\tid,\n\t\t\tdefinition,\n\t\t\tcurrentRecord,\n\t\t\tvalidated,\n\t\t)\n\t\tthis.buffer.push({ kind: 'update', collection: collectionName, id, data: validated })\n\n\t\tconst preview = await this.previewUpdate(definition, currentRecord, allowed)\n\t\treturn { ...currentRecord, ...preview, updatedAt: Date.now() } as CollectionRecord\n\t}\n\n\tprivate async deleteRecord(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t): Promise<void> {\n\t\tthis.ensureActive()\n\n\t\tconst currentRecord = await this.getEffectiveRecord(collectionName, definition, id)\n\t\tif (!currentRecord) {\n\t\t\tthrow new RecordNotFoundError(collectionName, id)\n\t\t}\n\t\tthis.buffer.push({ kind: 'delete', collection: collectionName, id })\n\t}\n\n\t/**\n\t * The values an update will write, resolved against `current` (the effective\n\t * record) for read-your-writes inside the transaction. Secret fields are shown\n\t * in their at-rest form, like the record a committed update returns.\n\t */\n\tprivate async previewUpdate(\n\t\tdefinition: CollectionDefinition,\n\t\tcurrent: CollectionRecord,\n\t\tdata: Record<string, unknown>,\n\t): Promise<Record<string, unknown>> {\n\t\tconst resolved: Record<string, unknown> = {}\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tresolved[key] = isAtomicOp(value) ? resolveAtomicOp(current[key], value) : value\n\t\t}\n\t\tconst atRest = await toAtRestWriteData(resolved, definition, this.config.secretKeyProvider)\n\t\treturn toRichtextReadShape(atRest, definition.fields)\n\t}\n\n\t/**\n\t * The effective state of a record: the committed row overlaid with this\n\t * transaction's buffered mutations, in call order.\n\t */\n\tprivate async getEffectiveRecord(\n\t\tcollectionName: string,\n\t\tdefinition: CollectionDefinition,\n\t\tid: string,\n\t): Promise<CollectionRecord | null> {\n\t\tconst rows = await this.config.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(collectionName)} WHERE id = ? AND _deleted = 0`,\n\t\t\t[id],\n\t\t)\n\t\tlet record: CollectionRecord | null = rows[0]\n\t\t\t? deserializeRecord(rows[0], definition.fields)\n\t\t\t: null\n\n\t\tfor (const entry of this.buffer) {\n\t\t\tif (entry.collection !== collectionName) continue\n\t\t\tif (entry.kind === 'insert') {\n\t\t\t\tif (entry.insert.recordId !== id) continue\n\t\t\t\tconst now = Date.now()\n\t\t\t\trecord = {\n\t\t\t\t\tid,\n\t\t\t\t\t...toRichtextReadShape(entry.insert.data, definition.fields),\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t}\n\t\t\t} else if (entry.id === id && entry.kind === 'update') {\n\t\t\t\tif (record) {\n\t\t\t\t\tlet allowed: Record<string, unknown>\n\t\t\t\t\ttry {\n\t\t\t\t\t\tallowed = validateUpdateStateMachine(collectionName, id, definition, record, entry.data)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Already reported to the caller when the update was buffered.\n\t\t\t\t\t\tallowed = {}\n\t\t\t\t\t}\n\t\t\t\t\tconst preview = await this.previewUpdate(definition, record, allowed)\n\t\t\t\t\trecord = { ...record, ...preview, updatedAt: Date.now() }\n\t\t\t\t}\n\t\t\t} else if (entry.id === id) {\n\t\t\t\trecord = null\n\t\t\t}\n\t\t}\n\n\t\treturn record\n\t}\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { collectionIndexName, legacyCollectionIndexName } from '@korajs/core/internal'\nimport type { StorageAdapter } from '../types'\n\n/**\n * Retire indexes created under the pre-beta.13 naming scheme (STORE-15).\n *\n * `idx_<collection>_<field>` collided across collections (`a_b`.`c` and\n * `a`.`b_c`), so one of the two indexes was silently never created. The schema\n * DDL now creates collision-free names ({@link collectionIndexName}); this pass\n * drops each legacy index that sits on the table and column it was named for,\n * once its replacement exists. A legacy name that belongs to another table is\n * left to that table's own pass, so nothing a collection still needs is dropped.\n *\n * SQLite cannot rename an index; drop-and-recreate is the rename.\n *\n * @param adapter - The opened adapter (schema DDL already applied)\n * @param schema - The schema whose collections are checked\n */\nexport async function dropLegacyIndexes(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<void> {\n\tconst indexed = new Map<string, Set<string>>()\n\tfor (const [name, definition] of Object.entries(schema.collections)) {\n\t\tindexed.set(name, new Set(definition.indexes))\n\t}\n\tfor (const relation of Object.values(schema.relations)) {\n\t\tindexed.get(relation.from)?.add(relation.field)\n\t}\n\n\tconst existing = await adapter.query<{ name: string; tbl_name: string }>(\n\t\t\"SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' AND name LIKE 'idx_%'\",\n\t)\n\tconst byName = new Map(existing.map((row) => [row.name, row.tbl_name]))\n\n\tfor (const [collection, fields] of indexed) {\n\t\tfor (const field of fields) {\n\t\t\tconst legacy = legacyCollectionIndexName(collection, field)\n\t\t\tconst current = collectionIndexName(collection, field)\n\t\t\tif (legacy === current) continue\n\t\t\tif (byName.get(legacy) !== collection) continue\n\t\t\tif (byName.get(current) !== collection) continue\n\t\t\tconst columns = await adapter.query<{ name: string }>(\n\t\t\t\t`SELECT name FROM pragma_index_info(${sqlString(legacy)})`,\n\t\t\t)\n\t\t\tif (columns.length !== 1 || columns[0]?.name !== field) continue\n\t\t\tawait adapter.execute(`DROP INDEX IF EXISTS ${quoteIdent(legacy)}`)\n\t\t}\n\t}\n}\n\nfunction sqlString(value: string): string {\n\treturn `'${value.replace(/'/g, \"''\")}'`\n}\n","/**\n * Web Locks per local node id (RT-40). Under per-tab isolation every tab writes under\n * its own node id into one shared database; a live tab holds its node's lock for its\n * lifetime, so another tab can tell a closed tab's node (lock free: adopt its unsynced\n * writes) from a live one (lock held: leave it alone). An adopter holds the lock while\n * it uploads, so two tabs never adopt the same node at once.\n *\n * Without the Web Locks API (Node, workers without it) every node is reported free and\n * acquisition is a no-op: there is no other tab to coordinate with.\n */\n\ninterface LockLike {\n\tname?: string\n}\n\ninterface LockManagerLike {\n\trequest(\n\t\tname: string,\n\t\toptions: { mode?: 'exclusive' | 'shared'; ifAvailable?: boolean },\n\t\tcallback: (lock: LockLike | null) => Promise<void> | void,\n\t): Promise<unknown>\n\tquery?(): Promise<{ held?: LockLike[] }>\n}\n\nfunction lockManager(): LockManagerLike | null {\n\tconst nav = (globalThis as { navigator?: { locks?: LockManagerLike } }).navigator\n\treturn nav?.locks && typeof nav.locks.request === 'function' ? nav.locks : null\n}\n\n/** Lock name of a node id in a database. */\nexport function nodeLockName(dbName: string, nodeId: string): string {\n\treturn `kora-node:${dbName}:${nodeId}`\n}\n\n/**\n * Hold a node's lock until the returned function is called. Acquisition is\n * asynchronous (it waits while an adopter holds the lock); the caller never waits.\n */\nexport function acquireNodeLock(name: string): () => void {\n\tconst locks = lockManager()\n\tif (!locks) return () => {}\n\tlet release: () => void = () => {}\n\tlet released = false\n\tconst held = new Promise<void>((resolve) => {\n\t\trelease = () => {\n\t\t\treleased = true\n\t\t\tresolve()\n\t\t}\n\t})\n\tlocks\n\t\t.request(name, { mode: 'exclusive' }, async () => {\n\t\t\tif (released) return\n\t\t\tawait held\n\t\t})\n\t\t.catch(() => {\n\t\t\t// A lock that cannot be taken only weakens the liveness hint; never fatal.\n\t\t})\n\treturn () => release()\n}\n\n/**\n * Take a node's lock only when it is free. Resolves to a release function, or null\n * when another context (a live tab, another adopter) holds it.\n */\nexport function tryAcquireNodeLock(name: string): Promise<(() => void) | null> {\n\tconst locks = lockManager()\n\tif (!locks) return Promise.resolve(() => {})\n\treturn new Promise((resolveResult) => {\n\t\tlet release: () => void = () => {}\n\t\tconst held = new Promise<void>((resolve) => {\n\t\t\trelease = resolve\n\t\t})\n\t\tlocks\n\t\t\t.request(name, { mode: 'exclusive', ifAvailable: true }, async (lock) => {\n\t\t\t\tif (!lock) {\n\t\t\t\t\tresolveResult(null)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tresolveResult(() => release())\n\t\t\t\tawait held\n\t\t\t})\n\t\t\t.catch(() => resolveResult(null))\n\t})\n}\n\n/** Whether some context holds a node's lock. */\nexport async function isNodeLockHeld(name: string): Promise<boolean> {\n\tconst locks = lockManager()\n\tif (!locks?.query) return false\n\ttry {\n\t\tconst snapshot = await locks.query()\n\t\treturn (snapshot.held ?? []).some((lock) => lock.name === name)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import type { SchemaDefinition } from '@korajs/core'\nimport {\n\ttype SqliteQueryFn,\n\treadSqliteTableCatalog,\n\tsqliteConstraintRelaxationStatements,\n} from '@korajs/core/internal'\nimport type { StorageAdapter } from '../types'\n\n/**\n * One-time migration (RT-101): rebuild collection tables that still carry value-domain\n * constraints (an enum `CHECK`, `NOT NULL` on a schema field) created by beta.12 and\n * earlier DDL. Validation is the single authority for the value domain; a table\n * constraint cannot evolve with the schema, so it refused enum values added later and\n * nulls of fields made optional.\n *\n * Every table is rebuilt in ONE transaction (all or nothing), preserving rows, columns,\n * defaults, keys, indexes and triggers. Foreign key enforcement is switched off around\n * it when the database enforces foreign keys, as SQLite's table-rebuild procedure\n * requires. Idempotent: a relaxed table is left alone, so later opens do nothing;\n * resumable: an interrupted rebuild rolls back and runs again at the next open.\n *\n * Works for every client adapter (better-sqlite3, SQLite WASM/OPFS, and the IndexedDB\n * adapter, which runs SQLite in memory): they all store in SQLite.\n *\n * @param adapter - The opened adapter (schema DDL already applied)\n * @param schema - The schema whose collection tables are checked\n * @returns The collections whose tables were rebuilt\n */\nexport async function relaxValueDomainConstraints(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<string[]> {\n\tconst collections = Object.keys(schema.collections)\n\t// Only enum checks on the schema's enum fields are Kora's; any other CHECK was added\n\t// by hand and is kept through the rebuild, and never triggers one (RT-111).\n\tconst enumColumns = (collection: string): string[] =>\n\t\tObject.entries(schema.collections[collection]?.fields ?? {})\n\t\t\t.filter(([, descriptor]) => descriptor.kind === 'enum')\n\t\t\t.map(([field]) => field)\n\tconst viaAdapter: SqliteQueryFn = (sql) => adapter.query<Record<string, unknown>>(sql)\n\tconst pending: string[] = []\n\tfor (const collection of collections) {\n\t\tconst catalog = await readSqliteTableCatalog(viaAdapter, collection)\n\t\tif (\n\t\t\tcatalog &&\n\t\t\tsqliteConstraintRelaxationStatements(catalog, enumColumns(collection)).length > 0\n\t\t) {\n\t\t\tpending.push(collection)\n\t\t}\n\t}\n\tif (pending.length === 0) return []\n\n\tconst enforced = await adapter.query<{ foreign_keys: number }>('PRAGMA foreign_keys')\n\tconst foreignKeysOn = Number(enforced[0]?.foreign_keys) === 1\n\tif (foreignKeysOn) await adapter.execute('PRAGMA foreign_keys = OFF')\n\tconst rebuilt: string[] = []\n\ttry {\n\t\tawait adapter.transaction(async (tx) => {\n\t\t\tconst viaTx: SqliteQueryFn = (sql) => tx.query<Record<string, unknown>>(sql)\n\t\t\t// Re-read inside the transaction: another tab may have relaxed a table already.\n\t\t\tfor (const collection of pending) {\n\t\t\t\tconst catalog = await readSqliteTableCatalog(viaTx, collection)\n\t\t\t\tif (!catalog) continue\n\t\t\t\tconst statements = sqliteConstraintRelaxationStatements(catalog, enumColumns(collection))\n\t\t\t\tif (statements.length === 0) continue\n\t\t\t\tfor (const sql of statements) await tx.execute(sql)\n\t\t\t\trebuilt.push(collection)\n\t\t\t}\n\t\t})\n\t} finally {\n\t\tif (foreignKeysOn) await adapter.execute('PRAGMA foreign_keys = ON')\n\t}\n\treturn rebuilt\n}\n","import { generateUUIDv7 } from '@korajs/core'\n\nexport type StoreIsolation = 'shared' | 'per-tab'\n\nfunction perTabStorageKey(dbName: string): string {\n\treturn `kora-tab-node-${dbName}`\n}\n\n/**\n * Load a per-tab node id from sessionStorage (browser only).\n */\nexport function loadPerTabNodeId(dbName: string): string | null {\n\tif (typeof sessionStorage === 'undefined') {\n\t\treturn null\n\t}\n\treturn sessionStorage.getItem(perTabStorageKey(dbName))\n}\n\n/**\n * Persist a per-tab node id for this browser tab.\n */\nexport function savePerTabNodeId(dbName: string, nodeId: string): void {\n\tif (typeof sessionStorage === 'undefined') {\n\t\treturn\n\t}\n\tsessionStorage.setItem(perTabStorageKey(dbName), nodeId)\n}\n\n/**\n * Resolve or create a node id for `per-tab` isolation.\n */\nexport function resolvePerTabNodeId(dbName: string): string {\n\tconst existing = loadPerTabNodeId(dbName)\n\t// Never adopt an id in Kora's reserved `kora:` namespace (RT-61).\n\tif (existing && !existing.startsWith('kora:')) {\n\t\treturn existing\n\t}\n\tconst nodeId = generateUUIDv7()\n\tsavePerTabNodeId(dbName, nodeId)\n\treturn nodeId\n}\n","const WIRE_BYTES_KEY = '__kora_bytes__'\n\n/**\n * JSON.stringify replacer that preserves binary field values (e.g. richtext).\n */\nexport function auditJsonReplacer(_key: string, value: unknown): unknown {\n\tif (value instanceof Uint8Array) {\n\t\tlet binary = ''\n\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\tbinary += String.fromCharCode(value[i] as number)\n\t\t}\n\t\treturn { [WIRE_BYTES_KEY]: btoa(binary) }\n\t}\n\treturn value\n}\n\n/**\n * JSON.parse reviver that restores binary field values.\n */\nexport function auditJsonReviver(_key: string, value: unknown): unknown {\n\tif (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\tWIRE_BYTES_KEY in value &&\n\t\ttypeof (value as Record<string, unknown>)[WIRE_BYTES_KEY] === 'string'\n\t) {\n\t\tconst encoded = (value as Record<string, unknown>)[WIRE_BYTES_KEY]\n\t\tif (typeof encoded !== 'string') {\n\t\t\treturn value\n\t\t}\n\t\tconst binary = atob(encoded)\n\t\tconst bytes = new Uint8Array(binary.length)\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tbytes[i] = binary.charCodeAt(i)\n\t\t}\n\t\treturn bytes\n\t}\n\treturn value\n}\n\n/**\n * Serialize a value for durable audit storage or export.\n */\nexport function serializeAuditJson(value: unknown): string {\n\treturn JSON.stringify(value, auditJsonReplacer)\n}\n\n/**\n * Deserialize audit JSON back to typed values.\n */\nexport function deserializeAuditJson<T>(json: string): T {\n\treturn JSON.parse(json, auditJsonReviver) as T\n}\n","import { generateUUIDv7 } from '@korajs/core'\nimport type { KoraEvent, MergeTrace } from '@korajs/core'\nimport type { StorageAdapter } from '../types'\nimport { deserializeAuditJson, serializeAuditJson } from './audit-json'\nimport type { AuditTraceQuery, PersistedAuditTrace } from './types'\n\ninterface AuditTraceRow {\n\tid: string\n\trecorded_at: number\n\tevent_type: string\n\tcollection: string\n\trecord_id: string\n\tfield: string\n\tstrategy: string\n\ttier: number\n\tconstraint_name: string | null\n\ttrace_json: string\n}\n\n/**\n * Build a {@link PersistedAuditTrace} from a merge-related Kora event.\n */\nexport function persistedAuditTraceFromEvent(\n\tevent: Extract<KoraEvent, { type: 'merge:completed' | 'merge:conflict' | 'constraint:violated' }>,\n): PersistedAuditTrace {\n\treturn {\n\t\tid: generateUUIDv7(),\n\t\trecordedAt: Date.now(),\n\t\teventType: event.type,\n\t\tconstraint: event.type === 'constraint:violated' ? event.constraint : undefined,\n\t\ttrace: event.trace,\n\t}\n}\n\n/**\n * Append a merge trace to the durable audit log.\n */\nexport async function appendAuditTrace(\n\tadapter: StorageAdapter,\n\ttrace: PersistedAuditTrace,\n): Promise<void> {\n\tconst collection = trace.trace.operationA.collection\n\tconst recordId = trace.trace.operationA.recordId\n\n\tawait adapter.execute(\n\t\t`INSERT INTO _kora_audit_traces (\n\t\t\tid, recorded_at, event_type, collection, record_id, field, strategy, tier, constraint_name, trace_json\n\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\ttrace.id,\n\t\t\ttrace.recordedAt,\n\t\t\ttrace.eventType,\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t\ttrace.trace.field,\n\t\t\ttrace.trace.strategy,\n\t\t\ttrace.trace.tier,\n\t\t\ttrace.constraint ?? null,\n\t\t\tserializeAuditJson(trace),\n\t\t],\n\t)\n}\n\n/**\n * Load persisted audit traces with optional filters.\n */\nexport async function readAuditTraces(\n\tadapter: StorageAdapter,\n\tquery?: AuditTraceQuery,\n): Promise<PersistedAuditTrace[]> {\n\tconst conditions: string[] = []\n\tconst params: unknown[] = []\n\n\tif (query?.collections && query.collections.length > 0) {\n\t\tconst placeholders = query.collections.map(() => '?').join(', ')\n\t\tconditions.push(`collection IN (${placeholders})`)\n\t\tparams.push(...query.collections)\n\t}\n\tif (query?.since !== undefined) {\n\t\tconditions.push('recorded_at >= ?')\n\t\tparams.push(query.since)\n\t}\n\tif (query?.until !== undefined) {\n\t\tconditions.push('recorded_at <= ?')\n\t\tparams.push(query.until)\n\t}\n\n\tconst whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''\n\tconst rows = await adapter.query<AuditTraceRow>(\n\t\t`SELECT * FROM _kora_audit_traces ${whereClause} ORDER BY recorded_at ASC, id ASC`,\n\t\tparams,\n\t)\n\n\treturn rows.map(rowToPersistedTrace)\n}\n\nfunction rowToPersistedTrace(row: AuditTraceRow): PersistedAuditTrace {\n\treturn deserializeAuditJson<PersistedAuditTrace>(row.trace_json)\n}\n\n/**\n * Count persisted audit traces (for diagnostics).\n */\nexport async function countAuditTraces(adapter: StorageAdapter): Promise<number> {\n\tconst rows = await adapter.query<{ count: number }>(\n\t\t'SELECT COUNT(*) as count FROM _kora_audit_traces',\n\t)\n\treturn rows[0]?.count ?? 0\n}\n\n/**\n * Extract collection and record id from a merge trace for indexing.\n */\nexport function auditTraceIndexFields(trace: MergeTrace): {\n\tcollection: string\n\trecordId: string\n} {\n\treturn {\n\t\tcollection: trace.operationA.collection,\n\t\trecordId: trace.operationA.recordId,\n\t}\n}\n","import type { Operation, SchemaDefinition } from '@korajs/core'\nimport { quoteIdent } from '@korajs/core'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport type { StorageAdapter } from '../types'\nimport type { OperationRow } from '../types'\nimport { deserializeAuditJson, serializeAuditJson } from './audit-json'\nimport { readAuditTraces } from './audit-trace-store'\nimport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './types'\n\nfunction encodeSection(name: string, content: Uint8Array): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(name)\n\tconst header = new Uint8Array(8)\n\tconst view = new DataView(header.buffer)\n\tview.setUint32(0, nameBytes.length, true)\n\tview.setUint32(4, content.length, true)\n\n\tconst result = new Uint8Array(header.length + nameBytes.length + content.length)\n\tresult.set(header, 0)\n\tresult.set(nameBytes, 8)\n\tresult.set(content, 8 + nameBytes.length)\n\treturn result\n}\n\nfunction encodeJsonSection(name: string, data: unknown): Uint8Array {\n\treturn encodeSection(name, new TextEncoder().encode(serializeAuditJson(data)))\n}\n\nfunction encodeNdjsonSection(name: string, records: unknown[]): Uint8Array {\n\tconst lines = `${records.map((record) => serializeAuditJson(record)).join('\\n')}\\n`\n\treturn encodeSection(name, new TextEncoder().encode(lines))\n}\n\nfunction readUint32(view: DataView, offset: number): number {\n\treturn view.getUint32(offset, true)\n}\n\ninterface Section {\n\tname: string\n\tcontent: Uint8Array\n}\n\nfunction parseSections(data: Uint8Array): Section[] {\n\tconst sections: Section[] = []\n\tconst view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n\tlet offset = 0\n\n\twhile (offset + 8 <= data.byteLength) {\n\t\tconst nameLen = readUint32(view, offset)\n\t\tconst contentLen = readUint32(view, offset + 4)\n\t\toffset += 8\n\n\t\tif (offset + nameLen + contentLen > data.byteLength) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst name = new TextDecoder().decode(data.slice(offset, offset + nameLen))\n\t\toffset += nameLen\n\n\t\tconst content = data.slice(offset, offset + contentLen)\n\t\toffset += contentLen\n\n\t\tsections.push({ name, content })\n\t}\n\n\treturn sections\n}\n\nfunction findSection(sections: Section[], name: string): Uint8Array | null {\n\tfor (const section of sections) {\n\t\tif (section.name === name) {\n\t\t\treturn section.content\n\t\t}\n\t}\n\treturn null\n}\n\nasync function computeSha256(data: Uint8Array<ArrayBuffer>): Promise<string> {\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\n\treturn Array.from(new Uint8Array(hashBuffer))\n\t\t.map((byte) => byte.toString(16).padStart(2, '0'))\n\t\t.join('')\n}\n\nasync function readAllOperations(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tcollectionFilter?: string[],\n): Promise<Operation[]> {\n\tconst collections = collectionFilter\n\t\t? Object.keys(schema.collections).filter((name) => collectionFilter.includes(name))\n\t\t: Object.keys(schema.collections)\n\n\tconst allOps: Operation[] = []\n\tfor (const collectionName of collections) {\n\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`,\n\t\t)\n\n\t\tfor (const row of rows) {\n\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t}\n\t}\n\n\treturn allOps\n}\n\nfunction filterOperationsByCollections(\n\toperations: Operation[],\n\tcollectionFilter?: string[],\n): Operation[] {\n\tif (!collectionFilter || collectionFilter.length === 0) {\n\t\treturn operations\n\t}\n\tconst allowed = new Set(collectionFilter)\n\treturn operations.filter((op) => allowed.has(op.collection))\n}\n\n/**\n * Export operations and persisted merge traces as a portable binary audit bundle.\n */\nexport async function exportAudit(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n\tschemaVersion: number,\n\toptions?: AuditExportOptions,\n): Promise<Uint8Array> {\n\tconst onProgress = options?.onProgress ?? (() => {})\n\tconst traceQuery: AuditTraceQuery = {\n\t\tcollections: options?.collections,\n\t\tsince: options?.since,\n\t\tuntil: options?.until,\n\t}\n\n\tonProgress({ phase: 'reading', progress: 0, message: 'Reading operations' })\n\tconst operations = filterOperationsByCollections(\n\t\tawait readAllOperations(adapter, schema, options?.collections),\n\t\toptions?.collections,\n\t)\n\n\tonProgress({ phase: 'reading', progress: 0.4, message: 'Reading merge traces' })\n\tconst mergeTraces = await readAuditTraces(adapter, traceQuery)\n\n\tonProgress({ phase: 'writing', progress: 0.7, message: 'Encoding audit export' })\n\tconst sections: Uint8Array[] = []\n\tlet contentForChecksum = new Uint8Array(0)\n\n\tconst addSection = (section: Uint8Array): void => {\n\t\tsections.push(section)\n\t\tconst combined = new Uint8Array(contentForChecksum.length + section.length)\n\t\tcombined.set(contentForChecksum, 0)\n\t\tcombined.set(section, contentForChecksum.length)\n\t\tcontentForChecksum = combined\n\t}\n\n\taddSection(encodeNdjsonSection('operations', operations))\n\taddSection(encodeNdjsonSection('merge_traces', mergeTraces))\n\n\tonProgress({ phase: 'verifying', progress: 0.9, message: 'Computing checksum' })\n\tconst checksum = await computeSha256(contentForChecksum as Uint8Array<ArrayBuffer>)\n\n\tconst manifest: AuditExportManifest = {\n\t\tversion: 1,\n\t\texportedAt: Date.now(),\n\t\tnodeId,\n\t\tschemaVersion,\n\t\toperationCount: operations.length,\n\t\tmergeTraceCount: mergeTraces.length,\n\t\tchecksum,\n\t}\n\n\tconst manifestSection = encodeJsonSection('manifest', manifest)\n\tconst checksumSection = encodeSection('checksum', new TextEncoder().encode(checksum))\n\n\tonProgress({ phase: 'writing', progress: 1, message: 'Finalizing' })\n\n\tconst parts = [manifestSection, ...sections, checksumSection]\n\tconst finalOutput = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0))\n\tlet offset = 0\n\tfor (const part of parts) {\n\t\tfinalOutput.set(part, offset)\n\t\toffset += part.length\n\t}\n\n\treturn finalOutput\n}\n\n/**\n * Decode an audit export binary into structured data.\n */\nexport function decodeAuditExport(data: Uint8Array): AuditExportPayload {\n\tconst sections = parseSections(data)\n\tconst manifest = JSON.parse(\n\t\tnew TextDecoder().decode(findSection(sections, 'manifest') ?? new Uint8Array()),\n\t) as AuditExportManifest\n\n\tconst operationsContent = findSection(sections, 'operations')\n\tconst mergeTracesContent = findSection(sections, 'merge_traces')\n\n\tconst operations = parseNdjsonSection<Operation>(operationsContent)\n\tconst mergeTraces = parseNdjsonSection<PersistedAuditTrace>(mergeTracesContent)\n\n\treturn { manifest, operations, mergeTraces }\n}\n\n/**\n * Read only the manifest from an audit export without decoding all sections.\n */\nexport function readAuditExportManifest(data: Uint8Array): AuditExportManifest {\n\tconst sections = parseSections(data)\n\tconst manifestContent = findSection(sections, 'manifest')\n\tif (!manifestContent) {\n\t\tthrow new Error('Invalid audit export: missing manifest section')\n\t}\n\treturn JSON.parse(new TextDecoder().decode(manifestContent)) as AuditExportManifest\n}\n\n/**\n * Verify the checksum of an audit export file.\n */\nexport async function verifyAuditExportChecksum(data: Uint8Array): Promise<boolean> {\n\tconst sections = parseSections(data)\n\tconst manifest = readAuditExportManifest(data)\n\tconst contentSections = sections.filter(\n\t\t(section) => section.name !== 'manifest' && section.name !== 'checksum',\n\t)\n\n\tlet content = new Uint8Array(0)\n\tfor (const section of contentSections) {\n\t\tconst encoded = encodeSection(section.name, section.content)\n\t\tconst combined = new Uint8Array(content.length + encoded.length)\n\t\tcombined.set(content, 0)\n\t\tcombined.set(encoded, content.length)\n\t\tcontent = combined\n\t}\n\n\tconst checksum = await computeSha256(content as Uint8Array<ArrayBuffer>)\n\treturn checksum === manifest.checksum\n}\n\nfunction parseNdjsonSection<T>(content: Uint8Array | null): T[] {\n\tif (!content || content.length === 0) {\n\t\treturn []\n\t}\n\tconst text = new TextDecoder().decode(content).trim()\n\tif (text.length === 0) {\n\t\treturn []\n\t}\n\treturn text.split('\\n').map((line) => deserializeAuditJson<T>(line))\n}\n","import { HybridLogicalClock, quoteIdent } from '@korajs/core'\nimport type { Operation, SchemaDefinition } from '@korajs/core'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_BASE_TABLE,\n\tFOLD_SNAPSHOT_TABLE,\n\tFOLD_STATE_TABLE,\n\tPROVISIONAL_OPS_TABLE,\n} from '../fold/record-folder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport { SEQ_CONFLICTS_TABLE, insertConflictRow } from '../store/sequence-repair'\nimport {\n\ttype LocalNodeRecord,\n\tTERMINAL_REJECTIONS_TABLE,\n\tensureLocalSyncRecordTables,\n} from '../sync/local-sync-records'\nimport { loadOwnAckedThrough } from '../sync/sync-durability'\nimport {\n\tDELIVERY_WATERMARK_META_KEY,\n\tDELTA_CURSOR_META_KEY,\n\tloadLastAckedServerVector,\n} from '../sync/sync-state'\nimport type { ApplyResult, OperationRow, StorageAdapter, Transaction } from '../types'\nimport type { ParsedBackup } from './backup'\n\n/** What a restore needs from the store it restores into. */\nexport interface RestoreHost {\n\treadonly adapter: StorageAdapter\n\treadonly schema: SchemaDefinition\n\t/** The normal remote-apply path (sync's): dedup by id, per-field merge, version vector. */\n\tapplyOperation(operation: Operation): Promise<ApplyResult>\n\t/** This database's own nodes (RT-38/40), never taken from a backup. */\n\tlistLocalNodes(): Promise<LocalNodeRecord[]>\n\t/**\n\t * Whether a node's writes would be authoritative here (Kora's reserved `kora:`\n\t * nodes, and the explicit server authorities this device learned). A merge import\n\t * never applies their operations: only the sync server delivers them.\n\t */\n\tisServerAuthority?(nodeId: string): boolean\n}\n\n/** Outcome counts of a restore. */\nexport interface RestoreCounts {\n\toperationsRestored: number\n\trecordsRestored: number\n\tunsyncedWritesKept: number\n\t/** Merge mode: operations of server-authority nodes left out (see `RestoreHost.isServerAuthority`). */\n\tserverOperationsSkipped?: number\n}\n\n/**\n * Merge a backup into the database (STORE-5): every operation goes through the normal\n * remote-apply path in HLC (causal) order, the version vector advances by MAX, the\n * terminal-rejection markers are added. Never imported: the node id, node tokens, local\n * node registry and principal bindings, sync watermarks, acknowledged prefixes.\n */\nexport async function restoreMerge(\n\thost: RestoreHost,\n\tbackup: ParsedBackup,\n\tfiltered: boolean,\n): Promise<RestoreCounts> {\n\tawait importTerminalRejections(host.adapter, backup)\n\tlet restored = 0\n\tlet skipped = 0\n\tconst authority = (nodeId: string): boolean => host.isServerAuthority?.(nodeId) ?? false\n\tfor (const operation of backup.operations) {\n\t\tif (!host.schema.collections[operation.collection]) continue\n\t\t// A server decision is applied only as the sync server delivers it: from a file,\n\t\t// an operation under a server node would win `merge('server-authoritative')`\n\t\t// fields on this device (and is never uploaded to be checked). One the server\n\t\t// already delivered is in the log anyway; the rest arrive by sync.\n\t\tif (authority(operation.nodeId)) {\n\t\t\tskipped++\n\t\t\tcontinue\n\t\t}\n\t\tif ((await host.applyOperation(operation)) === 'applied') restored++\n\t}\n\tif (!filtered && backup.versionVector.size > 0) {\n\t\t// With a collection filter the vector would claim other collections' operations.\n\t\tawait host.adapter.transaction(async (tx) => {\n\t\t\tfor (const [nodeId, sequence] of backup.versionVector) {\n\t\t\t\tif (authority(nodeId)) continue\n\t\t\t\tawait maxVector(tx, nodeId, sequence)\n\t\t\t}\n\t\t})\n\t}\n\treturn {\n\t\toperationsRestored: restored,\n\t\trecordsRestored: 0,\n\t\tunsyncedWritesKept: 0,\n\t\tserverOperationsSkipped: skipped,\n\t}\n}\n\n/**\n * Replace the database's data with a backup's (STORE-5), keeping this device's\n * identity:\n *\n * - The node id, node tokens, local node registry, principal bindings and acknowledged\n * prefixes are untouched; the exporting device's are never imported.\n * - This database's own nodes never move their sequence counters backwards (numbers the\n * server may hold are never reused). A node the server never accepted, whose unsynced\n * writes are not kept, restarts after its highest restored number (its numbers never\n * left the device), so its log stays contiguous.\n * - Unacknowledged writes of an accepted node, and with `keepUnsyncedWrites` every\n * unsynced own write, are re-applied on top of the restored data.\n * - Delivery watermarks restart at 0 and the delta cursor is dropped, so the sync server\n * re-sends everything in scope (deduplicated by id).\n * - Rows, operations, version vector and sync bookkeeping change in one transaction;\n * re-applied writes (and a backup without records, materialized through the\n * remote-apply path) follow it.\n */\nexport async function restoreReplace(\n\thost: RestoreHost,\n\tbackup: ParsedBackup,\n\toptions: { collections: string[] | null; keepUnsyncedWrites: boolean },\n): Promise<RestoreCounts> {\n\tconst { adapter, schema } = host\n\tconst targets = Object.keys(schema.collections).filter(\n\t\t(name) => !options.collections || options.collections.includes(name),\n\t)\n\tconst rawRecords = backup.manifest.includesRecords\n\tconst localNodes = await host.listLocalNodes()\n\tconst localIds = new Set(localNodes.map((node) => node.nodeId))\n\tconst acked = await loadAckedThrough(adapter, localNodes)\n\n\t// Writes that exist only on this device: re-applied after the replace.\n\tconst kept: Operation[] = []\n\tconst dropped = new Set<string>()\n\tfor (const node of localNodes) {\n\t\tconst keep = node.accepted || options.keepUnsyncedWrites\n\t\tconst floor = acked.get(node.nodeId) ?? 0\n\t\tfor (const collection of targets) {\n\t\t\tconst rows = await adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND sequence_number > ?`,\n\t\t\t\t[node.nodeId, floor],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (keep) kept.push(deserializeOperationWithCollection(row, collection))\n\t\t\t\telse dropped.add(node.nodeId)\n\t\t\t}\n\t\t}\n\t}\n\tkept.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\t// Counters that may restart: nodes the server never accepted whose writes are dropped.\n\tconst restartable = new Set(\n\t\tlocalNodes\n\t\t\t.filter((node) => !node.accepted && !options.keepUnsyncedWrites)\n\t\t\t.map((node) => node.nodeId),\n\t)\n\n\tawait ensureLocalSyncRecordTables(adapter)\n\tlet recordsRestored = 0\n\tconst hasConflicts = await tableExists(adapter, SEQ_CONFLICTS_TABLE)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const collection of targets) {\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(`_kora_ops_${collection}`)}`)\n\t\t\tawait tx.execute(`DELETE FROM ${quoteIdent(collection)}`)\n\t\t\tawait tx.execute('DELETE FROM _kora_scope_retractions WHERE collection = ?', [collection])\n\t\t\t// W7: the records' fold states go with their rows and log; the store\n\t\t\t// re-materializes the restored collections afterwards.\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_BASE_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ?`, [collection])\n\t\t\tawait tx.execute(`DELETE FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ?`, [collection])\n\t\t\tif (hasConflicts) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`DELETE FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND reemitted_as IS NULL`,\n\t\t\t\t\t[collection],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Version vector. Without a collection filter, remote nodes take the backup's\n\t\t// values; this database's own nodes never go backwards. With a filter, MAX only.\n\t\tconst current = await tx.query<{ node_id: string; sequence_number: number }>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tif (!options.collections) {\n\t\t\tfor (const row of current) {\n\t\t\t\tif (!localIds.has(row.node_id)) {\n\t\t\t\t\tawait tx.execute('DELETE FROM _kora_version_vector WHERE node_id = ?', [row.node_id])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const [nodeId, sequence] of backup.versionVector) {\n\t\t\tif (restartable.has(nodeId)) continue\n\t\t\tawait maxVector(tx, nodeId, sequence)\n\t\t}\n\n\t\t// The server must re-send everything in scope: this database no longer holds what\n\t\t// it delivered before.\n\t\tawait tx.execute('UPDATE _kora_meta SET value = ? WHERE key = ? OR key LIKE ?', [\n\t\t\t'0',\n\t\t\tDELIVERY_WATERMARK_META_KEY,\n\t\t\t`${DELIVERY_WATERMARK_META_KEY}:%`,\n\t\t])\n\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\n\t\tfor (const entry of backup.terminalRejections) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\n\t\t// W7 (RT-66): the exporting device's compacted history (base states), its row\n\t\t// snapshots and compacted prefixes, so records rebuild from base + log exactly.\n\t\tfor (const row of backup.foldBases) {\n\t\t\tif (!targets.includes(row.collection)) continue\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR REPLACE INTO ${FOLD_BASE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t\t[row.collection, row.recordId, row.state],\n\t\t\t)\n\t\t}\n\t\tfor (const row of backup.foldSnapshots) {\n\t\t\tif (!targets.includes(row.collection)) continue\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR REPLACE INTO ${FOLD_SNAPSHOT_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t\t[row.collection, row.recordId, row.state],\n\t\t\t)\n\t\t}\n\t\tif (!options.collections) {\n\t\t\t// Per node and global; a collection filter would claim other collections' ops.\n\t\t\tawait tx.execute(`DELETE FROM ${COMPACTED_THROUGH_TABLE}`)\n\t\t\tfor (const [nodeId, sequence] of backup.compactedThrough) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)`,\n\t\t\t\t\t[nodeId, sequence],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (rawRecords) {\n\t\t\tfor (const operation of backup.operations) {\n\t\t\t\tif (!targets.includes(operation.collection)) continue\n\t\t\t\tawait insertOperationRow(tx, operation)\n\t\t\t}\n\t\t\tfor (const collection of targets) {\n\t\t\t\tconst rows = backup.records.get(collection) ?? []\n\t\t\t\tif (rows.length === 0) continue\n\t\t\t\tconst columns = new Set(\n\t\t\t\t\t(await tx.query<{ name: string }>(`PRAGMA table_info(${quoteIdent(collection)})`)).map(\n\t\t\t\t\t\t(column) => column.name,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst keys = Object.keys(row).filter((key) => columns.has(key))\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`INSERT OR REPLACE INTO ${quoteIdent(collection)} (${keys.map((k) => quoteIdent(k)).join(', ')}) VALUES (${keys.map(() => '?').join(', ')})`,\n\t\t\t\t\t\tkeys.map((key) => toSqlValue(row[key])),\n\t\t\t\t\t)\n\t\t\t\t\trecordsRestored++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\tlet restored = rawRecords\n\t\t? backup.operations.filter((operation) => targets.includes(operation.collection)).length\n\t\t: 0\n\tif (!rawRecords) {\n\t\t// No materialized rows in the backup: the remote-apply path rebuilds them.\n\t\tfor (const operation of backup.operations) {\n\t\t\tif (!targets.includes(operation.collection)) continue\n\t\t\tif ((await host.applyOperation(operation)) === 'applied') restored++\n\t\t}\n\t}\n\tlet unsyncedWritesKept = 0\n\tfor (const operation of kept) {\n\t\tif ((await host.applyOperation(operation)) === 'applied') unsyncedWritesKept++\n\t}\n\n\tawait adapter.transaction(async (tx) => {\n\t\t// Restartable counters continue after the highest number now in the log.\n\t\tfor (const nodeId of restartable) {\n\t\t\tconst highest = await highestSequence(tx, targets, nodeId)\n\t\t\tawait tx.execute('DELETE FROM _kora_version_vector WHERE node_id = ?', [nodeId])\n\t\t\tif (highest > 0) {\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t'INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)',\n\t\t\t\t\t[nodeId, highest],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\t// Nothing dropped may still wait to upload.\n\t\tif (dropped.size > 0 || !options.keepUnsyncedWrites) {\n\t\t\tconst union = targets\n\t\t\t\t.map((c) => `SELECT id FROM ${quoteIdent(`_kora_ops_${c}`)}`)\n\t\t\t\t.join(' UNION ')\n\t\t\tif (union) {\n\t\t\t\tawait tx.execute(`DELETE FROM _kora_sync_queue WHERE id NOT IN (${union})`)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn { operationsRestored: restored, recordsRestored, unsyncedWritesKept }\n}\n\nasync function importTerminalRejections(\n\tadapter: StorageAdapter,\n\tbackup: ParsedBackup,\n): Promise<void> {\n\tif (backup.terminalRejections.length === 0) return\n\tawait ensureLocalSyncRecordTables(adapter)\n\tawait adapter.transaction(async (tx) => {\n\t\tfor (const entry of backup.terminalRejections) {\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT OR IGNORE INTO ${TERMINAL_REJECTIONS_TABLE} (operation_id, node_id, sequence_number, code, rejected_at) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t[entry.operationId, entry.nodeId, entry.sequenceNumber, entry.code, entry.rejectedAt],\n\t\t\t)\n\t\t}\n\t})\n}\n\n/** Append a canonical operation row; a taken `(node, sequence)` goes to the conflicts table. */\nasync function insertOperationRow(tx: Transaction, operation: Operation): Promise<void> {\n\tconst table = quoteIdent(`_kora_ops_${operation.collection}`)\n\tconst row = serializeOperation(operation)\n\tconst existing = await tx.query<{ id: string }>(`SELECT id FROM ${table} WHERE id = ?`, [row.id])\n\tif (existing.length > 0) return\n\tconst holder = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${table} WHERE node_id = ? AND sequence_number = ?`,\n\t\t[row.node_id, row.sequence_number],\n\t)\n\tif (holder.length > 0) {\n\t\tawait insertConflictRow(\n\t\t\ttx,\n\t\t\toperation.collection,\n\t\t\trow,\n\t\t\t'backup-sequence-conflict',\n\t\t\tnull,\n\t\t\tnull,\n\t\t\tDate.now(),\n\t\t)\n\t\treturn\n\t}\n\tawait tx.execute(\n\t\t`INSERT INTO ${table} (id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\trow.id,\n\t\t\trow.node_id,\n\t\t\trow.type,\n\t\t\trow.record_id,\n\t\t\trow.data,\n\t\t\trow.previous_data,\n\t\t\trow.timestamp,\n\t\t\trow.sequence_number,\n\t\t\trow.causal_deps,\n\t\t\trow.schema_version,\n\t\t],\n\t)\n}\n\nasync function maxVector(tx: Transaction, nodeId: string, sequence: number): Promise<void> {\n\tawait tx.execute(\n\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t[nodeId, sequence],\n\t)\n}\n\nasync function highestSequence(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<number> {\n\tlet highest = 0\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ m: number | null }>(\n\t\t\t`SELECT MAX(sequence_number) AS m FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\thighest = Math.max(highest, rows[0]?.m ?? 0)\n\t}\n\treturn highest\n}\n\n/**\n * Per own node, how far the sync server acknowledged its operations: the W3 contiguous\n * acknowledged prefix, else the last acknowledged server vector, else 0.\n */\nasync function loadAckedThrough(\n\tadapter: StorageAdapter,\n\tnodes: readonly LocalNodeRecord[],\n): Promise<Map<string, number>> {\n\tconst lastAcked = await loadLastAckedServerVector(adapter)\n\tconst result = new Map<string, number>()\n\tfor (const node of nodes) {\n\t\tconst prefix = await loadOwnAckedThrough(adapter, node.nodeId)\n\t\tresult.set(node.nodeId, prefix ?? lastAcked.get(node.nodeId) ?? 0)\n\t}\n\treturn result\n}\n\nasync function tableExists(adapter: StorageAdapter, name: string): Promise<boolean> {\n\tconst rows = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[name],\n\t)\n\treturn rows.length > 0\n}\n\nfunction toSqlValue(value: unknown): unknown {\n\tif (typeof value === 'boolean') return value ? 1 : 0\n\tif (value instanceof Uint8Array) return value\n\tif (value !== null && typeof value === 'object') return JSON.stringify(value)\n\treturn value\n}\n","import {\n\tCausalTracker,\n\tHybridLogicalClock,\n\tKoraError,\n\tassertOperationTransformCoverage,\n\tcreateVersionVector,\n\tderiveSideEffectOpId,\n\tdeserializeFoldState,\n\texpandFieldVersionedOperations,\n\tfoldPlanFingerprints,\n\tgenerateUUIDv7,\n\tisReservedNodeId,\n\tisServerNodeId,\n\tmismatchedFoldFields,\n\toperationSchemaView,\n\tquoteIdent,\n\treplayOperationsForRecord,\n} from '@korajs/core'\nimport type {\n\tFoldState,\n\tHLCTimestamp,\n\tKoraEventEmitter,\n\tMergeTrace,\n\tOperation,\n\tOperationLog,\n\tOperationTransform,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n\tVersionVector,\n} from '@korajs/core'\nimport { readBackupManifest as readManifest } from '../backup/backup'\nimport type { BackupManifest, BackupOptions, RestoreOptions, RestoreResult } from '../backup/types'\nimport { Collection } from '../collection/collection'\nimport { compactOperationLog } from '../compaction/compact-operation-log'\nimport type { CompactionResult, CompactionStrategy } from '../compaction/types'\nimport {\n\tNodeOwnedByAnotherUserError,\n\tOptimisticLockError,\n\tSchemaVersionAheadError,\n\tStoreNotOpenError,\n} from '../errors'\nimport { compactFoldedLog } from '../fold/compact-folded-log'\nimport { LEGACY_BODIES_META_KEY, canonicalizeLegacyLogBodies } from '../fold/legacy-bodies'\nimport {\n\tCOMPACTED_THROUGH_TABLE,\n\tFOLD_MATERIALIZATION_CURRENT,\n\tFOLD_MATERIALIZATION_LEGACY,\n\tFOLD_MATERIALIZATION_META_KEY,\n\tFOLD_STATE_TABLE,\n\tFOLD_TABLES_DDL,\n\tRecordFolder,\n\tisCompacted,\n} from '../fold/record-folder'\nimport {\n\ttype KeptRecords,\n\ttype RematerializationMode,\n\trematerializeDatabase,\n} from '../fold/rematerialize'\nimport {\n\tLOG_QUARANTINE_TABLE,\n\ttype LogIntegrityReport,\n\tscanLogIntegrity,\n} from '../log-integrity/log-integrity'\nimport {\n\ttype FieldVersions,\n\teffectiveFieldVersion,\n\tfieldVersionsForFields,\n\tparseFieldVersions,\n\tresolvePerFieldLww,\n\tserializeFieldVersions,\n} from '../lww/field-versions'\nimport { isIncomingNewerThanRow, serializeRowVersion } from '../lww/row-version'\nimport { runSchemaMigrations } from '../migrations/run-migrations'\nimport {\n\tSTORED_SCHEMA_VERSION_SQL,\n\tparseSchemaAhead,\n\tstoredSchemaVersion,\n} from '../migrations/schema-ceiling'\nimport type { LocalMutationContext } from '../mutations/types'\nimport { isStorageFullError } from '../mutations/write-context'\nimport { QueryBuilder } from '../query/query-builder'\nimport {\n\tbuildFieldFastForwardUpdateQuery,\n\tbuildInsertQuery,\n\tbuildLwwSoftDeleteQuery,\n\tbuildSoftDeleteQuery,\n} from '../query/sql-builder'\nimport { RelationEnforcer } from '../relations/relation-enforcer'\nimport { buildReplaySnapshot } from '../replay/replay-to'\nimport type { ReplaySnapshot } from '../replay/replay-to'\nimport { SequenceManager } from '../sequences/sequence-manager'\nimport {\n\tdeserializeOperationWithCollection,\n\tdeserializeRecord,\n\tserializeOperation,\n\tserializeRecord,\n} from '../serialization/serializer'\nimport { ensureStoredTextCodec } from '../serialization/stored-text-migration'\nimport {\n\ttype RecordsChangeListener,\n\tSubscriptionManager,\n} from '../subscription/subscription-manager'\nimport {\n\ttype AdoptionSchedule,\n\ttype LocalNodeRecord,\n\ttype TerminalRejection,\n\tassignLocalNodePrincipal,\n\tconfirmLocalNodePrincipal,\n\tdropLocalNode,\n\tfindTerminalRejections,\n\tforgetLocalNode,\n\tlistLocalNodes,\n\tloadAcceptedCycle,\n\tloadAdoptionSchedule,\n\tmarkLocalNodeAccepted,\n\tmarkLocalNodeRefused,\n\trecordLocalNodeRefusedFor,\n\trecordTerminalRejections,\n\tregisterLocalNode,\n\tsaveAdoptionSchedule,\n\tseedTerminalRejectionsOnce,\n\tsetLocalNodePrincipal,\n} from '../sync/local-sync-records'\nimport type { ClockRebaseResult } from '../sync/rebase-unsynced-operations'\nimport { rebaseUnsyncedOperationsInLog } from '../sync/rebase-unsynced-operations'\nimport { renumberOperationRow, rewriteDependentsInTx } from '../sync/rehash-operation'\nimport type { ResequenceResult } from '../sync/rehash-operation'\nimport type { NodeRotationResult } from '../sync/rotate-node-id'\nimport { rotateUnsyncedOperationsInLog } from '../sync/rotate-node-id'\nimport type { UnappliedOperation } from '../sync/sync-durability'\nimport {\n\tloadAcceptedDownlinkScope,\n\tloadOwnAckedThrough,\n\tloadUnappliedOperations,\n\tremoveUnappliedOperations,\n\tsaveAcceptedDownlinkScope,\n\tsaveOwnAckedThrough,\n\tsaveUnappliedOperations,\n} from '../sync/sync-durability'\nimport {\n\tDELIVERY_WATERMARK_META_KEY,\n\tDELTA_CURSOR_META_KEY,\n\tNODE_TOKEN_META_KEY,\n\tcollectOperationsAheadOfServer,\n\tdeleteDeliveryWatermark,\n\tloadAllDeliveryWatermarks,\n\tloadAuthoritativeNodeIds,\n\tloadDeliveryWatermark,\n\tloadDeltaCursor,\n\tloadLastAckedServerVector,\n\tloadNodeToken,\n\tloadRevokedAuthoritativeNodeIds,\n\tmergeVersionVectors,\n\tnodeTokenKey,\n\tsaveAuthoritativeNodeIds,\n\tsaveDeliveryWatermark,\n\tsaveDeltaCursor,\n\tsaveLastAckedServerVector,\n\tsaveNodeToken,\n\tsaveRevokedAuthoritativeNodeIds,\n} from '../sync/sync-state'\nimport { TransactionContext } from '../transaction/transaction-context'\nimport type {\n\tApplyRemoteOptions,\n\tApplyResult,\n\tLocalMutationHandler,\n\tMaterializedRowSnapshot,\n\tMetaRow,\n\tOperationRow,\n\tRawCollectionRow,\n\tRowVersionState,\n\tStorageAdapter,\n\tStoreConfig,\n\tStoreIsolation,\n\tTransaction,\n\tVersionVectorRow,\n} from '../types'\nimport { dropLegacyIndexes } from './legacy-indexes'\nimport { acquireNodeLock, isNodeLockHeld, nodeLockName, tryAcquireNodeLock } from './node-lock'\nimport { relaxValueDomainConstraints } from './relax-constraints'\nimport { allocateNextSequenceInTransaction } from './sequence-allocator'\nimport {\n\tSEQ_CONFLICTS_TABLE,\n\tinsertConflictRow,\n\tisOperationLogged,\n\tloadRetainedConflictRows,\n\trepairSequenceUniqueness,\n} from './sequence-repair'\nimport { savePerTabNodeId } from './tab-node-id'\nimport { resolvePerTabNodeId } from './tab-node-id'\n\n/**\n * Store is the main orchestrator. It owns a schema, a storage adapter,\n * a clock, and a subscription manager. It creates Collection instances\n * for each schema collection, and provides the sync contract via\n * applyRemoteOperation and getOperationRange.\n *\n * @example\n * ```typescript\n * const store = new Store({ schema, adapter })\n * await store.open()\n * const todo = await store.collection('todos').insert({ title: 'Hello' })\n * await store.close()\n * ```\n */\n/** `_kora_meta` key: per-collection fold plan fingerprints the rows were folded with (RT-63). */\nconst FOLD_PLAN_META_KEY = 'fold_plan_fingerprints'\n/** `_kora_meta` key: a full resync was requested to settle row snapshots (RT-68). */\nconst SNAPSHOT_RESYNC_META_KEY = 'fold_snapshot_resync'\n/**\n * Node id of provisional side effects (RT-69). In the reserved `kora:` namespace: no\n * device authors under it, and its effects never enter the log or the upload queue.\n */\nconst PROVISIONAL_NODE_ID = 'kora:provisional'\n\n/** A node id this client must never author under (RT-61): Kora's reserved namespace. */\nexport class ReservedNodeIdError extends KoraError {\n\tconstructor(nodeId: string, source: string) {\n\t\tsuper(\n\t\t\t`Node id \"${nodeId}\" (${source}) is in Kora's reserved \"kora:\" namespace; devices never author under it.`,\n\t\t\t'RESERVED_NODE_ID',\n\t\t\t{ nodeId, source, fix: 'Configure a node id that does not start with \"kora:\".' },\n\t\t)\n\t\tthis.name = 'ReservedNodeIdError'\n\t}\n}\n\n/**\n * Per collection, the record ids that own quarantined log rows (RT-68); a\n * quarantined row whose record id cannot be read keeps its whole collection.\n */\nasync function loadQuarantinedRecords(adapter: StorageAdapter): Promise<KeptRecords> {\n\tconst records = new Map<string, Set<string>>()\n\tconst collections = new Set<string>()\n\tconst exists = await adapter.query<{ name: string }>(\n\t\t\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?\",\n\t\t[LOG_QUARANTINE_TABLE],\n\t)\n\tif (exists.length === 0) return { records, collections }\n\tconst rows = await adapter.query<{ collection: string; row_json: string }>(\n\t\t`SELECT collection, row_json FROM ${LOG_QUARANTINE_TABLE}`,\n\t)\n\tfor (const row of rows) {\n\t\tlet recordId: unknown = null\n\t\ttry {\n\t\t\trecordId = (JSON.parse(row.row_json) as { record_id?: unknown }).record_id\n\t\t} catch {\n\t\t\trecordId = null\n\t\t}\n\t\tif (typeof recordId === 'string' && recordId.length > 0) {\n\t\t\tconst set = records.get(row.collection) ?? new Set<string>()\n\t\t\tset.add(recordId)\n\t\t\trecords.set(row.collection, set)\n\t\t} else {\n\t\t\tcollections.add(row.collection)\n\t\t}\n\t}\n\treturn { records, collections }\n}\n\n/** Collections whose stored fold states hold a field of another fold kind than the schema's. */\nasync function collectionsWithMismatchedStates(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n): Promise<string[]> {\n\tconst out: string[] = []\n\tfor (const collection of Object.keys(schema.collections)) {\n\t\tconst rows = await adapter.query<{ state: string }>(\n\t\t\t`SELECT state FROM ${FOLD_STATE_TABLE} WHERE collection = ?`,\n\t\t\t[collection],\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tlet state: FoldState\n\t\t\ttry {\n\t\t\t\tstate = deserializeFoldState(row.state)\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (mismatchedFoldFields(state, schema).length > 0) {\n\t\t\t\tout.push(collection)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n\n/**\n * Make `nodeId` the database's node id (`_kora_meta.node_id`). The unkeyed legacy node\n * token belongs to the node id it replaces, so it moves to that node's own key first:\n * it must never be presented as the new node's token.\n */\nasync function moveDatabaseNodeId(tx: Transaction, nodeId: string): Promise<void> {\n\tconst meta = await tx.query<MetaRow>(\"SELECT value FROM _kora_meta WHERE key = 'node_id'\")\n\tconst previous = meta[0]?.value\n\tif (previous === nodeId) return\n\tconst legacy = await tx.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\tNODE_TOKEN_META_KEY,\n\t])\n\tif (legacy[0] && previous) {\n\t\tawait tx.execute('INSERT OR IGNORE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tnodeTokenKey(previous),\n\t\t\tlegacy[0].value,\n\t\t])\n\t}\n\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [NODE_TOKEN_META_KEY])\n\tawait tx.execute(\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\", [nodeId])\n}\n\n/** Result of {@link Store.bindPrincipal} (RT-42). */\nexport interface PrincipalBinding {\n\t/** The node id local writes use from now on. */\n\tnodeId: string\n\t/** The node id in use before the call. */\n\tpreviousNodeId: string\n\t/** The store moved to another node id. */\n\tswitched: boolean\n\t/** The node id is pinned and belongs to another user: nothing may upload it now. */\n\tconflict: boolean\n}\n\nexport class Store implements OperationLog {\n\tprivate opened = false\n\tprivate nodeId = ''\n\tprivate sequenceNumber = 0\n\tprivate versionVector: VersionVector = createVersionVector()\n\tprivate clock: HybridLogicalClock | null = null\n\tprivate collections = new Map<string, Collection>()\n\tprivate subscriptionManager: SubscriptionManager\n\tprivate sequenceManager: SequenceManager | null = null\n\n\tprivate readonly schema: SchemaDefinition\n\tprivate readonly adapter: StorageAdapter\n\tprivate readonly configNodeId: string | undefined\n\t/** The owner of the pinned node while it belongs to another user than the signed-in one (F9). */\n\tprivate pinnedNodeOwnedBy: string | null = null\n\t/** The sync server refused the pinned node as another user's (F9). */\n\tprivate pinnedNodeRefusedByServer = false\n\t/** The user of the last {@link bindPrincipal}. */\n\tprivate signedInPrincipal: string | null = null\n\tprivate readonly dbName: string\n\tprivate readonly isolation: StoreIsolation\n\tprivate readonly emitter: KoraEventEmitter | null\n\tprivate localMutationHandler: LocalMutationHandler | null\n\tprivate relationEnforcer: RelationEnforcer | null = null\n\tprivate causalTracker: CausalTracker | null = null\n\tprivate readonly secretKeyProvider: SecretKeyProvider | undefined\n\t/** Releases the per-tab node lock (RT-40); null when none is held. */\n\tprivate releaseNodeLock: (() => void) | null = null\n\t/** How rows are materialized ({@link StoreConfig.materialization}). */\n\tprivate readonly materialization: 'fold' | 'legacy'\n\t/** The W7 record fold; null under legacy materialization. */\n\tprivate readonly folder: RecordFolder | null\n\t/** True once every row of the database is a materialization of its fold state. */\n\tprivate foldActive = false\n\t/** Schema transforms applied at fold time (RT-84); never to stored operations. */\n\tprivate readonly operationTransforms: readonly OperationTransform[]\n\t/** Largest operation a local write may produce (RT-86); default in the write path. */\n\tprivate readonly maxOperationBytes: number | undefined\n\n\tconstructor(config: StoreConfig) {\n\t\tthis.materialization = config.materialization ?? 'fold'\n\t\tthis.operationTransforms = config.operationTransforms ?? []\n\t\tthis.maxOperationBytes = config.maxOperationBytes\n\t\tthis.folder =\n\t\t\tthis.materialization === 'fold'\n\t\t\t\t? new RecordFolder(config.schema, this.operationTransforms)\n\t\t\t\t: null\n\t\tthis.schema = config.schema\n\t\tthis.adapter = config.adapter\n\t\tthis.configNodeId = config.nodeId\n\t\tthis.dbName = config.dbName ?? 'kora-db'\n\t\tthis.isolation = config.isolation ?? 'shared'\n\t\tthis.emitter = config.emitter ?? null\n\t\tthis.localMutationHandler = config.localMutationHandler ?? null\n\t\tthis.secretKeyProvider = config.secretKeyProvider\n\t\tthis.subscriptionManager = new SubscriptionManager({\n\t\t\tonQuerySubscribed: config.onQuerySubscribed,\n\t\t\t// STORE-12: every subscription failure is observable (DevTools, app listeners).\n\t\t\tonQueryError: (failure) => {\n\t\t\t\tconst code =\n\t\t\t\t\tfailure.error instanceof KoraError ? failure.error.code : failure.error.name || 'Error'\n\t\t\t\tthis.emitter?.emit({\n\t\t\t\t\ttype: 'query:error',\n\t\t\t\t\tqueryId: failure.queryId,\n\t\t\t\t\tcollection: failure.collection,\n\t\t\t\t\tphase: failure.phase,\n\t\t\t\t\tcode,\n\t\t\t\t\tmessage: failure.error.message,\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Open the store: initialize the database, load or generate a node ID,\n\t * restore the sequence number and version vector, and create Collection instances.\n\t */\n\tasync open(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.adapter.open(this.schema)\n\t\t} catch (error) {\n\t\t\tconst ahead =\n\t\t\t\terror instanceof SchemaVersionAheadError\n\t\t\t\t\t? { stored: error.storedVersion, code: error.codeVersion }\n\t\t\t\t\t: parseSchemaAhead(error)\n\t\t\tif (ahead !== null) throw this.schemaAhead(ahead.stored)\n\t\t\tthrow error\n\t\t}\n\t\t// A database a newer build already migrated is refused before anything here writes\n\t\t// to it (RT-109). The DDL executors refuse it before their DDL; this also covers\n\t\t// adapters that restore their data after it (the IndexedDB fallback).\n\t\tconst stored = storedSchemaVersion(\n\t\t\tawait this.adapter.query<{ value: unknown }>(STORED_SCHEMA_VERSION_SQL),\n\t\t)\n\t\tif (stored > this.schema.version) {\n\t\t\tawait this.adapter.close().catch(() => undefined)\n\t\t\tthrow this.schemaAhead(stored)\n\t\t}\n\t\tawait this.adapter.execute(\n\t\t\t'CREATE TABLE IF NOT EXISTS _kora_scope_retractions (collection TEXT NOT NULL, record_id TEXT NOT NULL, PRIMARY KEY (collection, record_id))',\n\t\t)\n\t\tfor (const ddl of FOLD_TABLES_DDL) await this.adapter.execute(ddl)\n\t\tthis.foldActive = false\n\n\t\t// Tables created before beta.13 restate enum membership and requiredness as CHECK /\n\t\t// NOT NULL constraints that cannot evolve with the schema: rebuild them once without\n\t\t// (RT-101). Validation is the single authority for the value domain.\n\t\tawait relaxValueDomainConstraints(this.adapter, this.schema)\n\t\t// Indexes named under the old, colliding scheme are replaced (STORE-15).\n\t\tawait dropLegacyIndexes(this.adapter, this.schema)\n\n\t\t// Load or generate node ID\n\t\tconst persistedNodeId = await this.readPersistedNodeId()\n\t\tthis.nodeId = await this.loadOrGenerateNodeId()\n\t\t// Every node id this database authors under is registered (RT-38, RT-40).\n\t\tawait registerLocalNode(this.adapter, this.nodeId)\n\t\tawait this.registerUnregisteredAuthors(persistedNodeId)\n\n\t\t// Log integrity first (W8 step 0): repair rows an earlier release damaged and\n\t\t// quarantine the unrecoverable ones, before anything reads or folds the log.\n\t\tawait this.scanLog('quick')\n\n\t\t// (node_id, sequence_number) is unique in the operation log: repair any\n\t\t// duplicates an earlier version wrote, then enforce it with an index (W6).\n\t\tawait repairSequenceUniqueness(this.adapter, this.schema, this.nodeId)\n\t\t// The terminal rejections an earlier release kept only in the app's list become\n\t\t// durable markers (RT-36).\n\t\tawait seedTerminalRejectionsOnce(this.adapter)\n\t\t// Raw-string columns use the lossless stored-text codec (RT-65); rows written\n\t\t// before it get their U+FFFF re-encoded once, before anything reads them.\n\t\tawait ensureStoredTextCodec(this.adapter, this.schema)\n\t\tif (this.isolation === 'per-tab' && !this.configNodeId) {\n\t\t\t// A live tab holds its node's lock, so a later tab adopts the node's unsynced\n\t\t\t// writes only after this tab is gone (RT-40).\n\t\t\tthis.releaseNodeLock = acquireNodeLock(nodeLockName(this.dbName, this.nodeId))\n\t\t}\n\t\tthis.clock = new HybridLogicalClock(this.nodeId)\n\t\tthis.causalTracker = new CausalTracker()\n\n\t\t// The fold is active for writes as soon as the database's rows are known to be\n\t\t// fold materializations (W7); a pre-W7 database is re-materialized after its\n\t\t// schema migrations, whose backfills then write the legacy way.\n\t\tif (this.folder) {\n\t\t\tthis.folder.setAuthoritativeNodeIds((await loadAuthoritativeNodeIds(this.adapter)) ?? [])\n\t\t\tthis.foldActive =\n\t\t\t\t(await this.readMeta(FOLD_MATERIALIZATION_META_KEY)) === FOLD_MATERIALIZATION_CURRENT\n\t\t}\n\n\t\t// Run schema migrations if needed. Backfills write operations through the local\n\t\t// write path, so the node id and clock must exist first (STORE-13).\n\t\ttry {\n\t\t\t// Transforms that cannot read the stored log would fold those operations as\n\t\t\t// absent and erase them from their records: refuse to open instead (RT-103).\n\t\t\tawait this.assertTransformCoverage()\n\t\t\tawait this.runMigrationsIfNeeded()\n\t\t\tawait this.ensureLegacyBodiesCanonical()\n\t\t\tawait this.ensureMaterialization()\n\t\t} catch (error) {\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = null\n\t\t\tthrow error\n\t\t}\n\n\t\t// Initialize sequence manager\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\n\t\t// Load sequence number and version vector\n\t\tthis.sequenceNumber = await this.loadSequenceNumber()\n\t\tthis.versionVector = await this.loadVersionVector()\n\n\t\t// Create RelationEnforcer if the schema has relations.\n\t\t// The enforcer is shared across all Collection instances so that\n\t\t// cascading deletes can cross collection boundaries.\n\t\tconst hasRelations = Object.keys(this.schema.relations).length > 0\n\t\tthis.relationEnforcer = hasRelations ? new RelationEnforcer({ schema: this.schema }) : null\n\n\t\t// Create collection instances\n\t\tfor (const [name, definition] of Object.entries(this.schema.collections)) {\n\t\t\tconst col = new Collection(\n\t\t\t\tname,\n\t\t\t\tdefinition,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.adapter,\n\t\t\t\tthis.clock,\n\t\t\t\tthis.nodeId,\n\t\t\t\t(collectionName, operation) => this.publishLocalOperation(collectionName, operation),\n\t\t\t\tthis.relationEnforcer,\n\t\t\t\tthis.localMutationHandler,\n\t\t\t\tthis.causalTracker,\n\t\t\t\tthis.secretKeyProvider,\n\t\t\t\t(error) => this.reportStorageError(error),\n\t\t\t\t() => this.activeFold(),\n\t\t\t\tthis.maxOperationBytes,\n\t\t\t\t() => this.assertLocalWriteAllowed(),\n\t\t\t)\n\t\t\tthis.collections.set(name, col)\n\t\t}\n\n\t\tthis.opened = true\n\t}\n\n\t/**\n\t * Close the store: clear subscriptions and close the adapter.\n\t */\n\tasync close(): Promise<void> {\n\t\tthis.subscriptionManager.clear()\n\t\tthis.collections.clear()\n\t\tthis.opened = false\n\t\ttry {\n\t\t\tawait this.adapter.close()\n\t\t} finally {\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = null\n\t\t}\n\t}\n\n\t/**\n\t * Check the operation log (W8 step 0): every row must round-trip through the\n\t * canonical operation serializer. Rows an earlier release damaged in a recoverable\n\t * way (a JSON-encoded timestamp written by a beta.12 backup restore) are repaired;\n\t * unrecoverable rows move to the quarantine table, where no fold reads them. Also\n\t * reports sequence gaps in this database's own nodes (compaction, a lost tail).\n\t *\n\t * The store runs a quick variant (SQL prefilter) on every open. Rebuilding state from\n\t * the log must only run on a `clean` report.\n\t *\n\t * @param options - `repair: false` only reports; `mode: 'quick'` checks only the rows\n\t * a SQL prefilter flags (default `'full'`: every row)\n\t * @returns The integrity report; emits `store:log-integrity` when rows changed\n\t */\n\tasync verifyLogIntegrity(options?: {\n\t\trepair?: boolean\n\t\tmode?: 'full' | 'quick'\n\t}): Promise<LogIntegrityReport> {\n\t\tthis.ensureOpen()\n\t\treturn this.scanLog(options?.mode ?? 'full', options?.repair ?? true)\n\t}\n\n\tprivate async scanLog(mode: 'full' | 'quick', repair = true): Promise<LogIntegrityReport> {\n\t\tconst localNodeIds = (await listLocalNodes(this.adapter)).map((node) => node.nodeId)\n\t\tconst report = await scanLogIntegrity(this.adapter, this.schema, {\n\t\t\tmode,\n\t\t\trepair,\n\t\t\tlocalNodeIds,\n\t\t})\n\t\tif (repair && (report.repaired.length > 0 || report.newlyQuarantined.length > 0)) {\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:log-integrity',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\trepaired: report.repaired.length,\n\t\t\t\tquarantined: report.newlyQuarantined.length,\n\t\t\t\tgaps: report.gaps.length,\n\t\t\t\tclean: report.clean,\n\t\t\t\tmessage: `Operation log of \"${this.dbName}\": ${report.repaired.length} row(s) repaired, ${report.newlyQuarantined.length} row(s) quarantined (${LOG_QUARANTINE_TABLE}).`,\n\t\t\t})\n\t\t}\n\t\treturn report\n\t}\n\n\t/**\n\t * Get a Collection instance for CRUD operations.\n\t * @throws {StoreNotOpenError} If the store is not open\n\t * @throws {Error} If the collection name is not in the schema\n\t */\n\tcollection(name: string): CollectionAccessor {\n\t\tthis.ensureOpen()\n\t\tconst col = this.collections.get(name)\n\t\tif (!col) {\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown collection \"${name}\". Available: ${[...this.collections.keys()].join(', ')}`,\n\t\t\t)\n\t\t}\n\n\t\tconst definition = this.schema.collections[name]\n\t\tif (!definition) {\n\t\t\tthrow new Error(`Collection definition not found for \"${name}\"`)\n\t\t}\n\n\t\treturn {\n\t\t\tinsert: (data: Record<string, unknown>) => col.insert(data),\n\t\t\tfindById: (id: string) => col.findById(id),\n\t\t\tupdate: (id: string, data: Record<string, unknown>) => col.update(id, data),\n\t\t\tdelete: (id: string) => col.delete(id),\n\t\t\twhere: (conditions) =>\n\t\t\t\tnew QueryBuilder(\n\t\t\t\t\tname,\n\t\t\t\t\tdefinition,\n\t\t\t\t\tthis.adapter,\n\t\t\t\t\tthis.subscriptionManager,\n\t\t\t\t\tconditions,\n\t\t\t\t\tthis.schema,\n\t\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the current version vector.\n\t */\n\tgetVersionVector(): VersionVector {\n\t\tthis.ensureOpen()\n\t\treturn new Map(this.versionVector)\n\t}\n\n\t/**\n\t * Get the node ID for this store instance.\n\t */\n\t/**\n\t * Records the offset between server time and this device's clock\n\t * (serverTime - localTime), learned at sync handshake. Lets the store's HLC\n\t * validate remote timestamps correctly even when the local clock is wrong.\n\t */\n\tsetClockReferenceOffset(offsetMs: number): void {\n\t\tthis.clock?.setReferenceOffset(offsetMs)\n\t}\n\n\tgetNodeId(): string {\n\t\tthis.ensureOpen()\n\t\treturn this.nodeId\n\t}\n\n\t/** The schema transforms the fold applies (transforms at fold time, RT-84). */\n\tgetOperationTransforms(): readonly OperationTransform[] {\n\t\treturn this.operationTransforms\n\t}\n\n\t/**\n\t * Apply a remote operation received from sync.\n\t * Checks for duplicates, applies to the data table, persists the operation,\n\t * and updates the version vector.\n\t */\n\tasync applyRemoteOperation(\n\t\tstored: Operation,\n\t\toptions?: ApplyRemoteOptions,\n\t): Promise<ApplyResult> {\n\t\tthis.ensureOpen()\n\n\t\tconst collection = stored.collection\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) {\n\t\t\treturn 'skipped'\n\t\t}\n\t\tconst fold = this.activeFold()\n\t\tif (fold) {\n\t\t\t// The fold reads the operation through the schema transforms itself (RT-84).\n\t\t\treturn this.applyRemoteFolded(stored, fold, options)\n\t\t}\n\t\t// Legacy materialization writes rows directly: it materializes the operation as\n\t\t// this schema reads it, and logs the operation exactly as written (RT-84).\n\t\tconst view = operationSchemaView(stored, this.schema.version, this.operationTransforms)\n\t\tif (view === null) return 'skipped'\n\t\tconst op = view\n\n\t\t// Materialization may use overridden data/timestamp (authoritative merge\n\t\t// results), but the LOG below always stores the canonical operation:\n\t\t// operations are immutable and content-addressed, so merged values must\n\t\t// never be persisted under the original operation's id.\n\t\tconst materializeTimestamp = options?.materializeTimestamp ?? op.timestamp\n\t\tconst remoteVersion = serializeRowVersion(materializeTimestamp)\n\t\tconst wallTime = materializeTimestamp.wallTime\n\t\tconst materializeSource = options?.materializeData ?? op.data\n\t\t// Duration is reported to DevTools only; it never orders anything.\n\t\tconst startedAt = Date.now()\n\t\tconst outcome = { duplicate: false, revived: false }\n\n\t\t// Apply the operation to the data table (LWW-guarded; op log always appended below)\n\t\ttry {\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\t// Content-addressed dedup INSIDE the write transaction: two concurrent\n\t\t\t\t// deliveries of one operation serialize here, and the second sees the\n\t\t\t\t// first's row instead of failing on the primary key (STORE-15).\n\t\t\t\tif (await isOperationLogged(tx, collection, op.id)) {\n\t\t\t\t\toutcome.duplicate = true\n\t\t\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tif (retracted.length > 0) {\n\t\t\t\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 0 WHERE id = ?`, [\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t])\n\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t)\n\t\t\t\t\t\toutcome.revived = true\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Advance the local HLC; severe clock drift throws ClockDriftError (surfaced as sync:apply-failed).\n\t\t\t\tif (this.clock) {\n\t\t\t\t\t// A scope entry's newest field version can be later than its timestamp (the\n\t\t\t\t\t// record's creation, RT-27): the clock must move past every version it carries.\n\t\t\t\t\tthis.clock.receive(op.fieldVersions ? newestFieldVersion(op) : op.timestamp)\n\t\t\t\t}\n\n\t\t\t\t// Optimistic-concurrency guard: if the caller computed its data from a\n\t\t\t\t// snapshot, verify the row hasn't changed since. Throwing rolls the\n\t\t\t\t// whole transaction back (nothing written, op NOT logged) so the caller\n\t\t\t\t// can recompute against fresh state and retry.\n\t\t\t\tconst checkGuard = (row: RawCollectionRow | undefined): void => {\n\t\t\t\t\tconst guard = options?.guardRowState\n\t\t\t\t\tif (!guard) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst version = typeof row?._version === 'string' ? row._version : null\n\t\t\t\t\tconst fieldVersions =\n\t\t\t\t\t\ttypeof row?._field_versions === 'string' ? row._field_versions : null\n\t\t\t\t\tif (version !== guard.version || fieldVersions !== guard.fieldVersions) {\n\t\t\t\t\t\tthrow new OptimisticLockError(collection, op.recordId)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (options?.logOnly) {\n\t\t\t\t\t// Append-only: the caller (after folding the record's log) determined\n\t\t\t\t\t// this op does not change the authoritative row. Persist it for future\n\t\t\t\t\t// folds but leave the row untouched. Fall through to op-log insert + VV.\n\t\t\t\t} else if (\n\t\t\t\t\top.type === 'insert' &&\n\t\t\t\t\top.data &&\n\t\t\t\t\top.fieldVersions &&\n\t\t\t\t\t!options?.materializeData &&\n\t\t\t\t\t!options?.forceMaterialize &&\n\t\t\t\t\t!options?.materializeTimestamp\n\t\t\t\t) {\n\t\t\t\t\t// Server scope-entry insert (RT-27): every field carries its own version.\n\t\t\t\t\tawait this.applyFieldVersionedInsert(tx, op, definition, op.data, checkGuard)\n\t\t\t\t} else if (op.type === 'insert' && materializeSource) {\n\t\t\t\t\tconst serializedData = serializeRecord(materializeSource, definition.fields)\n\t\t\t\t\tconst existing = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT _updated_at, _version, _field_versions, _deleted FROM ${collection} WHERE id = ?`,\n\t\t\t\t\t\t[op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst row = existing[0]\n\t\t\t\t\tcheckGuard(row)\n\n\t\t\t\t\tif (!row) {\n\t\t\t\t\t\tconst record: Record<string, unknown> = {\n\t\t\t\t\t\t\tid: op.recordId,\n\t\t\t\t\t\t\t...serializedData,\n\t\t\t\t\t\t\t_created_at: wallTime,\n\t\t\t\t\t\t\t_updated_at: wallTime,\n\t\t\t\t\t\t\t_version: remoteVersion,\n\t\t\t\t\t\t\t// Stamp every inserted field so per-field LWW has a real baseline.\n\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(\n\t\t\t\t\t\t\t\tfieldVersionsForFields(Object.keys(serializedData), remoteVersion),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst insertQuery = buildInsertQuery(collection, record)\n\t\t\t\t\t\tawait tx.execute(insertQuery.sql, insertQuery.params)\n\n\t\t\t\t\t\t// Catch up on operations delivered BEFORE this insert (transports may\n\t\t\t\t\t\t// reorder): any update/delete already logged for this record was\n\t\t\t\t\t\t// applied while no row existed, so it never materialized. The row is\n\t\t\t\t\t\t// a fold of the log — fold the orphans now, in timestamp order,\n\t\t\t\t\t\t// inside this same transaction. Per-field LWW makes the result\n\t\t\t\t\t\t// identical to what an in-order device computed.\n\t\t\t\t\t\tawait this.foldOrphanedOperations(tx, collection, definition, op.recordId, op)\n\t\t\t\t\t} else if (\n\t\t\t\t\t\trow._deleted === 1 &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait tx.query<{ record_id: string }>(\n\t\t\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\t// The row is hidden by a scope retraction (a view change, not a domain\n\t\t\t\t\t\t// delete) and the record is entering the scope again, typically through\n\t\t\t\t\t\t// a server scope-entry insert (RT-19). Show it again and merge per field,\n\t\t\t\t\t\t// exactly like an insert collision on a live row: fields this device\n\t\t\t\t\t\t// holds newer versions of are kept.\n\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\tparseFieldVersions(row._field_versions),\n\t\t\t\t\t\t\tObject.keys(serializedData),\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\ttypeof row._version === 'string' ? row._version : undefined,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t_deleted: 0,\n\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// `_created_at` is left alone: the record was created long before it\n\t\t\t\t\t\t// re-entered this device's view.\n\t\t\t\t\t\tconst reactivate = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tawait tx.execute(reactivate.sql, reactivate.params)\n\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (row._deleted === 1) {\n\t\t\t\t\t\t// Insert vs tombstone: a strictly newer insert resurrects the record\n\t\t\t\t\t\t// with its full field set; an older one is stale (delete wins).\n\t\t\t\t\t\tif (isIncomingNewerThanRow(materializeTimestamp, row)) {\n\t\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t...serializedData,\n\t\t\t\t\t\t\t\t_deleted: 0,\n\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(\n\t\t\t\t\t\t\t\t\tfieldVersionsForFields(Object.keys(serializedData), remoteVersion),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst upsert = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t\t{ maxCreatedAt: wallTime },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tawait tx.execute(upsert.sql, upsert.params)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Insert collision on a LIVE row (relayed insert racing a local one,\n\t\t\t\t\t\t// or an insert-vs-insert merge). A plain INSERT would violate the\n\t\t\t\t\t\t// primary key; resolve per-field instead, exactly like an update, so\n\t\t\t\t\t\t// every node converges no matter which insert (or interleaved\n\t\t\t\t\t\t// update) it saw first. `_created_at` converges to the max insert\n\t\t\t\t\t\t// wall time seen, applied even when every field loses.\n\t\t\t\t\t\tconst currentVersions = parseFieldVersions(row._field_versions)\n\t\t\t\t\t\tconst rowVersion = typeof row._version === 'string' ? row._version : undefined\n\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {}\n\t\t\t\t\t\tlet fieldVersionsJson: string\n\t\t\t\t\t\tif (options?.forceMaterialize) {\n\t\t\t\t\t\t\t// Authoritative merged insert: every field is written.\n\t\t\t\t\t\t\tconst merged = { ...currentVersions }\n\t\t\t\t\t\t\tfor (const field of Object.keys(serializedData)) {\n\t\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t\t\tmerged[field] = remoteVersion\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfieldVersionsJson = serializeFieldVersions(merged)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\t\tcurrentVersions,\n\t\t\t\t\t\t\t\tObject.keys(serializedData),\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\trowVersion,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\t\tfieldChanges[field] = serializedData[field]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfieldVersionsJson = serializeFieldVersions(merged)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst upsert = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t{ ...fieldChanges, _field_versions: fieldVersionsJson },\n\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t{ maxCreatedAt: wallTime },\n\t\t\t\t\t\t)\n\t\t\t\t\t\tawait tx.execute(upsert.sql, upsert.params)\n\t\t\t\t\t}\n\t\t\t\t} else if (op.type === 'update' && materializeSource) {\n\t\t\t\t\tconst serializedChanges = serializeRecord(materializeSource, definition.fields)\n\t\t\t\t\tconst changedFields = Object.keys(serializedChanges)\n\n\t\t\t\t\t// Read the current per-field versions INSIDE the transaction so the\n\t\t\t\t\t// resolve-then-write is atomic with respect to any concurrent local\n\t\t\t\t\t// mutation — this is what prevents a relayed remote op from clobbering\n\t\t\t\t\t// a newer local edit that lands between the read and the write.\n\t\t\t\t\tconst currentRows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t\t[op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tconst currentRow = currentRows[0]\n\t\t\t\t\tcheckGuard(currentRow)\n\n\t\t\t\t\tif (currentRow) {\n\t\t\t\t\t\tconst currentVersions = parseFieldVersions(currentRow._field_versions)\n\t\t\t\t\t\tconst rowVersion =\n\t\t\t\t\t\t\ttypeof currentRow._version === 'string' ? currentRow._version : undefined\n\n\t\t\t\t\t\tif (options?.forceMaterialize) {\n\t\t\t\t\t\t\t// Authoritative merged result (richtext / add-wins-set / constraint\n\t\t\t\t\t\t\t// resolution computed by the merge engine): write every changed\n\t\t\t\t\t\t\t// field and stamp its per-field version to this op's version, while\n\t\t\t\t\t\t\t// advancing the row watermark monotonically.\n\t\t\t\t\t\t\tconst merged = { ...currentVersions }\n\t\t\t\t\t\t\tfor (const field of changedFields) {\n\t\t\t\t\t\t\t\tmerged[field] = remoteVersion\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst fieldChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t...serializedChanges,\n\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\tfieldChanges._deleted = 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst forceQuery = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\tfieldChanges,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tawait tx.execute(forceQuery.sql, forceQuery.params)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Deterministic field-level LWW: write only the fields this op\n\t\t\t\t\t\t\t// wins (strictly newer than the field's stored version). Same\n\t\t\t\t\t\t\t// result on every node regardless of arrival order.\n\t\t\t\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\t\t\t\tcurrentVersions,\n\t\t\t\t\t\t\t\tchangedFields,\n\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\trowVersion,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tif (winners.length > 0 || options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\tconst winningChanges: Record<string, unknown> = {\n\t\t\t\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\t\t\t\twinningChanges[field] = serializedChanges[field]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (options?.reactivateIfDeleted) {\n\t\t\t\t\t\t\t\t\twinningChanges._deleted = 0\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst forceQuery = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\t\t\t\tcollection,\n\t\t\t\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\t\t\t\twinningChanges,\n\t\t\t\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t\t\t\t\twallTime,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tawait tx.execute(forceQuery.sql, forceQuery.params)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// currentRow absent: nothing materialized to update (insert not yet\n\t\t\t\t\t// applied, or hard-absent). The op is still appended to the log below;\n\t\t\t\t\t// the pipeline handles tombstone reactivation separately.\n\t\t\t\t} else if (op.type === 'delete') {\n\t\t\t\t\tconst deleteQuery = buildLwwSoftDeleteQuery(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\top.recordId,\n\t\t\t\t\t\twallTime,\n\t\t\t\t\t\tremoteVersion,\n\t\t\t\t\t)\n\t\t\t\t\tawait tx.execute(deleteQuery.sql, deleteQuery.params)\n\t\t\t\t}\n\n\t\t\t\t// Persist the operation\n\t\t\t\tawait this.appendRemoteOperationRow(tx, stored)\n\n\t\t\t\t// Version vector: MAX with the stored value, never a value computed outside\n\t\t\t\t// this transaction (another tab may have advanced it). The in-memory\n\t\t\t\t// vector is updated only after commit.\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t\t\t)\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.reportStorageError(error)\n\t\t\tthrow error\n\t\t}\n\n\t\t// Committed. A duplicate still advances this runtime's vector and refreshes\n\t\t// its queries: another tab sharing the database may have applied the\n\t\t// operation first, and this tab must not stay blind to it (STORE-10).\n\t\tthis.recordOperationSequence(op)\n\t\tif (outcome.duplicate) {\n\t\t\tif (outcome.revived) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t} else {\n\t\t\t\tthis.subscriptionManager.notify(collection, op)\n\t\t\t}\n\t\t\treturn 'duplicate'\n\t\t}\n\n\t\tthis.subscriptionManager.notify(collection, op)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'operation:applied',\n\t\t\toperation: op,\n\t\t\tduration: Date.now() - startedAt,\n\t\t})\n\n\t\treturn 'applied'\n\t}\n\n\t/**\n\t * W7 remote apply: append the operation, then merge it into its record's fold\n\t * state, which re-materializes the row, all in one write transaction. There is no\n\t * read-decide-write race to guard: the state is read and written inside the\n\t * transaction, and the merge does not depend on the order operations arrive in.\n\t */\n\tprivate async applyRemoteFolded(\n\t\top: Operation,\n\t\tfold: RecordFolder,\n\t\toptions: ApplyRemoteOptions | undefined,\n\t): Promise<ApplyResult> {\n\t\tconst collection = op.collection\n\t\tconst startedAt = Date.now()\n\t\tconst outcome = { duplicate: false, revived: false, traces: [] as MergeTrace[] }\n\t\ttry {\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tif ((await isOperationLogged(tx, collection, op.id)) || (await isCompacted(tx, op))) {\n\t\t\t\t\toutcome.duplicate = true\n\t\t\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t\tif (retracted.length > 0) {\n\t\t\t\t\t\t// The record re-enters the scope: show it again with every field of\n\t\t\t\t\t\t// its state (writes merged while it was hidden included).\n\t\t\t\t\t\tconst state = await fold.loadState(tx, collection, op.recordId)\n\t\t\t\t\t\tif (state) {\n\t\t\t\t\t\t\tawait fold.materializeRow(tx, state, 'all', { clearRetraction: true })\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutcome.revived = true\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (this.clock) {\n\t\t\t\t\t// A scope entry's newest field version can be later than its timestamp (the\n\t\t\t\t\t// record's creation, RT-27): the clock must move past every version it carries.\n\t\t\t\t\tthis.clock.receive(op.fieldVersions ? newestFieldVersion(op) : op.timestamp)\n\t\t\t\t}\n\t\t\t\tawait this.appendRemoteOperationRow(tx, op)\n\t\t\t\tconst applied = await fold.applyInTx(tx, op, 'remote')\n\t\t\t\toutcome.traces = applied.traces\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t\t\t)\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tthis.reportStorageError(error)\n\t\t\tthrow error\n\t\t}\n\n\t\tthis.recordOperationSequence(op)\n\t\tif (outcome.duplicate) {\n\t\t\tif (outcome.revived) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t} else {\n\t\t\t\tthis.subscriptionManager.notify(collection, op)\n\t\t\t}\n\t\t\treturn 'duplicate'\n\t\t}\n\t\tthis.subscriptionManager.notify(collection, op)\n\t\tthis.emitMergeTraces(op, outcome.traces)\n\t\toptions?.onMergeTraces?.(outcome.traces)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'operation:applied',\n\t\t\toperation: op,\n\t\t\tduration: Date.now() - startedAt,\n\t\t})\n\t\treturn 'applied'\n\t}\n\n\t/** DevTools: every fold decision that was a conflict, plus one completion per merge. */\n\tprivate emitMergeTraces(op: Operation, traces: MergeTrace[]): void {\n\t\tif (!this.emitter || traces.length === 0) return\n\t\tconst first = traces[0] as MergeTrace\n\t\tthis.emitter.emit({ type: 'merge:started', operationA: first.operationA, operationB: op })\n\t\tfor (const trace of traces) this.emitter.emit({ type: 'merge:conflict', trace })\n\t\tthis.emitter.emit({ type: 'merge:completed', trace: first })\n\t}\n\n\t/** The record fold, once the database's rows are fold materializations. */\n\tprivate activeFold(): RecordFolder | undefined {\n\t\treturn this.foldActive && this.folder ? this.folder : undefined\n\t}\n\n\t/**\n\t * The record's W7 fold state (null under legacy materialization or when the\n\t * record has none). For DevTools, tests and the server-comparison harness.\n\t */\n\tasync getFoldState(collection: string, recordId: string): Promise<FoldState | null> {\n\t\tthis.ensureOpen()\n\t\tconst fold = this.activeFold()\n\t\tif (!fold) return null\n\t\tlet state: FoldState | null = null\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tstate = await fold.loadState(tx, collection, recordId)\n\t\t})\n\t\treturn state\n\t}\n\n\t/** Whether rows are materialized by the W7 fold (false under `materialization: 'legacy'`). */\n\tisFoldMaterialized(): boolean {\n\t\treturn this.activeFold() !== undefined\n\t}\n\n\tprivate async readMeta(key: string): Promise<string | null> {\n\t\tconst rows = await this.adapter.query<MetaRow>('SELECT value FROM _kora_meta WHERE key = ?', [\n\t\t\tkey,\n\t\t])\n\t\treturn rows[0]?.value ?? null\n\t}\n\n\tprivate async writeMeta(key: string, value: string): Promise<void> {\n\t\tawait this.adapter.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tkey,\n\t\t\tvalue,\n\t\t])\n\t}\n\n\t/**\n\t * Write every genuine beta.12 clear of the op log into its logged body, once per\n\t * database (RT-83, RT-85): the fold folds bodies as written, so the clear must be in\n\t * the body. Records already materialized by the fold are re-folded.\n\t */\n\tprivate async ensureLegacyBodiesCanonical(): Promise<void> {\n\t\tconst folder = this.folder\n\t\tif (!folder) return\n\t\tif ((await this.readMeta(LEGACY_BODIES_META_KEY)) !== null) return\n\t\tconst rewritten = await canonicalizeLegacyLogBodies(this.adapter, this.schema, this.nodeId)\n\t\tif (rewritten.length > 0 && this.foldActive) {\n\t\t\tconst seen = new Set<string>()\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tfor (const { collection, recordId } of rewritten) {\n\t\t\t\t\tconst key = `${collection}\\u0000${recordId}`\n\t\t\t\t\tif (seen.has(key)) continue\n\t\t\t\t\tseen.add(key)\n\t\t\t\t\tawait folder.refoldInTx(tx, collection, recordId)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tawait this.writeMeta(LEGACY_BODIES_META_KEY, String(rewritten.length))\n\t}\n\n\t/**\n\t * Make every row a materialization of its record's fold state (W7), once per\n\t * database and fold-state version. Runs after the W8 log-integrity scan: a\n\t * clean log is rebuilt with the fold; an incomplete (compacted) log rebuilds on\n\t * top of the rows as base snapshots; a log with quarantined rows is never\n\t * rebuilt from (rows are kept and become base snapshots), and\n\t * `store:rematerialized` reports which happened.\n\t */\n\tprivate async ensureMaterialization(forceSnapshot = false): Promise<void> {\n\t\tconst current = await this.readMeta(FOLD_MATERIALIZATION_META_KEY)\n\t\tif (!this.folder) {\n\t\t\tif (current !== FOLD_MATERIALIZATION_LEGACY) {\n\t\t\t\tawait this.writeMeta(FOLD_MATERIALIZATION_META_KEY, FOLD_MATERIALIZATION_LEGACY)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (current === FOLD_MATERIALIZATION_CURRENT) {\n\t\t\tthis.foldActive = true\n\t\t\tawait this.ensureFoldPlan()\n\t\t\treturn\n\t\t}\n\t\tconst report = await this.scanLog('full')\n\t\t// Only the records that own a quarantined row are kept as they are (RT-68); the\n\t\t// rest are rebuilt from a log that is complete for them unless it was compacted\n\t\t// or has holes.\n\t\tconst kept = await loadQuarantinedRecords(this.adapter)\n\t\t// A hole in an own node's sequence that a quarantined row explains belongs to\n\t\t// that row's record (kept above), not to the whole log.\n\t\tconst quarantinedSeqs = new Set(\n\t\t\treport.quarantined.map((row) => `${row.nodeId ?? ''}\\u0000${row.sequenceNumber ?? ''}`),\n\t\t)\n\t\tconst unexplainedGaps = report.gaps.filter((gap) => {\n\t\t\tfor (let s = gap.from; s <= gap.to; s++) {\n\t\t\t\tif (!quarantinedSeqs.has(`${gap.nodeId}\\u0000${s}`)) return true\n\t\t\t}\n\t\t\treturn false\n\t\t})\n\t\tconst mode: Exclude<RematerializationMode, 'kept'> =\n\t\t\t!forceSnapshot && unexplainedGaps.length === 0 && report.compactedAt === null\n\t\t\t\t? 'log'\n\t\t\t\t: 'snapshot+log'\n\t\tconst result = await rematerializeDatabase(this.adapter, this.schema, this.folder, mode, kept)\n\t\tawait this.writeMeta(FOLD_MATERIALIZATION_META_KEY, FOLD_MATERIALIZATION_CURRENT)\n\t\tawait this.writeMeta(\n\t\t\tFOLD_PLAN_META_KEY,\n\t\t\tJSON.stringify(foldPlanFingerprints(this.schema, this.operationTransforms)),\n\t\t)\n\t\tthis.foldActive = true\n\t\tif (result.snapshots > 0) await this.requestSnapshotResync()\n\t\tif (result.changedRows > 0) {\n\t\t\t// Other tabs on this database hear about it once the bus is wired (RT-98).\n\t\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t\t}\n\t\t}\n\t\tif (result.records > 0) {\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:rematerialized',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\tmode: result.mode,\n\t\t\t\trecords: result.records,\n\t\t\t\tchangedRows: result.changedRows,\n\t\t\t\tmessage:\n\t\t\t\t\tresult.mode === 'kept'\n\t\t\t\t\t\t? `Operation log of \"${this.dbName}\" has quarantined rows: the records that own them were kept as they were (row snapshots); ${result.records} record(s) re-materialized, ${result.changedRows} row(s) changed.`\n\t\t\t\t\t\t: `Re-materialized ${result.records} record(s) of \"${this.dbName}\" with the per-field fold (${result.mode}); ${result.changedRows} row(s) changed.`,\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Refuse to open when a schema version in the local operation log has no transform\n\t * path to the current schema (RT-103). Operations of a NEWER schema (authored by an\n\t * upgraded peer) are not checked: they are kept aside until this device upgrades.\n\t */\n\tprivate async assertTransformCoverage(): Promise<void> {\n\t\tconst transforms = this.operationTransforms\n\t\tif (transforms === undefined || transforms.length === 0) return\n\t\tconst versions = new Set<number>()\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<{ v: number }>(\n\t\t\t\t`SELECT DISTINCT schema_version AS v FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst version = Number(row.v)\n\t\t\t\tif (version < this.schema.version) versions.add(version)\n\t\t\t}\n\t\t}\n\t\tassertOperationTransformCoverage(\n\t\t\tversions,\n\t\t\tthis.schema.version,\n\t\t\ttransforms,\n\t\t\t`local database \"${this.dbName}\"`,\n\t\t)\n\t}\n\n\t/**\n\t * Re-fold the records of every collection whose fold plan changed since the rows\n\t * were materialized (RT-63): a field that became `merge('counter')`, an array that\n\t * became append-only, a new or edited resolver. Their stored states hold fields of\n\t * the old kind, which the fold refuses (`FoldStateError`). Each record is rebuilt\n\t * from its log with the new plan; compacted bases and row snapshots are adapted\n\t * (a re-planned field restarts from its materialized value at its version). The\n\t * client's equivalent of the server stores' `fold_plan_fingerprint`.\n\t */\n\tprivate async ensureFoldPlan(): Promise<void> {\n\t\tconst folder = this.folder\n\t\tif (!folder) return\n\t\tconst current = foldPlanFingerprints(this.schema, this.operationTransforms)\n\t\tconst storedRaw = await this.readMeta(FOLD_PLAN_META_KEY)\n\t\tlet changed: string[]\n\t\tif (storedRaw === null) {\n\t\t\t// Materialized before the fingerprint was recorded: re-fold the collections\n\t\t\t// whose stored states actually hold a field of another kind.\n\t\t\tchanged = await collectionsWithMismatchedStates(this.adapter, this.schema)\n\t\t} else {\n\t\t\tlet stored: Record<string, unknown> = {}\n\t\t\ttry {\n\t\t\t\tstored = JSON.parse(storedRaw) as Record<string, unknown>\n\t\t\t} catch {\n\t\t\t\tstored = {}\n\t\t\t}\n\t\t\tchanged = Object.keys(current).filter((name) => stored[name] !== current[name])\n\t\t}\n\t\tif (changed.length > 0) {\n\t\t\tconst result = await rematerializeDatabase(\n\t\t\t\tthis.adapter,\n\t\t\t\tthis.schema,\n\t\t\t\tfolder,\n\t\t\t\t'log',\n\t\t\t\tundefined,\n\t\t\t\tchanged,\n\t\t\t)\n\t\t\tif (result.snapshots > 0) await this.requestSnapshotResync()\n\t\t\tfor (const collection of changed) this.subscriptionManager.invalidate(collection)\n\t\t\tthis.emitter?.emit({\n\t\t\t\ttype: 'store:rematerialized',\n\t\t\t\tdbName: this.dbName,\n\t\t\t\tmode: result.mode,\n\t\t\t\trecords: result.records,\n\t\t\t\tchangedRows: result.changedRows,\n\t\t\t\tmessage: `The fold plan of ${changed.map((name) => `\"${name}\"`).join(', ')} changed (schema): re-folded ${result.records} record(s) of \"${this.dbName}\"; ${result.changedRows} row(s) changed.`,\n\t\t\t})\n\t\t}\n\t\tawait this.writeMeta(FOLD_PLAN_META_KEY, JSON.stringify(current))\n\t}\n\n\t/**\n\t * Row snapshots were created (RT-68): ask the sync server for a full resync (the\n\t * delivery watermarks restart at 0, as after a restore), so each such record gets\n\t * its complete history back; {@link settleSnapshotRecords} then drops the\n\t * snapshots once the resync has caught up.\n\t */\n\tprivate async requestSnapshotResync(): Promise<void> {\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tawait tx.execute('UPDATE _kora_meta SET value = ? WHERE key = ? OR key LIKE ?', [\n\t\t\t\t'0',\n\t\t\t\tDELIVERY_WATERMARK_META_KEY,\n\t\t\t\t`${DELIVERY_WATERMARK_META_KEY}:%`,\n\t\t\t])\n\t\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [DELTA_CURSOR_META_KEY])\n\t\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\t\tSNAPSHOT_RESYNC_META_KEY,\n\t\t\t\t'pending',\n\t\t\t])\n\t\t})\n\t}\n\n\t/**\n\t * Records whose state still folds against a row snapshot (approximate: a late\n\t * concurrent write older than a field's version is not folded, RT-68).\n\t */\n\tasync getSnapshotRecords(): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.folder\n\t\tif (!folder) return []\n\t\tlet out: Array<{ collection: string; recordId: string }> = []\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tout = await folder.listSnapshotRecords(tx)\n\t\t})\n\t\treturn out\n\t}\n\n\t/**\n\t * Called by sync when a delivery stream has caught up (its final batch fully\n\t * applied). After the full resync {@link requestSnapshotResync} asked for, every\n\t * row-snapshot record whose insert is back in the log is re-folded from its\n\t * complete history and stops being approximate (RT-68). Also retires the\n\t * provisional cascades of remote deletes (RT-69): the server's own copies were\n\t * delivered by now, and any it did not derive must not stay applied locally.\n\t *\n\t * With `provisionalOnly` only the provisional cascades are retired (RT-93: a stream\n\t * batch from a server that derives no cascades, which is not the end of a resync).\n\t *\n\t * @param options - `provisionalOnly`: leave row snapshots for the next catch-up\n\t * @returns How many snapshots were dropped\n\t */\n\tasync settleAfterCatchUp(options: { provisionalOnly?: boolean } = {}): Promise<number> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.activeFold()\n\t\tif (!folder) return 0\n\t\tconst pending =\n\t\t\toptions.provisionalOnly !== true &&\n\t\t\t(await this.readMeta(SNAPSHOT_RESYNC_META_KEY)) === 'pending'\n\t\tlet settled = 0\n\t\tconst touched = new Set<string>()\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const { collection, recordId } of await folder.listProvisionalRecords(tx)) {\n\t\t\t\tawait folder.deleteProvisional(tx, collection, recordId, null)\n\t\t\t\tawait folder.refoldInTx(tx, collection, recordId)\n\t\t\t\ttouched.add(collection)\n\t\t\t}\n\t\t\tif (pending) {\n\t\t\t\tfor (const { collection, recordId } of await folder.listSnapshotRecords(tx)) {\n\t\t\t\t\tif (await folder.settleSnapshotInTx(tx, collection, recordId)) {\n\t\t\t\t\t\tsettled += 1\n\t\t\t\t\t\ttouched.add(collection)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait tx.execute('DELETE FROM _kora_meta WHERE key = ?', [SNAPSHOT_RESYNC_META_KEY])\n\t\t\t}\n\t\t})\n\t\tfor (const collection of touched) this.subscriptionManager.invalidate(collection)\n\t\treturn settled\n\t}\n\n\t/**\n\t * Apply the cascades / set-nulls of a REMOTE delete as local-only provisional\n\t * effects (RT-69): folded into the children like operations, but never logged,\n\t * sequenced or queued for upload. The server derives and relays its own copy;\n\t * when it arrives (same parent, same record) the provisional effect is retired.\n\t *\n\t * @param parent - The remote delete\n\t * @param effects - Its side effects, as the referential check derived them\n\t */\n\tasync applyProvisionalSideEffects(\n\t\tparent: Operation,\n\t\teffects: ReadonlyArray<{\n\t\t\ttype: 'delete' | 'update'\n\t\t\tcollection: string\n\t\t\trecordId: string\n\t\t\tdata: Record<string, unknown> | null\n\t\t\tpreviousData: Record<string, unknown> | null\n\t\t\truleId: string\n\t\t}>,\n\t): Promise<number> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.activeFold()\n\t\tif (!folder || effects.length === 0) return 0\n\t\tconst touched = new Set<string>()\n\t\tlet applied = 0\n\t\t// Stamped right after the parent (its HLC, next logical ticks), exactly like the\n\t\t// server's copy, so a write to the child later than the delete still wins.\n\t\tconst clock = new HybridLogicalClock(PROVISIONAL_NODE_ID, {\n\t\t\tnow: () => parent.timestamp.wallTime,\n\t\t})\n\t\tclock.advanceTo(parent.timestamp)\n\t\tconst built: Operation[] = []\n\t\tfor (const effect of effects) {\n\t\t\tif (!this.schema.collections[effect.collection]) continue\n\t\t\tconst op: Operation = {\n\t\t\t\tid: await deriveSideEffectOpId(parent.id, `provisional/${effect.ruleId}`, effect.recordId),\n\t\t\t\tnodeId: PROVISIONAL_NODE_ID,\n\t\t\t\ttype: effect.type,\n\t\t\t\tcollection: effect.collection,\n\t\t\t\trecordId: effect.recordId,\n\t\t\t\tdata: effect.type === 'delete' ? null : effect.data,\n\t\t\t\tpreviousData: effect.type === 'delete' ? null : effect.previousData,\n\t\t\t\ttimestamp: clock.now(),\n\t\t\t\tsequenceNumber: 0,\n\t\t\t\tcausalDeps: [parent.id],\n\t\t\t\tschemaVersion: this.schema.version,\n\t\t\t}\n\t\t\tbuilt.push(op)\n\t\t}\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const op of built) {\n\t\t\t\tawait folder.applyProvisionalInTx(tx, op, parent.id)\n\t\t\t\ttouched.add(op.collection)\n\t\t\t\tapplied += 1\n\t\t\t}\n\t\t})\n\t\tfor (const collection of touched) this.subscriptionManager.invalidate(collection)\n\t\treturn applied\n\t}\n\n\t/**\n\t * Node ids whose writes win `merge('server-authoritative')` fields (the server's,\n\t * from the sync handshake). Every `kora:server:` id is authoritative by prefix, so\n\t * only explicit ids (legacy server node ids, configured extras) are kept: the device\n\t * persists the UNION of every explicit id it has learned and never drops one (RT-75).\n\t * Handshakes differ per server instance (each lists what it knows), so a list that\n\t * omits an id is not a revocation.\n\t *\n\t * Revocation is explicit (RT-81): ids a handshake lists in `revokedAuthoritativeNodeIds`\n\t * are removed from the union, persisted as revoked, and never learned again. Records\n\t * of collections with such fields are re-folded only when the explicit set changes\n\t * (grows, or loses a revoked id).\n\t *\n\t * @param nodeIds - The server's authoritative node ids (one handshake's list)\n\t * @param revokedNodeIds - Explicit ids the server revoked (one handshake's list)\n\t */\n\tasync setAuthoritativeNodeIds(\n\t\tnodeIds: readonly string[],\n\t\trevokedNodeIds: readonly string[] = [],\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tconst folder = this.folder\n\t\tconst persisted = await loadAuthoritativeNodeIds(this.adapter)\n\t\tconst persistedRevoked = await loadRevokedAuthoritativeNodeIds(this.adapter)\n\t\tconst revoked = new Set(\n\t\t\t[...persistedRevoked, ...revokedNodeIds].filter((id) => !isServerNodeId(id)),\n\t\t)\n\t\tif (revoked.size > persistedRevoked.length) {\n\t\t\tawait saveRevokedAuthoritativeNodeIds(this.adapter, [...revoked].sort())\n\t\t}\n\t\tconst previous = new Set(\n\t\t\t[...(persisted ?? []), ...(folder ? folder.getAuthoritativeNodeIds() : [])].filter(\n\t\t\t\t(id) => !isServerNodeId(id),\n\t\t\t),\n\t\t)\n\t\tconst known = new Set([...previous].filter((id) => !revoked.has(id)))\n\t\tconst dropped = previous.size - known.size\n\t\tconst learned = [...new Set(nodeIds)].filter(\n\t\t\t(id) => !isServerNodeId(id) && !known.has(id) && !revoked.has(id),\n\t\t)\n\t\tconst next = [...known, ...learned].sort()\n\t\tconst stored = persisted === null ? null : [...persisted].sort()\n\t\tif (stored === null || JSON.stringify(stored) !== JSON.stringify(next)) {\n\t\t\t// One persisted list (`sync_authoritative_node_ids`) serves the fold and the\n\t\t\t// sync engine's verification exemptions, so they can never disagree.\n\t\t\tawait saveAuthoritativeNodeIds(this.adapter, next)\n\t\t}\n\t\tif (!folder) return\n\t\tfolder.setAuthoritativeNodeIds(next)\n\t\tif (learned.length === 0 && dropped === 0) return\n\t\tconst fold = this.activeFold()\n\t\tif (!fold) return\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tif (!fold.hasAuthoritativeFields(collection)) continue\n\t\t\tconst ids = await this.adapter.query<{ record_id: string }>(\n\t\t\t\t`SELECT record_id FROM ${FOLD_STATE_TABLE} WHERE collection = ?`,\n\t\t\t\t[collection],\n\t\t\t)\n\t\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\t\tfor (const { record_id } of ids) await fold.refoldInTx(tx, collection, record_id)\n\t\t\t})\n\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t}\n\t}\n\n\t/**\n\t * Re-fold the records of these operations from base + log (W7 exclusion: an\n\t * operation with a terminal-rejection marker is left out).\n\t */\n\tprivate async refoldRecordsOf(operationIds: readonly string[]): Promise<void> {\n\t\tconst fold = this.activeFold()\n\t\tif (!fold || operationIds.length === 0) return\n\t\tconst touched = new Map<string, Set<string>>()\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\tfor (let i = 0; i < operationIds.length; i += 500) {\n\t\t\t\tconst chunk = operationIds.slice(i, i + 500)\n\t\t\t\tconst rows = await this.adapter.query<{ record_id: string }>(\n\t\t\t\t\t`SELECT DISTINCT record_id FROM ${table} WHERE id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t\tchunk,\n\t\t\t\t)\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst set = touched.get(collection) ?? new Set<string>()\n\t\t\t\t\tset.add(row.record_id)\n\t\t\t\t\ttouched.set(collection, set)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (touched.size === 0) return\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const [collection, records] of touched) {\n\t\t\t\tfor (const recordId of records) await fold.refoldInTx(tx, collection, recordId)\n\t\t\t}\n\t\t})\n\t\tfor (const [collection, records] of touched) {\n\t\t\tthis.subscriptionManager.invalidate(collection, [...records])\n\t\t}\n\t}\n\n\t/**\n\t * Append a remote operation to the log. If another operation of the same node\n\t * already holds its sequence number (a beta.12 device could produce such\n\t * pairs), the log keeps the existing row and this one is recorded in the\n\t * sequence-conflicts table, where dedup and record folds still see it.\n\t */\n\tprivate async appendRemoteOperationRow(tx: Transaction, op: Operation): Promise<void> {\n\t\tconst table = quoteIdent(`_kora_ops_${op.collection}`)\n\t\tconst holder = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${table} WHERE node_id = ? AND sequence_number = ?`,\n\t\t\t[op.nodeId, op.sequenceNumber],\n\t\t)\n\t\tconst opRow = serializeOperation(op)\n\t\tif (holder.length > 0) {\n\t\t\tawait insertConflictRow(\n\t\t\t\ttx,\n\t\t\t\top.collection,\n\t\t\t\topRow,\n\t\t\t\t'remote-sequence-conflict',\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tDate.now(),\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst opInsert = buildInsertQuery(\n\t\t\t`_kora_ops_${op.collection}`,\n\t\t\topRow as unknown as Record<string, unknown>,\n\t\t)\n\t\tawait tx.execute(opInsert.sql, opInsert.params)\n\t}\n\n\t/**\n\t * Hide a record from this client's authorized materialized view. This writes no\n\t * replicated operation and therefore cannot be mistaken for a domain deletion.\n\t * The marker lets a later authoritative backfill reactivate the retained row.\n\t */\n\tasync applyScopeRetraction(collection: string, recordId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) return\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 1 WHERE id = ?`, [recordId])\n\t\t\tawait tx.execute(\n\t\t\t\t'INSERT OR REPLACE INTO _kora_scope_retractions (collection, record_id) VALUES (?, ?)',\n\t\t\t\t[collection, recordId],\n\t\t\t)\n\t\t})\n\t\tthis.subscriptionManager.invalidate(collection, [recordId])\n\t}\n\n\t/** Hide all live rows that no longer match a newly accepted server scope. */\n\tasync applyScopeNarrowing(\n\t\tscopes: Record<string, Record<string, unknown>>,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tthis.ensureOpen()\n\t\tconst retractions: Array<{ collection: string; recordId: string }> = []\n\t\tfor (const [collection, definition] of Object.entries(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE _deleted = 0`,\n\t\t\t)\n\t\t\tconst predicate = scopes[collection]\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst record = deserializeRecord(row, definition.fields)\n\t\t\t\tconst matches =\n\t\t\t\t\tpredicate !== undefined &&\n\t\t\t\t\tObject.entries(predicate).every(([field, expected]) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\texpected &&\n\t\t\t\t\t\t\ttypeof expected === 'object' &&\n\t\t\t\t\t\t\t!Array.isArray(expected) &&\n\t\t\t\t\t\t\t'$in' in expected\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tconst values = (expected as { $in?: unknown }).$in\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\tArray.isArray(values) && values.some((value) => Object.is(record[field], value))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn Object.is(record[field], expected)\n\t\t\t\t\t})\n\t\t\t\tif (!matches) {\n\t\t\t\t\tawait this.applyScopeRetraction(collection, String(record.id))\n\t\t\t\t\tretractions.push({ collection, recordId: String(record.id) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn retractions\n\t}\n\n\t/**\n\t * Materialize a server scope-entry insert (RT-19) whose fields each carry their\n\t * own version (RT-27). The entry restates the record's current server values; a\n\t * single whole-row stamp would let a field the server last wrote long ago\n\t * overwrite this device's newer unsynced edit of it, after which the device's own\n\t * operation uploads and wins on the server (divergence). So every field is resolved\n\t * on its own, by last-write-wins against this row's `_field_versions`:\n\t *\n\t * - no row: inserted with each field stamped at its own version, `_created_at`\n\t * at the record's creation (the entry's `timestamp`), then any orphaned\n\t * updates/deletes are folded in as for any insert;\n\t * - live row, or a row hidden by a scope retraction: per-field LWW (a retracted\n\t * row is shown again; `_created_at` is kept);\n\t * - domain tombstone: revived only when the entry's newest field version is\n\t * newer than the tombstone, then per-field LWW.\n\t *\n\t * Deterministic and idempotent: the outcome depends only on the stored and\n\t * incoming per-field versions, and a re-applied entry wins no field.\n\t */\n\tprivate async applyFieldVersionedInsert(\n\t\ttx: Transaction,\n\t\top: Operation,\n\t\tdefinition: NonNullable<SchemaDefinition['collections'][string]>,\n\t\tdata: Record<string, unknown>,\n\t\tcheckGuard: (row: RawCollectionRow | undefined) => void,\n\t): Promise<void> {\n\t\tconst collection = op.collection\n\t\tconst serialized = serializeRecord(data, definition.fields)\n\t\tconst versions = op.fieldVersions ?? {}\n\t\tconst latest = newestFieldVersion(op)\n\t\tconst latestVersion = serializeRowVersion(latest)\n\t\tconst incoming: FieldVersions = {}\n\t\tfor (const field of Object.keys(serialized)) {\n\t\t\t// A field without its own version (renamed by a schema transform) falls back\n\t\t\t// to the entry's newest version: the single-stamp rule of RT-19.\n\t\t\tconst version = versions[field]\n\t\t\tincoming[field] = version ? serializeRowVersion(version) : latestVersion\n\t\t}\n\n\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t`SELECT _updated_at, _version, _field_versions, _deleted FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[op.recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tcheckGuard(row)\n\n\t\tif (!row) {\n\t\t\tconst record: Record<string, unknown> = {\n\t\t\t\tid: op.recordId,\n\t\t\t\t...serialized,\n\t\t\t\t_created_at: op.timestamp.wallTime,\n\t\t\t\t_updated_at: latest.wallTime,\n\t\t\t\t_version: latestVersion,\n\t\t\t\t_field_versions: serializeFieldVersions(incoming),\n\t\t\t}\n\t\t\tconst insertQuery = buildInsertQuery(collection, record)\n\t\t\tawait tx.execute(insertQuery.sql, insertQuery.params)\n\t\t\tawait this.foldOrphanedOperations(tx, collection, definition, op.recordId, op)\n\t\t\treturn\n\t\t}\n\n\t\tlet retracted = false\n\t\tif (row._deleted === 1) {\n\t\t\tretracted =\n\t\t\t\t(\n\t\t\t\t\tawait tx.query<{ record_id: string }>(\n\t\t\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, op.recordId],\n\t\t\t\t\t)\n\t\t\t\t).length > 0\n\t\t\t// A domain delete newer than everything the entry carries still wins.\n\t\t\tif (!retracted && !isIncomingNewerThanRow(latest, row)) return\n\t\t}\n\n\t\tconst current = parseFieldVersions(row._field_versions)\n\t\tconst rowVersion = typeof row._version === 'string' ? row._version : undefined\n\t\tconst merged: FieldVersions = { ...current }\n\t\tconst changes: Record<string, unknown> = {}\n\t\tfor (const [field, version] of Object.entries(incoming)) {\n\t\t\tif (version > effectiveFieldVersion(current, field, rowVersion)) {\n\t\t\t\tchanges[field] = serialized[field]\n\t\t\t\tmerged[field] = version\n\t\t\t}\n\t\t}\n\t\tif (row._deleted === 1) {\n\t\t\tchanges._deleted = 0\n\t\t}\n\t\tchanges._field_versions = serializeFieldVersions(merged)\n\t\tconst update = buildFieldFastForwardUpdateQuery(\n\t\t\tcollection,\n\t\t\top.recordId,\n\t\t\tchanges,\n\t\t\tlatestVersion,\n\t\t\tlatest.wallTime,\n\t\t)\n\t\tawait tx.execute(update.sql, update.params)\n\t\tif (retracted) {\n\t\t\tawait tx.execute(\n\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t[collection, op.recordId],\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Materialize update/delete operations that were logged for a record BEFORE\n\t * its insert arrived (reordered delivery). Runs inside the insert's write\n\t * transaction, folding each orphan in timestamp order through the exact\n\t * per-field LWW / LWW-delete rules the normal apply paths use, so the final\n\t * row state equals what a device that received the operations in causal\n\t * order computed. Called only when the insert created a previously-absent\n\t * row — in that case every logged update/delete for the record is\n\t * necessarily an orphan (rows are soft-deleted, never removed, so a row\n\t * that is absent now was never materialized).\n\t */\n\tprivate async foldOrphanedOperations(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\tdefinition: NonNullable<SchemaDefinition['collections'][string]>,\n\t\trecordId: string,\n\t\tinsertOp: Operation,\n\t): Promise<void> {\n\t\tconst orphanRows = [\n\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ? AND type IN ('update', 'delete')`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t\t['update', 'delete'],\n\t\t\t)),\n\t\t]\n\t\tif (orphanRows.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst orphans = orphanRows\n\t\t\t.map((r) => deserializeOperationWithCollection(r, collection))\n\t\t\t.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\n\t\tfor (const orphan of orphans) {\n\t\t\tconst orphanVersion = serializeRowVersion(orphan.timestamp)\n\t\t\tconst orphanWall = orphan.timestamp.wallTime\n\n\t\t\tif (orphan.type === 'update' && orphan.data) {\n\t\t\t\tconst orphanChanges = serializeRecord(orphan.data, definition.fields)\n\t\t\t\tconst rows = await tx.query<RawCollectionRow>(\n\t\t\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t\t\t[recordId],\n\t\t\t\t)\n\t\t\t\tconst current = rows[0]\n\t\t\t\tif (!current) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst { winners, merged } = resolvePerFieldLww(\n\t\t\t\t\tparseFieldVersions(current._field_versions),\n\t\t\t\t\tObject.keys(orphanChanges),\n\t\t\t\t\torphanVersion,\n\t\t\t\t\ttypeof current._version === 'string' ? current._version : undefined,\n\t\t\t\t)\n\t\t\t\tif (winners.length > 0) {\n\t\t\t\t\tconst winningChanges: Record<string, unknown> = {\n\t\t\t\t\t\t_field_versions: serializeFieldVersions(merged),\n\t\t\t\t\t}\n\t\t\t\t\tfor (const field of winners) {\n\t\t\t\t\t\twinningChanges[field] = orphanChanges[field]\n\t\t\t\t\t}\n\t\t\t\t\tconst query = buildFieldFastForwardUpdateQuery(\n\t\t\t\t\t\tcollection,\n\t\t\t\t\t\trecordId,\n\t\t\t\t\t\twinningChanges,\n\t\t\t\t\t\torphanVersion,\n\t\t\t\t\t\torphanWall,\n\t\t\t\t\t)\n\t\t\t\t\tawait tx.execute(query.sql, query.params)\n\t\t\t\t}\n\t\t\t} else if (orphan.type === 'delete') {\n\t\t\t\tconst query = buildLwwSoftDeleteQuery(collection, recordId, orphanWall, orphanVersion)\n\t\t\t\tawait tx.execute(query.sql, query.params)\n\t\t\t}\n\t\t}\n\n\t\t// Atomic-op fields need composition, not last-write-wins: the per-field LWW\n\t\t// loop above would keep only one concurrent increment's resolved value and drop\n\t\t// the rest. Re-materialize just the atomic fields by folding [insert, ...orphans]\n\t\t// in HLC order through the shared atomic-aware replay — the same fold the server\n\t\t// and the live apply path use — so an atomic op that arrived before its insert\n\t\t// (reordered delivery) composes correctly instead of losing deltas. Only the\n\t\t// field VALUES are overwritten; their per-field versions were already stamped to\n\t\t// the latest writer by the loop above, so future LWW stays correct.\n\t\tconst atomicFields = new Set<string>()\n\t\tfor (const orphan of orphans) {\n\t\t\tif (orphan.type === 'update' && orphan.atomicOps) {\n\t\t\t\tfor (const field of Object.keys(orphan.atomicOps)) {\n\t\t\t\t\tatomicFields.add(field)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (atomicFields.size > 0) {\n\t\t\t// A scope-entry insert expands into its per-field writes (RT-27).\n\t\t\tconst ordered = expandFieldVersionedOperations([insertOp, ...orphans])\n\t\t\tconst folded = replayOperationsForRecord(ordered)\n\t\t\tif (folded) {\n\t\t\t\tconst composed: Record<string, unknown> = {}\n\t\t\t\tfor (const field of atomicFields) {\n\t\t\t\t\tif (field in folded) {\n\t\t\t\t\t\tcomposed[field] = folded[field]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst serialized = serializeRecord(composed, definition.fields)\n\t\t\t\tconst cols = Object.keys(serialized)\n\t\t\t\tif (cols.length > 0) {\n\t\t\t\t\tconst setClause = cols.map((c) => `${quoteIdent(c)} = ?`).join(', ')\n\t\t\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET ${setClause} WHERE id = ?`, [\n\t\t\t\t\t\t...cols.map((c) => serialized[c]),\n\t\t\t\t\t\trecordId,\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get operations from a node within a sequence number range.\n\t * Implements the OperationLog interface for computeDelta.\n\t */\n\tasync getRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]> {\n\t\treturn this.getOperationRange(nodeId, fromSeq, toSeq)\n\t}\n\n\t/**\n\t * Get operations from a node within a sequence number range.\n\t */\n\tasync getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst allOps: Operation[] = []\n\n\t\tfor (const collectionName of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} WHERE node_id = ? AND sequence_number >= ? AND sequence_number <= ? ORDER BY sequence_number ASC`,\n\t\t\t\t[nodeId, fromSeq, toSeq],\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t}\n\t\t}\n\n\t\t// Sort by sequence number across collections\n\t\tallOps.sort((a, b) => a.sequenceNumber - b.sequenceNumber)\n\t\treturn allOps\n\t}\n\n\t/**\n\t * Load every operation from the local append-only log across all collections.\n\t * Used by sync delta computation, backup export, and time-travel replay.\n\t */\n\tasync getAllOperations(): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst allOps: Operation[] = []\n\n\t\tfor (const collectionName of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collectionName}`)} ORDER BY sequence_number ASC`,\n\t\t\t)\n\t\t\tfor (const row of rows) {\n\t\t\t\tallOps.push(deserializeOperationWithCollection(row, collectionName))\n\t\t\t}\n\t\t}\n\n\t\treturn allOps\n\t}\n\n\t/**\n\t * Rebuild an in-memory snapshot of materialized state at a causal cut in the op log.\n\t * Does not mutate the live store — intended for DevTools time-travel inspection.\n\t *\n\t * @param operationId - Content-addressed id of the operation to replay through (inclusive)\n\t * @throws {OperationError} When the operation id is not present in the local log\n\t */\n\tasync replayTo(operationId: string): Promise<ReplaySnapshot> {\n\t\tthis.ensureOpen()\n\t\tconst start = Date.now()\n\t\tconst allOps = await this.getAllOperations()\n\t\tconst aliasRows = await this.adapter.query<{ id: string; reemitted_as: string }>(\n\t\t\t`SELECT id, reemitted_as FROM ${SEQ_CONFLICTS_TABLE} WHERE reemitted_as IS NOT NULL AND reemitted_as <> id`,\n\t\t)\n\t\tconst aliases = new Map(aliasRows.map((row) => [row.id, row.reemitted_as]))\n\t\tconst snapshot = buildReplaySnapshot(\n\t\t\tthis.schema,\n\t\t\tallOps,\n\t\t\toperationId,\n\t\t\taliases,\n\t\t\tthis.operationTransforms,\n\t\t)\n\n\t\tif (this.emitter) {\n\t\t\tthis.emitter.emit({\n\t\t\t\ttype: 'replay:completed',\n\t\t\t\ttargetOperationId: operationId,\n\t\t\t\toperationsApplied: snapshot.operationsApplied.length,\n\t\t\t\tduration: Date.now() - start,\n\t\t\t})\n\t\t}\n\n\t\treturn snapshot\n\t}\n\n\t/**\n\t * Persist a merge trace to the durable audit log.\n\t */\n\tasync appendAuditTrace(trace: import('../audit/types').PersistedAuditTrace): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tconst { appendAuditTrace: append } = await import('../audit/audit-trace-store')\n\t\tawait append(this.adapter, trace)\n\t}\n\n\t/**\n\t * Read persisted audit traces with optional filters.\n\t */\n\tasync getAuditTraces(\n\t\tquery?: import('../audit/types').AuditTraceQuery,\n\t): Promise<import('../audit/types').PersistedAuditTrace[]> {\n\t\tthis.ensureOpen()\n\t\tconst { readAuditTraces } = await import('../audit/audit-trace-store')\n\t\treturn readAuditTraces(this.adapter, query)\n\t}\n\n\t/**\n\t * Export operations and merge traces as a portable audit bundle.\n\t */\n\tasync exportAudit(options?: import('../audit/types').AuditExportOptions): Promise<Uint8Array> {\n\t\tthis.ensureOpen()\n\t\tconst { exportAudit: doExport } = await import('../audit/export-audit')\n\t\treturn doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options)\n\t}\n\n\t/**\n\t * Get the schema definition.\n\t */\n\tgetSchema(): SchemaDefinition {\n\t\treturn this.schema\n\t}\n\n\t/**\n\t * Route local CRUD through the unified apply pipeline (korajs ApplyPipeline).\n\t */\n\tsetLocalMutationHandler(handler: LocalMutationHandler | null): void {\n\t\tthis.localMutationHandler = handler\n\t\tfor (const col of this.collections.values()) {\n\t\t\tcol.setMutationHandler(handler)\n\t\t}\n\t}\n\n\t/**\n\t * Notify this store that another same-origin runtime committed an operation to\n\t * the shared local database. The operation has already been persisted and\n\t * materialized by the database owner; this method only advances in-memory causal\n\t * watermarks and invalidates local reactive queries so already-open tabs stay\n\t * live without reapplying or rewriting the operation.\n\t */\n\tnotifyExternalOperation(operation: Operation): void {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[operation.collection]\n\t\tif (!definition) {\n\t\t\treturn\n\t\t}\n\t\tthis.recordOperationSequence(operation)\n\t\tthis.subscriptionManager.invalidateFromPeer(operation.collection)\n\t}\n\n\t/**\n\t * Notify this store that another same-origin runtime changed rows of a collection\n\t * in the shared local database without an operation this tab can see (a re-fold,\n\t * a scope retraction, a restore; RT-98). Only re-runs the affected live queries.\n\t *\n\t * @param collection - The collection whose rows changed\n\t */\n\tnotifyExternalChange(collection: string): void {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) return\n\t\tthis.subscriptionManager.invalidateFromPeer(collection)\n\t}\n\n\t/**\n\t * Listen to every committed change this store makes to collection rows: local\n\t * writes, remote applies, and changes without a new operation (re-folds, scope\n\t * retraction, cascade settling, rematerialization, restore). The cross-tab bus\n\t * relays these to other tabs on the same database (RT-98).\n\t *\n\t * @returns An unsubscribe function\n\t */\n\tonRecordsChanged(listener: RecordsChangeListener): () => void {\n\t\treturn this.subscriptionManager.onRecordsChanged(listener)\n\t}\n\n\t/**\n\t * Build the local write context for a collection: everything the single local\n\t * write path needs (used by Collection writes and by ApplyPipeline).\n\t */\n\tcreateMutationContext(\n\t\tcollection: string,\n\t\toptions?: {\n\t\t\textraCausalDeps?: string[]\n\t\t\t/**\n\t\t\t * Stamp the writes with this clock instead of the store's (it must be this\n\t\t\t * node's). Used for the side effects of a remote delete, stamped right after\n\t\t\t * the delete like the server's copy (seam 5), never with the device's \"now\".\n\t\t\t */\n\t\t\tclock?: HybridLogicalClock\n\t\t},\n\t): LocalMutationContext {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition || !this.clock) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\tconst beforeLocalDelete = this.localMutationHandler?.beforeLocalDelete\n\t\tconst fold = this.activeFold()\n\t\treturn {\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tcollection,\n\t\t\tdefinition,\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: options?.clock ?? this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\tonMutation: (collectionName, operation) =>\n\t\t\t\tthis.publishLocalOperation(collectionName, operation),\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(options?.extraCausalDeps ? { extraCausalDeps: options.extraCausalDeps } : {}),\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(this.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t\tassertLocalWriteAllowed: () => this.assertLocalWriteAllowed(),\n\t\t\t...(beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: beforeLocalDelete.bind(this.localMutationHandler) }\n\t\t\t\t: {}),\n\t\t\tonStorageError: (error) => this.reportStorageError(error),\n\t\t}\n\t}\n\n\t/**\n\t * Load a materialized row by ID, including soft-deleted tombstones.\n\t */\n\tasync findMaterializedRow(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<MaterializedRowSnapshot | null> {\n\t\tthis.ensureOpen()\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\n\t\treturn {\n\t\t\trecord: deserializeRecord(row, definition.fields),\n\t\t\tdeleted: row._deleted === 1,\n\t\t}\n\t}\n\n\t/**\n\t * Raw version state of a materialized row, for optimistic-concurrency guarded\n\t * applies: capture this snapshot before computing a merge, pass it as\n\t * `guardRowState`, and the apply refuses to write if the row changed since.\n\t * Returns null when no row exists (which is itself a valid guard state — the\n\t * apply then requires the row to still be absent).\n\t */\n\tasync getRowVersionState(collection: string, recordId: string): Promise<RowVersionState | null> {\n\t\tthis.ensureOpen()\n\t\tif (!this.schema.collections[collection]) {\n\t\t\treturn null\n\t\t}\n\t\tconst rows = await this.adapter.query<RawCollectionRow>(\n\t\t\t`SELECT _version, _field_versions FROM ${quoteIdent(collection)} WHERE id = ?`,\n\t\t\t[recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\t\treturn {\n\t\t\tversion: typeof row._version === 'string' ? row._version : null,\n\t\t\tfieldVersions: typeof row._field_versions === 'string' ? row._field_versions : null,\n\t\t}\n\t}\n\n\t/**\n\t * Latest operation from this device for a record (used for delete-vs-update merge on sync).\n\t */\n\t/**\n\t * Load the last server version vector acknowledged by this client (persisted in `_kora_meta`).\n\t */\n\tasync loadLastAckedServerVector(): Promise<VersionVector> {\n\t\tthis.ensureOpen()\n\t\treturn loadLastAckedServerVector(this.adapter)\n\t}\n\n\t/**\n\t * Persist the last server version vector this client believes the server has applied.\n\t */\n\tasync saveLastAckedServerVector(vector: VersionVector): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveLastAckedServerVector(this.adapter, vector)\n\t}\n\n\t/**\n\t * Load the per-device node token the sync server issued for this node id (RT-12).\n\t */\n\tasync loadNodeToken(nodeId?: string): Promise<string | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadNodeToken(this.adapter, nodeId ?? this.nodeId)\n\t}\n\n\t/**\n\t * Persist the per-device node token under its node id (the current one by default).\n\t */\n\tasync saveNodeToken(token: string, nodeId?: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveNodeToken(this.adapter, token, nodeId ?? this.nodeId)\n\t}\n\n\t/**\n\t * Load the node ids the sync server named authoritative (protocol v2), or null when\n\t * no protocol-2 server ever answered.\n\t */\n\tasync loadAuthoritativeNodeIds(): Promise<string[] | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadAuthoritativeNodeIds(this.adapter)\n\t}\n\n\t/**\n\t * Persist the node ids the sync server named authoritative (protocol v2). Same as\n\t * {@link setAuthoritativeNodeIds}: merged into the union of learned explicit ids,\n\t * and the fold re-folds affected records only when that set grows.\n\t */\n\tasync saveAuthoritativeNodeIds(nodeIds: string[]): Promise<void> {\n\t\tawait this.setAuthoritativeNodeIds(nodeIds)\n\t}\n\n\t/**\n\t * Load persisted delta cursor for resuming paginated initial sync.\n\t */\n\tasync loadDeltaCursor(): Promise<string | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadDeltaCursor(this.adapter)\n\t}\n\n\t/**\n\t * Persist or clear the delta cursor for paginated initial sync resume.\n\t */\n\tasync saveDeltaCursor(cursor: string | null): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveDeltaCursor(this.adapter, cursor)\n\t}\n\n\t/**\n\t * Load the persisted delivery watermark for a view signature (0 when none recorded).\n\t * Defaults to the unfiltered view so existing single-watermark reads keep working.\n\t */\n\tasync loadDeliveryWatermark(signature = ''): Promise<number> {\n\t\tthis.ensureOpen()\n\t\treturn loadDeliveryWatermark(this.adapter, signature)\n\t}\n\n\t/**\n\t * Persist the delivery watermark for a view signature so it survives a client restart.\n\t */\n\tasync saveDeliveryWatermark(signature: string, watermark: number): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveDeliveryWatermark(this.adapter, signature, watermark)\n\t}\n\n\t/**\n\t * Load every persisted view watermark, keyed by signature.\n\t */\n\tasync loadAllDeliveryWatermarks(): Promise<Record<string, number>> {\n\t\tthis.ensureOpen()\n\t\treturn loadAllDeliveryWatermarks(this.adapter)\n\t}\n\n\t/**\n\t * Delete a persisted view watermark (safe: the view back-fills from 0 when next visited).\n\t */\n\tasync deleteDeliveryWatermark(signature: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait deleteDeliveryWatermark(this.adapter, signature)\n\t}\n\n\t/**\n\t * Record delivered operations the sync engine deliberately did not apply (inbound\n\t * quarantine, W4) and, when given, advance a view's delivery watermark in the same\n\t * transaction, so the watermark never passes an operation that is neither applied nor\n\t * recorded.\n\t */\n\tasync saveInboundQuarantine(\n\t\tentries: UnappliedOperation[],\n\t\twatermark?: { signature: string; watermark: number },\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveUnappliedOperations(this.adapter, entries, watermark)\n\t}\n\n\t/** Every quarantined inbound operation, oldest delivery first. */\n\tasync loadInboundQuarantine(): Promise<UnappliedOperation[]> {\n\t\tthis.ensureOpen()\n\t\treturn loadUnappliedOperations(this.adapter)\n\t}\n\n\t/** Remove quarantined inbound operations (applied on replay, or reconciled). */\n\tasync removeInboundQuarantine(operationIds: string[]): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait removeUnappliedOperations(this.adapter, operationIds)\n\t}\n\n\t/**\n\t * The contiguous acknowledged prefix of this device's own operations for a node id,\n\t * or null when none was recorded under that contract (W3).\n\t */\n\tasync loadOwnAckedThrough(nodeId: string): Promise<number | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadOwnAckedThrough(this.adapter, nodeId)\n\t}\n\n\t/** Persist the contiguous acknowledged own-operation prefix for a node id. */\n\tasync saveOwnAckedThrough(nodeId: string, sequence: number): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveOwnAckedThrough(this.adapter, nodeId, sequence)\n\t}\n\n\t/** The downlink scope the sync server last accepted (null when none). */\n\tasync loadAcceptedDownlinkScope(): Promise<Record<string, Record<string, unknown>> | null> {\n\t\tthis.ensureOpen()\n\t\treturn loadAcceptedDownlinkScope(this.adapter)\n\t}\n\n\t/** Persist (or clear) the downlink scope the sync server last accepted. */\n\tasync saveAcceptedDownlinkScope(\n\t\tscope: Record<string, Record<string, unknown>> | null,\n\t): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveAcceptedDownlinkScope(this.adapter, scope)\n\t}\n\n\t/**\n\t * Local operations not yet reflected on the server version vector.\n\t */\n\tasync getUnsyncedOperations(serverVector: VersionVector): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\treturn collectOperationsAheadOfServer(\n\t\t\tthis.getVersionVector(),\n\t\t\tserverVector,\n\t\t\t(nodeId, fromSeq, toSeq) => this.getOperationRange(nodeId, fromSeq, toSeq),\n\t\t)\n\t}\n\n\t/**\n\t * Re-stamp never-acknowledged local operations after a fast device clock was\n\t * corrected, so sync can resume immediately. Safe because unacknowledged\n\t * operations are private to this device (like unpushed git commits);\n\t * acknowledged/shared operations are immutable and never touched.\n\t *\n\t * After the rewrite the store's HLC is advanced past the highest new\n\t * timestamp so subsequent local writes keep sorting after the rebased ops.\n\t * No data-change notifications are emitted: materialized values are\n\t * unchanged, only version stamps move.\n\t */\n\t/**\n\t * Move this device to a fresh node id, re-authoring its never-acknowledged\n\t * operations under it (RT-21). Used when the sync server refuses the current node\n\t * id (`NODE_ID_CLAIMED`): the device keeps every local write and uploads it under\n\t * the new id. Acknowledged history stays under the old id. Persisted atomically;\n\t * later writes use the new id.\n\t *\n\t * @param unsyncedOpIds - Ids of this node's operations the server never acknowledged\n\t * @returns The new node id and the rewritten operations (for the outbound queue)\n\t * @throws {KoraError} When the node id is pinned (`StoreConfig.nodeId`, or per-tab isolation)\n\t */\n\tasync rotateNodeId(unsyncedOpIds: string[]): Promise<NodeRotationResult> {\n\t\tthis.ensureOpen()\n\t\tif (this.configNodeId || this.isolation === 'per-tab') {\n\t\t\tthrow new KoraError(\n\t\t\t\t'This store uses a pinned node id, so it cannot move to a fresh one after the sync server refused it.',\n\t\t\t\t'NODE_ID_PINNED',\n\t\t\t\t{\n\t\t\t\t\tnodeId: this.nodeId,\n\t\t\t\t\tfix: 'Remove StoreConfig.nodeId, or give the device a node id no other device uses.',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tconst oldNodeId = this.nodeId\n\t\tconst oldClock = this.clock\n\t\tconst oldBinding = (await listLocalNodes(this.adapter)).find(\n\t\t\t(node) => node.nodeId === oldNodeId,\n\t\t)\n\t\tconst result = await rotateUnsyncedOperationsInLog(\n\t\t\tthis.adapter,\n\t\t\tthis.schema,\n\t\t\tunsyncedOpIds,\n\t\t\toldNodeId,\n\t\t\tgenerateUUIDv7(),\n\t\t)\n\t\tawait registerLocalNode(this.adapter, result.nodeId)\n\t\t// The re-authored writes keep their author (RT-50): the fresh node carries the old\n\t\t// node's binding, so they are never held as unassigned or given to another user.\n\t\tif (oldBinding?.principal) {\n\t\t\tawait setLocalNodePrincipal(\n\t\t\t\tthis.adapter,\n\t\t\t\tresult.nodeId,\n\t\t\t\toldBinding.principal,\n\t\t\t\toldBinding.binding ?? 'app',\n\t\t\t)\n\t\t}\n\t\tthis.nodeId = result.nodeId\n\t\tconst clock = new HybridLogicalClock(this.nodeId)\n\t\tif (oldClock) {\n\t\t\tconst last = oldClock.now()\n\t\t\tclock.advanceTo({ ...last, nodeId: this.nodeId })\n\t\t\tconst offset = oldClock.getReferenceOffset()\n\t\t\tif (offset !== null) clock.setReferenceOffset(offset)\n\t\t}\n\t\tthis.clock = clock\n\t\tthis.causalTracker = new CausalTracker()\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\t\tthis.versionVector = await this.loadVersionVector()\n\t\t// The persisted counter (MAX with the stored value, W6), not a local count.\n\t\tthis.sequenceNumber = this.versionVector.get(this.nodeId) ?? result.operations.length\n\t\tfor (const collection of this.collections.values()) {\n\t\t\tcollection.rebindNode(clock, this.nodeId, this.relationEnforcer, this.causalTracker)\n\t\t}\n\t\t// The re-authored operations have new ids: their records' fold states still name\n\t\t// the old ones, so they are re-folded from the log.\n\t\tawait this.refoldRecordsOf(result.operations.map((op) => op.id))\n\t\treturn result\n\t}\n\n\t/**\n\t * Re-author another local node's never-acknowledged operations under a fresh node id\n\t * bound to `principal` (the user they belong to). Used when the sync server refuses an\n\t * adopted node whose writes belong to the signed-in user (the app assigned them, or\n\t * the node was created for them) but which no claims-aware server ever accepted: a\n\t * beta.12 database's node with history the server recorded no owner for. The store's\n\t * own node id, clock and counters are untouched; the fresh node is registered, so the\n\t * sync engine adopts it like any other local node.\n\t *\n\t * @param fromNodeId - The refused local node (never the store's own)\n\t * @param unsyncedOpIds - Ids of its operations the server never acknowledged\n\t * @param principal - The user the writes belong to (the fresh node's binding)\n\t * @returns The fresh node id and the rewritten operations (for the outbound queue)\n\t * @throws {KoraError} `NODE_ID_UNKNOWN` when `fromNodeId` is the store's own node or\n\t * not a local node\n\t */\n\tasync reauthorLocalNode(\n\t\tfromNodeId: string,\n\t\tunsyncedOpIds: string[],\n\t\tprincipal: string,\n\t): Promise<NodeRotationResult> {\n\t\tthis.ensureOpen()\n\t\tconst from = (await listLocalNodes(this.adapter)).find((node) => node.nodeId === fromNodeId)\n\t\tif (fromNodeId === this.nodeId || !from) {\n\t\t\tthrow new KoraError(\n\t\t\t\t`Node id \"${fromNodeId}\" is not another local node of this database, so its writes cannot be re-authored.`,\n\t\t\t\t'NODE_ID_UNKNOWN',\n\t\t\t\t{ nodeId: fromNodeId, storeNodeId: this.nodeId },\n\t\t\t)\n\t\t}\n\t\tconst result = await rotateUnsyncedOperationsInLog(\n\t\t\tthis.adapter,\n\t\t\tthis.schema,\n\t\t\tunsyncedOpIds,\n\t\t\tfromNodeId,\n\t\t\tgenerateUUIDv7(),\n\t\t\t{ moveDatabaseNode: false },\n\t\t)\n\t\tawait registerLocalNode(this.adapter, result.nodeId)\n\t\tawait setLocalNodePrincipal(this.adapter, result.nodeId, principal, 'fresh')\n\t\tthis.versionVector = await this.loadVersionVector()\n\t\tawait this.refoldRecordsOf(result.operations.map((op) => op.id))\n\t\treturn result\n\t}\n\n\t/**\n\t * Move this database back to a node id it authored under before (RT-38): after the\n\t * sync server refused the current node, the device tries a node a returning user\n\t * owns. Nothing is rewritten; later writes use `nodeId`.\n\t *\n\t * @throws {KoraError} When the node id is pinned, or `nodeId` is not a local node\n\t */\n\tasync switchNodeId(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (this.configNodeId || this.isolation === 'per-tab') {\n\t\t\tthrow new KoraError(\n\t\t\t\t'This store uses a pinned node id, so it cannot switch to another one.',\n\t\t\t\t'NODE_ID_PINNED',\n\t\t\t\t{ nodeId: this.nodeId },\n\t\t\t)\n\t\t}\n\t\tif (nodeId === this.nodeId) return\n\t\tif (isReservedNodeId(nodeId)) throw new ReservedNodeIdError(nodeId, 'switchNodeId')\n\t\tconst known = (await listLocalNodes(this.adapter)).some((node) => node.nodeId === nodeId)\n\t\tif (!known) {\n\t\t\tthrow new KoraError(\n\t\t\t\t`Node id \"${nodeId}\" was never used by this database, so the store cannot switch to it.`,\n\t\t\t\t'NODE_ID_UNKNOWN',\n\t\t\t\t{ nodeId },\n\t\t\t)\n\t\t}\n\t\tawait this.adapter.transaction((tx) => moveDatabaseNodeId(tx, nodeId))\n\t\tawait this.rebindToNode(nodeId)\n\t}\n\n\t/** Point the clock, sequence counter and collections at `nodeId` (already persisted). */\n\tprivate async rebindToNode(nodeId: string): Promise<void> {\n\t\tconst oldClock = this.clock\n\t\tthis.nodeId = nodeId\n\t\tconst clock = new HybridLogicalClock(this.nodeId)\n\t\tif (oldClock) {\n\t\t\tconst last = oldClock.now()\n\t\t\tclock.advanceTo({ ...last, nodeId: this.nodeId })\n\t\t\tconst offset = oldClock.getReferenceOffset()\n\t\t\tif (offset !== null) clock.setReferenceOffset(offset)\n\t\t}\n\t\tthis.clock = clock\n\t\tthis.causalTracker = new CausalTracker()\n\t\tthis.sequenceManager = new SequenceManager(this.adapter, this.nodeId)\n\t\tthis.versionVector = await this.loadVersionVector()\n\t\tthis.sequenceNumber = this.versionVector.get(this.nodeId) ?? 0\n\t\tfor (const collection of this.collections.values()) {\n\t\t\tcollection.rebindNode(clock, this.nodeId, this.relationEnforcer, this.causalTracker)\n\t\t}\n\t}\n\n\t/**\n\t * Bind this database's writes to the signed-in user (RT-42). Call it whenever the\n\t * signed-in user is known or changes, BEFORE the next local write (`createApp` does\n\t * so at start and on every auth change of `sync.authClient`).\n\t *\n\t * - The current node belongs to `principal`: nothing changes.\n\t * - The current node is unbound and has no history (no write, never synced): it is\n\t * bound to `principal` (every write under it from now on is theirs).\n\t * - The current node is unbound but has history (a database from before RT-42, or\n\t * writes made while nobody was signed in): its owner is NOT guessed (RT-50). The\n\t * store moves to `principal`'s own node, and the old node's owner is learned from\n\t * the sync server (the first accepted handshake as it binds it; a refusal rules\n\t * that user out). A node that never synced cannot be attributed by anyone: its\n\t * unsynced writes are held for the app to assign or discard (`app.sync.assignHeld`,\n\t * `app.sync.discardHeld`).\n\t * - It belongs to another user: the store moves to `principal`'s own local node (the\n\t * most recent one, not held), or to a fresh node bound to `principal`. Nothing is\n\t * rewritten: the other user's unsynced writes stay under their node, and sync never\n\t * uploads them on this user's session (they count as `heldOperations`).\n\t *\n\t * A pinned node id (`StoreConfig.nodeId`, such as an auth device id) cannot move:\n\t * `conflict` is then true when it belongs to another user, and sync refuses to\n\t * upload it under `principal`; an unbound pinned node with history stays unbound\n\t * until the server accepts it for a user. Under `per-tab` isolation the tab moves to\n\t * a fresh per-tab node.\n\t *\n\t * @param principal - The signed-in user id\n\t * @returns The node now in use and whether it changed\n\t */\n\tasync bindPrincipal(principal: string): Promise<PrincipalBinding> {\n\t\tconst binding = await this.bindPrincipalToNode(principal)\n\t\t// The server's word was about the previous user; another user may own the node.\n\t\tif (principal !== this.signedInPrincipal) this.pinnedNodeRefusedByServer = false\n\t\t// While the pinned node belongs to another user, local writes are refused (F9):\n\t\t// they could only be written under that user's node and would upload as theirs.\n\t\tthis.pinnedNodeOwnedBy = binding.conflict\n\t\t\t? ((await listLocalNodes(this.adapter)).find((node) => node.nodeId === this.nodeId)\n\t\t\t\t\t?.principal ?? null)\n\t\t\t: null\n\t\tthis.signedInPrincipal = principal\n\t\treturn binding\n\t}\n\n\t/**\n\t * The sync server refused this store's pinned node id because another user owns it\n\t * (`owned: true`), or later accepted it (`false`). A pinned node cannot move to a fresh\n\t * id, so writes made under it could only ever upload as its owner: while the server\n\t * says so, local writes are refused (F9). A no-op for a store whose node is not pinned\n\t * (it moves to a fresh node instead).\n\t *\n\t * @param owned - Whether the server reported the node owned by another user\n\t */\n\tsetPinnedNodeOwnedElsewhere(owned: boolean): void {\n\t\tif (!this.configNodeId) return\n\t\tthis.pinnedNodeRefusedByServer = owned\n\t}\n\n\t/** Refuse a local write while the pinned node belongs to another user (F9). */\n\tprivate assertLocalWriteAllowed(): void {\n\t\tif (this.pinnedNodeOwnedBy === null && !this.pinnedNodeRefusedByServer) return\n\t\tthrow new NodeOwnedByAnotherUserError(this.nodeId, this.signedInPrincipal)\n\t}\n\n\tprivate async bindPrincipalToNode(principal: string): Promise<PrincipalBinding> {\n\t\tthis.ensureOpen()\n\t\tconst previousNodeId = this.nodeId\n\t\tconst nodes = await listLocalNodes(this.adapter)\n\t\tconst current = nodes.find((node) => node.nodeId === this.nodeId)\n\t\tconst owner = current?.principal ?? null\n\t\tif (owner === principal) {\n\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t}\n\t\tif (owner === null) {\n\t\t\tconst written = (await this.loadVersionVector()).get(this.nodeId) ?? 0\n\t\t\tif (written === 0 && !(current?.accepted ?? false)) {\n\t\t\t\tawait setLocalNodePrincipal(this.adapter, this.nodeId, principal, 'fresh')\n\t\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t\t}\n\t\t\tif (this.configNodeId) {\n\t\t\t\t// Cannot move: the server decides whose it is at the first handshake.\n\t\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: false }\n\t\t\t}\n\t\t} else if (this.configNodeId) {\n\t\t\treturn { nodeId: this.nodeId, previousNodeId, switched: false, conflict: true }\n\t\t}\n\t\tif (this.isolation === 'per-tab') {\n\t\t\t// A per-tab node belongs to its tab; another user in this tab gets a fresh one.\n\t\t\tconst fresh = generateUUIDv7()\n\t\t\tawait registerLocalNode(this.adapter, fresh)\n\t\t\tawait setLocalNodePrincipal(this.adapter, fresh, principal, 'fresh')\n\t\t\tsavePerTabNodeId(this.dbName, fresh)\n\t\t\tthis.releaseNodeLock?.()\n\t\t\tthis.releaseNodeLock = acquireNodeLock(nodeLockName(this.dbName, fresh))\n\t\t\tawait this.rebindToNode(fresh)\n\t\t\treturn { nodeId: fresh, previousNodeId, switched: true, conflict: false }\n\t\t}\n\t\tconst own = nodes\n\t\t\t.filter((node) => node.principal === principal && !node.held)\n\t\t\t.sort((a, b) => b.createdAt - a.createdAt)[0]\n\t\tif (own) {\n\t\t\tawait this.switchNodeId(own.nodeId)\n\t\t\treturn { nodeId: own.nodeId, previousNodeId, switched: true, conflict: false }\n\t\t}\n\t\tconst fresh = generateUUIDv7()\n\t\tawait this.adapter.transaction((tx) => moveDatabaseNodeId(tx, fresh))\n\t\tawait registerLocalNode(this.adapter, fresh)\n\t\tawait setLocalNodePrincipal(this.adapter, fresh, principal, 'fresh')\n\t\tawait this.rebindToNode(fresh)\n\t\treturn { nodeId: fresh, previousNodeId, switched: true, conflict: false }\n\t}\n\n\t/**\n\t * A sync handshake as `nodeId` was accepted for `principal` (RT-50): bind an unbound\n\t * node (or replace a guessed binding) from the server's answer.\n\t */\n\tasync confirmNodePrincipal(nodeId: string, principal: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait confirmLocalNodePrincipal(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * The sync server refused `nodeId` for `principal` (RT-50): clear a guessed binding,\n\t * and remember that an unbound node is not theirs.\n\t */\n\tasync recordNodeRefusedFor(nodeId: string, principal: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait recordLocalNodeRefusedFor(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * Assign a held, unbound local node's writes to `principal` (RT-50): an explicit app\n\t * decision for writes nobody can attribute (a database that never synced).\n\t *\n\t * @returns false when the node is unknown, the store's own, already bound, or was\n\t * refused for `principal` by the server\n\t */\n\tasync assignNodePrincipal(nodeId: string, principal: string): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return false\n\t\treturn assignLocalNodePrincipal(this.adapter, nodeId, principal)\n\t}\n\n\t/**\n\t * Forget a local node other than the store's own whatever it still holds (RT-50: the\n\t * app discarded its held writes, which were marked never to upload first).\n\t */\n\tasync dropLocalNode(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return\n\t\tawait dropLocalNode(this.adapter, nodeId)\n\t}\n\n\t/** The adoption schedule of this database's local nodes (RT-46). */\n\tasync loadAdoptionSchedule(): Promise<AdoptionSchedule> {\n\t\tthis.ensureOpen()\n\t\treturn loadAdoptionSchedule(this.adapter)\n\t}\n\n\t/** Persist the adoption schedule (RT-46). */\n\tasync saveAdoptionSchedule(schedule: AdoptionSchedule): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait saveAdoptionSchedule(this.adapter, schedule)\n\t}\n\n\t/**\n\t * Raise a local node's sequence counter to at least `floor`, in a transaction (the\n\t * same MAX every reservation uses, W6), so the next write never reuses a number the\n\t * server already holds (RT-35: the device lost the tail of its log, for example on a\n\t * reload inside the IndexedDB snapshot window or after restoring an older copy).\n\t *\n\t * @returns Whether the counter moved\n\t */\n\tasync raiseSequenceFloor(nodeId: string, floor: number): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tlet raised = false\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tconst rows = await tx.query<VersionVectorRow>(\n\t\t\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t\t\t[nodeId],\n\t\t\t)\n\t\t\tconst current = rows[0]?.sequence_number ?? 0\n\t\t\tif (floor <= current) return\n\t\t\tawait tx.execute(\n\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t[nodeId, floor],\n\t\t\t)\n\t\t\traised = true\n\t\t})\n\t\tif (raised) {\n\t\t\tconst previous = this.versionVector.get(nodeId) ?? 0\n\t\t\tthis.versionVector.set(nodeId, Math.max(previous, floor))\n\t\t\tif (nodeId === this.nodeId) this.sequenceNumber = Math.max(this.sequenceNumber, floor)\n\t\t}\n\t\treturn raised\n\t}\n\n\t/**\n\t * Give one of a local node's operations a fresh sequence number above `floor`\n\t * (RT-35): the server refused it with `SEQUENCE_CONFLICT` because it holds another\n\t * operation of this node under that number (one this device lost). A version-1\n\t * operation keeps its id (its hash does not cover the sequence number), exactly like\n\t * the W6 sequence repair; a version-2 operation (protocol v2) is re-hashed under the\n\t * new number, so it carries a new id. The old identity is recorded in\n\t * `_kora_seq_conflicts` (`reemitted_as`).\n\t *\n\t * A new id would leave later operations naming the old one in `causalDeps`: those in\n\t * `rewritableDependents` (operations the server never stored: never sent) are\n\t * rewritten to name the new id, and re-hashed, transitively, in the same\n\t * transaction. Dependents already sent keep their ids (the server may hold them);\n\t * their dep resolves through the `_kora_seq_conflicts` record. Every touched record\n\t * is re-folded (fold stamps carry operation ids).\n\t *\n\t * @param rewritableDependents - Ids of this node's operations that were never sent\n\t * @returns The renumbered operation and the rewritten dependents, or null when the\n\t * operation is not in the log\n\t */\n\tasync resequenceOperation(\n\t\toperationId: string,\n\t\tnodeId: string,\n\t\tfloor: number,\n\t\trewritableDependents: readonly string[] = [],\n\t): Promise<ResequenceResult | null> {\n\t\tthis.ensureOpen()\n\t\tconst found: { result: ResequenceResult | null } = { result: null }\n\t\tconst collections = Object.keys(this.schema.collections)\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const collection of collections) {\n\t\t\t\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${table} WHERE id = ? AND node_id = ?`,\n\t\t\t\t\t[operationId, nodeId],\n\t\t\t\t)\n\t\t\t\tconst row = rows[0]\n\t\t\t\tif (!row) continue\n\t\t\t\tawait tx.execute(\n\t\t\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t[nodeId, floor],\n\t\t\t\t)\n\t\t\t\tconst sequence = await allocateNextSequenceInTransaction(tx, nodeId)\n\t\t\t\t// A version-2 id covers the sequence number (CORE-1): such an operation is\n\t\t\t\t// re-hashed under the new number (the server never stored it).\n\t\t\t\tconst moved = await renumberOperationRow(tx, collection, row, sequence)\n\t\t\t\tawait insertConflictRow(\n\t\t\t\t\ttx,\n\t\t\t\t\tcollection,\n\t\t\t\t\trow,\n\t\t\t\t\t'server-sequence-conflict',\n\t\t\t\t\tmoved.id,\n\t\t\t\t\tsequence,\n\t\t\t\t\tDate.now(),\n\t\t\t\t)\n\t\t\t\tconst idMapping: Record<string, string> = moved.id !== row.id ? { [row.id]: moved.id } : {}\n\t\t\t\tconst rewritable = new Set(rewritableDependents)\n\t\t\t\trewritable.delete(row.id)\n\t\t\t\tconst dependents =\n\t\t\t\t\tmoved.id !== row.id\n\t\t\t\t\t\t? await rewriteDependentsInTx(tx, collections, nodeId, idMapping, rewritable)\n\t\t\t\t\t\t: []\n\t\t\t\tfound.result = { operation: moved, dependents, idMapping }\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t\tconst result = found.result\n\t\tif (!result) return null\n\t\tthis.recordOperationSequence(result.operation)\n\t\tif (Object.keys(result.idMapping).length > 0) {\n\t\t\tawait this.refoldRecordsOf([result.operation.id, ...result.dependents.map((op) => op.id)])\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Durability barrier (RT-35): resolves once every write committed so far is durable\n\t * on this device. Sync awaits it before an operation leaves the device.\n\t */\n\tasync ensureDurable(): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait this.adapter.ensureDurable?.()\n\t}\n\n\t/** Record operations the server refused for good (RT-36). Never cleared. */\n\tasync recordTerminalRejections(entries: TerminalRejection[]): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait recordTerminalRejections(this.adapter, entries)\n\t\t// The server never stored these operations: re-fold their records without them,\n\t\t// so this device converges to the server's state (W7 step 2).\n\t\tawait this.refoldRecordsOf(entries.map((entry) => entry.operationId))\n\t}\n\n\t/** Which of these operation ids the server refused for good (RT-36). */\n\tasync findTerminalRejections(operationIds: string[]): Promise<Set<string>> {\n\t\tthis.ensureOpen()\n\t\treturn findTerminalRejections(this.adapter, operationIds)\n\t}\n\n\t/** Every node id this database authored operations under (RT-38, RT-40). */\n\tasync listLocalNodes(): Promise<LocalNodeRecord[]> {\n\t\tthis.ensureOpen()\n\t\treturn listLocalNodes(this.adapter)\n\t}\n\n\t/** Forget a drained local node other than this store's own (RT-40). */\n\tasync forgetLocalNode(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return\n\t\tawait forgetLocalNode(this.adapter, nodeId)\n\t}\n\n\t/** The current refusal cycle: the count of accepted sync handshakes (RT-38). */\n\tasync loadAcceptedCycle(): Promise<number> {\n\t\tthis.ensureOpen()\n\t\treturn loadAcceptedCycle(this.adapter)\n\t}\n\n\t/** Record an accepted sync handshake as `nodeId` (RT-38). */\n\tasync markLocalNodeAccepted(nodeId: string): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait markLocalNodeAccepted(this.adapter, nodeId)\n\t}\n\n\t/** Record that the sync server refused `nodeId`; `held` holds its writes (RT-38). */\n\tasync markLocalNodeRefused(nodeId: string, held: boolean): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tawait markLocalNodeRefused(this.adapter, nodeId, held)\n\t}\n\n\t/**\n\t * Take over another local node's unsynced writes (RT-40): resolves to a release\n\t * function when no live tab uses `nodeId` (its lock is free), or null when one does.\n\t * Without Web Locks (Node, old browsers) the node is assumed free.\n\t */\n\tasync claimLocalNode(nodeId: string): Promise<(() => void) | null> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return null\n\t\treturn tryAcquireNodeLock(nodeLockName(this.dbName, nodeId))\n\t}\n\n\t/** Whether a live tab holds `nodeId` (per-tab isolation, RT-40). */\n\tasync isLocalNodeLive(nodeId: string): Promise<boolean> {\n\t\tthis.ensureOpen()\n\t\tif (nodeId === this.nodeId) return true\n\t\treturn isNodeLockHeld(nodeLockName(this.dbName, nodeId))\n\t}\n\n\tasync rebaseUnsyncedOperations(\n\t\tunsyncedOpIds: string[],\n\t\tcorrectedNowMs: number,\n\t): Promise<ClockRebaseResult> {\n\t\tthis.ensureOpen()\n\t\tconst result = await rebaseUnsyncedOperationsInLog(\n\t\t\tthis.adapter,\n\t\t\tthis.schema,\n\t\t\tunsyncedOpIds,\n\t\t\tcorrectedNowMs,\n\t\t)\n\t\tif (result.newMaxTimestamp && this.clock) {\n\t\t\tthis.clock.advanceTo(result.newMaxTimestamp)\n\t\t}\n\t\t// Re-stamped operations order differently: re-fold their records.\n\t\tawait this.refoldRecordsOf(result.operations.map((op) => op.id))\n\t\treturn result\n\t}\n\n\t/**\n\t * Count of local operations ahead of the server version vector.\n\t */\n\tasync countUnsyncedOperations(serverVector: VersionVector): Promise<number> {\n\t\tconst ops = await this.getUnsyncedOperations(serverVector)\n\t\treturn ops.length\n\t}\n\n\t/**\n\t * Compact the local operation log. Only removes ops the server has acknowledged\n\t * (per {@link CompactionStrategy}). With the W7 fold (STORE-14), the effect of the\n\t * removed operations is first joined into each record's base fold state, so a\n\t * re-fold (rejection exclusion, a later re-materialization) and the merge of a\n\t * late operation stay exact; delete, atomic and custom-resolver operations are\n\t * kept, and a re-delivered compacted id is a duplicate by its node's compacted\n\t * prefix.\n\t */\n\tasync compact(strategy: CompactionStrategy): Promise<CompactionResult> {\n\t\tthis.ensureOpen()\n\t\tconst fold = this.activeFold()\n\t\tif (strategy.mode === 'never') {\n\t\t\treturn compactOperationLog(this.adapter, this.schema, strategy, createVersionVector())\n\t\t}\n\n\t\tconst serverVector = strategy.serverVector ?? (await loadLastAckedServerVector(this.adapter))\n\t\tif (fold) {\n\t\t\treturn compactFoldedLog(this.adapter, this.schema, fold, strategy, serverVector)\n\t\t}\n\t\treturn compactOperationLog(this.adapter, this.schema, strategy, serverVector)\n\t}\n\n\t/**\n\t * Merge session remote vector with persisted last-acked vector (max per node).\n\t */\n\tmergeServerVectors(sessionVector: VersionVector, persistedVector: VersionVector): VersionVector {\n\t\treturn mergeVersionVectors(persistedVector, sessionVector)\n\t}\n\n\tasync getLatestLocalOperationForRecord(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation | null> {\n\t\tthis.ensureOpen()\n\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ? AND record_id = ? ORDER BY sequence_number DESC LIMIT 1`,\n\t\t\t[this.nodeId, recordId],\n\t\t)\n\t\tconst row = rows[0]\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\t\treturn deserializeOperationWithCollection(row, collection)\n\t}\n\n\t/**\n\t * Latest operation for a record from any node (for 3-way merge when local op log is empty).\n\t */\n\tasync getLatestOperationForRecord(\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation | null> {\n\t\tthis.ensureOpen()\n\t\tconst rows = await this.adapter.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t[recordId],\n\t\t)\n\n\t\tlet latest: Operation | null = null\n\t\tfor (const row of rows) {\n\t\t\tconst op = deserializeOperationWithCollection(row, collection)\n\t\t\tif (!latest || HybridLogicalClock.compare(op.timestamp, latest.timestamp) > 0) {\n\t\t\t\tlatest = op\n\t\t\t}\n\t\t}\n\t\treturn latest\n\t}\n\n\t/**\n\t * All operations for a record, sorted in HLC total order (wallTime, logical,\n\t * nodeId). Used by the apply pipeline to materialize atomic-op fields by folding\n\t * the record's log, matching the server's materialization exactly.\n\t */\n\tasync getOperationsForRecord(collection: string, recordId: string): Promise<Operation[]> {\n\t\tthis.ensureOpen()\n\t\tconst rows = [\n\t\t\t...(await this.adapter.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t// Other nodes' operations kept only in the sequence-conflicts table still\n\t\t\t// belong to the record's history.\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => this.adapter.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t)),\n\t\t]\n\t\tconst ops = rows.map((row) => deserializeOperationWithCollection(row, collection))\n\t\tops.sort((a, b) => HybridLogicalClock.compare(a.timestamp, b.timestamp))\n\t\treturn ops\n\t}\n\n\t/** Expose the subscription manager for direct access (e.g., by QueryBuilder) */\n\tgetSubscriptionManager(): SubscriptionManager {\n\t\treturn this.subscriptionManager\n\t}\n\n\t/**\n\t * Get the sequence manager for offline-safe sequence generation.\n\t * @throws {StoreNotOpenError} If the store is not open\n\t */\n\tgetSequenceManager(): SequenceManager {\n\t\tthis.ensureOpen()\n\t\tif (!this.sequenceManager) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\treturn this.sequenceManager\n\t}\n\n\t/**\n\t * Create a TransactionContext for atomic multi-collection operations.\n\t * The returned context buffers all mutations and commits them atomically.\n\t *\n\t * After commit, the caller is responsible for notifying subscriptions\n\t * and emitting events for each operation.\n\t */\n\tcreateTransaction(): TransactionContext {\n\t\tthis.ensureOpen()\n\t\tif (!this.clock) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\tconst beforeLocalDelete = this.localMutationHandler?.beforeLocalDelete\n\t\tconst fold = this.activeFold()\n\t\treturn new TransactionContext({\n\t\t\t...(this.maxOperationBytes !== undefined\n\t\t\t\t? { maxOperationBytes: this.maxOperationBytes }\n\t\t\t\t: {}),\n\t\t\tassertLocalWriteAllowed: () => this.assertLocalWriteAllowed(),\n\t\t\t...(fold ? { fold } : {}),\n\t\t\tschema: this.schema,\n\t\t\tadapter: this.adapter,\n\t\t\tclock: this.clock,\n\t\t\tnodeId: this.nodeId,\n\t\t\trelationEnforcer: this.relationEnforcer,\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t...(beforeLocalDelete\n\t\t\t\t? { beforeLocalDelete: beforeLocalDelete.bind(this.localMutationHandler) }\n\t\t\t\t: {}),\n\t\t\tonStorageError: (error) => this.reportStorageError(error),\n\t\t})\n\t}\n\n\t/**\n\t * Execute a function within a transaction. All mutations performed on the\n\t * TransactionContext are committed atomically. Subscription notifications\n\t * are batched and fired after the commit.\n\t *\n\t * If the function throws, the transaction is rolled back and the error is re-thrown.\n\t *\n\t * @param fn - Function receiving a TransactionContext for buffered operations\n\t * @returns The operations that were committed\n\t */\n\tasync transaction(fn: (tx: TransactionContext) => Promise<void>): Promise<Operation[]> {\n\t\tconst tx = this.createTransaction()\n\t\ttry {\n\t\t\tawait fn(tx)\n\t\t} catch (error) {\n\t\t\ttx.rollback()\n\t\t\tthrow error\n\t\t}\n\t\tconst { operations } = await tx.commit()\n\n\t\t// Notify subscriptions and emit events after commit\n\t\tfor (const op of operations) {\n\t\t\tthis.publishLocalOperation(op.collection, op)\n\t\t}\n\n\t\treturn operations\n\t}\n\n\t/**\n\t * Export all data as a portable backup binary.\n\t * Includes operations, version vector, metadata, and optionally materialized records.\n\t *\n\t * @param options - Backup options (includeRecords, collections, onProgress)\n\t * @returns Backup as a Uint8Array\n\t */\n\tasync exportBackup(options?: BackupOptions): Promise<Uint8Array> {\n\t\tthis.ensureOpen()\n\t\tconst { exportBackup: doExport } = await import('../backup/backup')\n\t\treturn doExport(this.adapter, this.schema, this.nodeId, this.schema.version, options)\n\t}\n\n\t/**\n\t * Restore data from a backup binary (format version 2, STORE-5).\n\t *\n\t * - `merge: true`: every backup operation is applied through the remote-apply path\n\t * (deduplicated by id, merged per field), the version vector advances by MAX, and\n\t * nothing of the exporting device's identity or sync state is imported.\n\t * - Replace (default): the data is replaced by the backup's while this device keeps\n\t * its node id, local nodes and principal bindings, its own sequence counters never\n\t * move backwards, and unsynced own writes are kept (see\n\t * `RestoreOptions.keepUnsyncedWrites`). Then {@link reloadFromDisk} runs.\n\t *\n\t * A version-1 file (Kora 1.0.0-beta.12 and earlier) is converted first, exactly as\n\t * `convertBackupV1` does (`result.convertedFromVersion: 1`); one holding an operation\n\t * whose timestamp cannot be recovered is refused (`BACKUP_OPERATION_INVALID`).\n\t *\n\t * @param data - The backup data\n\t * @param options - Restore options (merge, collections, keepUnsyncedWrites, onProgress)\n\t * @param internal - `applyOperation`: the app's remote-apply path (defaults to\n\t * {@link applyRemoteOperation}); `createApp` passes the merge-aware pipeline sync uses\n\t * @returns Result of the restore operation\n\t */\n\tasync importBackup(\n\t\tdata: Uint8Array,\n\t\toptions?: RestoreOptions,\n\t\tinternal?: { applyOperation?: (operation: Operation) => Promise<ApplyResult> },\n\t): Promise<RestoreResult> {\n\t\tthis.ensureOpen()\n\t\tconst started = Date.now()\n\t\tconst onProgress = options?.onProgress ?? (() => {})\n\t\tconst { BackupFormatError, convertBackupV1, parseBackup, readBackupManifest } = await import(\n\t\t\t'../backup/backup'\n\t\t)\n\t\tconst { restoreMerge, restoreReplace } = await import('../backup/restore')\n\t\tonProgress({ phase: 'verifying', progress: 0, message: 'Verifying backup' })\n\t\tlet parsed: Awaited<ReturnType<typeof parseBackup>>\n\t\tlet convertedFromVersion: 1 | undefined\n\t\ttry {\n\t\t\t// A version-1 file (beta.12 and earlier) is converted here, with the same\n\t\t\t// deterministic rules as convertBackupV1 (F3): the exporting device's identity is\n\t\t\t// dropped and damaged timestamps are recovered. An operation that cannot be\n\t\t\t// recovered still refuses the file; dropping it stays an explicit choice.\n\t\t\tlet bytes = data\n\t\t\tif (readBackupManifest(data).version === 1) {\n\t\t\t\tbytes = await convertBackupV1(data)\n\t\t\t\tconvertedFromVersion = 1\n\t\t\t}\n\t\t\tparsed = await parseBackup(\n\t\t\t\tbytes,\n\t\t\t\toptions?.collections ? { collections: options.collections } : undefined,\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof BackupFormatError)) throw error\n\t\t\treturn {\n\t\t\t\toperationsRestored: 0,\n\t\t\t\trecordsRestored: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error.message,\n\t\t\t\terrorCode: error.code,\n\t\t\t\tduration: Date.now() - started,\n\t\t\t}\n\t\t}\n\t\tif (parsed.manifest.schemaVersion > this.schema.version) {\n\t\t\treturn {\n\t\t\t\toperationsRestored: 0,\n\t\t\t\trecordsRestored: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `The backup was written by schema version ${parsed.manifest.schemaVersion}; this app runs version ${this.schema.version}. Update the app before restoring it.`,\n\t\t\t\terrorCode: 'BACKUP_SCHEMA_NEWER',\n\t\t\t\tduration: Date.now() - started,\n\t\t\t}\n\t\t}\n\t\tonProgress({ phase: 'restoring', progress: 0.3, message: 'Restoring' })\n\t\tconst explicitAuthorities = new Set((await loadAuthoritativeNodeIds(this.adapter)) ?? [])\n\t\tconst host = {\n\t\t\tadapter: this.adapter,\n\t\t\tschema: this.schema,\n\t\t\tapplyOperation:\n\t\t\t\tinternal?.applyOperation ?? ((op: Operation) => this.applyRemoteOperation(op)),\n\t\t\tlistLocalNodes: () => listLocalNodes(this.adapter),\n\t\t\tisServerAuthority: (nodeId: string) =>\n\t\t\t\tisReservedNodeId(nodeId) || explicitAuthorities.has(nodeId),\n\t\t}\n\t\tif (options?.merge) await this.mergeBackupFoldState(parsed, options.collections !== undefined)\n\t\tconst counts = options?.merge\n\t\t\t? await restoreMerge(host, parsed, options.collections !== undefined)\n\t\t\t: await restoreReplace(host, parsed, {\n\t\t\t\t\tcollections: options?.collections ?? null,\n\t\t\t\t\tkeepUnsyncedWrites: options?.keepUnsyncedWrites ?? true,\n\t\t\t\t})\n\t\tif (!options?.merge && this.folder) {\n\t\t\t// Restored rows and log replace what the fold states described: rebuild them,\n\t\t\t// from the backup's base states and log (RT-66). A file from an earlier\n\t\t\t// release carries no base states, and its log may have been compacted: its\n\t\t\t// records are rebuilt on top of its rows instead (row snapshots).\n\t\t\tawait this.adapter.execute('DELETE FROM _kora_meta WHERE key = ?', [\n\t\t\t\tFOLD_MATERIALIZATION_META_KEY,\n\t\t\t])\n\t\t\tthis.foldActive = false\n\t\t\tawait this.ensureMaterialization(parsed.manifest.includesFoldState !== true)\n\t\t}\n\t\tawait this.reloadFromDisk()\n\t\tonProgress({ phase: 'restoring', progress: 1, message: 'Done' })\n\t\treturn {\n\t\t\toperationsRestored: counts.operationsRestored,\n\t\t\trecordsRestored: counts.recordsRestored,\n\t\t\t...(options?.merge ? {} : { unsyncedWritesKept: counts.unsyncedWritesKept }),\n\t\t\t...(counts.serverOperationsSkipped\n\t\t\t\t? { serverOperationsSkipped: counts.serverOperationsSkipped }\n\t\t\t\t: {}),\n\t\t\t...(convertedFromVersion ? { convertedFromVersion } : {}),\n\t\t\tsuccess: true,\n\t\t\tduration: Date.now() - started,\n\t\t}\n\t}\n\n\t/**\n\t * Merge mode (RT-66): join the backup's compacted base states and row snapshots\n\t * into this database's, and re-fold those records, before the backup's operations\n\t * are applied. The join is the fold's state-based merge, so the result equals\n\t * folding both devices' histories together. Compacted prefixes advance by MAX\n\t * (unfiltered restores only: the prefix is per node, across collections).\n\t */\n\tprivate async mergeBackupFoldState(\n\t\tparsed: import('../backup/backup').ParsedBackup,\n\t\tfiltered: boolean,\n\t): Promise<void> {\n\t\tconst folder = this.activeFold()\n\t\tif (!folder) return\n\t\tconst touched = new Map<string, Set<string>>()\n\t\tawait this.adapter.transaction(async (tx) => {\n\t\t\tfor (const [rows, kind] of [\n\t\t\t\t[parsed.foldBases, 'base'],\n\t\t\t\t[parsed.foldSnapshots, 'snapshot'],\n\t\t\t] as const) {\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tif (!this.schema.collections[row.collection]) continue\n\t\t\t\t\tlet state: FoldState\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstate = deserializeFoldState(row.state)\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (state.c !== row.collection || state.r !== row.recordId) continue\n\t\t\t\t\tif (kind === 'base') await folder.joinIntoBase(tx, state)\n\t\t\t\t\telse await folder.saveSnapshot(tx, state)\n\t\t\t\t\tconst ids = touched.get(row.collection) ?? new Set<string>()\n\t\t\t\t\tids.add(row.recordId)\n\t\t\t\t\ttouched.set(row.collection, ids)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!filtered) {\n\t\t\t\tfor (const [nodeId, sequence] of parsed.compactedThrough) {\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t`INSERT INTO ${COMPACTED_THROUGH_TABLE} (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t\t\t\t[nodeId, sequence],\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [collection, ids] of touched) {\n\t\t\t\tfor (const recordId of ids) await folder.refoldInTx(tx, collection, recordId)\n\t\t\t}\n\t\t})\n\t\tfor (const [collection, ids] of touched)\n\t\t\tthis.subscriptionManager.invalidate(collection, [...ids])\n\t}\n\n\t/**\n\t * Re-read this store's state from the database after it changed underneath it (a\n\t * backup restore): the node id, version vector and own sequence counter, the clock\n\t * (advanced past every timestamp in the log), and a fresh causal tracker. Every live\n\t * query re-runs. The local node registry and terminal rejections are always read\n\t * from the database, so they need no reload.\n\t */\n\tasync reloadFromDisk(): Promise<void> {\n\t\tthis.ensureOpen()\n\t\tlet nodeId = this.nodeId\n\t\tif (!this.configNodeId && this.isolation !== 'per-tab') {\n\t\t\tconst rows = await this.adapter.query<MetaRow>(\n\t\t\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t\t\t)\n\t\t\tnodeId = rows[0]?.value ?? this.nodeId\n\t\t}\n\t\tawait this.rebindToNode(nodeId)\n\t\tconst newest = await this.loadNewestLogTimestamp()\n\t\tif (newest && this.clock) {\n\t\t\tthis.clock.advanceTo({ ...newest, nodeId: this.nodeId })\n\t\t}\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tthis.subscriptionManager.invalidate(collection)\n\t\t}\n\t}\n\n\t/** The greatest HLC timestamp in the operation log (canonical strings sort by HLC). */\n\tprivate async loadNewestLogTimestamp(): Promise<HLCTimestamp | null> {\n\t\tlet newest: string | null = null\n\t\tfor (const collection of Object.keys(this.schema.collections)) {\n\t\t\tconst rows = await this.adapter.query<{ t: string | null }>(\n\t\t\t\t`SELECT MAX(timestamp) AS t FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t\t)\n\t\t\tconst value = rows[0]?.t ?? null\n\t\t\tif (value !== null && (newest === null || value > newest)) newest = value\n\t\t}\n\t\treturn newest === null ? null : HybridLogicalClock.deserialize(newest)\n\t}\n\n\t/**\n\t * Read backup manifest without loading the entire backup.\n\t *\n\t * @param data - The raw backup data\n\t * @returns The backup manifest\n\t */\n\tstatic readBackupManifest(data: Uint8Array): BackupManifest {\n\t\treturn readManifest(data)\n\t}\n\n\tprivate recordOperationSequence(operation: Operation): void {\n\t\tconst prev = this.versionVector.get(operation.nodeId) ?? 0\n\t\tif (operation.sequenceNumber > prev) {\n\t\t\tthis.versionVector.set(operation.nodeId, operation.sequenceNumber)\n\t\t}\n\t\tif (operation.nodeId === this.nodeId) {\n\t\t\tthis.sequenceNumber = Math.max(this.sequenceNumber, operation.sequenceNumber)\n\t\t}\n\t}\n\n\t/** Post-commit publication of a committed local operation. */\n\tprivate publishLocalOperation(collection: string, operation: Operation): void {\n\t\tthis.recordOperationSequence(operation)\n\t\tthis.subscriptionManager.notify(collection, operation)\n\t\tthis.emitter?.emit({ type: 'operation:created', operation })\n\t}\n\n\t/**\n\t * Map an out-of-space storage failure to `store:quota-exceeded` (STORE-15).\n\t * The error itself still propagates to the caller; this only makes the\n\t * condition observable on every adapter, not just IndexedDB.\n\t */\n\tprivate reportStorageError(error: unknown): void {\n\t\tif (!isStorageFullError(error)) return\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'store:quota-exceeded',\n\t\t\tdbName: this.dbName,\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t})\n\t}\n\n\t/** Report a database a newer build migrated (`store:schema-ahead`) and build the error. */\n\tprivate schemaAhead(storedVersion: number): SchemaVersionAheadError {\n\t\tconst error = new SchemaVersionAheadError(this.dbName, storedVersion, this.schema.version)\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'store:schema-ahead',\n\t\t\tdbName: this.dbName,\n\t\t\tstoredVersion,\n\t\t\tcodeVersion: this.schema.version,\n\t\t\tmessage: error.message,\n\t\t})\n\t\treturn error\n\t}\n\n\t/**\n\t * Run pending schema migrations (STORE-13, NEW-STORE-1): one transaction per version\n\t * (DDL, backfills, `schema_version`); backfills write operations through the local\n\t * write path so they sync, unless declared `localOnly`.\n\t */\n\tprivate async runMigrationsIfNeeded(): Promise<void> {\n\t\tconst clock = this.clock\n\t\tif (!clock) throw new StoreNotOpenError()\n\t\tconst fold = this.activeFold()\n\t\tawait runSchemaMigrations({\n\t\t\tadapter: this.adapter,\n\t\t\tschema: this.schema,\n\t\t\tenv: {\n\t\t\t\t...(fold ? { fold } : {}),\n\t\t\t\tschema: this.schema,\n\t\t\t\tclock,\n\t\t\t\tnodeId: this.nodeId,\n\t\t\t\trelationEnforcer: null,\n\t\t\t\t...(this.secretKeyProvider ? { secretKeyProvider: this.secretKeyProvider } : {}),\n\t\t\t},\n\t\t\tcausalTracker: this.causalTracker,\n\t\t\tonOperation: (operation) => this.publishLocalOperation(operation.collection, operation),\n\t\t})\n\t}\n\n\t/** The node id the database persisted before this open, if any. */\n\tprivate async readPersistedNodeId(): Promise<string | null> {\n\t\tconst rows = await this.adapter.query<MetaRow>(\n\t\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t\t)\n\t\treturn rows[0]?.value ?? null\n\t}\n\n\t/**\n\t * Register node ids this database authored under that the registry does not know\n\t * yet: the node id a pinned `nodeId` (the auth device id) just replaced, and the\n\t * authors of queued operations. A beta.12 database had no registry, and a template\n\t * app created before its user signed in authored under a random node; once the\n\t * store is pinned to the device id, that node's queued writes would otherwise sit in\n\t * the queue forever, neither uploaded nor reported. Registered, they are adopted or\n\t * held (`status.heldNodes`) like any other local node's writes. Only the outbound\n\t * queue is read: received operations never enter it.\n\t */\n\tprivate async registerUnregisteredAuthors(persistedNodeId: string | null): Promise<void> {\n\t\tconst authors = new Set<string>()\n\t\tif (persistedNodeId !== null && persistedNodeId !== this.nodeId) authors.add(persistedNodeId)\n\t\tconst queued = await this.adapter.query<{ payload: string }>(\n\t\t\t'SELECT payload FROM _kora_sync_queue',\n\t\t)\n\t\tfor (const row of queued) {\n\t\t\ttry {\n\t\t\t\tconst nodeId = (JSON.parse(row.payload) as { node_id?: unknown }).node_id\n\t\t\t\tif (typeof nodeId === 'string' && nodeId.length > 0) authors.add(nodeId)\n\t\t\t} catch {\n\t\t\t\t// An unreadable queue row is surfaced by the queue's own load.\n\t\t\t}\n\t\t}\n\t\tauthors.delete(this.nodeId)\n\t\tfor (const nodeId of authors) {\n\t\t\tif (isReservedNodeId(nodeId)) continue\n\t\t\tawait registerLocalNode(this.adapter, nodeId)\n\t\t}\n\t}\n\n\tprivate async loadOrGenerateNodeId(): Promise<string> {\n\t\t// The `kora:` namespace is Kora's own (server nodes `kora:server:<id>` are\n\t\t// authoritative by prefix, RT-61): a device never authors under such an id.\n\t\tif (this.configNodeId && isReservedNodeId(this.configNodeId)) {\n\t\t\tthrow new ReservedNodeIdError(this.configNodeId, 'StoreConfig.nodeId')\n\t\t}\n\t\tif (this.configNodeId) {\n\t\t\tif (this.isolation !== 'per-tab') {\n\t\t\t\tawait this.adapter.execute(\n\t\t\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\",\n\t\t\t\t\t[this.configNodeId],\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn this.configNodeId\n\t\t}\n\n\t\tif (this.isolation === 'per-tab') {\n\t\t\treturn resolvePerTabNodeId(this.dbName)\n\t\t}\n\n\t\t// Try to load existing node ID\n\t\tconst rows = await this.adapter.query<MetaRow>(\n\t\t\t\"SELECT value FROM _kora_meta WHERE key = 'node_id'\",\n\t\t)\n\t\tif (rows[0] && !isReservedNodeId(rows[0].value)) {\n\t\t\treturn rows[0].value\n\t\t}\n\n\t\t// Generate a new node id (a UUIDv7, never in the reserved `kora:` namespace). A\n\t\t// persisted reserved id (written by something other than this client) is never\n\t\t// adopted: the database gets a fresh identity instead.\n\t\tconst newNodeId = generateUUIDv7()\n\t\tawait this.adapter.execute(\n\t\t\t\"INSERT OR REPLACE INTO _kora_meta (key, value) VALUES ('node_id', ?)\",\n\t\t\t[newNodeId],\n\t\t)\n\t\treturn newNodeId\n\t}\n\n\tprivate async loadSequenceNumber(): Promise<number> {\n\t\tconst rows = await this.adapter.query<VersionVectorRow>(\n\t\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t\t[this.nodeId],\n\t\t)\n\t\treturn rows[0]?.sequence_number ?? 0\n\t}\n\n\tprivate async loadVersionVector(): Promise<VersionVector> {\n\t\tconst rows = await this.adapter.query<VersionVectorRow>(\n\t\t\t'SELECT node_id, sequence_number FROM _kora_version_vector',\n\t\t)\n\t\tconst vector = createVersionVector()\n\t\tfor (const row of rows) {\n\t\t\tvector.set(row.node_id, row.sequence_number)\n\t\t}\n\t\treturn vector\n\t}\n\n\tprivate ensureOpen(): void {\n\t\tif (!this.opened) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t}\n}\n\n/**\n * Public-facing collection accessor. Provides CRUD + where.\n */\nexport interface CollectionAccessor {\n\tinsert(data: Record<string, unknown>): Promise<import('../types').CollectionRecord>\n\tfindById(id: string): Promise<import('../types').CollectionRecord | null>\n\tupdate(id: string, data: Record<string, unknown>): Promise<import('../types').CollectionRecord>\n\tdelete(id: string): Promise<void>\n\twhere(conditions: Record<string, unknown>): QueryBuilder\n}\n\n/**\n * The newest HLC an operation carries: its timestamp, or for a scope-entry insert\n * (RT-27) the greatest of its timestamp and every per-field version.\n */\nfunction newestFieldVersion(op: Operation): HLCTimestamp {\n\tlet newest = op.timestamp\n\tfor (const version of Object.values(op.fieldVersions ?? {})) {\n\t\tif (HybridLogicalClock.compare(version, newest) > 0) newest = version\n\t}\n\treturn newest\n}\n","// @korajs/store — public API\n// Every export here is a public API commitment. Be explicit.\n\n// === Types ===\nexport type {\n\tApplyRemoteOptions,\n\tApplyResult,\n\tLocalMutationHandler,\n\tMaterializedRowSnapshot,\n\tRowVersionState,\n\tCollectionRecord,\n\tReplaySnapshot,\n\tMigrationPlan,\n\tOrderByClause,\n\tOrderByDirection,\n\tQueryDescriptor,\n\tStoreConfig,\n\tStoreIsolation,\n\tStorageFallbackReason,\n\tStorageOpenState,\n\tStorageAdapter,\n\tSubscriptionCallback,\n\tTransaction,\n\tWhereClause,\n\tWhereOperators,\n} from './types'\n\n// === Errors ===\nexport {\n\tAdapterError,\n\tBridgeTerminatedError,\n\tLeaderUnresponsiveError,\n\tNoLeaderError,\n\tNodeOwnedByAnotherUserError,\n\tOptimisticLockError,\n\tPersistenceError,\n\tQueryError,\n\tRecordNotFoundError,\n\tRequestAbortedError,\n\tSchemaVersionAheadError,\n\tStorageBackendMismatchError,\n\tStorageDurabilityError,\n\tStorageInUseError,\n\tStoreNotOpenError,\n\tUnsyncedDataError,\n\tWorkerInitError,\n\tWorkerTimeoutError,\n} from './errors'\n\n// === Operation log compaction ===\nexport type { CompactionResult, CompactionStrategy } from './compaction/types'\nexport { COMPACTION_BASELINE_META_KEY } from './compaction/types'\nexport {\n\tcompactOperationLog,\n\tcomputeAckCompactionWatermark,\n} from './compaction/compact-operation-log'\n\n// === W7 record fold (client materialization) ===\nexport { mergeYjsUpdates } from './fold/record-folder'\nexport type { RematerializationMode } from './fold/rematerialize'\n\n// === Clock rebase (timestamp rebase of unsynced operations) ===\nexport type { ClockRebaseResult } from './sync/rebase-unsynced-operations'\nexport type { NodeRotationResult } from './sync/rotate-node-id'\nexport type { ResequenceResult } from './sync/rehash-operation'\nexport type { UnappliedOperation } from './sync/sync-durability'\nexport type {\n\tAdoptionSchedule,\n\tLocalNodeRecord,\n\tParkedAdoption,\n\tTerminalRejection,\n} from './sync/local-sync-records'\nexport type { PrincipalBinding } from './store/store'\n\n// === Sync state helpers ===\nexport {\n\tcollectOperationsAheadOfServer,\n\tdeserializeVersionVectorFromMeta,\n\tLAST_ACKED_SERVER_VECTOR_META_KEY,\n\tmergeVersionVectors,\n\tserializeVersionVectorToMeta,\n} from './sync/sync-state'\n\n// === Store ===\nexport { Store } from './store/store'\nexport type { CollectionAccessor } from './store/store'\n\n// === Query ===\nexport { QueryBuilder } from './query/query-builder'\nexport { normalizeWhere, queryKey } from './query/query-key'\nexport { VIRTUAL_TIMESTAMP_FIELDS, VIRTUAL_TIMESTAMP_FIELD_NAMES } from './query/sql-builder'\nexport type { VirtualTimestampField } from './query/sql-builder'\nexport type { QueryErrorPhase, QuerySubscriptionError, SubscribeOptions } from './types'\n\n// === Durable storage (navigator.storage.persist), never on the startup path ===\nexport { StoragePersistence } from './persistence/storage-persistence'\nexport type {\n\tPersistenceRequestReason,\n\tPersistenceStorageManager,\n\tStoragePersistenceOptions,\n\tStoragePersistenceState,\n\tStoragePersistenceStatus,\n} from './persistence/storage-persistence'\nexport { QueryStore } from './reactivity/query-store'\nexport { assertQueryReady } from './reactivity/assert-query-ready'\nexport {\n\tgetSharedQueryStoreCache,\n\tQueryStoreCache,\n} from './reactivity/query-store-cache'\n\n// === Subscription ===\nexport { SubscriptionManager } from './subscription/subscription-manager'\nexport type {\n\tRecordsChange,\n\tRecordsChangeListener,\n\tRegisterOptions,\n\tSubscriptionManagerOptions,\n\tSubscriptionStats,\n} from './subscription/subscription-manager'\nexport type { ResultsEqual } from './subscription/result-equality'\nexport { SubscriptionBloomFilter } from './subscription/bloom-filter'\n\n// === Collection ===\nexport { Collection } from './collection/collection'\n\n// === State Machine Validation ===\nexport {\n\tInvalidStateTransitionError,\n\tvalidateStateTransition,\n\tvalidateUpdateStateMachine,\n} from './state-machine/state-validator'\n\n// === Transaction ===\nexport { TransactionContext } from './transaction/transaction-context'\nexport type {\n\tTransactionCollectionAccessor,\n\tTransactionContextConfig,\n} from './transaction/transaction-context'\n\n// === Sequences ===\nexport { SequenceManager } from './sequences/sequence-manager'\n\n// === Richtext controller (framework bindings) ===\nexport { createRichTextController } from './richtext/create-richtext-controller'\nexport { asRichTextSyncEngine } from './richtext/as-rich-text-sync-engine'\nexport type {\n\tCreateRichTextControllerOptions,\n\tRichTextAwarenessUser,\n\tRichTextController,\n\tRichTextControllerSnapshot,\n\tRichTextCursorInfo,\n\tRichTextSyncEngine,\n} from './richtext/types'\n\n// === Richtext Serialization ===\nexport {\n\tdecodeRichtext,\n\tencodeRichtext,\n\trichtextToPlainText,\n\trichtextStatesEqual,\n} from './serialization/richtext-serializer'\n\n// === Query Utilities ===\nexport { pluralize, singularize } from './query/pluralize'\n\n// === Backup/Restore ===\nexport {\n\tBACKUP_VERSION,\n\tBackupFormatError,\n\tconvertBackupV1,\n\texportBackup,\n\treadBackupManifest,\n\trestoreBackup,\n\tverifyBackupChecksum,\n} from './backup'\nexport type {\n\tConvertBackupV1Options,\n\tBackupManifest,\n\tBackupOptions,\n\tBackupProgress,\n\tRestoreOptions,\n\tRestoreResult,\n} from './backup'\n\n// === Log integrity (W8 step 0) ===\nexport { LOG_QUARANTINE_TABLE } from './log-integrity/log-integrity'\nexport type {\n\tLogIntegrityReport,\n\tLogIntegrityRow,\n\tLogRowProblem,\n\tLogSequenceGap,\n} from './log-integrity/log-integrity'\n\n// === Audit export ===\nexport {\n\tdecodeAuditExport,\n\tpersistedAuditTraceFromEvent,\n\treadAuditExportManifest,\n\tverifyAuditExportChecksum,\n} from './audit'\nexport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditExportProgress,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './audit'\n\n// === Content-addressed blob store ===\nexport {\n\tBlobIntegrityError,\n\tMemoryBlobStore,\n\ttype ContentAddressedBlobStore,\n} from './blob/content-addressed-blob-store'\nexport {\n\tOpfsBlobStore,\n\tcreateOpfsBlobDirectory,\n\tcreateOpfsBlobStore,\n\ttype OpfsBlobDirectory,\n} from './blob/opfs-blob-store'\nexport {\n\tDEFAULT_CHUNK_SIZE,\n\tchunkBlob,\n\treassembleBlob,\n\ttype BlobManifest,\n\ttype BlobManifestMetadata,\n} from './blob/blob-chunking'\nexport {\n\tprepareBlobForSend,\n\treceiveBlob,\n\ttype ChunkProvider,\n\ttype ReceiveBlobResult,\n\ttype ReceiveBlobStores,\n} from './blob/blob-transfer'\nexport {\n\tfetchBlobManifest,\n\tparseBlobManifest,\n\tputBlobForTransfer,\n\tresolveBlobManifest,\n\tserializeBlobManifest,\n} from './blob/blob-manifest-transfer'\nexport {\n\tcreateMemoryServerBlobStore,\n\ttoServerBlobCallbacks,\n\ttype ServerBlobCallbacks,\n} from './blob/server-blob-callbacks'\nexport {\n\tcollectBlobGarbage,\n\textractBlobRefs,\n\ttype BlobGcOptions,\n\ttype BlobGcResult,\n} from './blob/blob-gc'\nexport {\n\tcreateChunkPortPair,\n\tcreateRemoteChunkProvider,\n\tserveBlobChunks,\n\ttype ChunkMessage,\n\ttype ChunkMessagePort,\n\ttype ChunkRequestMessage,\n\ttype ChunkResponseMessage,\n\ttype RemoteChunkProvider,\n\ttype RemoteChunkProviderOptions,\n} from './blob/blob-chunk-transport'\n","import type { KoraEventEmitter } from '@korajs/core'\n\n/**\n * Durable-storage state of this origin, as far as Kora knows (NEW-STORE-4).\n * - `unknown`: not checked yet (the boot check runs in the background).\n * - `persisted`: the browser granted persistent storage; it will not evict this\n * origin's data under storage pressure.\n * - `best-effort`: storage may be evicted under pressure (the browser default).\n * - `unsupported`: the runtime has no StorageManager persistence API (Node,\n * older browsers, some WebViews).\n * - `error`: the check or request threw; `lastError` says why.\n */\nexport type StoragePersistenceState =\n\t| 'unknown'\n\t| 'persisted'\n\t| 'best-effort'\n\t| 'unsupported'\n\t| 'error'\n\n/** Snapshot returned by `app.storage.persistence.status()`. */\nexport interface StoragePersistenceStatus {\n\tstate: StoragePersistenceState\n\t/** True only when the browser reported persistent storage. */\n\tpersisted: boolean\n\t/** True once `persist()` was asked for (explicitly or by an automatic trigger). */\n\trequested: boolean\n\t/** Message of the last failure, when `state` is `error`. */\n\tlastError?: string\n}\n\n/** Why an automatic (background) persistence request was made. */\nexport type PersistenceRequestReason = 'explicit' | 'sign-in' | 'first-write' | 'installed-app'\n\n/** The subset of `navigator.storage` used here. */\nexport interface PersistenceStorageManager {\n\tpersist?: () => Promise<boolean>\n\tpersisted?: () => Promise<boolean>\n}\n\n/** Options for {@link StoragePersistence}. */\nexport interface StoragePersistenceOptions {\n\t/** Receives `storage:persistence` events. */\n\temitter?: KoraEventEmitter | null\n\t/**\n\t * The StorageManager to use. Defaults to `globalThis.navigator.storage`,\n\t * resolved on each call so tests and late polyfills are honoured.\n\t */\n\tstorage?: PersistenceStorageManager | null\n}\n\nfunction defaultStorageManager(): PersistenceStorageManager | null {\n\tconst nav = (globalThis as { navigator?: { storage?: PersistenceStorageManager } }).navigator\n\treturn nav?.storage ?? null\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error)\n}\n\n/**\n * Tracks and requests durable storage (`navigator.storage.persist()`) without ever\n * putting it on the startup path (NEW-STORE-4).\n *\n * In Firefox `persist()` opens a permission prompt and its promise stays pending\n * until the user answers, so awaiting it inside startup could hang `app.ready`\n * forever. Kora therefore:\n * - checks `persisted()` at boot, which never prompts, in the background;\n * - requests persistence only on an explicit `request()` or, without awaiting,\n * after a meaningful moment (sign-in, the first local write, running as an\n * installed app);\n * - surfaces every result through `status()` and the `storage:persistence` event,\n * never by blocking.\n */\nexport class StoragePersistence {\n\tprivate current: StoragePersistenceStatus = {\n\t\tstate: 'unknown',\n\t\tpersisted: false,\n\t\trequested: false,\n\t}\n\tprivate inFlightRequest: Promise<StoragePersistenceStatus> | null = null\n\tprivate readonly emitter: KoraEventEmitter | null\n\tprivate readonly storageOverride: PersistenceStorageManager | null | undefined\n\n\tconstructor(options: StoragePersistenceOptions = {}) {\n\t\tthis.emitter = options.emitter ?? null\n\t\tthis.storageOverride = options.storage\n\t}\n\n\t/** Synchronous snapshot of the last known state. Never prompts. */\n\tstatus(): StoragePersistenceStatus {\n\t\treturn { ...this.current }\n\t}\n\n\t/**\n\t * Read whether storage is already persistent (`navigator.storage.persisted()`).\n\t * Never prompts and never throws: a failure becomes `state: 'error'`.\n\t */\n\tasync check(): Promise<StoragePersistenceStatus> {\n\t\tconst storage = this.storage()\n\t\tif (!storage || typeof storage.persisted !== 'function') {\n\t\t\tthis.update({ state: 'unsupported', persisted: false })\n\t\t\tif (storage) this.emit('unsupported', false)\n\t\t\treturn this.status()\n\t\t}\n\t\ttry {\n\t\t\tconst persisted = (await storage.persisted()) === true\n\t\t\t// A grant observed by a concurrent request() is never downgraded here.\n\t\t\tif (!this.current.persisted) {\n\t\t\t\tthis.update({ state: persisted ? 'persisted' : 'best-effort', persisted })\n\t\t\t}\n\t\t\tthis.emit('checked', this.current.persisted)\n\t\t} catch (error) {\n\t\t\tthis.update({ state: 'error', persisted: false, lastError: errorMessage(error) })\n\t\t\tthis.emit('error', false, errorMessage(error))\n\t\t}\n\t\treturn this.status()\n\t}\n\n\t/**\n\t * Ask the browser for persistent storage (`navigator.storage.persist()`).\n\t * May show a permission prompt (Firefox), so call it from a user gesture or a\n\t * meaningful moment, and do not block rendering on it. Concurrent calls share\n\t * one request. Never throws: a failure becomes `state: 'error'`.\n\t *\n\t * @returns The state after the browser answered\n\t */\n\trequest(): Promise<StoragePersistenceStatus> {\n\t\tif (this.inFlightRequest) return this.inFlightRequest\n\t\tconst storage = this.storage()\n\t\tif (!storage || typeof storage.persist !== 'function') {\n\t\t\tthis.update({ state: 'unsupported', persisted: false })\n\t\t\tif (storage) this.emit('unsupported', false)\n\t\t\treturn Promise.resolve(this.status())\n\t\t}\n\t\tif (this.current.persisted) return Promise.resolve(this.status())\n\t\tconst persist = storage.persist.bind(storage)\n\t\tthis.current = { ...this.current, requested: true }\n\t\tconst pending = (async (): Promise<StoragePersistenceStatus> => {\n\t\t\ttry {\n\t\t\t\tconst persisted = (await persist()) === true\n\t\t\t\tthis.update({ state: persisted ? 'persisted' : 'best-effort', persisted })\n\t\t\t\tthis.emit('requested', persisted)\n\t\t\t} catch (error) {\n\t\t\t\tthis.update({ state: 'error', persisted: false, lastError: errorMessage(error) })\n\t\t\t\tthis.emit('error', false, errorMessage(error))\n\t\t\t} finally {\n\t\t\t\tthis.inFlightRequest = null\n\t\t\t}\n\t\t\treturn this.status()\n\t\t})()\n\t\tthis.inFlightRequest = pending\n\t\treturn pending\n\t}\n\n\t/**\n\t * Fire-and-forget `request()` for an automatic trigger. Never awaited by Kora,\n\t * so a pending prompt cannot block anything; the outcome arrives as a\n\t * `storage:persistence` event. Skipped when storage is already persistent or a\n\t * request was already made this session.\n\t *\n\t * @param _reason - Which trigger fired (kept for tracing at call sites)\n\t */\n\trequestInBackground(_reason: PersistenceRequestReason): void {\n\t\tif (this.current.persisted || this.current.requested) return\n\t\tvoid this.request()\n\t}\n\n\tprivate storage(): PersistenceStorageManager | null {\n\t\treturn this.storageOverride === undefined ? defaultStorageManager() : this.storageOverride\n\t}\n\n\tprivate update(next: Omit<StoragePersistenceStatus, 'requested'>): void {\n\t\tthis.current = { ...next, requested: this.current.requested }\n\t}\n\n\tprivate emit(\n\t\tstate: 'checked' | 'requested' | 'unsupported' | 'error',\n\t\tpersisted: boolean,\n\t\tmessage?: string,\n\t): void {\n\t\tthis.emitter?.emit({\n\t\t\ttype: 'storage:persistence',\n\t\t\tstate,\n\t\t\tpersisted,\n\t\t\t...(message !== undefined ? { message } : {}),\n\t\t})\n\t}\n}\n","import type { QueryBuilder } from '../query/query-builder'\nimport type { CollectionRecord } from '../types'\n\n/**\n * Frozen empty array returned as the initial snapshot before any data loads.\n * Same reference every time prevents infinite update loops in UI bindings.\n */\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\n/**\n * Bridges the async QueryBuilder.subscribe() API with synchronous snapshot reads\n * required by React useSyncExternalStore, Vue composables, and Svelte stores.\n *\n * Uses lazy subscription: the underlying query subscription starts when the first\n * listener attaches and stops when the last listener detaches.\n */\nexport class QueryStore<T = CollectionRecord> {\n\tprivate snapshot: readonly T[] = EMPTY_ARRAY as readonly T[]\n\tprivate listeners = new Set<() => void>()\n\tprivate unsubscribeQuery: (() => void) | null = null\n\tprivate active = false\n\tprivate hasEmittedSnapshot = false\n\tprivate error: Error | null = null\n\tprivate readonly queryBuilder: QueryBuilder<T>\n\n\tconstructor(queryBuilder: QueryBuilder<T>) {\n\t\tthis.queryBuilder = queryBuilder\n\t}\n\n\t/**\n\t * Subscribe to snapshot changes.\n\t *\n\t * @returns Unsubscribe function\n\t */\n\tsubscribe = (onStoreChange: () => void): (() => void) => {\n\t\tthis.listeners.add(onStoreChange)\n\n\t\tif (!this.active) {\n\t\t\tthis.startSubscription()\n\t\t}\n\n\t\treturn () => {\n\t\t\tthis.listeners.delete(onStoreChange)\n\t\t\tif (this.listeners.size === 0) {\n\t\t\t\tthis.stopSubscription()\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Synchronous read of the latest query results. */\n\tgetSnapshot = (): readonly T[] => {\n\t\treturn this.snapshot\n\t}\n\n\t/**\n\t * Whether the underlying query subscription has delivered at least one\n\t * authoritative result for the current subscription lifecycle.\n\t */\n\thasSnapshot = (): boolean => {\n\t\treturn this.hasEmittedSnapshot\n\t}\n\n\t/**\n\t * The latest query failure, or null. Set when the query (or a re-run after a\n\t * write) fails; cleared by the next successful delivery. Listeners are notified\n\t * on both transitions, so bindings read it next to `getSnapshot()`.\n\t */\n\tgetError = (): Error | null => {\n\t\treturn this.error\n\t}\n\n\t/** Tear down listeners and the underlying query subscription. */\n\tdestroy(): void {\n\t\tthis.stopSubscription()\n\t\tthis.listeners.clear()\n\t\tthis.snapshot = EMPTY_ARRAY as readonly T[]\n\t\tthis.hasEmittedSnapshot = false\n\t\tthis.error = null\n\t}\n\n\tprivate startSubscription(): void {\n\t\tthis.active = true\n\t\tthis.unsubscribeQuery = this.queryBuilder.subscribe(\n\t\t\t(results: readonly T[]) => {\n\t\t\t\tif (!this.active) return\n\t\t\t\tthis.hasEmittedSnapshot = true\n\t\t\t\tthis.error = null\n\t\t\t\tthis.snapshot = Object.freeze([...results])\n\t\t\t\tthis.notifyListeners()\n\t\t\t},\n\t\t\t{\n\t\t\t\t// STORE-12: the failure reaches bindings as error state; the last\n\t\t\t\t// snapshot stays readable and the next success clears the error.\n\t\t\t\tonError: (failure) => {\n\t\t\t\t\tif (!this.active) return\n\t\t\t\t\tthis.error = failure.error\n\t\t\t\t\tthis.notifyListeners()\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t}\n\n\tprivate stopSubscription(): void {\n\t\tthis.active = false\n\t\tif (this.unsubscribeQuery) {\n\t\t\tthis.unsubscribeQuery()\n\t\t\tthis.unsubscribeQuery = null\n\t\t}\n\t}\n\n\tprivate notifyListeners(): void {\n\t\tfor (const listener of this.listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n}\n","import { AppNotReadyError } from '@korajs/core'\nimport type { QueryBuilder } from '../query/query-builder'\n\nconst LEGACY_PENDING_COLLECTION = '__pending__'\n\n/**\n * Ensures a query builder is backed by an open store (not a legacy pending placeholder).\n */\nexport function assertQueryReady(query: QueryBuilder<unknown>): void {\n\tconst descriptor = query.getDescriptor()\n\tif (descriptor.collection === LEGACY_PENDING_COLLECTION) {\n\t\tthrow new AppNotReadyError(\n\t\t\t'Cannot use useQuery() before app.ready. Await app.ready or wrap your UI in <KoraProvider app={app}>.',\n\t\t)\n\t}\n}\n","import type { QueryBuilder } from '../query/query-builder'\nimport { queryKey } from '../query/query-key'\nimport type { CollectionRecord } from '../types'\nimport { QueryStore } from './query-store'\n\ninterface CacheEntry {\n\tqueryStore: QueryStore<CollectionRecord>\n\trefCount: number\n}\n\n/**\n * Reference-counted cache of {@link QueryStore} instances keyed by query descriptor.\n * Identical queries from different components share one underlying subscription.\n */\nexport class QueryStoreCache {\n\tprivate entries = new Map<string, CacheEntry>()\n\n\tconstructor(private readonly scopeKey = 'default') {}\n\n\tgetOrCreate<T>(queryBuilder: QueryBuilder<T>): QueryStore<T> {\n\t\tconst key = this.getKey(queryBuilder)\n\t\tconst existing = this.entries.get(key)\n\n\t\tif (existing) {\n\t\t\texisting.refCount++\n\t\t\treturn existing.queryStore as QueryStore<T>\n\t\t}\n\n\t\tconst queryStore = new QueryStore<T>(queryBuilder)\n\t\tthis.entries.set(key, {\n\t\t\tqueryStore: queryStore as QueryStore<CollectionRecord>,\n\t\t\trefCount: 1,\n\t\t})\n\t\treturn queryStore\n\t}\n\n\trelease(queryBuilder: QueryBuilder<unknown>): void {\n\t\tconst key = this.getKey(queryBuilder)\n\t\tconst entry = this.entries.get(key)\n\t\tif (!entry) {\n\t\t\treturn\n\t\t}\n\n\t\tentry.refCount--\n\t\tif (entry.refCount <= 0) {\n\t\t\tentry.queryStore.destroy()\n\t\t\tthis.entries.delete(key)\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tentry.queryStore.destroy()\n\t\t}\n\t\tthis.entries.clear()\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size\n\t}\n\n\tprivate getKey(queryBuilder: QueryBuilder<unknown>): string {\n\t\treturn `${this.scopeKey}:${queryKey(queryBuilder.getDescriptor())}`\n\t}\n}\n\nlet sharedCache: QueryStoreCache | null = null\n\n/**\n * Process-wide shared query store cache for framework bindings.\n *\n * @deprecated Prefer {@link KoraApp.getQueryStoreCache} via `KoraProvider` context\n * so each app instance owns an isolated cache.\n */\nexport function getSharedQueryStoreCache(): QueryStoreCache {\n\tif (!sharedCache) {\n\t\tsharedCache = new QueryStoreCache()\n\t}\n\treturn sharedCache\n}\n","import * as Y from 'yjs'\nimport { encodeRichtext } from '../serialization/richtext-serializer'\nimport type {\n\tCreateRichTextControllerOptions,\n\tRichTextAwarenessState,\n\tRichTextAwarenessUser,\n\tRichTextController,\n\tRichTextControllerSnapshot,\n\tRichTextCursorInfo,\n} from './types'\n\nconst LOAD_ORIGIN = 'kora-load'\nconst REMOTE_ORIGIN = 'kora-remote'\nconst DOC_CHANNEL_ORIGIN = 'kora-doc-channel'\nconst TEXT_KEY = 'content'\nconst PERSIST_DEBOUNCE_MS = 400\n\n/**\n * Framework-agnostic richtext binding: Yjs document lifecycle, persistence,\n * incremental doc channel, and awareness cursors.\n *\n * Every save writes the full state of the live Y.Doc, which holds every local edit\n * and every merged remote change, so a stored change arriving while a save waits\n * cannot drop local typing. A refused save keeps the edits unsaved\n * (`hasUnsavedChanges`, `getUnsavedState()`) and the next edit or `retrySave()`\n * saves them again; the first successful save clears `error`.\n */\nexport function createRichTextController(\n\toptions: CreateRichTextControllerOptions,\n): RichTextController {\n\tconst {\n\t\tcollection,\n\t\tcollectionName,\n\t\trecordId,\n\t\tfieldName,\n\t\tstore,\n\t\tsyncEngine = null,\n\t\tuseDocChannel,\n\t} = options\n\n\tconst doc = new Y.Doc()\n\tconst text = doc.getText(TEXT_KEY)\n\tconst undoManager = new Y.UndoManager(text)\n\n\tlet user = options.user\n\tlet disposed = false\n\tlet ready = false\n\tlet error: Error | null = null\n\tlet canUndo = false\n\tlet canRedo = false\n\tlet cursors: RichTextCursorInfo[] = []\n\t// Local edits are counted; a save that succeeds covers every edit made before it\n\t// read the document. Edits after the last covered one are unsaved.\n\tlet editGeneration = 0\n\tlet savedGeneration = 0\n\tlet saving: Promise<void> | null = null\n\tlet saveAgain = false\n\n\tconst listeners = new Set<() => void>()\n\tlet snapshot: RichTextControllerSnapshot = {\n\t\tready: false,\n\t\terror: null,\n\t\tcanUndo: false,\n\t\tcanRedo: false,\n\t\tcursors: [],\n\t\thasUnsavedChanges: false,\n\t}\n\tconst docChannelActiveRef = { current: false }\n\tlet persistTimer: ReturnType<typeof setTimeout> | null = null\n\n\tlet recordUnsubscribe: (() => void) | null = null\n\tlet docChannelUnsubscribe: (() => void) | null = null\n\tlet awarenessUnsubscribe: (() => void) | null = null\n\n\tconst refreshSnapshot = (): void => {\n\t\tsnapshot = {\n\t\t\tready,\n\t\t\terror,\n\t\t\tcanUndo,\n\t\t\tcanRedo,\n\t\t\tcursors: [...cursors],\n\t\t\thasUnsavedChanges: editGeneration > savedGeneration,\n\t\t}\n\t}\n\n\tconst notify = (): void => {\n\t\trefreshSnapshot()\n\t\tfor (const listener of listeners) {\n\t\t\tlistener()\n\t\t}\n\t}\n\n\tconst syncHistoryState = (): void => {\n\t\tcanUndo = undoManager.undoStack.length > 0\n\t\tcanRedo = undoManager.redoStack.length > 0\n\t\tnotify()\n\t}\n\n\tconst getSnapshot = (): RichTextControllerSnapshot => snapshot\n\n\tconst resolveAwarenessUser = (): RichTextAwarenessUser => {\n\t\tif (user) {\n\t\t\treturn user\n\t\t}\n\t\tif (syncEngine) {\n\t\t\tconst existing = syncEngine.getAwarenessManager().getLocalState()?.user\n\t\t\tif (existing) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tname: 'Anonymous',\n\t\t\tcolor: '#6366f1',\n\t\t}\n\t}\n\n\tconst setCursor = (anchor: number, head: number): void => {\n\t\tif (!syncEngine) {\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst state: RichTextAwarenessState = {\n\t\t\tuser: resolveAwarenessUser(),\n\t\t\tcursor: {\n\t\t\t\tcollection: collectionName,\n\t\t\t\trecordId,\n\t\t\t\tfield: fieldName,\n\t\t\t\tanchor,\n\t\t\t\thead,\n\t\t\t},\n\t\t}\n\t\tawareness.setLocalState(state)\n\t}\n\n\tconst clearCursor = (): void => {\n\t\tif (!syncEngine) {\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst current = awareness.getLocalState()\n\t\tif (!current?.cursor) {\n\t\t\treturn\n\t\t}\n\t\tif (\n\t\t\tcurrent.cursor.collection !== collectionName ||\n\t\t\tcurrent.cursor.recordId !== recordId ||\n\t\t\tcurrent.cursor.field !== fieldName\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tawareness.setLocalState({ user: current.user })\n\t}\n\n\tconst applyRemoteSnapshot = (value: unknown): void => {\n\t\tconst encoded = encodeRichtextInput(value)\n\t\tif (!encoded) {\n\t\t\treturn\n\t\t}\n\n\t\tconst currentSnapshot = Y.encodeStateAsUpdate(doc)\n\t\tif (updatesEqual(currentSnapshot, encoded)) {\n\t\t\treturn\n\t\t}\n\n\t\t// A Yjs merge: the stored state joins the live document and local edits that\n\t\t// are not saved yet stay in it, so the next save (of the live document) keeps them.\n\t\tY.applyUpdate(doc, encoded, REMOTE_ORIGIN)\n\t\tsyncHistoryState()\n\t}\n\n\t/** Save the live document once; the outcome updates `error` and the unsaved state. */\n\tconst persistOnce = async (): Promise<void> => {\n\t\tconst generation = editGeneration\n\t\tconst state = Y.encodeStateAsUpdate(doc)\n\t\ttry {\n\t\t\tawait collection.update(recordId, {\n\t\t\t\t[fieldName]: state,\n\t\t\t})\n\t\t\tif (generation > savedGeneration) savedGeneration = generation\n\t\t\terror = null\n\t\t} catch (cause) {\n\t\t\terror = cause instanceof Error ? cause : new Error(String(cause))\n\t\t}\n\t\tif (!disposed) notify()\n\t}\n\n\t/**\n\t * Save the live document. Saves run one at a time; a request during a save runs\n\t * one more save after it, which reads the document then and so holds every edit.\n\t */\n\tconst flushPersist = (): Promise<void> => {\n\t\tif (saving) {\n\t\t\tsaveAgain = true\n\t\t\treturn saving\n\t\t}\n\t\tconst run = (async () => {\n\t\t\tdo {\n\t\t\t\tsaveAgain = false\n\t\t\t\tawait persistOnce()\n\t\t\t} while (saveAgain)\n\t\t})()\n\t\tsaving = run\n\t\tvoid run.finally(() => {\n\t\t\tif (saving === run) saving = null\n\t\t})\n\t\treturn run\n\t}\n\n\tconst schedulePersist = (): void => {\n\t\tif (persistTimer) {\n\t\t\tclearTimeout(persistTimer)\n\t\t}\n\t\tpersistTimer = setTimeout(() => {\n\t\t\tpersistTimer = null\n\t\t\tvoid flushPersist()\n\t\t}, PERSIST_DEBOUNCE_MS)\n\t}\n\n\tconst onDocUpdate = (update: Uint8Array, origin: unknown): void => {\n\t\tsyncHistoryState()\n\t\tif (origin === LOAD_ORIGIN || origin === REMOTE_ORIGIN || origin === DOC_CHANNEL_ORIGIN) {\n\t\t\treturn\n\t\t}\n\n\t\teditGeneration += 1\n\n\t\tif (docChannelActiveRef.current && syncEngine) {\n\t\t\tsyncEngine.getRichtextDocChannel?.().send(collectionName, recordId, fieldName, update)\n\t\t\tschedulePersist()\n\t\t\treturn\n\t\t}\n\n\t\tvoid flushPersist()\n\t}\n\n\tconst subscribeRecordChanges = (): void => {\n\t\trecordUnsubscribe?.()\n\t\trecordUnsubscribe = store\n\t\t\t.collection(collectionName)\n\t\t\t.where({ id: recordId })\n\t\t\t.subscribe((results) => {\n\t\t\t\tconst record = results[0]\n\t\t\t\tif (!record) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tapplyRemoteSnapshot(record[fieldName])\n\t\t\t})\n\t}\n\n\tconst subscribeDocChannel = (): void => {\n\t\tdocChannelUnsubscribe?.()\n\t\tif (!ready || !syncEngine || !docChannelActiveRef.current) {\n\t\t\treturn\n\t\t}\n\n\t\tconst channel = syncEngine.getRichtextDocChannel?.()\n\t\tif (!channel) {\n\t\t\treturn\n\t\t}\n\n\t\tdocChannelUnsubscribe = channel.subscribe(collectionName, recordId, fieldName, (update) => {\n\t\t\tY.applyUpdate(doc, update, DOC_CHANNEL_ORIGIN)\n\t\t\tsyncHistoryState()\n\t\t})\n\t}\n\n\tconst updateCursors = (): void => {\n\t\tif (!syncEngine) {\n\t\t\tcursors = []\n\t\t\tnotify()\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst localClientId = awareness.clientId\n\t\tconst states = awareness.getStates()\n\t\tconst fieldCursors: RichTextCursorInfo[] = []\n\n\t\tfor (const [clientId, state] of states) {\n\t\t\tif (clientId === localClientId) continue\n\t\t\tif (!state.cursor) continue\n\t\t\tif (\n\t\t\t\tstate.cursor.collection !== collectionName ||\n\t\t\t\tstate.cursor.recordId !== recordId ||\n\t\t\t\tstate.cursor.field !== fieldName\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfieldCursors.push({\n\t\t\t\tclientId,\n\t\t\t\tuserName: state.user.name,\n\t\t\t\tcolor: state.user.color,\n\t\t\t\tanchor: state.cursor.anchor,\n\t\t\t\thead: state.cursor.head,\n\t\t\t})\n\t\t}\n\n\t\tcursors = fieldCursors\n\t\tnotify()\n\t}\n\n\tconst subscribeAwareness = (): void => {\n\t\tawarenessUnsubscribe?.()\n\t\tif (!syncEngine) {\n\t\t\tcursors = []\n\t\t\tnotify()\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tawarenessUnsubscribe = awareness.on('change', () => {\n\t\t\tupdateCursors()\n\t\t})\n\t\tupdateCursors()\n\t}\n\n\tconst initialize = async (): Promise<void> => {\n\t\tready = false\n\t\terror = null\n\t\tnotify()\n\n\t\ttry {\n\t\t\tconst record = await collection.findById(recordId)\n\t\t\tif (disposed) return\n\n\t\t\tdoc.transact(() => {\n\t\t\t\tconst target = doc.getText(TEXT_KEY)\n\t\t\t\ttarget.delete(0, target.length)\n\t\t\t}, LOAD_ORIGIN)\n\n\t\t\tconst encoded = encodeRichtextInput(record?.[fieldName])\n\t\t\tif (encoded) {\n\t\t\t\tY.applyUpdate(doc, encoded, LOAD_ORIGIN)\n\t\t\t}\n\n\t\t\tconst channel = syncEngine?.getRichtextDocChannel?.()\n\t\t\tdocChannelActiveRef.current =\n\t\t\t\tchannel?.shouldUseChannel(encoded?.length ?? 0, useDocChannel) ?? false\n\n\t\t\tready = true\n\t\t\tsyncHistoryState()\n\t\t\tsubscribeRecordChanges()\n\t\t\tsubscribeDocChannel()\n\t\t\tsubscribeAwareness()\n\t\t\tnotify()\n\t\t} catch (cause) {\n\t\t\tif (disposed) return\n\t\t\terror = cause instanceof Error ? cause : new Error(String(cause))\n\t\t\tnotify()\n\t\t}\n\t}\n\n\tdoc.on('update', onDocUpdate)\n\tvoid initialize()\n\n\treturn {\n\t\tdoc,\n\t\ttext,\n\t\tgetSnapshot,\n\t\tsubscribe(listener) {\n\t\t\tlisteners.add(listener)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t}\n\t\t},\n\t\tundo() {\n\t\t\tundoManager.undo()\n\t\t\tsyncHistoryState()\n\t\t},\n\t\tredo() {\n\t\t\tundoManager.redo()\n\t\t\tsyncHistoryState()\n\t\t},\n\t\tsetCursor,\n\t\tclearCursor,\n\t\tsetUser(nextUser: RichTextAwarenessUser | undefined) {\n\t\t\tuser = nextUser\n\t\t},\n\t\tretrySave() {\n\t\t\tif (persistTimer) {\n\t\t\t\tclearTimeout(persistTimer)\n\t\t\t\tpersistTimer = null\n\t\t\t}\n\t\t\treturn flushPersist()\n\t\t},\n\t\tgetUnsavedState() {\n\t\t\treturn editGeneration > savedGeneration ? Y.encodeStateAsUpdate(doc) : null\n\t\t},\n\t\tdestroy() {\n\t\t\tif (disposed) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdisposed = true\n\t\t\t// Edits waiting for the debounced save are saved now, not dropped.\n\t\t\tif (persistTimer) {\n\t\t\t\tclearTimeout(persistTimer)\n\t\t\t\tpersistTimer = null\n\t\t\t}\n\t\t\tif (editGeneration > savedGeneration) {\n\t\t\t\tvoid flushPersist()\n\t\t\t}\n\t\t\tdoc.off('update', onDocUpdate)\n\t\t\trecordUnsubscribe?.()\n\t\t\tdocChannelUnsubscribe?.()\n\t\t\tawarenessUnsubscribe?.()\n\t\t\tclearCursor()\n\t\t\tundoManager.destroy()\n\t\t\tdocChannelActiveRef.current = false\n\t\t\tlisteners.clear()\n\t\t},\n\t}\n}\n\nfunction encodeRichtextInput(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\ttry {\n\t\treturn encodeRichtext(value as Parameters<typeof encodeRichtext>[0])\n\t} catch {\n\t\tif (typeof value === 'string') {\n\t\t\tconst fallbackDoc = new Y.Doc()\n\t\t\tfallbackDoc.getText(TEXT_KEY).insert(0, value)\n\t\t\treturn Y.encodeStateAsUpdate(fallbackDoc)\n\t\t}\n\t\tthrow new Error('Richtext record value must be a string, Uint8Array, ArrayBuffer, or null.')\n\t}\n}\n\nfunction updatesEqual(left: Uint8Array, right: Uint8Array): boolean {\n\tif (left.length !== right.length) {\n\t\treturn false\n\t}\n\tfor (let index = 0; index < left.length; index++) {\n\t\tif (left[index] !== right[index]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n","import type { RichTextSyncEngine } from './types'\n\n/**\n * Narrows a sync engine reference to the richtext controller surface.\n * SyncEngine satisfies this interface at runtime; types live in different packages.\n */\nexport function asRichTextSyncEngine(engine: unknown): RichTextSyncEngine | null {\n\tif (engine == null) {\n\t\treturn null\n\t}\n\treturn engine as RichTextSyncEngine\n}\n","export {\n\tBACKUP_VERSION,\n\tBackupFormatError,\n\tconvertBackupV1,\n\texportBackup,\n\tparseBackup,\n\treadBackupManifest,\n\trestoreBackup,\n\tverifyBackupChecksum,\n} from './backup'\nexport type { ConvertBackupV1Options, ParsedBackup } from './backup'\nexport type {\n\tBackupManifest,\n\tBackupOptions,\n\tBackupProgress,\n\tRestoreOptions,\n\tRestoreResult,\n} from './types'\n","export {\n\tappendAuditTrace,\n\tauditTraceIndexFields,\n\tcountAuditTraces,\n\tpersistedAuditTraceFromEvent,\n\treadAuditTraces,\n} from './audit-trace-store'\nexport {\n\tauditJsonReplacer,\n\tauditJsonReviver,\n\tdeserializeAuditJson,\n\tserializeAuditJson,\n} from './audit-json'\nexport {\n\tdecodeAuditExport,\n\texportAudit,\n\treadAuditExportManifest,\n\tverifyAuditExportChecksum,\n} from './export-audit'\nexport type {\n\tAuditExportManifest,\n\tAuditExportOptions,\n\tAuditExportPayload,\n\tAuditExportProgress,\n\tAuditTraceQuery,\n\tPersistedAuditTrace,\n} from './types'\n","import { type BlobRef, type BlobRefMetadata, createBlobRef, hashBlob } from '@korajs/core'\n\n/**\n * Thrown when a blob read fails its integrity check: the bytes stored under a\n * hash do not actually hash to that value (corruption or tampering).\n */\nexport class BlobIntegrityError extends Error {\n\tconstructor(\n\t\treadonly expectedHash: string,\n\t\treadonly actualHash: string,\n\t) {\n\t\tsuper(`Blob integrity check failed: content under hash ${expectedHash} hashes to ${actualHash}`)\n\t\tthis.name = 'BlobIntegrityError'\n\t}\n}\n\n/**\n * A content-addressed store for the bytes behind `blob` fields.\n *\n * Blobs are keyed by the SHA-256 hash of their content, so identical content is\n * stored exactly once (deduplication) and a peer never needs to transfer bytes\n * it already holds. Reads are integrity-checked: the returned bytes are verified\n * to hash to the requested key.\n */\nexport interface ContentAddressedBlobStore {\n\t/**\n\t * Store bytes and return their content-addressed reference. Storing content\n\t * that already exists is a no-op that returns the same reference (dedup).\n\t */\n\tput(bytes: Uint8Array, metadata?: BlobRefMetadata): Promise<BlobRef>\n\t/**\n\t * Retrieve the bytes for a hash, or null if absent. The returned bytes are\n\t * verified to hash to the requested value; a mismatch throws\n\t * {@link BlobIntegrityError} rather than returning corrupt data.\n\t */\n\tget(hash: string): Promise<Uint8Array | null>\n\t/** Whether the store holds content for the given hash. */\n\thas(hash: string): Promise<boolean>\n\t/** Remove the content for a hash. Returns whether anything was removed. */\n\tdelete(hash: string): Promise<boolean>\n\t/** Number of distinct blobs held. */\n\tsize(): Promise<number>\n\t/**\n\t * List the hashes of every blob currently held. Used by garbage collection to\n\t * find content no live reference points to. Order is unspecified.\n\t */\n\tlist(): Promise<string[]>\n}\n\n/**\n * In-memory {@link ContentAddressedBlobStore}. The reference backend used for\n * tests and for environments without a persistent blob backend yet. Persistent\n * backends (OPFS client-side, filesystem/S3 server-side) implement the same\n * interface.\n */\nexport class MemoryBlobStore implements ContentAddressedBlobStore {\n\tprivate readonly blobs = new Map<string, Uint8Array>()\n\n\tasync put(bytes: Uint8Array, metadata: BlobRefMetadata = {}): Promise<BlobRef> {\n\t\tconst ref = await createBlobRef(bytes, metadata)\n\t\tif (!this.blobs.has(ref.hash)) {\n\t\t\t// Copy so later mutation of the caller's buffer cannot corrupt the store.\n\t\t\tconst stored = new Uint8Array(bytes.byteLength)\n\t\t\tstored.set(bytes)\n\t\t\tthis.blobs.set(ref.hash, stored)\n\t\t}\n\t\treturn ref\n\t}\n\n\tasync get(hash: string): Promise<Uint8Array | null> {\n\t\tconst stored = this.blobs.get(hash)\n\t\tif (stored === undefined) {\n\t\t\treturn null\n\t\t}\n\t\tconst actualHash = await hashBlob(stored)\n\t\tif (actualHash !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actualHash)\n\t\t}\n\t\t// Return a copy so callers cannot mutate the stored bytes.\n\t\tconst out = new Uint8Array(stored.byteLength)\n\t\tout.set(stored)\n\t\treturn out\n\t}\n\n\tasync has(hash: string): Promise<boolean> {\n\t\treturn this.blobs.has(hash)\n\t}\n\n\tasync delete(hash: string): Promise<boolean> {\n\t\treturn this.blobs.delete(hash)\n\t}\n\n\tasync size(): Promise<number> {\n\t\treturn this.blobs.size\n\t}\n\n\tasync list(): Promise<string[]> {\n\t\treturn [...this.blobs.keys()]\n\t}\n}\n","import { type BlobRef, type BlobRefMetadata, createBlobRef, hashBlob } from '@korajs/core'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * The minimal directory abstraction an {@link OpfsBlobStore} needs. Blobs are\n * laid out as `<shard>/<name>` (shard = first two hex chars of the hash) so a\n * single directory never holds millions of entries.\n *\n * The real backend ({@link createOpfsBlobDirectory}) is the browser Origin\n * Private File System; tests supply an in-memory implementation. Keeping this\n * port small means the content-addressed logic (hashing, integrity, dedup,\n * sharding) is fully testable without a browser.\n */\nexport interface OpfsBlobDirectory {\n\t/** Read the bytes at `<shard>/<name>`, or null if absent. */\n\tread(shard: string, name: string): Promise<Uint8Array | null>\n\t/**\n\t * Write bytes at `<shard>/<name>`, creating the shard directory as needed.\n\t * Must be atomic: a crash mid-write may not leave a partially-written file\n\t * that a later read would trust.\n\t */\n\twrite(shard: string, name: string, bytes: Uint8Array): Promise<void>\n\t/** Remove `<shard>/<name>`. Returns whether anything was removed. */\n\tremove(shard: string, name: string): Promise<boolean>\n\t/** Whether `<shard>/<name>` exists. */\n\thas(shard: string, name: string): Promise<boolean>\n\t/** Count of stored blobs across all shards (temp files excluded). */\n\tcount(): Promise<number>\n\t/** Every stored blob name (hash) across all shards (temp files excluded). */\n\tkeys(): Promise<string[]>\n}\n\n/**\n * A persistent {@link ContentAddressedBlobStore} for the browser, backed by the\n * Origin Private File System (OPFS) — the same durable storage the SQLite WASM\n * adapter uses. Blobs survive reloads, are sharded by hash prefix, deduplicated,\n * and integrity-verified on read (the returned bytes are checked to hash to the\n * requested key). Writes commit atomically so a torn write cannot surface as\n * trusted data.\n *\n * The store itself is environment-neutral: it talks to an {@link OpfsBlobDirectory}.\n * Use {@link createOpfsBlobStore} in a browser to get one backed by real OPFS.\n */\nexport class OpfsBlobStore implements ContentAddressedBlobStore {\n\tconstructor(private readonly dir: OpfsBlobDirectory) {}\n\n\tprivate shardFor(hash: string): string {\n\t\t// Two hex chars → 256 shards. Hashes are hex, so this is always well-formed.\n\t\treturn hash.slice(0, 2)\n\t}\n\n\tasync put(bytes: Uint8Array, metadata: BlobRefMetadata = {}): Promise<BlobRef> {\n\t\tconst ref = await createBlobRef(bytes, metadata)\n\t\tconst shard = this.shardFor(ref.hash)\n\n\t\t// Dedup: identical content already stored is a no-op.\n\t\tif (await this.dir.has(shard, ref.hash)) {\n\t\t\treturn ref\n\t\t}\n\n\t\t// Copy into an exactly-sized buffer so a subarray view writes its own bytes.\n\t\tconst out = new Uint8Array(bytes.byteLength)\n\t\tout.set(bytes)\n\t\tawait this.dir.write(shard, ref.hash, out)\n\t\treturn ref\n\t}\n\n\tasync get(hash: string): Promise<Uint8Array | null> {\n\t\tconst bytes = await this.dir.read(this.shardFor(hash), hash)\n\t\tif (bytes === null) {\n\t\t\treturn null\n\t\t}\n\t\tconst actual = await hashBlob(bytes)\n\t\tif (actual !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actual)\n\t\t}\n\t\treturn bytes\n\t}\n\n\tasync has(hash: string): Promise<boolean> {\n\t\treturn this.dir.has(this.shardFor(hash), hash)\n\t}\n\n\tasync delete(hash: string): Promise<boolean> {\n\t\treturn this.dir.remove(this.shardFor(hash), hash)\n\t}\n\n\tasync size(): Promise<number> {\n\t\treturn this.dir.count()\n\t}\n\n\tasync list(): Promise<string[]> {\n\t\treturn this.dir.keys()\n\t}\n}\n\n// --- Real OPFS binding (browser only) ---\n\n/** Minimal structural views of the File System Access handles we use. */\ninterface OpfsWritableStream {\n\twrite(data: Uint8Array): Promise<void>\n\tclose(): Promise<void>\n}\ninterface OpfsFileHandle {\n\tcreateWritable(options?: { keepExistingData?: boolean }): Promise<OpfsWritableStream>\n\tgetFile(): Promise<{ arrayBuffer(): Promise<ArrayBuffer> }>\n}\ninterface OpfsDirectoryHandle {\n\tgetDirectoryHandle(name: string, options?: { create?: boolean }): Promise<OpfsDirectoryHandle>\n\tgetFileHandle(name: string, options?: { create?: boolean }): Promise<OpfsFileHandle>\n\tremoveEntry(name: string, options?: { recursive?: boolean }): Promise<void>\n\tkeys(): AsyncIterableIterator<string>\n}\n\ninterface StorageManagerLike {\n\tgetDirectory(): Promise<OpfsDirectoryHandle>\n}\n\nfunction getStorageManager(): StorageManagerLike {\n\tconst nav = (globalThis as unknown as { navigator?: { storage?: StorageManagerLike } }).navigator\n\tif (!nav?.storage || typeof nav.storage.getDirectory !== 'function') {\n\t\tthrow new Error(\n\t\t\t'OPFS is unavailable in this environment. The OPFS blob store requires a browser with Origin Private File System support; use MemoryBlobStore or a server-side store elsewhere.',\n\t\t)\n\t}\n\treturn nav.storage\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === 'object' &&\n\t\terror !== null &&\n\t\t(error as { name?: string }).name === 'NotFoundError'\n\t)\n}\n\n/**\n * Create an {@link OpfsBlobDirectory} backed by the browser's Origin Private\n * File System, rooted at a named subdirectory. It does not request persistent\n * storage: that is `app.storage.persistence`, kept off the startup path.\n *\n * @param rootDirName - The OPFS subdirectory to store blobs under (default `kora-blobs`)\n * @throws {Error} If OPFS is unavailable (e.g. called outside a browser)\n */\nexport async function createOpfsBlobDirectory(\n\trootDirName = 'kora-blobs',\n): Promise<OpfsBlobDirectory> {\n\tconst storage = getStorageManager()\n\t// NEW-STORE-4: no persist() here. In Firefox it opens a permission prompt that\n\t// stays pending until the user answers, and this runs inside app startup.\n\t// Durable storage is checked and requested by StoragePersistence\n\t// (app.storage.persistence), never on the startup path.\n\tconst opfsRoot = await storage.getDirectory()\n\tconst root = await opfsRoot.getDirectoryHandle(rootDirName, { create: true })\n\n\tasync function shardHandle(shard: string, create: boolean): Promise<OpfsDirectoryHandle | null> {\n\t\ttry {\n\t\t\treturn await root.getDirectoryHandle(shard, { create })\n\t\t} catch (error) {\n\t\t\tif (isNotFoundError(error)) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\treturn {\n\t\tasync read(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tlet handle: OpfsFileHandle\n\t\t\ttry {\n\t\t\t\thandle = await dir.getFileHandle(name, { create: false })\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tconst file = await handle.getFile()\n\t\t\treturn new Uint8Array(await file.arrayBuffer())\n\t\t},\n\t\tasync write(shard, name, bytes) {\n\t\t\tconst dir = await root.getDirectoryHandle(shard, { create: true })\n\t\t\tconst handle = await dir.getFileHandle(name, { create: true })\n\t\t\t// createWritable buffers to a swap file and only commits on close(), so\n\t\t\t// the target file is updated atomically. Combined with integrity-on-read,\n\t\t\t// a torn write is never trusted.\n\t\t\tconst writable = await handle.createWritable({ keepExistingData: false })\n\t\t\ttry {\n\t\t\t\tawait writable.write(bytes)\n\t\t\t} finally {\n\t\t\t\tawait writable.close()\n\t\t\t}\n\t\t},\n\t\tasync remove(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait dir.removeEntry(name)\n\t\t\t\treturn true\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\t\tasync has(shard, name) {\n\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\tif (!dir) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait dir.getFileHandle(name, { create: false })\n\t\t\t\treturn true\n\t\t\t} catch (error) {\n\t\t\t\tif (isNotFoundError(error)) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\t\tasync count() {\n\t\t\tlet total = 0\n\t\t\tfor await (const shard of root.keys()) {\n\t\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\t\tif (!dir) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor await (const name of dir.keys()) {\n\t\t\t\t\tif (!name.endsWith('.tmp')) {\n\t\t\t\t\t\ttotal++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn total\n\t\t},\n\t\tasync keys() {\n\t\t\tconst names: string[] = []\n\t\t\tfor await (const shard of root.keys()) {\n\t\t\t\tconst dir = await shardHandle(shard, false)\n\t\t\t\tif (!dir) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor await (const name of dir.keys()) {\n\t\t\t\t\tif (!name.endsWith('.tmp')) {\n\t\t\t\t\t\tnames.push(name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn names\n\t\t},\n\t}\n}\n\n/**\n * Create a persistent {@link OpfsBlobStore} backed by real browser OPFS.\n *\n * @param rootDirName - The OPFS subdirectory to store blobs under (default `kora-blobs`)\n * @throws {Error} If OPFS is unavailable (e.g. called outside a browser)\n */\nexport async function createOpfsBlobStore(rootDirName = 'kora-blobs'): Promise<OpfsBlobStore> {\n\treturn new OpfsBlobStore(await createOpfsBlobDirectory(rootDirName))\n}\n","import { hashBlob } from '@korajs/core'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/** Default chunk size for out-of-band blob transfer (256 KiB). */\nexport const DEFAULT_CHUNK_SIZE = 256 * 1024\n\n/**\n * A manifest describing how a blob is split into content-addressed chunks.\n *\n * The manifest is small and travels with the operation stream (or alongside it);\n * the chunk bytes travel out of band. Because every chunk is content-addressed,\n * identical chunks across blobs are stored and transferred once, and a peer only\n * ever requests chunk hashes it does not already hold.\n */\nexport interface BlobManifest {\n\t/** Hex SHA-256 hash of the full reassembled blob (its content address). */\n\tblobHash: string\n\t/** Total size of the full blob in bytes. */\n\tsize: number\n\t/** The chunk size used to split the blob. */\n\tchunkSize: number\n\t/** Ordered hashes of each chunk. Repeats when identical chunks recur. */\n\tchunkHashes: string[]\n\tmimeType?: string\n\tfilename?: string\n}\n\n/** Optional metadata carried on a manifest. */\nexport interface BlobManifestMetadata {\n\tmimeType?: string\n\tfilename?: string\n}\n\n/**\n * Split a blob into content-addressed chunks and produce its manifest.\n *\n * @param bytes - The full blob content\n * @param chunkSize - Bytes per chunk (defaults to {@link DEFAULT_CHUNK_SIZE})\n * @param metadata - Optional mime type / filename to record on the manifest\n * @returns The manifest and a map of chunk hash to chunk bytes (deduplicated)\n */\nexport async function chunkBlob(\n\tbytes: Uint8Array,\n\tchunkSize: number = DEFAULT_CHUNK_SIZE,\n\tmetadata: BlobManifestMetadata = {},\n): Promise<{ manifest: BlobManifest; chunks: Map<string, Uint8Array> }> {\n\tif (chunkSize <= 0) {\n\t\tthrow new Error(`chunkBlob requires a positive chunkSize, got ${chunkSize}`)\n\t}\n\n\tconst chunkHashes: string[] = []\n\tconst chunks = new Map<string, Uint8Array>()\n\n\tfor (let offset = 0; offset < bytes.byteLength; offset += chunkSize) {\n\t\tconst end = Math.min(offset + chunkSize, bytes.byteLength)\n\t\tconst chunk = new Uint8Array(end - offset)\n\t\tchunk.set(bytes.subarray(offset, end))\n\t\tconst hash = await hashBlob(chunk)\n\t\tchunkHashes.push(hash)\n\t\t// Identical chunks collapse to one stored entry; the ordered hash list\n\t\t// still records every position so reassembly reproduces the exact bytes.\n\t\tif (!chunks.has(hash)) {\n\t\t\tchunks.set(hash, chunk)\n\t\t}\n\t}\n\n\tconst blobHash = await hashBlob(bytes)\n\tconst manifest: BlobManifest = {\n\t\tblobHash,\n\t\tsize: bytes.byteLength,\n\t\tchunkSize,\n\t\tchunkHashes,\n\t}\n\tif (metadata.mimeType !== undefined) {\n\t\tmanifest.mimeType = metadata.mimeType\n\t}\n\tif (metadata.filename !== undefined) {\n\t\tmanifest.filename = metadata.filename\n\t}\n\n\treturn { manifest, chunks }\n}\n\n/**\n * Reassemble a blob from chunks held in a content-addressed store, verifying\n * integrity at both levels: each chunk is verified by the store on read, and the\n * reassembled whole is verified against the manifest's blob hash.\n *\n * @param manifest - The blob manifest\n * @param chunkStore - A store holding the chunk bytes keyed by chunk hash\n * @returns The full reassembled blob bytes\n * @throws {BlobIntegrityError} If the reassembled bytes do not match blobHash\n * @throws {Error} If a chunk named in the manifest is missing from the store\n */\nexport async function reassembleBlob(\n\tmanifest: BlobManifest,\n\tchunkStore: ContentAddressedBlobStore,\n): Promise<Uint8Array> {\n\tconst parts: Uint8Array[] = []\n\tlet total = 0\n\n\tfor (const hash of manifest.chunkHashes) {\n\t\tconst chunk = await chunkStore.get(hash)\n\t\tif (chunk === null) {\n\t\t\tthrow new Error(`Cannot reassemble blob ${manifest.blobHash}: missing chunk ${hash}`)\n\t\t}\n\t\tparts.push(chunk)\n\t\ttotal += chunk.byteLength\n\t}\n\n\tconst out = new Uint8Array(total)\n\tlet offset = 0\n\tfor (const part of parts) {\n\t\tout.set(part, offset)\n\t\toffset += part.byteLength\n\t}\n\n\tconst actual = await hashBlob(out)\n\tif (actual !== manifest.blobHash) {\n\t\tthrow new BlobIntegrityError(manifest.blobHash, actual)\n\t}\n\treturn out\n}\n","import { type BlobRef, hashBlob } from '@korajs/core'\nimport { type BlobManifest, chunkBlob, reassembleBlob } from './blob-chunking'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * A source of chunk bytes on the sending side of a transfer. In production this\n * is backed by the sync connection (the receiver requests a chunk hash, the peer\n * that holds the blob answers with the bytes); in tests it is backed by a map.\n */\nexport interface ChunkProvider {\n\t/** Fetch the bytes for a chunk hash, or null if the provider does not have it. */\n\tgetChunk(hash: string): Promise<Uint8Array | null>\n}\n\n/** Result of receiving a blob out of band. */\nexport interface ReceiveBlobResult {\n\t/** The content-addressed reference to the reassembled blob. */\n\tref: BlobRef\n\t/** Number of chunks actually fetched from the provider. */\n\tchunksFetched: number\n\t/** Number of chunks skipped because they were already held locally. */\n\tchunksSkipped: number\n}\n\n/** Stores used while receiving a blob. */\nexport interface ReceiveBlobStores {\n\t/**\n\t * Where fetched chunks are staged, keyed by chunk hash. A persistent chunk\n\t * store makes a transfer resumable: an interrupted transfer leaves its chunks\n\t * here, and a resumed transfer skips them.\n\t */\n\tchunkStore: ContentAddressedBlobStore\n\t/** Where the fully reassembled, verified blob is written. */\n\tblobStore: ContentAddressedBlobStore\n}\n\n/**\n * Receive a blob out of band, chunk by chunk, resumably and with integrity\n * verification at every step.\n *\n * For each chunk named in the manifest: if the chunk store already holds it (a\n * prior, possibly interrupted transfer), it is skipped; otherwise it is fetched\n * from the provider and verified to hash to the expected chunk hash before being\n * staged. Once every chunk is present, the blob is reassembled, verified against\n * the manifest's blob hash, and written to the blob store (which deduplicates).\n *\n * The transfer is idempotent: running it again after completion fetches nothing\n * and returns the same reference.\n *\n * @param manifest - The manifest of the blob to receive\n * @param provider - The source of chunk bytes\n * @param stores - The chunk staging store and the destination blob store\n * @returns The reference plus how many chunks were fetched versus skipped\n * @throws {BlobIntegrityError} If a fetched chunk or the whole blob fails verification\n * @throws {Error} If the provider cannot supply a required chunk\n */\nexport async function receiveBlob(\n\tmanifest: BlobManifest,\n\tprovider: ChunkProvider,\n\tstores: ReceiveBlobStores,\n): Promise<ReceiveBlobResult> {\n\tlet chunksFetched = 0\n\tlet chunksSkipped = 0\n\n\t// Distinct chunk hashes only: a manifest may repeat a hash, but we need each\n\t// unique chunk exactly once. Skipping duplicates also means a blob made of\n\t// identical chunks transfers that chunk a single time.\n\tconst seen = new Set<string>()\n\tfor (const hash of manifest.chunkHashes) {\n\t\tif (seen.has(hash)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(hash)\n\n\t\tif (await stores.chunkStore.has(hash)) {\n\t\t\tchunksSkipped++\n\t\t\tcontinue\n\t\t}\n\n\t\tconst bytes = await provider.getChunk(hash)\n\t\tif (bytes === null) {\n\t\t\tthrow new Error(`Blob transfer failed: provider could not supply chunk ${hash}`)\n\t\t}\n\t\tconst actual = await hashBlob(bytes)\n\t\tif (actual !== hash) {\n\t\t\tthrow new BlobIntegrityError(hash, actual)\n\t\t}\n\t\tawait stores.chunkStore.put(bytes)\n\t\tchunksFetched++\n\t}\n\n\tconst full = await reassembleBlob(manifest, stores.chunkStore)\n\tconst ref = await stores.blobStore.put(full, {\n\t\tmimeType: manifest.mimeType,\n\t\tfilename: manifest.filename,\n\t})\n\n\treturn { ref, chunksFetched, chunksSkipped }\n}\n\n/**\n * Prepare a blob for out-of-band sending: split it into chunks, stage those\n * chunks in a content-addressed store, and return the manifest plus a\n * {@link ChunkProvider} that serves the chunks from that store.\n *\n * @param bytes - The full blob content\n * @param chunkStore - Where to stage the chunks (served to receivers)\n * @param options - Optional chunk size and metadata\n * @returns The manifest and a provider that serves the staged chunks\n */\nexport async function prepareBlobForSend(\n\tbytes: Uint8Array,\n\tchunkStore: ContentAddressedBlobStore,\n\toptions: { chunkSize?: number; mimeType?: string; filename?: string } = {},\n): Promise<{ manifest: BlobManifest; provider: ChunkProvider }> {\n\tconst { manifest, chunks } = await chunkBlob(bytes, options.chunkSize, {\n\t\tmimeType: options.mimeType,\n\t\tfilename: options.filename,\n\t})\n\tfor (const chunk of chunks.values()) {\n\t\tawait chunkStore.put(chunk)\n\t}\n\tconst provider: ChunkProvider = {\n\t\tgetChunk: (hash) => chunkStore.get(hash),\n\t}\n\treturn { manifest, provider }\n}\n","import { type BlobRef, type BlobRefMetadata, hashBlob } from '@korajs/core'\nimport { type BlobManifest, chunkBlob } from './blob-chunking'\nimport type { ChunkProvider } from './blob-transfer'\nimport { BlobIntegrityError, type ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * Serialize a {@link BlobManifest} to canonical bytes for content addressing.\n *\n * Fields are emitted in a fixed order so the same manifest always produces the\n * same bytes, which is what lets the manifest be stored and fetched under its own\n * SHA-256 hash. Optional fields are omitted when absent.\n */\nexport function serializeBlobManifest(manifest: BlobManifest): Uint8Array {\n\tconst canonical: Record<string, unknown> = {\n\t\tblobHash: manifest.blobHash,\n\t\tsize: manifest.size,\n\t\tchunkSize: manifest.chunkSize,\n\t\tchunkHashes: manifest.chunkHashes,\n\t}\n\tif (manifest.mimeType !== undefined) {\n\t\tcanonical.mimeType = manifest.mimeType\n\t}\n\tif (manifest.filename !== undefined) {\n\t\tcanonical.filename = manifest.filename\n\t}\n\treturn new TextEncoder().encode(JSON.stringify(canonical))\n}\n\n/**\n * Parse canonical manifest bytes back into a {@link BlobManifest}, validating the\n * shape. Throws on malformed input rather than returning a partial manifest.\n */\nexport function parseBlobManifest(bytes: Uint8Array): BlobManifest {\n\tconst parsed: unknown = JSON.parse(new TextDecoder().decode(bytes))\n\tif (typeof parsed !== 'object' || parsed === null) {\n\t\tthrow new Error('Invalid blob manifest: not an object')\n\t}\n\tconst obj = parsed as Record<string, unknown>\n\tif (typeof obj.blobHash !== 'string') {\n\t\tthrow new Error('Invalid blob manifest: missing blobHash')\n\t}\n\tif (typeof obj.size !== 'number' || typeof obj.chunkSize !== 'number') {\n\t\tthrow new Error('Invalid blob manifest: missing size or chunkSize')\n\t}\n\tif (!Array.isArray(obj.chunkHashes) || obj.chunkHashes.some((h) => typeof h !== 'string')) {\n\t\tthrow new Error('Invalid blob manifest: chunkHashes must be an array of strings')\n\t}\n\tconst manifest: BlobManifest = {\n\t\tblobHash: obj.blobHash,\n\t\tsize: obj.size,\n\t\tchunkSize: obj.chunkSize,\n\t\tchunkHashes: obj.chunkHashes as string[],\n\t}\n\tif (typeof obj.mimeType === 'string') {\n\t\tmanifest.mimeType = obj.mimeType\n\t}\n\tif (typeof obj.filename === 'string') {\n\t\tmanifest.filename = obj.filename\n\t}\n\treturn manifest\n}\n\n/**\n * Store a blob for out-of-band transfer, addressed entirely by content.\n *\n * Stages the blob's chunks (so this device can serve them), stores the full blob\n * (so local reads by hash are O(1)), and stores the blob's manifest as its own\n * content-addressed object. The returned {@link BlobRef} carries `manifestHash`,\n * so a peer that receives the reference in a synced record can pull the bytes\n * knowing only the reference — no separate manifest hand-off.\n *\n * @param store - The content-addressed store to stage chunks, blob, and manifest in\n * @param bytes - The full blob content\n * @param options - Optional chunk size and metadata\n * @returns The reference (including `manifestHash`) and the manifest\n */\nexport async function putBlobForTransfer(\n\tstore: ContentAddressedBlobStore,\n\tbytes: Uint8Array,\n\toptions: { chunkSize?: number } & BlobRefMetadata = {},\n): Promise<{ ref: BlobRef; manifest: BlobManifest }> {\n\tconst { manifest, chunks } = await chunkBlob(bytes, options.chunkSize, {\n\t\t...(options.mimeType !== undefined ? { mimeType: options.mimeType } : {}),\n\t\t...(options.filename !== undefined ? { filename: options.filename } : {}),\n\t})\n\tfor (const chunk of chunks.values()) {\n\t\tawait store.put(chunk)\n\t}\n\t// Full blob for local O(1) reads by content hash.\n\tconst baseRef = await store.put(bytes, {\n\t\t...(options.mimeType !== undefined ? { mimeType: options.mimeType } : {}),\n\t\t...(options.filename !== undefined ? { filename: options.filename } : {}),\n\t})\n\t// Manifest as its own content-addressed object, served over the same channel.\n\tconst manifestRef = await store.put(serializeBlobManifest(manifest))\n\treturn { ref: { ...baseRef, manifestHash: manifestRef.hash }, manifest }\n}\n\n/**\n * Fetch and integrity-verify a blob's manifest from a {@link ChunkProvider}.\n *\n * The manifest is a content-addressed object like a chunk, so it is requested by\n * its hash, verified to hash to that value, and parsed. Used to resolve a\n * {@link BlobRef}'s manifest before pulling the blob's chunks.\n *\n * @param provider - The source to fetch the manifest bytes from\n * @param manifestHash - The manifest's content hash (from `BlobRef.manifestHash`)\n * @throws {BlobIntegrityError} If the fetched bytes do not hash to `manifestHash`\n * @throws {Error} If the provider cannot supply the manifest\n */\nexport async function fetchBlobManifest(\n\tprovider: ChunkProvider,\n\tmanifestHash: string,\n): Promise<BlobManifest> {\n\tconst bytes = await provider.getChunk(manifestHash)\n\tif (bytes === null) {\n\t\tthrow new Error(`Blob manifest ${manifestHash} could not be fetched from the provider`)\n\t}\n\tconst actual = await hashBlob(bytes)\n\tif (actual !== manifestHash) {\n\t\tthrow new BlobIntegrityError(manifestHash, actual)\n\t}\n\treturn parseBlobManifest(bytes)\n}\n\n/**\n * Resolve the manifest for a {@link BlobRef} that was stored via\n * {@link putBlobForTransfer}. Fetches and verifies the manifest by the ref's\n * `manifestHash`.\n *\n * @throws {Error} If the ref has no `manifestHash` (it was not stored for transfer)\n */\nexport async function resolveBlobManifest(\n\tprovider: ChunkProvider,\n\tref: BlobRef,\n): Promise<BlobManifest> {\n\tif (ref.manifestHash === undefined) {\n\t\tthrow new Error(\n\t\t\t`Blob ${ref.hash} has no manifest to resolve. Store it with putBlobForTransfer (or app.blobs.put) so its reference carries a manifestHash, or pull with an explicit manifest.`,\n\t\t)\n\t}\n\treturn fetchBlobManifest(provider, ref.manifestHash)\n}\n","import { hashBlob } from '@korajs/core'\nimport { type ContentAddressedBlobStore, MemoryBlobStore } from './content-addressed-blob-store'\n\n/**\n * The server-side blob callbacks a `KoraSyncServer` accepts: read a chunk by\n * hash (to serve it) and persist an uploaded chunk by hash (to store it).\n */\nexport interface ServerBlobCallbacks {\n\tresolveBlobChunk: (hash: string) => Promise<Uint8Array | null>\n\tpersistBlobChunk: (hash: string, bytes: Uint8Array) => Promise<void>\n}\n\n/**\n * Adapt a {@link ContentAddressedBlobStore} into the read/persist callbacks a\n * `KoraSyncServer` needs for central blob storage. The server package depends\n * only on these plain function signatures, so a self-hosted server can back its\n * blob storage with any store (for example a `FilesystemBlobStore`) without the\n * server package taking a dependency on `@korajs/store`.\n *\n * @example\n * ```typescript\n * const server = new KoraSyncServer({\n * store,\n * ...toServerBlobCallbacks(new FilesystemBlobStore('/var/kora/blobs')),\n * })\n * ```\n */\nexport function toServerBlobCallbacks(store: ContentAddressedBlobStore): ServerBlobCallbacks {\n\treturn {\n\t\tresolveBlobChunk: (hash) => store.get(hash),\n\t\tasync persistBlobChunk(hash, bytes) {\n\t\t\t// The store keys by the hash it computes from the bytes; verify it matches\n\t\t\t// the declared hash so a mismatched upload is rejected, not silently stored\n\t\t\t// under the wrong key.\n\t\t\tconst actual = await hashBlob(bytes)\n\t\t\tif (actual !== hash) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait store.put(bytes)\n\t\t},\n\t}\n}\n\n/**\n * Convenience: an in-memory central blob store plus its server callbacks. For\n * tests and single-process deployments. Persistent deployments should back\n * {@link toServerBlobCallbacks} with a durable store instead.\n */\nexport function createMemoryServerBlobStore(): {\n\tstore: MemoryBlobStore\n\tcallbacks: ServerBlobCallbacks\n} {\n\tconst store = new MemoryBlobStore()\n\treturn { store, callbacks: toServerBlobCallbacks(store) }\n}\n","import { type BlobRef, isBlobRef } from '@korajs/core'\nimport { parseBlobManifest } from './blob-manifest-transfer'\nimport type { ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/** Outcome of a blob garbage-collection sweep. */\nexport interface BlobGcResult {\n\t/** Total distinct blobs held before the sweep. */\n\tscanned: number\n\t/** Distinct hashes kept because a live reference points to them (blob, manifest, or chunk). */\n\tlive: number\n\t/** Number of blobs deleted (or, with `dryRun`, that would be deleted). */\n\tcollected: number\n\t/** The hashes deleted (or, with `dryRun`, that would be deleted). */\n\tcollectedHashes: string[]\n}\n\n/** Options for {@link collectBlobGarbage}. */\nexport interface BlobGcOptions {\n\t/** Compute what would be collected without deleting anything. */\n\tdryRun?: boolean\n}\n\n/**\n * Extract the {@link BlobRef}s referenced by a materialized record. Scans the\n * record's top-level field values, so it works without the schema; a `blob`\n * field simply holds a `BlobRef`.\n */\nexport function extractBlobRefs(record: Record<string, unknown>): BlobRef[] {\n\tconst refs: BlobRef[] = []\n\tfor (const value of Object.values(record)) {\n\t\tif (isBlobRef(value)) {\n\t\t\trefs.push(value)\n\t\t}\n\t}\n\treturn refs\n}\n\n/**\n * Garbage-collect a content-addressed blob store by mark-and-sweep: keep every\n * blob reachable from a live reference, delete the rest.\n *\n * The live set is closed over the reference graph — for each live {@link BlobRef}\n * it retains the blob hash, the manifest hash, and every chunk hash named in that\n * manifest. Because chunks (and blobs) are shared by content address, a chunk\n * referenced by any surviving blob is retained even if another blob that used it\n * was collected. This makes GC safe under deduplication.\n *\n * Mark-and-sweep (rather than reference counting) is deliberate: counts are\n * fragile under concurrent edits and CRDT merges, whereas a sweep against the\n * current live set is always correct for the state it observes. Run it\n * periodically or on demand.\n *\n * A manifest that cannot be read or parsed (corruption) contributes no chunk\n * hashes; its own hash still counts as live. The blob it describes is already\n * unusable, so its chunks becoming collectable is acceptable, and GC never\n * throws on a single bad manifest.\n *\n * @param store - The blob store to sweep\n * @param liveRefs - Every reference still reachable from live records\n * @param options - `dryRun` to report without deleting\n */\nexport async function collectBlobGarbage(\n\tstore: ContentAddressedBlobStore,\n\tliveRefs: Iterable<BlobRef>,\n\toptions: BlobGcOptions = {},\n): Promise<BlobGcResult> {\n\tconst live = new Set<string>()\n\tfor (const ref of liveRefs) {\n\t\tlive.add(ref.hash)\n\t\tif (ref.manifestHash === undefined) {\n\t\t\tcontinue\n\t\t}\n\t\tlive.add(ref.manifestHash)\n\t\ttry {\n\t\t\tconst manifestBytes = await store.get(ref.manifestHash)\n\t\t\tif (manifestBytes !== null) {\n\t\t\t\tconst manifest = parseBlobManifest(manifestBytes)\n\t\t\t\tfor (const chunkHash of manifest.chunkHashes) {\n\t\t\t\t\tlive.add(chunkHash)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// A corrupt/unreadable manifest contributes no chunk hashes; the blob is\n\t\t\t// already broken. Never abort the whole sweep for one bad manifest.\n\t\t}\n\t}\n\n\tconst all = await store.list()\n\tconst collectedHashes: string[] = []\n\tfor (const hash of all) {\n\t\tif (live.has(hash)) {\n\t\t\tcontinue\n\t\t}\n\t\tcollectedHashes.push(hash)\n\t\tif (!options.dryRun) {\n\t\t\tawait store.delete(hash)\n\t\t}\n\t}\n\n\treturn {\n\t\tscanned: all.length,\n\t\tlive: live.size,\n\t\tcollected: collectedHashes.length,\n\t\tcollectedHashes,\n\t}\n}\n","import { generateUUIDv7 } from '@korajs/core'\nimport type { ChunkProvider } from './blob-transfer'\nimport type { ContentAddressedBlobStore } from './content-addressed-blob-store'\n\n/**\n * Blob chunk exchange messages. These ride any message transport (the sync\n * WebSocket in production, an in-memory pair in tests). A receiver requests a\n * chunk by hash and correlates the answer by `requestId`.\n */\nexport interface ChunkRequestMessage {\n\ttype: 'blob-chunk-request'\n\trequestId: string\n\thash: string\n}\nexport interface ChunkResponseMessage {\n\ttype: 'blob-chunk-response'\n\trequestId: string\n\t/** The chunk bytes, or null when the responder does not hold that hash. */\n\tbytes: Uint8Array | null\n\t/**\n\t * The server refused the request for rate, not because the chunk is missing\n\t * (RT-24). The requester retries after `retryAfterMs` instead of failing.\n\t */\n\tthrottled?: boolean\n\t/** With `throttled`: how long to wait before retrying, in ms. */\n\tretryAfterMs?: number\n}\nexport type ChunkMessage = ChunkRequestMessage | ChunkResponseMessage\n\n/**\n * A bidirectional message port carrying {@link ChunkMessage}s. Implemented over\n * the sync connection in production; `createChunkPortPair` provides an in-memory\n * duplex pair for tests.\n */\nexport interface ChunkMessagePort {\n\tsend(message: ChunkMessage): void\n\t/** Register a handler for incoming messages. Multiple handlers are allowed. */\n\tonMessage(handler: (message: ChunkMessage) => void): void\n}\n\n/** A {@link ChunkProvider} that fetches chunks over a message port. */\nexport interface RemoteChunkProvider extends ChunkProvider {\n\t/** Number of requests still awaiting a response (for diagnostics/tests). */\n\tpendingCount(): number\n}\n\n/** Options for {@link createRemoteChunkProvider}. */\nexport interface RemoteChunkProviderOptions {\n\t/** Per-attempt timeout in ms (default 30s). */\n\ttimeoutMs?: number\n\t/**\n\t * Longest total time one chunk may spend waiting on \"throttled\" answers before\n\t * the request fails (default 10 minutes). The transfer is resumable, so a failed\n\t * request can simply be retried later.\n\t */\n\tmaxThrottleWaitMs?: number\n\t/** Smallest back-off after a throttled answer, in ms (default 250). */\n\tminThrottleDelayMs?: number\n\t/** Largest single back-off after a throttled answer, in ms (default 30s). */\n\tmaxThrottleDelayMs?: number\n}\n\n/**\n * Create a {@link ChunkProvider} that requests chunks over a message port,\n * correlating each answer to its request and timing out a stalled request so a\n * dropped response cannot hang a transfer forever (the transfer is resumable, so\n * a timed-out request can simply be retried).\n *\n * A \"throttled\" answer (the server's blob request budget is spent, RT-24) is not a\n * failure: the request is re-sent after the server's `retryAfterMs` (bounded, with\n * exponential back-off when absent), until `maxThrottleWaitMs` has elapsed.\n *\n * @param port - The message port to the peer that holds the blob\n * @param options - Timeouts and throttle back-off bounds\n */\nexport function createRemoteChunkProvider(\n\tport: ChunkMessagePort,\n\toptions: RemoteChunkProviderOptions = {},\n): RemoteChunkProvider {\n\tconst timeoutMs = options.timeoutMs ?? 30_000\n\tconst maxThrottleWaitMs = options.maxThrottleWaitMs ?? 10 * 60_000\n\tconst minDelayMs = options.minThrottleDelayMs ?? 250\n\tconst maxDelayMs = options.maxThrottleDelayMs ?? 30_000\n\tconst pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\thash: string\n\t\t\tresolve: (bytes: Uint8Array | null) => void\n\t\t\treject: (error: Error) => void\n\t\t\ttimer: ReturnType<typeof setTimeout>\n\t\t\tstartedAtMs: number\n\t\t\tthrottledCount: number\n\t\t}\n\t>()\n\n\tconst armTimeout = (requestId: string, hash: string): ReturnType<typeof setTimeout> =>\n\t\tsetTimeout(() => {\n\t\t\tconst entry = pending.get(requestId)\n\t\t\tif (!entry) return\n\t\t\tpending.delete(requestId)\n\t\t\tentry.reject(new Error(`Blob chunk request for ${hash} timed out after ${timeoutMs}ms`))\n\t\t}, timeoutMs)\n\n\tport.onMessage((message) => {\n\t\tif (message.type !== 'blob-chunk-response') {\n\t\t\treturn\n\t\t}\n\t\tconst entry = pending.get(message.requestId)\n\t\tif (!entry) {\n\t\t\treturn\n\t\t}\n\t\tclearTimeout(entry.timer)\n\t\tif (message.throttled === true) {\n\t\t\t// Over the server's blob budget: back off and ask again, same request id.\n\t\t\tentry.throttledCount += 1\n\t\t\tconst backoff = Math.min(maxDelayMs, minDelayMs * 2 ** (entry.throttledCount - 1))\n\t\t\tconst delay = Math.min(maxDelayMs, Math.max(minDelayMs, message.retryAfterMs ?? backoff))\n\t\t\tif (Date.now() + delay - entry.startedAtMs > maxThrottleWaitMs) {\n\t\t\t\tpending.delete(message.requestId)\n\t\t\t\tentry.reject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Blob chunk request for ${entry.hash} was throttled for longer than ${maxThrottleWaitMs}ms`,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tentry.timer = setTimeout(() => {\n\t\t\t\tif (pending.get(message.requestId) !== entry) return\n\t\t\t\tentry.timer = armTimeout(message.requestId, entry.hash)\n\t\t\t\tport.send({ type: 'blob-chunk-request', requestId: message.requestId, hash: entry.hash })\n\t\t\t}, delay)\n\t\t\treturn\n\t\t}\n\t\tpending.delete(message.requestId)\n\t\tentry.resolve(message.bytes)\n\t})\n\n\treturn {\n\t\tpendingCount: () => pending.size,\n\t\tgetChunk(hash: string): Promise<Uint8Array | null> {\n\t\t\tconst requestId = generateUUIDv7()\n\t\t\treturn new Promise<Uint8Array | null>((resolve, reject) => {\n\t\t\t\tpending.set(requestId, {\n\t\t\t\t\thash,\n\t\t\t\t\tresolve,\n\t\t\t\t\treject,\n\t\t\t\t\ttimer: armTimeout(requestId, hash),\n\t\t\t\t\tstartedAtMs: Date.now(),\n\t\t\t\t\tthrottledCount: 0,\n\t\t\t\t})\n\t\t\t\tport.send({ type: 'blob-chunk-request', requestId, hash })\n\t\t\t})\n\t\t},\n\t}\n}\n\n/**\n * Serve blob chunk requests arriving on a message port from a blob store. Answers\n * each `blob-chunk-request` with the bytes for that hash, or null when the store\n * does not hold it. Returns nothing; attach it once per connection.\n *\n * @param port - The message port from the peer requesting chunks\n * @param blobStore - The store to serve chunks from (keyed by chunk hash)\n */\nexport function serveBlobChunks(\n\tport: ChunkMessagePort,\n\tblobStore: ContentAddressedBlobStore,\n): void {\n\tport.onMessage((message) => {\n\t\tif (message.type !== 'blob-chunk-request') {\n\t\t\treturn\n\t\t}\n\t\tvoid blobStore.get(message.hash).then(\n\t\t\t(bytes) => {\n\t\t\t\tport.send({ type: 'blob-chunk-response', requestId: message.requestId, bytes })\n\t\t\t},\n\t\t\t() => {\n\t\t\t\t// Integrity failure or read error: report as not-held rather than\n\t\t\t\t// crashing the connection. The requester treats null as unavailable.\n\t\t\t\tport.send({ type: 'blob-chunk-response', requestId: message.requestId, bytes: null })\n\t\t\t},\n\t\t)\n\t})\n}\n\n/**\n * Create a connected in-memory pair of {@link ChunkMessagePort}s. Messages sent\n * on one arrive on the other, asynchronously (next microtask) so the pair models\n * a real transport rather than re-entrant synchronous delivery. For tests.\n */\nexport function createChunkPortPair(): { a: ChunkMessagePort; b: ChunkMessagePort } {\n\tconst handlersA: Array<(m: ChunkMessage) => void> = []\n\tconst handlersB: Array<(m: ChunkMessage) => void> = []\n\n\tconst a: ChunkMessagePort = {\n\t\tsend(message) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tfor (const handler of handlersB) {\n\t\t\t\t\thandler(message)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tonMessage(handler) {\n\t\t\thandlersA.push(handler)\n\t\t},\n\t}\n\tconst b: ChunkMessagePort = {\n\t\tsend(message) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tfor (const handler of handlersA) {\n\t\t\t\t\thandler(message)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\tonMessage(handler) {\n\t\t\thandlersB.push(handler)\n\t\t},\n\t}\n\treturn { a, b }\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","import_core","import_core","import_core","import_core","import_core","import_core","Y","import_core","bytesReplacer","Store","import_core","import_core","import_core","rowVersion","import_core","import_core","import_core","import_core","import_core","import_core","canonical","import_core","import_core","import_core","import_core","propName","import_core","import_core","import_internal","import_core","import_core","import_core","import_core","import_core","import_core","import_internal","import_internal","import_core","import_core","encodeSection","encodeJsonSection","encodeNdjsonSection","parseSections","findSection","computeSha256","import_core","import_core","import_core","rowVersion","readAuditTraces","fresh","BackupFormatError","convertBackupV1","parseBackup","readBackupManifest","restoreMerge","restoreReplace","import_core","Y","TEXT_KEY","import_core","import_core","import_core","import_core","import_core","canonical","import_core","import_core","import_core"]}
|