@agentshouse/mdruntime 0.1.0-alpha.23 → 0.1.0-alpha.24
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/AGENTS.md +34 -18
- package/dist/change.d.ts +4 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js.map +1 -1
- package/dist/client.d.ts +9 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +15 -20
- package/dist/client.js.map +1 -1
- package/dist/connection.d.ts +14 -18
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +390 -291
- package/dist/connection.js.map +1 -1
- package/dist/durability.js +1 -1
- package/dist/durability.js.map +1 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +12 -14
- package/dist/host.js.map +1 -1
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +7 -0
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/outcome.d.ts +17 -20
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +1 -21
- package/dist/outcome.js.map +1 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +1 -1
- package/dist/overlay.js.map +1 -1
- package/dist/replica.d.ts +1 -0
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +54 -0
- package/dist/replica.js.map +1 -1
- package/dist/room-draft.d.ts +124 -0
- package/dist/room-draft.d.ts.map +1 -0
- package/dist/room-draft.js +403 -0
- package/dist/room-draft.js.map +1 -0
- package/dist/save.d.ts +4 -1
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +34 -100
- package/dist/save.js.map +1 -1
- package/dist/status.d.ts +4 -6
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js.map +1 -1
- package/dist/store.d.ts +18 -12
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +43 -34
- package/dist/store.js.map +1 -1
- package/dist/wire.d.ts +3 -3
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +6 -7
- package/dist/wire.js.map +1 -1
- package/package.json +1 -1
package/dist/replica.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import { immutable, type ChangeBatch } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, overlayChanged, sameLayerText, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n replay: readonly ReplayStep[];\n};\n\ntype ReplayStep = {\n id: string;\n before: Layer;\n after: Layer;\n effective: ChangeBatch;\n collection?: Collection;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n const collection = readCollection(\n record.documents,\n compositionOf(record),\n previous === undefined\n ? undefined\n : { text: previous.record.documents, collection: previous.collection },\n );\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n if (\n (record.model.status === 'current' || record.selectionModel.status === 'current') &&\n (previous === undefined ||\n !sameLayerText(record, previous.record) ||\n record.model !== previous.record.model ||\n record.selectionModel !== previous.record.selectionModel)\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record, previous);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n confirmed,\n );\n}\n\nfunction predicted(\n confirmed: ConfirmedLayer,\n batches: readonly ChangeBatch[],\n previous?: Replica,\n): { layer: Layer; replay: readonly ReplayStep[] } {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const replay: ReplayStep[] = [];\n const prior = new Map(previous?.replay.map((step) => [step.id, step]) ?? []);\n for (const batch of batches) {\n const before = layer;\n const old = prior.get(batch.id);\n const hasMove = batch.changes.some((change) => change.kind === 'move');\n const reuseRewrite =\n old?.collection !== undefined &&\n sameLayerText(before, old.before) &&\n old.collection.composition.collectionRoot === composition.collectionRoot &&\n old.collection.composition.model === composition.model &&\n old.collection.composition.selection?.model === composition.selection?.model &&\n JSON.stringify(old.collection.composition.selection?.roots) ===\n JSON.stringify(composition.selection?.roots);\n const collection = hasMove\n ? reuseRewrite\n ? old.collection\n : parseCollection(\n before.documents,\n composition,\n old?.collection === undefined\n ? { text: confirmed.record.documents, collection: confirmed.collection }\n : { text: old.before.documents, collection: old.collection },\n )\n : undefined;\n const effective =\n collection === undefined\n ? batch\n : reuseRewrite\n ? old.effective\n : providerRewritten(batch, { ...before, collection });\n layer =\n old === undefined\n ? overlay(before, [effective])\n : overlayChanged(before, [effective], old.before, [old.effective], old.after);\n replay.push({\n id: batch.id,\n before,\n after: layer,\n effective,\n ...(collection === undefined ? {} : { collection }),\n });\n }\n return { layer, replay };\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n previous?: Replica,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n replay: [],\n };\n }\n const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;\n const layer =\n rewriting === 'provider'\n ? predictedState!.layer\n : previous === undefined\n ? overlay(confirmed.record, batches)\n : overlayChanged(\n confirmed.record,\n batches,\n previous.confirmed.record,\n previous.queue,\n previous.visible,\n );\n return {\n confirmed,\n queue: batches,\n replay: predictedState?.replay ?? [],\n visible: {\n ...layer,\n collection: parseCollection(\n layer.documents,\n compositionOf(confirmed.record),\n previous === undefined\n ? undefined\n : { text: previous.visible.documents, collection: previous.visible.collection },\n ),\n },\n };\n}\n"],"names":["immutable","parseCollection","readCollection","validateCollection","overlay","overlayChanged","sameLayerText","providerRewritten","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","previous","collection","documents","undefined","text","readStaged","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","replay","prior","Map","map","step","id","batch","before","old","get","hasMove","changes","some","change","kind","reuseRewrite","JSON","stringify","effective","after","push","replicaOf","queue","rewriting","Object","freeze","length","visible","predictedState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import { parse, type Document } from '@agentshouse/mdmodel';\nimport { immutable, type ChangeBatch, type Precondition } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, overlayChanged, sameLayerText, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport { equalValue } from './room-draft.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n replay: readonly ReplayStep[];\n};\n\ntype ReplayStep = {\n id: string;\n before: Layer;\n after: Layer;\n effective: ChangeBatch;\n collection?: Collection;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n const collection = readCollection(\n record.documents,\n compositionOf(record),\n previous === undefined\n ? undefined\n : { text: previous.record.documents, collection: previous.collection },\n );\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n if (\n (record.model.status === 'current' || record.selectionModel.status === 'current') &&\n (previous === undefined ||\n !sameLayerText(record, previous.record) ||\n record.model !== previous.record.model ||\n record.selectionModel !== previous.record.selectionModel)\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record, previous);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n confirmed,\n );\n}\n\nfunction predicted(\n confirmed: ConfirmedLayer,\n batches: readonly ChangeBatch[],\n previous?: Replica,\n): { layer: Layer; replay: readonly ReplayStep[] } {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const replay: ReplayStep[] = [];\n const prior = new Map(previous?.replay.map((step) => [step.id, step]) ?? []);\n for (const batch of batches) {\n const before = layer;\n const old = prior.get(batch.id);\n const hasMove = batch.changes.some((change) => change.kind === 'move');\n const reuseRewrite =\n old?.collection !== undefined &&\n sameLayerText(before, old.before) &&\n old.collection.composition.collectionRoot === composition.collectionRoot &&\n old.collection.composition.model === composition.model &&\n old.collection.composition.selection?.model === composition.selection?.model &&\n JSON.stringify(old.collection.composition.selection?.roots) ===\n JSON.stringify(composition.selection?.roots);\n const collection = hasMove\n ? reuseRewrite\n ? old.collection\n : parseCollection(\n before.documents,\n composition,\n old?.collection === undefined\n ? { text: confirmed.record.documents, collection: confirmed.collection }\n : { text: old.before.documents, collection: old.collection },\n )\n : undefined;\n const effective =\n collection === undefined\n ? batch\n : reuseRewrite\n ? old.effective\n : providerRewritten(batch, { ...before, collection });\n layer =\n old === undefined\n ? overlay(before, [effective])\n : overlayChanged(before, [effective], old.before, [old.effective], old.after);\n replay.push({\n id: batch.id,\n before,\n after: layer,\n effective,\n ...(collection === undefined ? {} : { collection }),\n });\n }\n return { layer, replay };\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n previous?: Replica,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n replay: [],\n };\n }\n const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;\n const layer =\n rewriting === 'provider'\n ? predictedState!.layer\n : previous === undefined\n ? overlay(confirmed.record, batches)\n : overlayChanged(\n confirmed.record,\n batches,\n previous.confirmed.record,\n previous.queue,\n previous.visible,\n );\n return {\n confirmed,\n queue: batches,\n replay: predictedState?.replay ?? [],\n visible: {\n ...layer,\n collection: parseCollection(\n layer.documents,\n compositionOf(confirmed.record),\n previous === undefined\n ? undefined\n : { text: previous.visible.documents, collection: previous.visible.collection },\n ),\n },\n };\n}\n\nfunction present(layer: Layer, path: string): boolean {\n return layer.documents[path] !== undefined || layer.binaryTargets.includes(path);\n}\n\nfunction holds(layer: Layer, preconditions: readonly Precondition[]): boolean {\n const parsed = new Map<string, Document | null>();\n const documentAt = (path: string) => {\n if (!parsed.has(path)) {\n const text = layer.documents[path];\n const opened = text === undefined ? null : parse(text, path);\n parsed.set(path, opened?.ok === true ? opened.document : null);\n }\n return parsed.get(path) ?? null;\n };\n return preconditions.every((precondition) => {\n const path = precondition.path;\n if (precondition.kind === 'absent') return !present(layer, path);\n if (precondition.kind === 'present') return present(layer, path);\n if (precondition.kind === 'revision') {\n return present(layer, path) && layer.revisions[path] === precondition.revision;\n }\n const document = documentAt(path);\n if (document === null) return false;\n if (precondition.kind === 'field') {\n const value = Object.hasOwn(document.fields, precondition.name)\n ? document.fields[precondition.name]\n : undefined;\n return equalValue(value, precondition.value);\n }\n if (precondition.kind === 'section') {\n return (\n Object.hasOwn(document.sections, precondition.name) &&\n document.sections[precondition.name] === precondition.value\n );\n }\n return document.preamble === precondition.value;\n });\n}\n\nexport function withdrawals(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n withdrawable: (batch: ChangeBatch) => boolean,\n rewriting: Rewriting,\n): readonly ChangeBatch[] {\n if (!queue.some(withdrawable)) return [];\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const withdrawn: ChangeBatch[] = [];\n for (const batch of queue) {\n if (withdrawable(batch) && !holds(layer, batch.preconditions)) {\n withdrawn.push(batch);\n continue;\n }\n const effective =\n rewriting === 'provider' && batch.changes.some((change) => change.kind === 'move')\n ? providerRewritten(batch, {\n ...layer,\n collection: parseCollection(layer.documents, composition),\n })\n : batch;\n layer = overlay(layer, [effective]);\n }\n return withdrawn;\n}\n"],"names":["parse","immutable","parseCollection","readCollection","validateCollection","overlay","overlayChanged","sameLayerText","providerRewritten","equalValue","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","previous","collection","documents","undefined","text","readStaged","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","replay","prior","Map","map","step","id","batch","before","old","get","hasMove","changes","some","change","kind","reuseRewrite","JSON","stringify","effective","after","push","replicaOf","queue","rewriting","Object","freeze","length","visible","predictedState","present","includes","holds","preconditions","parsed","documentAt","has","opened","set","ok","document","every","precondition","revision","value","hasOwn","fields","name","sections","preamble","withdrawals","withdrawable","withdrawn"],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ProviderRefusal } from './adapter.js';
|
|
2
|
+
import type { Change, Precondition } from './change.js';
|
|
3
|
+
import type { VisibleLayer } from './replica.js';
|
|
4
|
+
export type FieldValue = {
|
|
5
|
+
readonly value: unknown;
|
|
6
|
+
} | null;
|
|
7
|
+
export type RoomDraftCreation = {
|
|
8
|
+
readonly type: string;
|
|
9
|
+
readonly fields: Readonly<Record<string, unknown>>;
|
|
10
|
+
readonly sections: Readonly<Record<string, string>>;
|
|
11
|
+
} | {
|
|
12
|
+
readonly markdown: string;
|
|
13
|
+
};
|
|
14
|
+
export type RoomDraftParts = {
|
|
15
|
+
readonly fields?: Readonly<Record<string, {
|
|
16
|
+
readonly value: unknown;
|
|
17
|
+
readonly base?: FieldValue;
|
|
18
|
+
}>>;
|
|
19
|
+
readonly sections?: Readonly<Record<string, {
|
|
20
|
+
readonly value: string;
|
|
21
|
+
readonly base?: string;
|
|
22
|
+
}>>;
|
|
23
|
+
readonly preamble?: {
|
|
24
|
+
readonly value: string;
|
|
25
|
+
readonly base?: string;
|
|
26
|
+
};
|
|
27
|
+
readonly markdown?: {
|
|
28
|
+
readonly value: string;
|
|
29
|
+
readonly base?: string;
|
|
30
|
+
};
|
|
31
|
+
readonly creation?: RoomDraftCreation;
|
|
32
|
+
readonly move?: {
|
|
33
|
+
readonly to: string;
|
|
34
|
+
readonly base?: string;
|
|
35
|
+
};
|
|
36
|
+
readonly removal?: {
|
|
37
|
+
readonly base?: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
type HeldParts = {
|
|
41
|
+
readonly fields?: Readonly<Record<string, {
|
|
42
|
+
readonly value: unknown;
|
|
43
|
+
readonly base: FieldValue;
|
|
44
|
+
}>>;
|
|
45
|
+
readonly sections?: Readonly<Record<string, {
|
|
46
|
+
readonly value: string;
|
|
47
|
+
readonly base: string;
|
|
48
|
+
}>>;
|
|
49
|
+
readonly preamble?: {
|
|
50
|
+
readonly value: string;
|
|
51
|
+
readonly base: string;
|
|
52
|
+
};
|
|
53
|
+
readonly markdown?: {
|
|
54
|
+
readonly value: string;
|
|
55
|
+
readonly base: string;
|
|
56
|
+
};
|
|
57
|
+
readonly creation?: RoomDraftCreation;
|
|
58
|
+
readonly move?: {
|
|
59
|
+
readonly to: string;
|
|
60
|
+
readonly base: string;
|
|
61
|
+
};
|
|
62
|
+
readonly removal?: {
|
|
63
|
+
readonly base: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
type ChangedUnderneath = {
|
|
67
|
+
readonly fields?: Readonly<Record<string, FieldValue>>;
|
|
68
|
+
readonly sections?: Readonly<Record<string, string | null>>;
|
|
69
|
+
readonly preamble?: string | null;
|
|
70
|
+
readonly markdown?: string | null;
|
|
71
|
+
readonly creation?: string;
|
|
72
|
+
readonly move?: string | null;
|
|
73
|
+
readonly removal?: string | null;
|
|
74
|
+
};
|
|
75
|
+
export type ReturnReason = (ProviderRefusal & {
|
|
76
|
+
readonly kind: 'conflicted' | 'rejected';
|
|
77
|
+
}) | {
|
|
78
|
+
readonly kind: 'expired';
|
|
79
|
+
} | {
|
|
80
|
+
readonly kind: 'withdrawn';
|
|
81
|
+
};
|
|
82
|
+
export type RoomDraft = {
|
|
83
|
+
readonly room: string;
|
|
84
|
+
readonly path: string;
|
|
85
|
+
readonly revision: string;
|
|
86
|
+
readonly parts: HeldParts;
|
|
87
|
+
readonly changedUnderneath: ChangedUnderneath;
|
|
88
|
+
readonly returned: ReturnReason | null;
|
|
89
|
+
};
|
|
90
|
+
export type RoomDraftWrite = {
|
|
91
|
+
readonly outcome: 'written';
|
|
92
|
+
readonly roomDraft: RoomDraft | null;
|
|
93
|
+
} | {
|
|
94
|
+
readonly outcome: 'stale';
|
|
95
|
+
readonly current: RoomDraft | null;
|
|
96
|
+
};
|
|
97
|
+
export type ChangedPart = {
|
|
98
|
+
readonly path: string;
|
|
99
|
+
readonly part: 'field' | 'section' | 'preamble' | 'markdown' | 'creation' | 'move' | 'removal';
|
|
100
|
+
readonly name?: string;
|
|
101
|
+
};
|
|
102
|
+
export type RoomDraftRecord = {
|
|
103
|
+
readonly locator: string;
|
|
104
|
+
readonly path: string;
|
|
105
|
+
readonly revision: string;
|
|
106
|
+
readonly parts: HeldParts;
|
|
107
|
+
readonly returned: ReturnReason | null;
|
|
108
|
+
};
|
|
109
|
+
export type SavedDraft = {
|
|
110
|
+
readonly path: string;
|
|
111
|
+
readonly parts: HeldParts;
|
|
112
|
+
};
|
|
113
|
+
export declare function readParts(value: unknown): RoomDraftParts;
|
|
114
|
+
export declare function held(current: HeldParts | undefined, parts: RoomDraftParts): HeldParts;
|
|
115
|
+
export declare function equalValue(left: unknown, right: unknown): boolean;
|
|
116
|
+
export declare function underneath(parts: HeldParts, path: string, visible: VisibleLayer | undefined): ChangedUnderneath;
|
|
117
|
+
export declare function changedParts(path: string, report: ChangedUnderneath): readonly ChangedPart[];
|
|
118
|
+
export declare function returnedInto(existing: HeldParts | undefined, returned: HeldParts): HeldParts;
|
|
119
|
+
export declare function changesOf(path: string, parts: HeldParts): {
|
|
120
|
+
changes: readonly Change[];
|
|
121
|
+
bases: readonly Precondition[];
|
|
122
|
+
};
|
|
123
|
+
export {};
|
|
124
|
+
//# sourceMappingURL=room-draft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room-draft.d.ts","sourceRoot":"","sources":["../src/room-draft.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { apply, parse, serialize } from '@agentshouse/mdmodel';
|
|
2
|
+
import { normalize } from './paths.js';
|
|
3
|
+
function malformed() {
|
|
4
|
+
throw new Error('room-draft-malformed');
|
|
5
|
+
}
|
|
6
|
+
function plain(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function frontmatterValue(value) {
|
|
10
|
+
if (Array.isArray(value)) return value.every(frontmatterValue);
|
|
11
|
+
return value === null || typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' && Number.isFinite(value);
|
|
12
|
+
}
|
|
13
|
+
function text(value) {
|
|
14
|
+
return typeof value === 'string' ? value : malformed();
|
|
15
|
+
}
|
|
16
|
+
function optionalText(value) {
|
|
17
|
+
return value === undefined ? undefined : text(value);
|
|
18
|
+
}
|
|
19
|
+
function entries(value, each) {
|
|
20
|
+
if (!plain(value)) malformed();
|
|
21
|
+
const read = {};
|
|
22
|
+
for (const [name, item] of Object.entries(value))read[name] = each(item);
|
|
23
|
+
return read;
|
|
24
|
+
}
|
|
25
|
+
function fieldValue(value) {
|
|
26
|
+
if (value === null) return null;
|
|
27
|
+
if (!plain(value) || !Object.hasOwn(value, 'value') || !frontmatterValue(value.value)) {
|
|
28
|
+
malformed();
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
value: value.value
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function textPart(value) {
|
|
35
|
+
if (!plain(value)) malformed();
|
|
36
|
+
const base = optionalText(value.base);
|
|
37
|
+
return {
|
|
38
|
+
value: text(value.value),
|
|
39
|
+
...base === undefined ? {} : {
|
|
40
|
+
base
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function creationOf(value) {
|
|
45
|
+
if (!plain(value)) malformed();
|
|
46
|
+
if (Object.hasOwn(value, 'markdown')) return {
|
|
47
|
+
markdown: text(value.markdown)
|
|
48
|
+
};
|
|
49
|
+
const fields = entries(value.fields, (item)=>frontmatterValue(item) ? item : malformed());
|
|
50
|
+
return {
|
|
51
|
+
type: text(value.type),
|
|
52
|
+
fields,
|
|
53
|
+
sections: entries(value.sections, text)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const PART_NAMES = new Set([
|
|
57
|
+
'fields',
|
|
58
|
+
'sections',
|
|
59
|
+
'preamble',
|
|
60
|
+
'markdown',
|
|
61
|
+
'creation',
|
|
62
|
+
'move',
|
|
63
|
+
'removal'
|
|
64
|
+
]);
|
|
65
|
+
export function readParts(value) {
|
|
66
|
+
if (!plain(value) || Object.keys(value).some((name)=>!PART_NAMES.has(name))) malformed();
|
|
67
|
+
const parts = {};
|
|
68
|
+
if (value.fields !== undefined) {
|
|
69
|
+
parts.fields = entries(value.fields, (item)=>{
|
|
70
|
+
if (!plain(item) || !Object.hasOwn(item, 'value') || !frontmatterValue(item.value)) {
|
|
71
|
+
malformed();
|
|
72
|
+
}
|
|
73
|
+
return item.base === undefined ? {
|
|
74
|
+
value: item.value
|
|
75
|
+
} : {
|
|
76
|
+
value: item.value,
|
|
77
|
+
base: fieldValue(item.base)
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (value.sections !== undefined) parts.sections = entries(value.sections, textPart);
|
|
82
|
+
if (value.preamble !== undefined) parts.preamble = textPart(value.preamble);
|
|
83
|
+
if (value.markdown !== undefined) parts.markdown = textPart(value.markdown);
|
|
84
|
+
if (value.creation !== undefined) parts.creation = creationOf(value.creation);
|
|
85
|
+
if (value.move !== undefined) {
|
|
86
|
+
if (!plain(value.move)) malformed();
|
|
87
|
+
const base = optionalText(value.move.base);
|
|
88
|
+
parts.move = {
|
|
89
|
+
to: text(value.move.to),
|
|
90
|
+
...base === undefined ? {} : {
|
|
91
|
+
base
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (value.removal !== undefined) {
|
|
96
|
+
if (!plain(value.removal)) malformed();
|
|
97
|
+
const base = optionalText(value.removal.base);
|
|
98
|
+
parts.removal = base === undefined ? {} : {
|
|
99
|
+
base
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return parts;
|
|
103
|
+
}
|
|
104
|
+
function named(record) {
|
|
105
|
+
return Object.entries(record ?? {});
|
|
106
|
+
}
|
|
107
|
+
function own(record, name) {
|
|
108
|
+
return record !== undefined && Object.hasOwn(record, name) ? record[name] : undefined;
|
|
109
|
+
}
|
|
110
|
+
function kept(prior, base) {
|
|
111
|
+
if (prior !== undefined) return prior.base;
|
|
112
|
+
if (base === undefined) throw new Error('room-draft-base-missing');
|
|
113
|
+
return base;
|
|
114
|
+
}
|
|
115
|
+
function editsText(parts) {
|
|
116
|
+
return parts.preamble !== undefined || named(parts.fields).length > 0 || named(parts.sections).length > 0;
|
|
117
|
+
}
|
|
118
|
+
export function held(current, parts) {
|
|
119
|
+
if (parts.markdown !== undefined && editsText(parts)) {
|
|
120
|
+
throw new Error('room-draft-markdown-exclusive');
|
|
121
|
+
}
|
|
122
|
+
const next = {};
|
|
123
|
+
const fields = named(parts.fields);
|
|
124
|
+
if (fields.length > 0) {
|
|
125
|
+
next.fields = Object.fromEntries(fields.map(([name, part])=>[
|
|
126
|
+
name,
|
|
127
|
+
{
|
|
128
|
+
value: part.value,
|
|
129
|
+
base: kept(own(current?.fields, name), part.base)
|
|
130
|
+
}
|
|
131
|
+
]));
|
|
132
|
+
}
|
|
133
|
+
const sections = named(parts.sections);
|
|
134
|
+
if (sections.length > 0) {
|
|
135
|
+
next.sections = Object.fromEntries(sections.map(([name, part])=>[
|
|
136
|
+
name,
|
|
137
|
+
{
|
|
138
|
+
value: part.value,
|
|
139
|
+
base: kept(own(current?.sections, name), part.base)
|
|
140
|
+
}
|
|
141
|
+
]));
|
|
142
|
+
}
|
|
143
|
+
if (parts.preamble !== undefined) {
|
|
144
|
+
next.preamble = {
|
|
145
|
+
value: parts.preamble.value,
|
|
146
|
+
base: kept(current?.preamble, parts.preamble.base)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (parts.markdown !== undefined) {
|
|
150
|
+
next.markdown = {
|
|
151
|
+
value: parts.markdown.value,
|
|
152
|
+
base: kept(current?.markdown, parts.markdown.base)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (parts.creation !== undefined) next.creation = parts.creation;
|
|
156
|
+
if (parts.move !== undefined) {
|
|
157
|
+
next.move = {
|
|
158
|
+
to: parts.move.to,
|
|
159
|
+
base: kept(current?.move, parts.move.base)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (parts.removal !== undefined) {
|
|
163
|
+
next.removal = {
|
|
164
|
+
base: kept(current?.removal, parts.removal.base)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (Object.keys(next).length === 0) throw new Error('room-draft-empty');
|
|
168
|
+
return next;
|
|
169
|
+
}
|
|
170
|
+
export function equalValue(left, right) {
|
|
171
|
+
if (left === right) return true;
|
|
172
|
+
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((item, index)=>equalValue(item, right[index]));
|
|
173
|
+
}
|
|
174
|
+
function sameField(left, right) {
|
|
175
|
+
if (left === null || right === null) return left === right;
|
|
176
|
+
return equalValue(left.value, right.value);
|
|
177
|
+
}
|
|
178
|
+
export function underneath(parts, path, visible) {
|
|
179
|
+
const markdown = visible?.documents[path] ?? null;
|
|
180
|
+
const document = visible?.collection.documents[path];
|
|
181
|
+
const report = {};
|
|
182
|
+
const fields = {};
|
|
183
|
+
for (const [name, part] of named(parts.fields)){
|
|
184
|
+
const current = document !== undefined && Object.hasOwn(document.fields, name) ? {
|
|
185
|
+
value: document.fields[name]
|
|
186
|
+
} : null;
|
|
187
|
+
if (!sameField(part.base, current)) fields[name] = current;
|
|
188
|
+
}
|
|
189
|
+
if (Object.keys(fields).length > 0) report.fields = fields;
|
|
190
|
+
const sections = {};
|
|
191
|
+
for (const [name, part] of named(parts.sections)){
|
|
192
|
+
const current = document !== undefined && Object.hasOwn(document.sections, name) ? document.sections[name] : null;
|
|
193
|
+
if (current !== part.base) sections[name] = current;
|
|
194
|
+
}
|
|
195
|
+
if (Object.keys(sections).length > 0) report.sections = sections;
|
|
196
|
+
const preamble = document?.preamble ?? null;
|
|
197
|
+
if (parts.preamble !== undefined && preamble !== parts.preamble.base) report.preamble = preamble;
|
|
198
|
+
if (parts.markdown !== undefined && markdown !== parts.markdown.base) report.markdown = markdown;
|
|
199
|
+
if (parts.creation !== undefined && markdown !== null) report.creation = markdown;
|
|
200
|
+
if (parts.move !== undefined && markdown !== parts.move.base) report.move = markdown;
|
|
201
|
+
if (parts.removal !== undefined && markdown !== parts.removal.base) report.removal = markdown;
|
|
202
|
+
return report;
|
|
203
|
+
}
|
|
204
|
+
export function changedParts(path, report) {
|
|
205
|
+
return [
|
|
206
|
+
...report.creation === undefined ? [] : [
|
|
207
|
+
{
|
|
208
|
+
path,
|
|
209
|
+
part: 'creation'
|
|
210
|
+
}
|
|
211
|
+
],
|
|
212
|
+
...named(report.fields).map(([name])=>({
|
|
213
|
+
path,
|
|
214
|
+
part: 'field',
|
|
215
|
+
name
|
|
216
|
+
})),
|
|
217
|
+
...named(report.sections).map(([name])=>({
|
|
218
|
+
path,
|
|
219
|
+
part: 'section',
|
|
220
|
+
name
|
|
221
|
+
})),
|
|
222
|
+
...report.preamble === undefined ? [] : [
|
|
223
|
+
{
|
|
224
|
+
path,
|
|
225
|
+
part: 'preamble'
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
...report.markdown === undefined ? [] : [
|
|
229
|
+
{
|
|
230
|
+
path,
|
|
231
|
+
part: 'markdown'
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
...report.move === undefined ? [] : [
|
|
235
|
+
{
|
|
236
|
+
path,
|
|
237
|
+
part: 'move'
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
...report.removal === undefined ? [] : [
|
|
241
|
+
{
|
|
242
|
+
path,
|
|
243
|
+
part: 'removal'
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
];
|
|
247
|
+
}
|
|
248
|
+
function joined(existing, returned) {
|
|
249
|
+
const merged = {
|
|
250
|
+
...existing
|
|
251
|
+
};
|
|
252
|
+
for (const [name, part] of named(returned))if (!Object.hasOwn(merged, name)) merged[name] = part;
|
|
253
|
+
return Object.keys(merged).length === 0 ? undefined : merged;
|
|
254
|
+
}
|
|
255
|
+
function ended(text) {
|
|
256
|
+
return text === '' || text.endsWith('\n') ? text : `${text}\n`;
|
|
257
|
+
}
|
|
258
|
+
function frontmatterOf(fields) {
|
|
259
|
+
const opened = parse('---\n---\n');
|
|
260
|
+
if (!opened.ok) return malformed();
|
|
261
|
+
let document = opened.document;
|
|
262
|
+
for (const [name, part] of fields){
|
|
263
|
+
const next = apply(document, {
|
|
264
|
+
kind: 'field',
|
|
265
|
+
name,
|
|
266
|
+
value: part.value,
|
|
267
|
+
prior: undefined
|
|
268
|
+
});
|
|
269
|
+
if (next.outcome !== 'applied') return malformed();
|
|
270
|
+
document = next.document;
|
|
271
|
+
}
|
|
272
|
+
return serialize(document);
|
|
273
|
+
}
|
|
274
|
+
function concatenated(markdown, parts) {
|
|
275
|
+
const fields = named(parts.fields);
|
|
276
|
+
const pieces = [
|
|
277
|
+
...fields.length === 0 ? [] : [
|
|
278
|
+
frontmatterOf(fields)
|
|
279
|
+
],
|
|
280
|
+
...parts.preamble === undefined ? [] : [
|
|
281
|
+
parts.preamble.value
|
|
282
|
+
],
|
|
283
|
+
...named(parts.sections).map(([name, part])=>`## ${name}\n${part.value}`)
|
|
284
|
+
];
|
|
285
|
+
if (pieces.length === 0) return markdown;
|
|
286
|
+
return `${ended(markdown)}\n${pieces.map(ended).join('')}`;
|
|
287
|
+
}
|
|
288
|
+
export function returnedInto(existing, returned) {
|
|
289
|
+
if (existing === undefined) return returned;
|
|
290
|
+
const next = {
|
|
291
|
+
...existing
|
|
292
|
+
};
|
|
293
|
+
const whole = existing.markdown ?? returned.markdown;
|
|
294
|
+
if (whole === undefined) {
|
|
295
|
+
const fields = joined(existing.fields, returned.fields);
|
|
296
|
+
const sections = joined(existing.sections, returned.sections);
|
|
297
|
+
if (fields !== undefined) next.fields = fields;
|
|
298
|
+
if (sections !== undefined) next.sections = sections;
|
|
299
|
+
const preamble = existing.preamble ?? returned.preamble;
|
|
300
|
+
if (preamble !== undefined) next.preamble = preamble;
|
|
301
|
+
} else {
|
|
302
|
+
delete next.fields;
|
|
303
|
+
delete next.sections;
|
|
304
|
+
delete next.preamble;
|
|
305
|
+
const value = concatenated(whole.value, existing.markdown === undefined ? existing : returned);
|
|
306
|
+
next.markdown = {
|
|
307
|
+
value,
|
|
308
|
+
base: whole.base
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const creation = existing.creation ?? returned.creation;
|
|
312
|
+
const move = existing.move ?? returned.move;
|
|
313
|
+
const removal = existing.removal ?? returned.removal;
|
|
314
|
+
if (creation !== undefined) next.creation = creation;
|
|
315
|
+
if (move !== undefined) next.move = move;
|
|
316
|
+
if (removal !== undefined) next.removal = removal;
|
|
317
|
+
return next;
|
|
318
|
+
}
|
|
319
|
+
export function changesOf(path, parts) {
|
|
320
|
+
const changes = [];
|
|
321
|
+
const bases = [];
|
|
322
|
+
const creation = parts.creation;
|
|
323
|
+
if (creation !== undefined) {
|
|
324
|
+
changes.push('markdown' in creation ? {
|
|
325
|
+
kind: 'create',
|
|
326
|
+
path,
|
|
327
|
+
content: creation.markdown
|
|
328
|
+
} : {
|
|
329
|
+
kind: 'create',
|
|
330
|
+
path,
|
|
331
|
+
fields: {
|
|
332
|
+
type: creation.type,
|
|
333
|
+
...creation.fields
|
|
334
|
+
},
|
|
335
|
+
sections: creation.sections
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
for (const [name, part] of named(parts.fields)){
|
|
339
|
+
changes.push({
|
|
340
|
+
kind: 'field',
|
|
341
|
+
path,
|
|
342
|
+
name,
|
|
343
|
+
value: part.value
|
|
344
|
+
});
|
|
345
|
+
bases.push({
|
|
346
|
+
kind: 'field',
|
|
347
|
+
path,
|
|
348
|
+
name,
|
|
349
|
+
value: part.base?.value
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
for (const [name, part] of named(parts.sections)){
|
|
353
|
+
changes.push({
|
|
354
|
+
kind: 'section',
|
|
355
|
+
path,
|
|
356
|
+
name,
|
|
357
|
+
value: part.value
|
|
358
|
+
});
|
|
359
|
+
bases.push({
|
|
360
|
+
kind: 'section',
|
|
361
|
+
path,
|
|
362
|
+
name,
|
|
363
|
+
value: part.base
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
if (parts.preamble !== undefined) {
|
|
367
|
+
changes.push({
|
|
368
|
+
kind: 'preamble',
|
|
369
|
+
path,
|
|
370
|
+
value: parts.preamble.value
|
|
371
|
+
});
|
|
372
|
+
bases.push({
|
|
373
|
+
kind: 'preamble',
|
|
374
|
+
path,
|
|
375
|
+
value: parts.preamble.base
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
if (parts.markdown !== undefined) {
|
|
379
|
+
changes.push({
|
|
380
|
+
kind: 'replace',
|
|
381
|
+
path,
|
|
382
|
+
content: parts.markdown.value
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (parts.move !== undefined) {
|
|
386
|
+
const to = normalize(parts.move.to);
|
|
387
|
+
changes.push({
|
|
388
|
+
kind: 'move',
|
|
389
|
+
path,
|
|
390
|
+
to: to === null || to === '' ? parts.move.to : to
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (parts.removal !== undefined) changes.push({
|
|
394
|
+
kind: 'remove',
|
|
395
|
+
path
|
|
396
|
+
});
|
|
397
|
+
return {
|
|
398
|
+
changes,
|
|
399
|
+
bases
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
//# sourceMappingURL=room-draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/room-draft.ts"],"sourcesContent":["import { apply, parse, serialize } from '@agentshouse/mdmodel';\nimport type { ProviderRefusal } from './adapter.js';\nimport type { Change, Precondition } from './change.js';\nimport { normalize } from './paths.js';\nimport type { VisibleLayer } from './replica.js';\n\nexport type FieldValue = { readonly value: unknown } | null;\n\nexport type RoomDraftCreation =\n | {\n readonly type: string;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly sections: Readonly<Record<string, string>>;\n }\n | { readonly markdown: string };\n\nexport type RoomDraftParts = {\n readonly fields?: Readonly<\n Record<string, { readonly value: unknown; readonly base?: FieldValue }>\n >;\n readonly sections?: Readonly<Record<string, { readonly value: string; readonly base?: string }>>;\n readonly preamble?: { readonly value: string; readonly base?: string };\n readonly markdown?: { readonly value: string; readonly base?: string };\n readonly creation?: RoomDraftCreation;\n readonly move?: { readonly to: string; readonly base?: string };\n readonly removal?: { readonly base?: string };\n};\n\ntype HeldParts = {\n readonly fields?: Readonly<\n Record<string, { readonly value: unknown; readonly base: FieldValue }>\n >;\n readonly sections?: Readonly<Record<string, { readonly value: string; readonly base: string }>>;\n readonly preamble?: { readonly value: string; readonly base: string };\n readonly markdown?: { readonly value: string; readonly base: string };\n readonly creation?: RoomDraftCreation;\n readonly move?: { readonly to: string; readonly base: string };\n readonly removal?: { readonly base: string };\n};\n\ntype ChangedUnderneath = {\n readonly fields?: Readonly<Record<string, FieldValue>>;\n readonly sections?: Readonly<Record<string, string | null>>;\n readonly preamble?: string | null;\n readonly markdown?: string | null;\n readonly creation?: string;\n readonly move?: string | null;\n readonly removal?: string | null;\n};\n\nexport type ReturnReason =\n | (ProviderRefusal & { readonly kind: 'conflicted' | 'rejected' })\n | { readonly kind: 'expired' }\n | { readonly kind: 'withdrawn' };\n\nexport type RoomDraft = {\n readonly room: string;\n readonly path: string;\n readonly revision: string;\n readonly parts: HeldParts;\n readonly changedUnderneath: ChangedUnderneath;\n readonly returned: ReturnReason | null;\n};\n\nexport type RoomDraftWrite =\n | { readonly outcome: 'written'; readonly roomDraft: RoomDraft | null }\n | { readonly outcome: 'stale'; readonly current: RoomDraft | null };\n\nexport type ChangedPart = {\n readonly path: string;\n readonly part: 'field' | 'section' | 'preamble' | 'markdown' | 'creation' | 'move' | 'removal';\n readonly name?: string;\n};\n\nexport type RoomDraftRecord = {\n readonly locator: string;\n readonly path: string;\n readonly revision: string;\n readonly parts: HeldParts;\n readonly returned: ReturnReason | null;\n};\n\nexport type SavedDraft = { readonly path: string; readonly parts: HeldParts };\n\nfunction malformed(): never {\n throw new Error('room-draft-malformed');\n}\n\nfunction plain(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction frontmatterValue(value: unknown): boolean {\n if (Array.isArray(value)) return value.every(frontmatterValue);\n return (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (typeof value === 'number' && Number.isFinite(value))\n );\n}\n\nfunction text(value: unknown): string {\n return typeof value === 'string' ? value : malformed();\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return value === undefined ? undefined : text(value);\n}\n\nfunction entries<T>(value: unknown, each: (item: unknown) => T): Readonly<Record<string, T>> {\n if (!plain(value)) malformed();\n const read: Record<string, T> = {};\n for (const [name, item] of Object.entries(value)) read[name] = each(item);\n return read;\n}\n\nfunction fieldValue(value: unknown): FieldValue {\n if (value === null) return null;\n if (!plain(value) || !Object.hasOwn(value, 'value') || !frontmatterValue(value.value)) {\n malformed();\n }\n return { value: value.value };\n}\n\nfunction textPart(value: unknown): { value: string; base?: string } {\n if (!plain(value)) malformed();\n const base = optionalText(value.base);\n return { value: text(value.value), ...(base === undefined ? {} : { base }) };\n}\n\nfunction creationOf(value: unknown): RoomDraftCreation {\n if (!plain(value)) malformed();\n if (Object.hasOwn(value, 'markdown')) return { markdown: text(value.markdown) };\n const fields = entries(value.fields, (item) => (frontmatterValue(item) ? item : malformed()));\n return { type: text(value.type), fields, sections: entries(value.sections, text) };\n}\n\nconst PART_NAMES = new Set([\n 'fields',\n 'sections',\n 'preamble',\n 'markdown',\n 'creation',\n 'move',\n 'removal',\n]);\n\nexport function readParts(value: unknown): RoomDraftParts {\n if (!plain(value) || Object.keys(value).some((name) => !PART_NAMES.has(name))) malformed();\n const parts: { -readonly [Name in keyof RoomDraftParts]: RoomDraftParts[Name] } = {};\n if (value.fields !== undefined) {\n parts.fields = entries(value.fields, (item) => {\n if (!plain(item) || !Object.hasOwn(item, 'value') || !frontmatterValue(item.value)) {\n malformed();\n }\n return item.base === undefined\n ? { value: item.value }\n : { value: item.value, base: fieldValue(item.base) };\n });\n }\n if (value.sections !== undefined) parts.sections = entries(value.sections, textPart);\n if (value.preamble !== undefined) parts.preamble = textPart(value.preamble);\n if (value.markdown !== undefined) parts.markdown = textPart(value.markdown);\n if (value.creation !== undefined) parts.creation = creationOf(value.creation);\n if (value.move !== undefined) {\n if (!plain(value.move)) malformed();\n const base = optionalText(value.move.base);\n parts.move = { to: text(value.move.to), ...(base === undefined ? {} : { base }) };\n }\n if (value.removal !== undefined) {\n if (!plain(value.removal)) malformed();\n const base = optionalText(value.removal.base);\n parts.removal = base === undefined ? {} : { base };\n }\n return parts;\n}\n\nfunction named<T>(record: Readonly<Record<string, T>> | undefined): readonly [string, T][] {\n return Object.entries(record ?? {});\n}\n\nfunction own<T>(record: Readonly<Record<string, T>> | undefined, name: string): T | undefined {\n return record !== undefined && Object.hasOwn(record, name) ? record[name] : undefined;\n}\n\nfunction kept<T>(prior: { readonly base: T } | undefined, base: T | undefined): T {\n if (prior !== undefined) return prior.base;\n if (base === undefined) throw new Error('room-draft-base-missing');\n return base;\n}\n\nfunction editsText(parts: RoomDraftParts): boolean {\n return (\n parts.preamble !== undefined ||\n named(parts.fields).length > 0 ||\n named(parts.sections).length > 0\n );\n}\n\nexport function held(current: HeldParts | undefined, parts: RoomDraftParts): HeldParts {\n if (parts.markdown !== undefined && editsText(parts)) {\n throw new Error('room-draft-markdown-exclusive');\n }\n const next: { -readonly [Name in keyof HeldParts]: HeldParts[Name] } = {};\n const fields = named(parts.fields);\n if (fields.length > 0) {\n next.fields = Object.fromEntries(\n fields.map(([name, part]) => [\n name,\n { value: part.value, base: kept(own(current?.fields, name), part.base) },\n ]),\n );\n }\n const sections = named(parts.sections);\n if (sections.length > 0) {\n next.sections = Object.fromEntries(\n sections.map(([name, part]) => [\n name,\n { value: part.value, base: kept(own(current?.sections, name), part.base) },\n ]),\n );\n }\n if (parts.preamble !== undefined) {\n next.preamble = {\n value: parts.preamble.value,\n base: kept(current?.preamble, parts.preamble.base),\n };\n }\n if (parts.markdown !== undefined) {\n next.markdown = {\n value: parts.markdown.value,\n base: kept(current?.markdown, parts.markdown.base),\n };\n }\n if (parts.creation !== undefined) next.creation = parts.creation;\n if (parts.move !== undefined) {\n next.move = { to: parts.move.to, base: kept(current?.move, parts.move.base) };\n }\n if (parts.removal !== undefined) {\n next.removal = { base: kept(current?.removal, parts.removal.base) };\n }\n if (Object.keys(next).length === 0) throw new Error('room-draft-empty');\n return next;\n}\n\nexport function equalValue(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n return (\n Array.isArray(left) &&\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((item, index) => equalValue(item, right[index]))\n );\n}\n\nfunction sameField(left: FieldValue, right: FieldValue): boolean {\n if (left === null || right === null) return left === right;\n return equalValue(left.value, right.value);\n}\n\nexport function underneath(\n parts: HeldParts,\n path: string,\n visible: VisibleLayer | undefined,\n): ChangedUnderneath {\n const markdown = visible?.documents[path] ?? null;\n const document = visible?.collection.documents[path];\n const report: { -readonly [Name in keyof ChangedUnderneath]: ChangedUnderneath[Name] } = {};\n const fields: Record<string, FieldValue> = {};\n for (const [name, part] of named(parts.fields)) {\n const current =\n document !== undefined && Object.hasOwn(document.fields, name)\n ? { value: document.fields[name] }\n : null;\n if (!sameField(part.base, current)) fields[name] = current;\n }\n if (Object.keys(fields).length > 0) report.fields = fields;\n const sections: Record<string, string | null> = {};\n for (const [name, part] of named(parts.sections)) {\n const current =\n document !== undefined && Object.hasOwn(document.sections, name)\n ? document.sections[name]\n : null;\n if (current !== part.base) sections[name] = current;\n }\n if (Object.keys(sections).length > 0) report.sections = sections;\n const preamble = document?.preamble ?? null;\n if (parts.preamble !== undefined && preamble !== parts.preamble.base) report.preamble = preamble;\n if (parts.markdown !== undefined && markdown !== parts.markdown.base) report.markdown = markdown;\n if (parts.creation !== undefined && markdown !== null) report.creation = markdown;\n if (parts.move !== undefined && markdown !== parts.move.base) report.move = markdown;\n if (parts.removal !== undefined && markdown !== parts.removal.base) report.removal = markdown;\n return report;\n}\n\nexport function changedParts(path: string, report: ChangedUnderneath): readonly ChangedPart[] {\n return [\n ...(report.creation === undefined ? [] : [{ path, part: 'creation' as const }]),\n ...named(report.fields).map(([name]) => ({ path, part: 'field' as const, name })),\n ...named(report.sections).map(([name]) => ({ path, part: 'section' as const, name })),\n ...(report.preamble === undefined ? [] : [{ path, part: 'preamble' as const }]),\n ...(report.markdown === undefined ? [] : [{ path, part: 'markdown' as const }]),\n ...(report.move === undefined ? [] : [{ path, part: 'move' as const }]),\n ...(report.removal === undefined ? [] : [{ path, part: 'removal' as const }]),\n ];\n}\n\nfunction joined<T>(\n existing: Readonly<Record<string, T>> | undefined,\n returned: Readonly<Record<string, T>> | undefined,\n): Readonly<Record<string, T>> | undefined {\n const merged = { ...existing };\n for (const [name, part] of named(returned)) if (!Object.hasOwn(merged, name)) merged[name] = part;\n return Object.keys(merged).length === 0 ? undefined : merged;\n}\n\nfunction ended(text: string): string {\n return text === '' || text.endsWith('\\n') ? text : `${text}\\n`;\n}\n\nfunction frontmatterOf(fields: readonly [string, { readonly value: unknown }][]): string {\n const opened = parse('---\\n---\\n');\n if (!opened.ok) return malformed();\n let document = opened.document;\n for (const [name, part] of fields) {\n const next = apply(document, { kind: 'field', name, value: part.value, prior: undefined });\n if (next.outcome !== 'applied') return malformed();\n document = next.document;\n }\n return serialize(document);\n}\n\nfunction concatenated(markdown: string, parts: HeldParts): string {\n const fields = named(parts.fields);\n const pieces = [\n ...(fields.length === 0 ? [] : [frontmatterOf(fields)]),\n ...(parts.preamble === undefined ? [] : [parts.preamble.value]),\n ...named(parts.sections).map(([name, part]) => `## ${name}\\n${part.value}`),\n ];\n if (pieces.length === 0) return markdown;\n return `${ended(markdown)}\\n${pieces.map(ended).join('')}`;\n}\n\nexport function returnedInto(existing: HeldParts | undefined, returned: HeldParts): HeldParts {\n if (existing === undefined) return returned;\n const next: { -readonly [Name in keyof HeldParts]: HeldParts[Name] } = { ...existing };\n const whole = existing.markdown ?? returned.markdown;\n if (whole === undefined) {\n const fields = joined(existing.fields, returned.fields);\n const sections = joined(existing.sections, returned.sections);\n if (fields !== undefined) next.fields = fields;\n if (sections !== undefined) next.sections = sections;\n const preamble = existing.preamble ?? returned.preamble;\n if (preamble !== undefined) next.preamble = preamble;\n } else {\n delete next.fields;\n delete next.sections;\n delete next.preamble;\n const value = concatenated(whole.value, existing.markdown === undefined ? existing : returned);\n next.markdown = { value, base: whole.base };\n }\n const creation = existing.creation ?? returned.creation;\n const move = existing.move ?? returned.move;\n const removal = existing.removal ?? returned.removal;\n if (creation !== undefined) next.creation = creation;\n if (move !== undefined) next.move = move;\n if (removal !== undefined) next.removal = removal;\n return next;\n}\n\nexport function changesOf(\n path: string,\n parts: HeldParts,\n): { changes: readonly Change[]; bases: readonly Precondition[] } {\n const changes: Change[] = [];\n const bases: Precondition[] = [];\n const creation = parts.creation;\n if (creation !== undefined) {\n changes.push(\n 'markdown' in creation\n ? { kind: 'create', path, content: creation.markdown }\n : {\n kind: 'create',\n path,\n fields: { type: creation.type, ...creation.fields },\n sections: creation.sections,\n },\n );\n }\n for (const [name, part] of named(parts.fields)) {\n changes.push({ kind: 'field', path, name, value: part.value });\n bases.push({ kind: 'field', path, name, value: part.base?.value });\n }\n for (const [name, part] of named(parts.sections)) {\n changes.push({ kind: 'section', path, name, value: part.value });\n bases.push({ kind: 'section', path, name, value: part.base });\n }\n if (parts.preamble !== undefined) {\n changes.push({ kind: 'preamble', path, value: parts.preamble.value });\n bases.push({ kind: 'preamble', path, value: parts.preamble.base });\n }\n if (parts.markdown !== undefined) {\n changes.push({ kind: 'replace', path, content: parts.markdown.value });\n }\n if (parts.move !== undefined) {\n const to = normalize(parts.move.to);\n changes.push({ kind: 'move', path, to: to === null || to === '' ? parts.move.to : to });\n }\n if (parts.removal !== undefined) changes.push({ kind: 'remove', path });\n return { changes, bases };\n}\n"],"names":["apply","parse","serialize","normalize","malformed","Error","plain","value","Array","isArray","frontmatterValue","every","Number","isFinite","text","optionalText","undefined","entries","each","read","name","item","Object","fieldValue","hasOwn","textPart","base","creationOf","markdown","fields","type","sections","PART_NAMES","Set","readParts","keys","some","has","parts","preamble","creation","move","to","removal","named","record","own","kept","prior","editsText","length","held","current","next","fromEntries","map","part","equalValue","left","right","index","sameField","underneath","path","visible","documents","document","collection","report","changedParts","joined","existing","returned","merged","ended","endsWith","frontmatterOf","opened","ok","kind","outcome","concatenated","pieces","join","returnedInto","whole","changesOf","changes","bases","push","content"],"mappings":"AAAA,SAASA,KAAK,EAAEC,KAAK,EAAEC,SAAS,QAAQ,uBAAuB;AAG/D,SAASC,SAAS,QAAQ,aAAa;AAiFvC,SAASC;IACP,MAAM,IAAIC,MAAM;AAClB;AAEA,SAASC,MAAMC,KAAc;IAC3B,OAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF;AACvE;AAEA,SAASG,iBAAiBH,KAAc;IACtC,IAAIC,MAAMC,OAAO,CAACF,QAAQ,OAAOA,MAAMI,KAAK,CAACD;IAC7C,OACEH,UAAU,QACV,OAAOA,UAAU,YACjB,OAAOA,UAAU,aAChB,OAAOA,UAAU,YAAYK,OAAOC,QAAQ,CAACN;AAElD;AAEA,SAASO,KAAKP,KAAc;IAC1B,OAAO,OAAOA,UAAU,WAAWA,QAAQH;AAC7C;AAEA,SAASW,aAAaR,KAAc;IAClC,OAAOA,UAAUS,YAAYA,YAAYF,KAAKP;AAChD;AAEA,SAASU,QAAWV,KAAc,EAAEW,IAA0B;IAC5D,IAAI,CAACZ,MAAMC,QAAQH;IACnB,MAAMe,OAA0B,CAAC;IACjC,KAAK,MAAM,CAACC,MAAMC,KAAK,IAAIC,OAAOL,OAAO,CAACV,OAAQY,IAAI,CAACC,KAAK,GAAGF,KAAKG;IACpE,OAAOF;AACT;AAEA,SAASI,WAAWhB,KAAc;IAChC,IAAIA,UAAU,MAAM,OAAO;IAC3B,IAAI,CAACD,MAAMC,UAAU,CAACe,OAAOE,MAAM,CAACjB,OAAO,YAAY,CAACG,iBAAiBH,MAAMA,KAAK,GAAG;QACrFH;IACF;IACA,OAAO;QAAEG,OAAOA,MAAMA,KAAK;IAAC;AAC9B;AAEA,SAASkB,SAASlB,KAAc;IAC9B,IAAI,CAACD,MAAMC,QAAQH;IACnB,MAAMsB,OAAOX,aAAaR,MAAMmB,IAAI;IACpC,OAAO;QAAEnB,OAAOO,KAAKP,MAAMA,KAAK;QAAG,GAAImB,SAASV,YAAY,CAAC,IAAI;YAAEU;QAAK,CAAC;IAAE;AAC7E;AAEA,SAASC,WAAWpB,KAAc;IAChC,IAAI,CAACD,MAAMC,QAAQH;IACnB,IAAIkB,OAAOE,MAAM,CAACjB,OAAO,aAAa,OAAO;QAAEqB,UAAUd,KAAKP,MAAMqB,QAAQ;IAAE;IAC9E,MAAMC,SAASZ,QAAQV,MAAMsB,MAAM,EAAE,CAACR,OAAUX,iBAAiBW,QAAQA,OAAOjB;IAChF,OAAO;QAAE0B,MAAMhB,KAAKP,MAAMuB,IAAI;QAAGD;QAAQE,UAAUd,QAAQV,MAAMwB,QAAQ,EAAEjB;IAAM;AACnF;AAEA,MAAMkB,aAAa,IAAIC,IAAI;IACzB;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,OAAO,SAASC,UAAU3B,KAAc;IACtC,IAAI,CAACD,MAAMC,UAAUe,OAAOa,IAAI,CAAC5B,OAAO6B,IAAI,CAAC,CAAChB,OAAS,CAACY,WAAWK,GAAG,CAACjB,QAAQhB;IAC/E,MAAMkC,QAA4E,CAAC;IACnF,IAAI/B,MAAMsB,MAAM,KAAKb,WAAW;QAC9BsB,MAAMT,MAAM,GAAGZ,QAAQV,MAAMsB,MAAM,EAAE,CAACR;YACpC,IAAI,CAACf,MAAMe,SAAS,CAACC,OAAOE,MAAM,CAACH,MAAM,YAAY,CAACX,iBAAiBW,KAAKd,KAAK,GAAG;gBAClFH;YACF;YACA,OAAOiB,KAAKK,IAAI,KAAKV,YACjB;gBAAET,OAAOc,KAAKd,KAAK;YAAC,IACpB;gBAAEA,OAAOc,KAAKd,KAAK;gBAAEmB,MAAMH,WAAWF,KAAKK,IAAI;YAAE;QACvD;IACF;IACA,IAAInB,MAAMwB,QAAQ,KAAKf,WAAWsB,MAAMP,QAAQ,GAAGd,QAAQV,MAAMwB,QAAQ,EAAEN;IAC3E,IAAIlB,MAAMgC,QAAQ,KAAKvB,WAAWsB,MAAMC,QAAQ,GAAGd,SAASlB,MAAMgC,QAAQ;IAC1E,IAAIhC,MAAMqB,QAAQ,KAAKZ,WAAWsB,MAAMV,QAAQ,GAAGH,SAASlB,MAAMqB,QAAQ;IAC1E,IAAIrB,MAAMiC,QAAQ,KAAKxB,WAAWsB,MAAME,QAAQ,GAAGb,WAAWpB,MAAMiC,QAAQ;IAC5E,IAAIjC,MAAMkC,IAAI,KAAKzB,WAAW;QAC5B,IAAI,CAACV,MAAMC,MAAMkC,IAAI,GAAGrC;QACxB,MAAMsB,OAAOX,aAAaR,MAAMkC,IAAI,CAACf,IAAI;QACzCY,MAAMG,IAAI,GAAG;YAAEC,IAAI5B,KAAKP,MAAMkC,IAAI,CAACC,EAAE;YAAG,GAAIhB,SAASV,YAAY,CAAC,IAAI;gBAAEU;YAAK,CAAC;QAAE;IAClF;IACA,IAAInB,MAAMoC,OAAO,KAAK3B,WAAW;QAC/B,IAAI,CAACV,MAAMC,MAAMoC,OAAO,GAAGvC;QAC3B,MAAMsB,OAAOX,aAAaR,MAAMoC,OAAO,CAACjB,IAAI;QAC5CY,MAAMK,OAAO,GAAGjB,SAASV,YAAY,CAAC,IAAI;YAAEU;QAAK;IACnD;IACA,OAAOY;AACT;AAEA,SAASM,MAASC,MAA+C;IAC/D,OAAOvB,OAAOL,OAAO,CAAC4B,UAAU,CAAC;AACnC;AAEA,SAASC,IAAOD,MAA+C,EAAEzB,IAAY;IAC3E,OAAOyB,WAAW7B,aAAaM,OAAOE,MAAM,CAACqB,QAAQzB,QAAQyB,MAAM,CAACzB,KAAK,GAAGJ;AAC9E;AAEA,SAAS+B,KAAQC,KAAuC,EAAEtB,IAAmB;IAC3E,IAAIsB,UAAUhC,WAAW,OAAOgC,MAAMtB,IAAI;IAC1C,IAAIA,SAASV,WAAW,MAAM,IAAIX,MAAM;IACxC,OAAOqB;AACT;AAEA,SAASuB,UAAUX,KAAqB;IACtC,OACEA,MAAMC,QAAQ,KAAKvB,aACnB4B,MAAMN,MAAMT,MAAM,EAAEqB,MAAM,GAAG,KAC7BN,MAAMN,MAAMP,QAAQ,EAAEmB,MAAM,GAAG;AAEnC;AAEA,OAAO,SAASC,KAAKC,OAA8B,EAAEd,KAAqB;IACxE,IAAIA,MAAMV,QAAQ,KAAKZ,aAAaiC,UAAUX,QAAQ;QACpD,MAAM,IAAIjC,MAAM;IAClB;IACA,MAAMgD,OAAiE,CAAC;IACxE,MAAMxB,SAASe,MAAMN,MAAMT,MAAM;IACjC,IAAIA,OAAOqB,MAAM,GAAG,GAAG;QACrBG,KAAKxB,MAAM,GAAGP,OAAOgC,WAAW,CAC9BzB,OAAO0B,GAAG,CAAC,CAAC,CAACnC,MAAMoC,KAAK,GAAK;gBAC3BpC;gBACA;oBAAEb,OAAOiD,KAAKjD,KAAK;oBAAEmB,MAAMqB,KAAKD,IAAIM,SAASvB,QAAQT,OAAOoC,KAAK9B,IAAI;gBAAE;aACxE;IAEL;IACA,MAAMK,WAAWa,MAAMN,MAAMP,QAAQ;IACrC,IAAIA,SAASmB,MAAM,GAAG,GAAG;QACvBG,KAAKtB,QAAQ,GAAGT,OAAOgC,WAAW,CAChCvB,SAASwB,GAAG,CAAC,CAAC,CAACnC,MAAMoC,KAAK,GAAK;gBAC7BpC;gBACA;oBAAEb,OAAOiD,KAAKjD,KAAK;oBAAEmB,MAAMqB,KAAKD,IAAIM,SAASrB,UAAUX,OAAOoC,KAAK9B,IAAI;gBAAE;aAC1E;IAEL;IACA,IAAIY,MAAMC,QAAQ,KAAKvB,WAAW;QAChCqC,KAAKd,QAAQ,GAAG;YACdhC,OAAO+B,MAAMC,QAAQ,CAAChC,KAAK;YAC3BmB,MAAMqB,KAAKK,SAASb,UAAUD,MAAMC,QAAQ,CAACb,IAAI;QACnD;IACF;IACA,IAAIY,MAAMV,QAAQ,KAAKZ,WAAW;QAChCqC,KAAKzB,QAAQ,GAAG;YACdrB,OAAO+B,MAAMV,QAAQ,CAACrB,KAAK;YAC3BmB,MAAMqB,KAAKK,SAASxB,UAAUU,MAAMV,QAAQ,CAACF,IAAI;QACnD;IACF;IACA,IAAIY,MAAME,QAAQ,KAAKxB,WAAWqC,KAAKb,QAAQ,GAAGF,MAAME,QAAQ;IAChE,IAAIF,MAAMG,IAAI,KAAKzB,WAAW;QAC5BqC,KAAKZ,IAAI,GAAG;YAAEC,IAAIJ,MAAMG,IAAI,CAACC,EAAE;YAAEhB,MAAMqB,KAAKK,SAASX,MAAMH,MAAMG,IAAI,CAACf,IAAI;QAAE;IAC9E;IACA,IAAIY,MAAMK,OAAO,KAAK3B,WAAW;QAC/BqC,KAAKV,OAAO,GAAG;YAAEjB,MAAMqB,KAAKK,SAAST,SAASL,MAAMK,OAAO,CAACjB,IAAI;QAAE;IACpE;IACA,IAAIJ,OAAOa,IAAI,CAACkB,MAAMH,MAAM,KAAK,GAAG,MAAM,IAAI7C,MAAM;IACpD,OAAOgD;AACT;AAEA,OAAO,SAASI,WAAWC,IAAa,EAAEC,KAAc;IACtD,IAAID,SAASC,OAAO,OAAO;IAC3B,OACEnD,MAAMC,OAAO,CAACiD,SACdlD,MAAMC,OAAO,CAACkD,UACdD,KAAKR,MAAM,KAAKS,MAAMT,MAAM,IAC5BQ,KAAK/C,KAAK,CAAC,CAACU,MAAMuC,QAAUH,WAAWpC,MAAMsC,KAAK,CAACC,MAAM;AAE7D;AAEA,SAASC,UAAUH,IAAgB,EAAEC,KAAiB;IACpD,IAAID,SAAS,QAAQC,UAAU,MAAM,OAAOD,SAASC;IACrD,OAAOF,WAAWC,KAAKnD,KAAK,EAAEoD,MAAMpD,KAAK;AAC3C;AAEA,OAAO,SAASuD,WACdxB,KAAgB,EAChByB,IAAY,EACZC,OAAiC;IAEjC,MAAMpC,WAAWoC,SAASC,SAAS,CAACF,KAAK,IAAI;IAC7C,MAAMG,WAAWF,SAASG,WAAWF,SAAS,CAACF,KAAK;IACpD,MAAMK,SAAmF,CAAC;IAC1F,MAAMvC,SAAqC,CAAC;IAC5C,KAAK,MAAM,CAACT,MAAMoC,KAAK,IAAIZ,MAAMN,MAAMT,MAAM,EAAG;QAC9C,MAAMuB,UACJc,aAAalD,aAAaM,OAAOE,MAAM,CAAC0C,SAASrC,MAAM,EAAET,QACrD;YAAEb,OAAO2D,SAASrC,MAAM,CAACT,KAAK;QAAC,IAC/B;QACN,IAAI,CAACyC,UAAUL,KAAK9B,IAAI,EAAE0B,UAAUvB,MAAM,CAACT,KAAK,GAAGgC;IACrD;IACA,IAAI9B,OAAOa,IAAI,CAACN,QAAQqB,MAAM,GAAG,GAAGkB,OAAOvC,MAAM,GAAGA;IACpD,MAAME,WAA0C,CAAC;IACjD,KAAK,MAAM,CAACX,MAAMoC,KAAK,IAAIZ,MAAMN,MAAMP,QAAQ,EAAG;QAChD,MAAMqB,UACJc,aAAalD,aAAaM,OAAOE,MAAM,CAAC0C,SAASnC,QAAQ,EAAEX,QACvD8C,SAASnC,QAAQ,CAACX,KAAK,GACvB;QACN,IAAIgC,YAAYI,KAAK9B,IAAI,EAAEK,QAAQ,CAACX,KAAK,GAAGgC;IAC9C;IACA,IAAI9B,OAAOa,IAAI,CAACJ,UAAUmB,MAAM,GAAG,GAAGkB,OAAOrC,QAAQ,GAAGA;IACxD,MAAMQ,WAAW2B,UAAU3B,YAAY;IACvC,IAAID,MAAMC,QAAQ,KAAKvB,aAAauB,aAAaD,MAAMC,QAAQ,CAACb,IAAI,EAAE0C,OAAO7B,QAAQ,GAAGA;IACxF,IAAID,MAAMV,QAAQ,KAAKZ,aAAaY,aAAaU,MAAMV,QAAQ,CAACF,IAAI,EAAE0C,OAAOxC,QAAQ,GAAGA;IACxF,IAAIU,MAAME,QAAQ,KAAKxB,aAAaY,aAAa,MAAMwC,OAAO5B,QAAQ,GAAGZ;IACzE,IAAIU,MAAMG,IAAI,KAAKzB,aAAaY,aAAaU,MAAMG,IAAI,CAACf,IAAI,EAAE0C,OAAO3B,IAAI,GAAGb;IAC5E,IAAIU,MAAMK,OAAO,KAAK3B,aAAaY,aAAaU,MAAMK,OAAO,CAACjB,IAAI,EAAE0C,OAAOzB,OAAO,GAAGf;IACrF,OAAOwC;AACT;AAEA,OAAO,SAASC,aAAaN,IAAY,EAAEK,MAAyB;IAClE,OAAO;WACDA,OAAO5B,QAAQ,KAAKxB,YAAY,EAAE,GAAG;YAAC;gBAAE+C;gBAAMP,MAAM;YAAoB;SAAE;WAC3EZ,MAAMwB,OAAOvC,MAAM,EAAE0B,GAAG,CAAC,CAAC,CAACnC,KAAK,GAAM,CAAA;gBAAE2C;gBAAMP,MAAM;gBAAkBpC;YAAK,CAAA;WAC3EwB,MAAMwB,OAAOrC,QAAQ,EAAEwB,GAAG,CAAC,CAAC,CAACnC,KAAK,GAAM,CAAA;gBAAE2C;gBAAMP,MAAM;gBAAoBpC;YAAK,CAAA;WAC9EgD,OAAO7B,QAAQ,KAAKvB,YAAY,EAAE,GAAG;YAAC;gBAAE+C;gBAAMP,MAAM;YAAoB;SAAE;WAC1EY,OAAOxC,QAAQ,KAAKZ,YAAY,EAAE,GAAG;YAAC;gBAAE+C;gBAAMP,MAAM;YAAoB;SAAE;WAC1EY,OAAO3B,IAAI,KAAKzB,YAAY,EAAE,GAAG;YAAC;gBAAE+C;gBAAMP,MAAM;YAAgB;SAAE;WAClEY,OAAOzB,OAAO,KAAK3B,YAAY,EAAE,GAAG;YAAC;gBAAE+C;gBAAMP,MAAM;YAAmB;SAAE;KAC7E;AACH;AAEA,SAASc,OACPC,QAAiD,EACjDC,QAAiD;IAEjD,MAAMC,SAAS;QAAE,GAAGF,QAAQ;IAAC;IAC7B,KAAK,MAAM,CAACnD,MAAMoC,KAAK,IAAIZ,MAAM4B,UAAW,IAAI,CAAClD,OAAOE,MAAM,CAACiD,QAAQrD,OAAOqD,MAAM,CAACrD,KAAK,GAAGoC;IAC7F,OAAOlC,OAAOa,IAAI,CAACsC,QAAQvB,MAAM,KAAK,IAAIlC,YAAYyD;AACxD;AAEA,SAASC,MAAM5D,IAAY;IACzB,OAAOA,SAAS,MAAMA,KAAK6D,QAAQ,CAAC,QAAQ7D,OAAO,GAAGA,KAAK,EAAE,CAAC;AAChE;AAEA,SAAS8D,cAAc/C,MAAwD;IAC7E,MAAMgD,SAAS5E,MAAM;IACrB,IAAI,CAAC4E,OAAOC,EAAE,EAAE,OAAO1E;IACvB,IAAI8D,WAAWW,OAAOX,QAAQ;IAC9B,KAAK,MAAM,CAAC9C,MAAMoC,KAAK,IAAI3B,OAAQ;QACjC,MAAMwB,OAAOrD,MAAMkE,UAAU;YAAEa,MAAM;YAAS3D;YAAMb,OAAOiD,KAAKjD,KAAK;YAAEyC,OAAOhC;QAAU;QACxF,IAAIqC,KAAK2B,OAAO,KAAK,WAAW,OAAO5E;QACvC8D,WAAWb,KAAKa,QAAQ;IAC1B;IACA,OAAOhE,UAAUgE;AACnB;AAEA,SAASe,aAAarD,QAAgB,EAAEU,KAAgB;IACtD,MAAMT,SAASe,MAAMN,MAAMT,MAAM;IACjC,MAAMqD,SAAS;WACTrD,OAAOqB,MAAM,KAAK,IAAI,EAAE,GAAG;YAAC0B,cAAc/C;SAAQ;WAClDS,MAAMC,QAAQ,KAAKvB,YAAY,EAAE,GAAG;YAACsB,MAAMC,QAAQ,CAAChC,KAAK;SAAC;WAC3DqC,MAAMN,MAAMP,QAAQ,EAAEwB,GAAG,CAAC,CAAC,CAACnC,MAAMoC,KAAK,GAAK,CAAC,GAAG,EAAEpC,KAAK,EAAE,EAAEoC,KAAKjD,KAAK,EAAE;KAC3E;IACD,IAAI2E,OAAOhC,MAAM,KAAK,GAAG,OAAOtB;IAChC,OAAO,GAAG8C,MAAM9C,UAAU,EAAE,EAAEsD,OAAO3B,GAAG,CAACmB,OAAOS,IAAI,CAAC,KAAK;AAC5D;AAEA,OAAO,SAASC,aAAab,QAA+B,EAAEC,QAAmB;IAC/E,IAAID,aAAavD,WAAW,OAAOwD;IACnC,MAAMnB,OAAiE;QAAE,GAAGkB,QAAQ;IAAC;IACrF,MAAMc,QAAQd,SAAS3C,QAAQ,IAAI4C,SAAS5C,QAAQ;IACpD,IAAIyD,UAAUrE,WAAW;QACvB,MAAMa,SAASyC,OAAOC,SAAS1C,MAAM,EAAE2C,SAAS3C,MAAM;QACtD,MAAME,WAAWuC,OAAOC,SAASxC,QAAQ,EAAEyC,SAASzC,QAAQ;QAC5D,IAAIF,WAAWb,WAAWqC,KAAKxB,MAAM,GAAGA;QACxC,IAAIE,aAAaf,WAAWqC,KAAKtB,QAAQ,GAAGA;QAC5C,MAAMQ,WAAWgC,SAAShC,QAAQ,IAAIiC,SAASjC,QAAQ;QACvD,IAAIA,aAAavB,WAAWqC,KAAKd,QAAQ,GAAGA;IAC9C,OAAO;QACL,OAAOc,KAAKxB,MAAM;QAClB,OAAOwB,KAAKtB,QAAQ;QACpB,OAAOsB,KAAKd,QAAQ;QACpB,MAAMhC,QAAQ0E,aAAaI,MAAM9E,KAAK,EAAEgE,SAAS3C,QAAQ,KAAKZ,YAAYuD,WAAWC;QACrFnB,KAAKzB,QAAQ,GAAG;YAAErB;YAAOmB,MAAM2D,MAAM3D,IAAI;QAAC;IAC5C;IACA,MAAMc,WAAW+B,SAAS/B,QAAQ,IAAIgC,SAAShC,QAAQ;IACvD,MAAMC,OAAO8B,SAAS9B,IAAI,IAAI+B,SAAS/B,IAAI;IAC3C,MAAME,UAAU4B,SAAS5B,OAAO,IAAI6B,SAAS7B,OAAO;IACpD,IAAIH,aAAaxB,WAAWqC,KAAKb,QAAQ,GAAGA;IAC5C,IAAIC,SAASzB,WAAWqC,KAAKZ,IAAI,GAAGA;IACpC,IAAIE,YAAY3B,WAAWqC,KAAKV,OAAO,GAAGA;IAC1C,OAAOU;AACT;AAEA,OAAO,SAASiC,UACdvB,IAAY,EACZzB,KAAgB;IAEhB,MAAMiD,UAAoB,EAAE;IAC5B,MAAMC,QAAwB,EAAE;IAChC,MAAMhD,WAAWF,MAAME,QAAQ;IAC/B,IAAIA,aAAaxB,WAAW;QAC1BuE,QAAQE,IAAI,CACV,cAAcjD,WACV;YAAEuC,MAAM;YAAUhB;YAAM2B,SAASlD,SAASZ,QAAQ;QAAC,IACnD;YACEmD,MAAM;YACNhB;YACAlC,QAAQ;gBAAEC,MAAMU,SAASV,IAAI;gBAAE,GAAGU,SAASX,MAAM;YAAC;YAClDE,UAAUS,SAAST,QAAQ;QAC7B;IAER;IACA,KAAK,MAAM,CAACX,MAAMoC,KAAK,IAAIZ,MAAMN,MAAMT,MAAM,EAAG;QAC9C0D,QAAQE,IAAI,CAAC;YAAEV,MAAM;YAAShB;YAAM3C;YAAMb,OAAOiD,KAAKjD,KAAK;QAAC;QAC5DiF,MAAMC,IAAI,CAAC;YAAEV,MAAM;YAAShB;YAAM3C;YAAMb,OAAOiD,KAAK9B,IAAI,EAAEnB;QAAM;IAClE;IACA,KAAK,MAAM,CAACa,MAAMoC,KAAK,IAAIZ,MAAMN,MAAMP,QAAQ,EAAG;QAChDwD,QAAQE,IAAI,CAAC;YAAEV,MAAM;YAAWhB;YAAM3C;YAAMb,OAAOiD,KAAKjD,KAAK;QAAC;QAC9DiF,MAAMC,IAAI,CAAC;YAAEV,MAAM;YAAWhB;YAAM3C;YAAMb,OAAOiD,KAAK9B,IAAI;QAAC;IAC7D;IACA,IAAIY,MAAMC,QAAQ,KAAKvB,WAAW;QAChCuE,QAAQE,IAAI,CAAC;YAAEV,MAAM;YAAYhB;YAAMxD,OAAO+B,MAAMC,QAAQ,CAAChC,KAAK;QAAC;QACnEiF,MAAMC,IAAI,CAAC;YAAEV,MAAM;YAAYhB;YAAMxD,OAAO+B,MAAMC,QAAQ,CAACb,IAAI;QAAC;IAClE;IACA,IAAIY,MAAMV,QAAQ,KAAKZ,WAAW;QAChCuE,QAAQE,IAAI,CAAC;YAAEV,MAAM;YAAWhB;YAAM2B,SAASpD,MAAMV,QAAQ,CAACrB,KAAK;QAAC;IACtE;IACA,IAAI+B,MAAMG,IAAI,KAAKzB,WAAW;QAC5B,MAAM0B,KAAKvC,UAAUmC,MAAMG,IAAI,CAACC,EAAE;QAClC6C,QAAQE,IAAI,CAAC;YAAEV,MAAM;YAAQhB;YAAMrB,IAAIA,OAAO,QAAQA,OAAO,KAAKJ,MAAMG,IAAI,CAACC,EAAE,GAAGA;QAAG;IACvF;IACA,IAAIJ,MAAMK,OAAO,KAAK3B,WAAWuE,QAAQE,IAAI,CAAC;QAAEV,MAAM;QAAUhB;IAAK;IACrE,OAAO;QAAEwB;QAASC;IAAM;AAC1B"}
|