@agentshouse/mdruntime 0.1.0-cc7bd7a53214e → 0.1.0-cd3486bd400ed

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.
Files changed (127) hide show
  1. package/AGENTS.md +106 -31
  2. package/README.md +11 -10
  3. package/dist/adapter.d.ts +65 -28
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -9
  6. package/dist/attached-model.d.ts +11 -0
  7. package/dist/attached-model.d.ts.map +1 -0
  8. package/dist/attached-model.js +47 -0
  9. package/dist/attempt.d.ts +16 -0
  10. package/dist/attempt.d.ts.map +1 -0
  11. package/dist/attempt.js +57 -0
  12. package/dist/bootstrap.d.ts +20 -6
  13. package/dist/bootstrap.d.ts.map +1 -1
  14. package/dist/bootstrap.js +89 -35
  15. package/dist/change-set.d.ts.map +1 -1
  16. package/dist/change-set.js +13 -7
  17. package/dist/change.d.ts +4 -0
  18. package/dist/change.d.ts.map +1 -1
  19. package/dist/chat/acts.d.ts +34 -0
  20. package/dist/chat/acts.d.ts.map +1 -0
  21. package/dist/chat/acts.js +36 -0
  22. package/dist/chat/messages.d.ts +21 -0
  23. package/dist/chat/messages.d.ts.map +1 -0
  24. package/dist/chat/messages.js +151 -0
  25. package/dist/chat/overlay.d.ts +31 -0
  26. package/dist/chat/overlay.d.ts.map +1 -0
  27. package/dist/chat/overlay.js +97 -0
  28. package/dist/chat/parts.d.ts +57 -0
  29. package/dist/chat/parts.d.ts.map +1 -0
  30. package/dist/chat/parts.js +119 -0
  31. package/dist/chat/process.d.ts +20 -0
  32. package/dist/chat/process.d.ts.map +1 -0
  33. package/dist/chat/process.js +32 -0
  34. package/dist/chat/provider.d.ts +57 -0
  35. package/dist/chat/provider.d.ts.map +1 -0
  36. package/dist/chat/provider.js +637 -0
  37. package/dist/chat/questions.d.ts +31 -0
  38. package/dist/chat/questions.d.ts.map +1 -0
  39. package/dist/chat/questions.js +111 -0
  40. package/dist/chat/read.d.ts +5 -0
  41. package/dist/chat/read.d.ts.map +1 -0
  42. package/dist/chat/read.js +13 -0
  43. package/dist/chat.d.ts +7 -0
  44. package/dist/chat.d.ts.map +1 -0
  45. package/dist/chat.js +2 -0
  46. package/dist/client.d.ts +11 -7
  47. package/dist/client.d.ts.map +1 -1
  48. package/dist/client.js +58 -25
  49. package/dist/collection.d.ts +6 -11
  50. package/dist/collection.d.ts.map +1 -1
  51. package/dist/collection.js +56 -19
  52. package/dist/connection.d.ts +18 -13
  53. package/dist/connection.d.ts.map +1 -1
  54. package/dist/connection.js +679 -568
  55. package/dist/conversation.d.ts +27 -8
  56. package/dist/conversation.d.ts.map +1 -1
  57. package/dist/conversation.js +210 -81
  58. package/dist/expectation.d.ts +21 -0
  59. package/dist/expectation.d.ts.map +1 -0
  60. package/dist/expectation.js +70 -0
  61. package/dist/failure.d.ts +13 -0
  62. package/dist/failure.d.ts.map +1 -0
  63. package/dist/failure.js +19 -0
  64. package/dist/host.d.ts +1 -0
  65. package/dist/host.d.ts.map +1 -1
  66. package/dist/host.js +8 -19
  67. package/dist/identity.d.ts +2 -0
  68. package/dist/identity.d.ts.map +1 -1
  69. package/dist/identity.js +10 -1
  70. package/dist/index.d.ts +7 -4
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +2 -0
  73. package/dist/memory.d.ts +12 -5
  74. package/dist/memory.d.ts.map +1 -1
  75. package/dist/memory.js +108 -36
  76. package/dist/model.d.ts +13 -12
  77. package/dist/model.d.ts.map +1 -1
  78. package/dist/model.js +6 -3
  79. package/dist/open.d.ts +2 -0
  80. package/dist/open.d.ts.map +1 -0
  81. package/dist/open.js +1 -0
  82. package/dist/outcome.d.ts +22 -3
  83. package/dist/outcome.d.ts.map +1 -1
  84. package/dist/outcome.js +35 -1
  85. package/dist/overlay.d.ts +1 -1
  86. package/dist/overlay.d.ts.map +1 -1
  87. package/dist/overlay.js +19 -15
  88. package/dist/paths.d.ts +0 -1
  89. package/dist/paths.d.ts.map +1 -1
  90. package/dist/paths.js +0 -16
  91. package/dist/query.d.ts +3 -1
  92. package/dist/query.d.ts.map +1 -1
  93. package/dist/query.js +74 -33
  94. package/dist/reach.d.ts.map +1 -1
  95. package/dist/reach.js +29 -35
  96. package/dist/react.d.ts +41 -0
  97. package/dist/react.d.ts.map +1 -0
  98. package/dist/react.js +64 -0
  99. package/dist/read-side.d.ts.map +1 -1
  100. package/dist/read-side.js +102 -46
  101. package/dist/refresh.d.ts +12 -1
  102. package/dist/refresh.d.ts.map +1 -1
  103. package/dist/refresh.js +35 -22
  104. package/dist/replica.d.ts +6 -6
  105. package/dist/replica.d.ts.map +1 -1
  106. package/dist/replica.js +53 -39
  107. package/dist/room-draft.d.ts +8 -8
  108. package/dist/room-draft.d.ts.map +1 -1
  109. package/dist/room-draft.js +13 -22
  110. package/dist/rows.d.ts +4 -1
  111. package/dist/rows.d.ts.map +1 -1
  112. package/dist/rows.js +82 -39
  113. package/dist/save.d.ts +4 -3
  114. package/dist/save.d.ts.map +1 -1
  115. package/dist/save.js +127 -68
  116. package/dist/search.d.ts +3 -2
  117. package/dist/search.d.ts.map +1 -1
  118. package/dist/status.d.ts +2 -2
  119. package/dist/status.d.ts.map +1 -1
  120. package/dist/status.js +0 -8
  121. package/dist/store.d.ts +26 -2
  122. package/dist/store.d.ts.map +1 -1
  123. package/dist/store.js +206 -90
  124. package/dist/wire.d.ts +6 -15
  125. package/dist/wire.d.ts.map +1 -1
  126. package/dist/wire.js +14 -17
  127. package/package.json +14 -2
@@ -0,0 +1,57 @@
1
+ import { changeBatchIdentity } from './identity.js';
2
+ export function identities(mint = () => changeBatchIdentity()) {
3
+ const kept = new Map();
4
+ let used = new Map();
5
+ return {
6
+ of(intent) {
7
+ const one = used.get(intent) ?? kept.get(intent) ?? mint();
8
+ used.set(intent, one);
9
+ return one;
10
+ },
11
+ settle(answered) {
12
+ if (answered !== 'offline') {
13
+ for (const [intent, one] of used) {
14
+ if (answered === 'unanswered')
15
+ kept.set(intent, one);
16
+ else
17
+ kept.delete(intent);
18
+ }
19
+ }
20
+ used = new Map();
21
+ },
22
+ };
23
+ }
24
+ export function intentOf(name, about) {
25
+ return `${name}\u0000${JSON.stringify(about)}`;
26
+ }
27
+ export function attempts(mint) {
28
+ const numbers = identities(mint);
29
+ const waiting = new Map();
30
+ return {
31
+ begin(act) {
32
+ const intents = [];
33
+ return {
34
+ identity(intent) {
35
+ intents.push(intent);
36
+ return numbers.of(intent);
37
+ },
38
+ settle(answered, drop) {
39
+ numbers.settle(answered);
40
+ if (answered === 'refused' || answered === 'offline')
41
+ drop(act);
42
+ if (answered === 'offline')
43
+ return;
44
+ for (const intent of intents) {
45
+ const earlier = waiting.get(intent);
46
+ if (earlier !== undefined && earlier !== act)
47
+ drop(earlier);
48
+ if (answered === 'unanswered')
49
+ waiting.set(intent, act);
50
+ else
51
+ waiting.delete(intent);
52
+ }
53
+ },
54
+ };
55
+ },
56
+ };
57
+ }
@@ -1,10 +1,24 @@
1
1
  import type { ModelState } from './model.js';
2
- import type { Adapter, AdapterFailure, Authorization, DiscoveredRoom } from './adapter.js';
3
- import { type Staged } from './replica.js';
4
- import { type Unconfirmed } from './transfer.js';
5
- export type BootstrapOutcome = Staged | Unconfirmed | AdapterFailure;
6
- export declare function bootstrapRoom(adapter: Adapter, authorization: Authorization, room: DiscoveredRoom, models: {
2
+ import type { Adapter, AdapterFailure, Authorization, DiscoveredRoom, RetryableRefusal, RoomModels } from './adapter.js';
3
+ import { type ConfirmedLayer } from './replica.js';
4
+ import type { StagedLayer, TransferRecord } from './store.js';
5
+ import { type Refused, type Unconfirmed } from './transfer.js';
6
+ export type Bootstrapped = {
7
+ kind: 'staged';
8
+ confirmed: ConfirmedLayer;
9
+ stored: StagedLayer;
10
+ };
11
+ export type BootstrapOutcome = Bootstrapped | Refused | Unconfirmed | RetryableRefusal | AdapterFailure;
12
+ export type HeldModels = {
7
13
  collection: ModelState;
8
14
  selection: ModelState;
9
- }, continuing: () => boolean): Promise<BootstrapOutcome>;
15
+ };
16
+ export type Remodel = (models: RoomModels | undefined, held: HeldModels) => HeldModels;
17
+ export type Staging = {
18
+ held(locator: string): TransferRecord | null;
19
+ staged(record: TransferRecord): Promise<StagedLayer>;
20
+ stage(record: TransferRecord, page: StagedLayer): Promise<boolean>;
21
+ abandon(locator: string): Promise<void>;
22
+ };
23
+ export declare function bootstrapRoom(adapter: Adapter, authorization: Authorization, room: DiscoveredRoom, held: HeldModels, remodel: Remodel, continuing: () => boolean, staging: Staging): Promise<BootstrapOutcome>;
10
24
  //# sourceMappingURL=bootstrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,cAAc,EAGf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,WAAW,GAAG,cAAc,CAAC;AAErE,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,EACzD,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,gBAAgB,CAAC,CA+C3B"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EAEb,cAAc,EAEd,gBAAgB,EAChB,UAAU,EACX,MAAM,cAAc,CAAC;AAItB,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAiB,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAE9F,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,OAAO,GACP,WAAW,GACX,gBAAgB,GAChB,cAAc,CAAC;AAEnB,MAAM,MAAM,UAAU,GAAG;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,KAAK,UAAU,CAAC;AAEvF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC,CAAC;AAgCF,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,EACzB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,gBAAgB,CAAC,CA4E3B"}
package/dist/bootstrap.js CHANGED
@@ -1,56 +1,110 @@
1
1
  import { declaredAttachments } from './attachment.js';
2
+ import { transferIdentity } from './identity.js';
3
+ import { advancement } from './refresh.js';
2
4
  import { readStaged } from './replica.js';
3
5
  import { unconfirmed } from './transfer.js';
4
- export async function bootstrapRoom(adapter, authorization, room, models, continuing) {
5
- const first = await adapter.bootstrap(authorization, {
6
- locator: room.locator,
7
- selection: room.replica.selection,
8
- });
9
- if (first.kind !== 'bootstrap')
10
- return first;
11
- const roomVersion = first.roomVersion;
12
- const documents = { ...first.documents };
13
- const revisions = { ...first.revisions };
14
- const changes = { ...first.changes };
15
- const binaryTargets = new Set(first.binaryTargets);
16
- const attachments = [first.attachments ?? []];
17
- let pageToken = first.pageToken;
18
- while (pageToken !== undefined) {
6
+ const RESUMABLE = new Set([
7
+ 'transport-uncertainty',
8
+ 'retryable-refusal',
9
+ 'unconfirmed',
10
+ ]);
11
+ function pageLayer(page) {
12
+ return {
13
+ documents: page.documents,
14
+ revisions: page.revisions,
15
+ changes: page.changes,
16
+ written: Object.fromEntries(Object.keys(page.documents).map((path) => [path, page.roomVersion])),
17
+ binaryTargets: page.binaryTargets,
18
+ };
19
+ }
20
+ async function heldTransfer(staging, room) {
21
+ const record = staging.held(room.locator);
22
+ if (record === null)
23
+ return null;
24
+ if (record.selection === room.replica.selection) {
25
+ return { record, layer: await staging.staged(record) };
26
+ }
27
+ await staging.abandon(room.locator);
28
+ return null;
29
+ }
30
+ export async function bootstrapRoom(adapter, authorization, room, held, remodel, continuing, staging) {
31
+ const locator = room.locator;
32
+ const selection = room.replica.selection;
33
+ const kept = await heldTransfer(staging, room);
34
+ const documents = { ...kept?.layer.documents };
35
+ const revisions = { ...kept?.layer.revisions };
36
+ const changes = { ...kept?.layer.changes };
37
+ const written = { ...kept?.layer.written };
38
+ const binaryTargets = new Set(kept?.layer.binaryTargets);
39
+ let transfer = kept?.record ?? null;
40
+ while (transfer === null || transfer.pageToken !== null) {
19
41
  if (!continuing())
20
42
  return unconfirmed;
21
43
  const page = await adapter.bootstrap(authorization, {
22
- locator: room.locator,
23
- selection: room.replica.selection,
24
- pageToken,
44
+ locator,
45
+ selection,
46
+ ...(transfer?.pageToken == null ? {} : { pageToken: transfer.pageToken }),
25
47
  });
26
- if (page.kind !== 'bootstrap')
48
+ if (page.kind !== 'bootstrap') {
49
+ if (!RESUMABLE.has(page.kind))
50
+ await staging.abandon(locator);
27
51
  return page;
28
- if (page.roomVersion !== roomVersion)
52
+ }
53
+ transfer = {
54
+ locator,
55
+ transfer: transfer?.transfer ?? transferIdentity(),
56
+ selection,
57
+ from: transfer?.from ?? page.roomVersion,
58
+ last: page.roomVersion,
59
+ pageToken: page.pageToken ?? null,
60
+ models: remodel(page.models, transfer?.models ?? held),
61
+ attachments: [...(transfer?.attachments ?? []), page.attachments ?? []],
62
+ };
63
+ const staged = pageLayer(page);
64
+ if (!(await staging.stage(transfer, staged)))
29
65
  return unconfirmed;
30
- Object.assign(documents, page.documents);
31
- Object.assign(revisions, page.revisions);
32
- Object.assign(changes, page.changes);
33
- for (const target of page.binaryTargets)
66
+ Object.assign(documents, staged.documents);
67
+ Object.assign(revisions, staged.revisions);
68
+ Object.assign(changes, staged.changes);
69
+ Object.assign(written, staged.written);
70
+ for (const target of staged.binaryTargets)
34
71
  binaryTargets.add(target);
35
- attachments.push(page.attachments ?? []);
36
- pageToken = page.pageToken;
37
72
  }
38
- return readStaged({
39
- locator: room.locator,
73
+ const record = {
74
+ locator,
40
75
  name: room.name,
76
+ handle: room.handle,
41
77
  operations: room.operations,
42
78
  replica: room.replica,
43
- attachedModel: room.attachedModel,
44
- model: models.collection,
79
+ model: transfer.models.collection,
45
80
  typedSelection: room.typedSelection ?? null,
46
- selectionModel: models.selection,
81
+ selectionModel: transfer.models.selection,
47
82
  providerOwnedPaths: room.providerOwnedPaths,
48
- roomVersion,
83
+ roomVersion: transfer.from,
84
+ transfer: transfer.transfer,
49
85
  documents,
50
86
  binaryTargets: [...binaryTargets].sort(),
51
87
  revisions,
52
88
  changes,
53
- written: Object.fromEntries(Object.keys(documents).map((path) => [path, roomVersion])),
54
- attachments: declaredAttachments(attachments),
55
- });
89
+ written,
90
+ attachments: declaredAttachments(transfer.attachments),
91
+ };
92
+ const reconciled = transfer.last === transfer.from
93
+ ? { kind: 'still-current' }
94
+ : await advancement(adapter, authorization, record, remodel, continuing);
95
+ if (reconciled.kind === 'advanced' || reconciled.kind === 'still-current') {
96
+ const read = readStaged(reconciled.kind === 'advanced' ? reconciled.record : record);
97
+ if (read.kind === 'refused') {
98
+ await staging.abandon(locator);
99
+ return read;
100
+ }
101
+ return { kind: 'staged', confirmed: read.confirmed, stored: record };
102
+ }
103
+ if (reconciled.kind === 'beyond-horizon') {
104
+ await staging.abandon(locator);
105
+ return unconfirmed;
106
+ }
107
+ if (!RESUMABLE.has(reconciled.kind))
108
+ await staging.abandon(locator);
109
+ return reconciled;
56
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"change-set.d.ts","sourceRoot":"","sources":["../src/change-set.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAU,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,GAAG,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,MAAM,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAqBF,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACtB,KAAK,EAAE,OAAO,GAAG,IAAI,EACrB,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,SAAS,CAiDX;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,SAAS,CAUX;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAUrE"}
1
+ {"version":3,"file":"change-set.d.ts","sourceRoot":"","sources":["../src/change-set.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAwB,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,GAAG,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,MAAM,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAqBF,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACtB,KAAK,EAAE,OAAO,GAAG,IAAI,EACrB,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,SAAS,CAqDX;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,SAAS,CAUX;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAUrE"}
@@ -1,15 +1,17 @@
1
+ import { passingDocument } from './collection.js';
1
2
  import { sameChange } from './overlay.js';
2
3
  import { beneath } from './paths.js';
3
4
  import { compositionOf, sameMembership } from './replica.js';
4
- import { rowsOf } from './rows.js';
5
+ import { markdownPath, rowsOf } from './rows.js';
5
6
  function rowsAt(locator, replica, path) {
6
7
  if (replica === null)
7
8
  return [];
8
- const document = replica.visible.collection.documents[path];
9
- if (document === undefined && !replica.visible.binaryTargets.includes(path)) {
9
+ const visible = replica.visible;
10
+ const document = markdownPath(path) ? passingDocument(visible.collection, path) : null;
11
+ const held = visible.documents[path] !== undefined && document !== undefined;
12
+ if (!held && !visible.binaryTargets.includes(path))
10
13
  return [];
11
- }
12
- return rowsOf(locator, path, document ?? null, compositionOf(replica.confirmed.record), replica.visible.changes[path] ?? null);
14
+ return rowsOf(locator, path, document ?? null, compositionOf(replica.confirmed.record), visible.changes[path] ?? null);
13
15
  }
14
16
  function modelShape(model) {
15
17
  return model.status === 'unavailable' ? 'unavailable' : JSON.stringify(model.types);
@@ -45,8 +47,12 @@ export function changeSet(locator, before, after, changed = {}) {
45
47
  documents.push({
46
48
  locator,
47
49
  path,
48
- before: rowsAt(locator, before, path),
49
- after: rowsAt(locator, after, path),
50
+ get before() {
51
+ return rowsAt(locator, before, path);
52
+ },
53
+ get after() {
54
+ return rowsAt(locator, after, path);
55
+ },
50
56
  });
51
57
  }
52
58
  return {
package/dist/change.d.ts CHANGED
@@ -51,6 +51,10 @@ export type Precondition = {
51
51
  readonly kind: 'revision';
52
52
  readonly path: string;
53
53
  readonly revision: string;
54
+ } | {
55
+ readonly kind: 'content';
56
+ readonly path: string;
57
+ readonly content: string;
54
58
  } | {
55
59
  readonly kind: 'present';
56
60
  readonly path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../src/change.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../src/change.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type Answered } from '../attempt.js';
2
+ import { type CallResult } from '../outcome.js';
3
+ import type { Expected } from './overlay.js';
4
+ export type ChatResult = CallResult | {
5
+ readonly kind: 'offline';
6
+ };
7
+ export type ChatOutcome = {
8
+ readonly state: 'sending';
9
+ } | {
10
+ readonly state: 'offline';
11
+ } | {
12
+ readonly state: 'failed';
13
+ readonly result: CallResult;
14
+ };
15
+ export declare function accepted(result: ChatResult): result is Extract<CallResult, {
16
+ readonly kind: 'action';
17
+ }>;
18
+ export declare function unanswered(result: ChatResult): boolean;
19
+ export declare function outcomeOf(result: ChatResult): ChatOutcome | null;
20
+ export declare function answeredOf(result: ChatResult): Answered;
21
+ export type Sender = {
22
+ carried(name: string, about: unknown, sending: (operation: string) => Promise<CallResult>): Promise<ChatResult>;
23
+ expect(expected: Expected): void;
24
+ draw(expected: Expected): void;
25
+ };
26
+ type Senders = {
27
+ readonly online: boolean;
28
+ identity(intent: string): string;
29
+ expect(expected: Expected): void;
30
+ draw(expected: Expected): void;
31
+ };
32
+ export declare function sender({ online, identity, expect, draw }: Senders): Sender;
33
+ export {};
34
+ //# sourceMappingURL=acts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acts.d.ts","sourceRoot":"","sources":["../../src/chat/acts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAE9D,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,GACjB,MAAM,IAAI,OAAO,CAAC,UAAU,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAE5D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEtD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,CAGhE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAIvD;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,GAClD,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,GAAG,MAAM,CAa1E"}
@@ -0,0 +1,36 @@
1
+ import { intentOf } from '../attempt.js';
2
+ import { UNCERTAIN } from '../outcome.js';
3
+ export function accepted(result) {
4
+ return result.kind === 'action';
5
+ }
6
+ export function unanswered(result) {
7
+ return result.kind === 'transport-uncertainty';
8
+ }
9
+ export function outcomeOf(result) {
10
+ if (accepted(result))
11
+ return null;
12
+ return result.kind === 'offline' ? { state: 'offline' } : { state: 'failed', result };
13
+ }
14
+ export function answeredOf(result) {
15
+ if (accepted(result))
16
+ return 'accepted';
17
+ if (result.kind === 'offline')
18
+ return 'offline';
19
+ return unanswered(result) ? 'unanswered' : 'refused';
20
+ }
21
+ export function sender({ online, identity, expect, draw }) {
22
+ return {
23
+ async carried(name, about, sending) {
24
+ if (!online)
25
+ return { kind: 'offline' };
26
+ try {
27
+ return await sending(identity(intentOf(name, about)));
28
+ }
29
+ catch {
30
+ return UNCERTAIN;
31
+ }
32
+ },
33
+ expect,
34
+ draw,
35
+ };
36
+ }
@@ -0,0 +1,21 @@
1
+ import type { ThreadMessageLike } from '@assistant-ui/react';
2
+ import type { TurnContext } from '../adapter.js';
3
+ import type { ConversationView } from '../conversation.js';
4
+ import { type Part } from './parts.js';
5
+ type Entry = ConversationView['messages'][number];
6
+ export type Said = {
7
+ readonly turn: string;
8
+ readonly user: boolean;
9
+ readonly text: string;
10
+ readonly parts: readonly Part[];
11
+ readonly context: TurnContext | null;
12
+ readonly failure: string | null;
13
+ readonly undelivered: boolean;
14
+ readonly files: readonly string[];
15
+ };
16
+ export declare function saidOf(entry: Entry): Said;
17
+ export declare function askedBefore(view: ConversationView | null, id: string | null): string | null;
18
+ export declare function chatMessages(view: ConversationView | null): ThreadMessageLike[];
19
+ export declare function contextOf(view: ConversationView | null): TurnContext | null;
20
+ export {};
21
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/chat/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAA0D,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAO/F,KAAK,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAYzC;AAkED,wBAAgB,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAO3F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,GAAG,iBAAiB,EAAE,CAsD/E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAS3E"}
@@ -0,0 +1,151 @@
1
+ import { contextIn, jobOf, partsOf, stillRunning } from './parts.js';
2
+ import { list, record, text } from './read.js';
3
+ export function saidOf(entry) {
4
+ const message = record(entry.message);
5
+ return {
6
+ turn: text(message, 'turn_id') ?? entry.turn,
7
+ user: text(message, 'role') === 'user',
8
+ text: text(message, 'text') ?? '',
9
+ parts: partsOf(list(message, 'parts')),
10
+ context: contextIn(message.context),
11
+ failure: text(message, 'failure'),
12
+ undelivered: message.telegram_undelivered === true,
13
+ files: list(message, 'files').flatMap((one) => text(record(one), 'name') ?? []),
14
+ };
15
+ }
16
+ function markerArgs(part) {
17
+ if (part.marker !== 'job')
18
+ return { marker: part.marker, text: part.text };
19
+ const job = jobOf(part.text);
20
+ return {
21
+ marker: part.marker,
22
+ text: part.text,
23
+ job: job.kind,
24
+ label: job.label,
25
+ state: job.state,
26
+ next: job.next ?? '',
27
+ };
28
+ }
29
+ function contentOf(id, parts, live) {
30
+ return parts.map((part, at) => {
31
+ const done = !live || at < parts.length - 1;
32
+ const call = (toolName, args) => ({
33
+ type: 'tool-call',
34
+ toolCallId: `${id}:${at}`,
35
+ toolName,
36
+ args,
37
+ result: done ? null : undefined,
38
+ });
39
+ switch (part.type) {
40
+ case 'text':
41
+ return { type: 'text', text: part.text };
42
+ case 'reasoning':
43
+ return { type: 'reasoning', text: part.text };
44
+ case 'commands':
45
+ return call('commands', { count: part.count });
46
+ case 'subagent':
47
+ return {
48
+ ...call('subagent', { description: part.description }),
49
+ result: part.done ? part.result : undefined,
50
+ };
51
+ case 'message':
52
+ return call('message', { command: part.command, target: part.target ?? '' });
53
+ case 'marker':
54
+ return call('marker', markerArgs(part));
55
+ case 'plan':
56
+ return {
57
+ ...call('plan', {}),
58
+ args: { steps: part.steps.map((step) => ({ ...step })) },
59
+ };
60
+ case 'image':
61
+ return { type: 'file', filename: part.name, mimeType: part.mediaType, data: '' };
62
+ }
63
+ });
64
+ }
65
+ function leftRunning(view) {
66
+ if (view.process?.running === false)
67
+ return new Map();
68
+ const turns = view.messages.flatMap((entry) => {
69
+ const one = saidOf(entry);
70
+ return one.user ? [] : [{ turn: one.turn, parts: one.parts, ended: true }];
71
+ });
72
+ return stillRunning(view.turn === null
73
+ ? turns
74
+ : [...turns, { turn: view.turn.turn, parts: partsOf(view.turn.parts), ended: false }]);
75
+ }
76
+ export function askedBefore(view, id) {
77
+ const said = (view?.messages ?? []).map((entry) => ({ ...saidOf(entry), id: entry.identity }));
78
+ const asked = said
79
+ .slice(0, said.findIndex((one) => one.id === id) + 1)
80
+ .reverse()
81
+ .find((one) => one.user);
82
+ return asked === undefined || asked.text === '' ? null : asked.text;
83
+ }
84
+ export function chatMessages(view) {
85
+ if (view === null)
86
+ return [];
87
+ const lasting = leftRunning(view);
88
+ const said = view.messages.map((entry, at) => {
89
+ const one = saidOf(entry);
90
+ const custom = { undelivered: one.undelivered };
91
+ if (one.user) {
92
+ return {
93
+ id: entry.identity,
94
+ role: 'user',
95
+ content: [{ type: 'text', text: one.text }],
96
+ attachments: one.files.map((name, at) => ({
97
+ id: `${entry.identity}:${at}`,
98
+ type: 'file',
99
+ name,
100
+ status: { type: 'complete' },
101
+ content: [],
102
+ })),
103
+ metadata: { custom },
104
+ };
105
+ }
106
+ const failed = one.failure === null
107
+ ? undefined
108
+ : { type: 'incomplete', reason: 'error', error: one.failure };
109
+ return {
110
+ id: entry.identity,
111
+ role: 'assistant',
112
+ content: contentOf(entry.identity, one.parts, false),
113
+ status: failed,
114
+ metadata: {
115
+ custom: {
116
+ ...custom,
117
+ lasting: lasting.get(one.turn) ?? [],
118
+ again: failed !== undefined &&
119
+ view.turn === null &&
120
+ at === view.messages.length - 1 &&
121
+ askedBefore(view, view.messages[at - 1]?.identity ?? null) !== null,
122
+ },
123
+ },
124
+ };
125
+ });
126
+ if (view.turn === null)
127
+ return said;
128
+ const running = `running:${view.turn.turn}`;
129
+ return [
130
+ ...said,
131
+ {
132
+ id: running,
133
+ role: 'assistant',
134
+ content: contentOf(running, partsOf(view.turn.parts), true),
135
+ status: { type: 'running' },
136
+ },
137
+ ];
138
+ }
139
+ export function contextOf(view) {
140
+ if (view === null)
141
+ return null;
142
+ const running = view.turn === null ? null : contextIn(view.turn.context);
143
+ if (running !== null)
144
+ return running;
145
+ for (const entry of [...view.messages].reverse()) {
146
+ const held = contextIn(record(entry.message).context);
147
+ if (held !== null)
148
+ return held;
149
+ }
150
+ return null;
151
+ }
@@ -0,0 +1,31 @@
1
+ import type { ChatDraft, ConversationEntry, ConversationView } from '../conversation.js';
2
+ import { type ExpectedOf, type Expecting } from '../expectation.js';
3
+ type Entries = readonly ConversationEntry[];
4
+ export type Expectation = {
5
+ readonly key: string;
6
+ readonly view: 'conversation';
7
+ draw(held: ConversationView): ConversationView;
8
+ shown(held: ConversationView): boolean;
9
+ } | {
10
+ readonly key: string;
11
+ readonly view: 'conversations';
12
+ draw(held: Entries): Entries;
13
+ shown(held: Entries): boolean;
14
+ };
15
+ export type Expected = ExpectedOf<Expectation>;
16
+ export type Overlay = Omit<Expecting<Expectation>, 'expect' | 'heard' | 'drawn'> & {
17
+ expect(act: number, expected: Expected): void;
18
+ heard(held: ConversationView): void;
19
+ heardList(held: Entries): void;
20
+ conversation(held: ConversationView): ConversationView;
21
+ conversations(held: Entries): Entries;
22
+ };
23
+ export declare function overlay(): Overlay;
24
+ export declare function sentMessage(key: string, into: readonly string[], said: ChatDraft, turn: string | null): Expectation;
25
+ export declare function optionChosen(conversation: string, option: string, value: string): Expectation;
26
+ export declare function questionAnswered(conversation: string, interaction: string): Expectation;
27
+ export declare function conversationListed(entry: ConversationEntry): Expectation;
28
+ export declare function conversationChanged(conversation: string, changes: Partial<Pick<ConversationEntry, 'name' | 'finished'>>, shown: (entry: ConversationEntry) => boolean): Expectation;
29
+ export declare function conversationGone(conversation: string): Expectation;
30
+ export {};
31
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/chat/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG/E,KAAK,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAAC;AAE5C,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CAAC;IAC/C,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC;CACxC,GACD;IACE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CAC/B,CAAC;AAEN,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC,GAAG;IACjF,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9C,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CAAC;IACvD,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CACvC,CAAC;AAEF,wBAAgB,OAAO,IAAI,OAAO,CAiBjC;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,WAAW,CA2Bb;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAkB7F;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAWvF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,CAQxE;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,EAC9D,KAAK,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,GAC3C,WAAW,CAQb;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,CAQlE"}