@acme-engine/core 0.1.0

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 (137) hide show
  1. package/dist/common.d.ts +40 -0
  2. package/dist/common.d.ts.map +1 -0
  3. package/dist/common.js +2 -0
  4. package/dist/common.js.map +1 -0
  5. package/dist/contracts.d.ts +65 -0
  6. package/dist/contracts.d.ts.map +1 -0
  7. package/dist/contracts.js +2 -0
  8. package/dist/contracts.js.map +1 -0
  9. package/dist/errors.d.ts +24 -0
  10. package/dist/errors.d.ts.map +1 -0
  11. package/dist/errors.js +20 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/evaluation.d.ts +14 -0
  14. package/dist/evaluation.d.ts.map +1 -0
  15. package/dist/evaluation.js +2 -0
  16. package/dist/evaluation.js.map +1 -0
  17. package/dist/execution-engine.d.ts +30 -0
  18. package/dist/execution-engine.d.ts.map +1 -0
  19. package/dist/execution-engine.js +885 -0
  20. package/dist/execution-engine.js.map +1 -0
  21. package/dist/execution-identity.d.ts +35 -0
  22. package/dist/execution-identity.d.ts.map +1 -0
  23. package/dist/execution-identity.js +177 -0
  24. package/dist/execution-identity.js.map +1 -0
  25. package/dist/execution-status.d.ts +2 -0
  26. package/dist/execution-status.d.ts.map +1 -0
  27. package/dist/execution-status.js +2 -0
  28. package/dist/execution-status.js.map +1 -0
  29. package/dist/execution-types.d.ts +58 -0
  30. package/dist/execution-types.d.ts.map +1 -0
  31. package/dist/execution-types.js +2 -0
  32. package/dist/execution-types.js.map +1 -0
  33. package/dist/hashing.d.ts +6 -0
  34. package/dist/hashing.d.ts.map +1 -0
  35. package/dist/hashing.js +73 -0
  36. package/dist/hashing.js.map +1 -0
  37. package/dist/index.d.ts +34 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +33 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/memory-engine.d.ts +13 -0
  42. package/dist/memory-engine.d.ts.map +1 -0
  43. package/dist/memory-engine.js +591 -0
  44. package/dist/memory-engine.js.map +1 -0
  45. package/dist/memory.d.ts +151 -0
  46. package/dist/memory.d.ts.map +1 -0
  47. package/dist/memory.js +2 -0
  48. package/dist/memory.js.map +1 -0
  49. package/dist/model-call-usage.d.ts +40 -0
  50. package/dist/model-call-usage.d.ts.map +1 -0
  51. package/dist/model-call-usage.js +0 -0
  52. package/dist/model-call-usage.js.map +1 -0
  53. package/dist/model-execution-engine.d.ts +16 -0
  54. package/dist/model-execution-engine.d.ts.map +1 -0
  55. package/dist/model-execution-engine.js +598 -0
  56. package/dist/model-execution-engine.js.map +1 -0
  57. package/dist/model-execution-identity.d.ts +16 -0
  58. package/dist/model-execution-identity.d.ts.map +1 -0
  59. package/dist/model-execution-identity.js +84 -0
  60. package/dist/model-execution-identity.js.map +1 -0
  61. package/dist/model-execution-types.d.ts +66 -0
  62. package/dist/model-execution-types.d.ts.map +1 -0
  63. package/dist/model-execution-types.js +8 -0
  64. package/dist/model-execution-types.js.map +1 -0
  65. package/dist/model-gateway-router.d.ts +11 -0
  66. package/dist/model-gateway-router.d.ts.map +1 -0
  67. package/dist/model-gateway-router.js +69 -0
  68. package/dist/model-gateway-router.js.map +1 -0
  69. package/dist/model-request-hash.d.ts +5 -0
  70. package/dist/model-request-hash.d.ts.map +1 -0
  71. package/dist/model-request-hash.js +11 -0
  72. package/dist/model-request-hash.js.map +1 -0
  73. package/dist/model-response-hash.d.ts +5 -0
  74. package/dist/model-response-hash.d.ts.map +1 -0
  75. package/dist/model-response-hash.js +11 -0
  76. package/dist/model-response-hash.js.map +1 -0
  77. package/dist/model-validation.d.ts +11 -0
  78. package/dist/model-validation.d.ts.map +1 -0
  79. package/dist/model-validation.js +580 -0
  80. package/dist/model-validation.js.map +1 -0
  81. package/dist/model.d.ts +125 -0
  82. package/dist/model.d.ts.map +1 -0
  83. package/dist/model.js +4 -0
  84. package/dist/model.js.map +1 -0
  85. package/dist/modules.d.ts +83 -0
  86. package/dist/modules.d.ts.map +1 -0
  87. package/dist/modules.js +7 -0
  88. package/dist/modules.js.map +1 -0
  89. package/dist/outbox.d.ts +88 -0
  90. package/dist/outbox.d.ts.map +1 -0
  91. package/dist/outbox.js +180 -0
  92. package/dist/outbox.js.map +1 -0
  93. package/dist/payload-encryptor.d.ts +92 -0
  94. package/dist/payload-encryptor.d.ts.map +1 -0
  95. package/dist/payload-encryptor.js +173 -0
  96. package/dist/payload-encryptor.js.map +1 -0
  97. package/dist/registries.d.ts +5 -0
  98. package/dist/registries.d.ts.map +1 -0
  99. package/dist/registries.js +159 -0
  100. package/dist/registries.js.map +1 -0
  101. package/dist/repository-digest.d.ts +5 -0
  102. package/dist/repository-digest.d.ts.map +1 -0
  103. package/dist/repository-digest.js +25 -0
  104. package/dist/repository-digest.js.map +1 -0
  105. package/dist/repository-model-call.d.ts +43 -0
  106. package/dist/repository-model-call.d.ts.map +1 -0
  107. package/dist/repository-model-call.js +2 -0
  108. package/dist/repository-model-call.js.map +1 -0
  109. package/dist/repository-model-execution.d.ts +49 -0
  110. package/dist/repository-model-execution.d.ts.map +1 -0
  111. package/dist/repository-model-execution.js +2 -0
  112. package/dist/repository-model-execution.js.map +1 -0
  113. package/dist/repository.d.ts +260 -0
  114. package/dist/repository.d.ts.map +1 -0
  115. package/dist/repository.js +2 -0
  116. package/dist/repository.js.map +1 -0
  117. package/dist/response-pipeline.d.ts +3 -0
  118. package/dist/response-pipeline.d.ts.map +1 -0
  119. package/dist/response-pipeline.js +132 -0
  120. package/dist/response-pipeline.js.map +1 -0
  121. package/dist/state-engine.d.ts +19 -0
  122. package/dist/state-engine.d.ts.map +1 -0
  123. package/dist/state-engine.js +272 -0
  124. package/dist/state-engine.js.map +1 -0
  125. package/dist/state-projection.d.ts +5 -0
  126. package/dist/state-projection.d.ts.map +1 -0
  127. package/dist/state-projection.js +145 -0
  128. package/dist/state-projection.js.map +1 -0
  129. package/dist/state.d.ts +41 -0
  130. package/dist/state.d.ts.map +1 -0
  131. package/dist/state.js +2 -0
  132. package/dist/state.js.map +1 -0
  133. package/dist/stranded-execution.d.ts +59 -0
  134. package/dist/stranded-execution.d.ts.map +1 -0
  135. package/dist/stranded-execution.js +235 -0
  136. package/dist/stranded-execution.js.map +1 -0
  137. package/package.json +36 -0
@@ -0,0 +1,272 @@
1
+ import { AcmeError } from './errors.js';
2
+ import { nodeHashing } from './hashing.js';
3
+ export const ACME_TRANSITION_ID_ALGORITHM = 'acme-transition-id-1';
4
+ function invalid(code, message, details, cause) {
5
+ const data = details === undefined
6
+ ? {
7
+ code,
8
+ message,
9
+ stage: 'preparing-commit',
10
+ retryable: false,
11
+ }
12
+ : {
13
+ code,
14
+ message,
15
+ stage: 'preparing-commit',
16
+ retryable: false,
17
+ details,
18
+ };
19
+ return cause === undefined
20
+ ? new AcmeError(data)
21
+ : new AcmeError(data, { cause });
22
+ }
23
+ function requireNonEmpty(value, field) {
24
+ if (value.length === 0) {
25
+ throw invalid('INVALID_REQUEST', `${field} must be non-empty.`, {
26
+ field,
27
+ });
28
+ }
29
+ }
30
+ function cloneAndFreeze(canonical, errorCode, phase) {
31
+ let clone;
32
+ try {
33
+ clone = JSON.parse(canonical);
34
+ }
35
+ catch (error) {
36
+ throw invalid(errorCode, `Could not clone ${phase} as JSON.`, { phase }, error);
37
+ }
38
+ return deepFreeze(clone);
39
+ }
40
+ function deepFreeze(value) {
41
+ if (value !== null && typeof value === 'object') {
42
+ for (const child of Object.values(value)) {
43
+ deepFreeze(child);
44
+ }
45
+ Object.freeze(value);
46
+ }
47
+ return value;
48
+ }
49
+ function schemaIssues(issues) {
50
+ return issues.map(({ code, message, path }) => ({
51
+ code,
52
+ message,
53
+ path: path.map((part) => (typeof part === 'symbol' ? String(part) : part)),
54
+ }));
55
+ }
56
+ function validateJson(schema, input, hashing, errorCode, phase) {
57
+ let result;
58
+ try {
59
+ result = schema.safeParse(input);
60
+ }
61
+ catch (error) {
62
+ throw invalid(errorCode, `Schema execution failed for ${phase}.`, { phase }, error);
63
+ }
64
+ if (!result.success) {
65
+ throw invalid(errorCode, `Schema validation failed for ${phase}.`, {
66
+ phase,
67
+ issues: schemaIssues(result.error.issues),
68
+ });
69
+ }
70
+ let inputCanonical;
71
+ let outputCanonical;
72
+ try {
73
+ inputCanonical = hashing.canonicalJson(input);
74
+ outputCanonical = hashing.canonicalJson(result.data);
75
+ }
76
+ catch (error) {
77
+ throw invalid(errorCode, `${phase} must be a JSON value.`, { phase }, error);
78
+ }
79
+ if (inputCanonical !== outputCanonical) {
80
+ throw invalid(errorCode, `Schema must not coerce or transform ${phase}.`, {
81
+ phase,
82
+ });
83
+ }
84
+ return {
85
+ canonical: outputCanonical,
86
+ value: cloneAndFreeze(outputCanonical, errorCode, phase),
87
+ };
88
+ }
89
+ function safeDomainIssues(issues) {
90
+ return issues.map((issue) => ({
91
+ code: typeof issue === 'object' &&
92
+ issue !== null &&
93
+ 'code' in issue &&
94
+ typeof issue.code === 'string'
95
+ ? issue.code
96
+ : 'INVALID_DOMAIN_ISSUE',
97
+ message: typeof issue === 'object' &&
98
+ issue !== null &&
99
+ 'message' in issue &&
100
+ typeof issue.message === 'string'
101
+ ? issue.message
102
+ : 'Domain invariant failed.',
103
+ path: typeof issue === 'object' &&
104
+ issue !== null &&
105
+ 'path' in issue &&
106
+ Array.isArray(issue.path)
107
+ ? issue.path
108
+ .filter((part) => typeof part === 'string' || typeof part === 'number')
109
+ .map((part) => part)
110
+ : [],
111
+ }));
112
+ }
113
+ function actualRevision(current) {
114
+ if (current === null) {
115
+ return 0;
116
+ }
117
+ if (!Number.isInteger(current.revision) || current.revision < 1) {
118
+ throw invalid('PERSISTENCE_CORRUPTION', 'Current state revision must be a positive integer.', { revision: current.revision });
119
+ }
120
+ return current.revision;
121
+ }
122
+ export function deriveTransitionId(input, hashing = nodeHashing) {
123
+ requireNonEmpty(input.executionId, 'executionId');
124
+ requireNonEmpty(input.operationKey, 'operationKey');
125
+ requireNonEmpty(input.namespace, 'namespace');
126
+ requireNonEmpty(input.entityId, 'entityId');
127
+ const identity = {
128
+ algorithm: ACME_TRANSITION_ID_ALGORITHM,
129
+ executionId: input.executionId,
130
+ operationKey: input.operationKey,
131
+ namespace: input.namespace,
132
+ entityId: input.entityId,
133
+ };
134
+ return `transition_${hashing.sha256(hashing.canonicalJson(identity))}`;
135
+ }
136
+ class PureStateEngine {
137
+ #hashing;
138
+ constructor(options) {
139
+ this.#hashing = options.hashing ?? nodeHashing;
140
+ }
141
+ prepare(module, current, expectedRevision, delta, context) {
142
+ requireNonEmpty(context.entityId, 'entityId');
143
+ requireNonEmpty(context.executionId, 'executionId');
144
+ requireNonEmpty(context.operationKey, 'operationKey');
145
+ requireNonEmpty(module.namespace, 'namespace');
146
+ if (!Number.isInteger(expectedRevision) || expectedRevision < 0) {
147
+ throw invalid('INVALID_REQUEST', 'Expected revision must be a non-negative integer.', { expectedRevision });
148
+ }
149
+ const fromRevision = actualRevision(current);
150
+ if (expectedRevision !== fromRevision) {
151
+ throw invalid('CONFLICT_STATE_REVISION', 'Expected state revision does not match current revision.', {
152
+ expectedRevision,
153
+ currentRevision: fromRevision,
154
+ });
155
+ }
156
+ let previous = null;
157
+ if (current !== null) {
158
+ if (current.entityId !== context.entityId ||
159
+ current.namespace !== module.namespace) {
160
+ throw invalid('INVALID_REQUEST', 'Current state does not match the requested state identity.', {
161
+ currentEntityId: current.entityId,
162
+ currentNamespace: current.namespace,
163
+ entityId: context.entityId,
164
+ namespace: module.namespace,
165
+ });
166
+ }
167
+ if (current.schemaVersion !== module.stateSchemaVersion) {
168
+ throw invalid('INVALID_REQUEST', 'Current state schema version is not supported by the module.', {
169
+ currentSchemaVersion: current.schemaVersion,
170
+ moduleSchemaVersion: module.stateSchemaVersion,
171
+ });
172
+ }
173
+ previous = validateJson(module.stateSchema, current.value, this.#hashing, 'PERSISTENCE_CORRUPTION', 'current state');
174
+ const computedPreviousHash = this.#hashing.sha256(previous.canonical);
175
+ if (computedPreviousHash !== current.valueHash) {
176
+ throw invalid('PERSISTENCE_CORRUPTION', 'Current state hash does not match its value.', {
177
+ recordedHash: current.valueHash,
178
+ computedHash: computedPreviousHash,
179
+ });
180
+ }
181
+ }
182
+ if (delta === undefined) {
183
+ return null;
184
+ }
185
+ if (delta.schemaVersion !== module.deltaSchemaVersion) {
186
+ throw invalid('DOMAIN_INVALID_RESULT', 'State delta schema version does not match the module.', {
187
+ deltaSchemaVersion: delta.schemaVersion,
188
+ moduleDeltaSchemaVersion: module.deltaSchemaVersion,
189
+ });
190
+ }
191
+ let base;
192
+ if (previous === null) {
193
+ let initial;
194
+ try {
195
+ initial = module.initialState({
196
+ entityId: context.entityId,
197
+ now: context.now,
198
+ });
199
+ }
200
+ catch (error) {
201
+ throw invalid('DOMAIN_INVALID_RESULT', 'Domain initial-state policy failed.', { phase: 'initial state' }, error);
202
+ }
203
+ base = validateJson(module.stateSchema, initial, this.#hashing, 'DOMAIN_INVALID_RESULT', 'initial state');
204
+ }
205
+ else {
206
+ base = previous;
207
+ }
208
+ const validatedDelta = validateJson(module.deltaSchema, delta.value, this.#hashing, 'DOMAIN_INVALID_RESULT', 'state delta');
209
+ let reduced;
210
+ try {
211
+ reduced = module.reduce(base.value, validatedDelta.value);
212
+ }
213
+ catch (error) {
214
+ throw invalid('DOMAIN_INVALID_RESULT', 'Domain state reducer failed.', { phase: 'reducer' }, error);
215
+ }
216
+ const next = validateJson(module.stateSchema, reduced, this.#hashing, 'DOMAIN_INVALID_RESULT', 'next state');
217
+ let domainIssues;
218
+ try {
219
+ domainIssues = module.invariants(next.value, previous === null ? null : previous.value);
220
+ }
221
+ catch (error) {
222
+ throw invalid('DOMAIN_INVALID_RESULT', 'Domain state invariants failed.', { phase: 'invariants' }, error);
223
+ }
224
+ if (!Array.isArray(domainIssues)) {
225
+ throw invalid('DOMAIN_INVALID_RESULT', 'Domain invariants must return an issue array.', { phase: 'invariants' });
226
+ }
227
+ if (domainIssues.length > 0) {
228
+ throw invalid('DOMAIN_INVALID_RESULT', 'Domain state invariants rejected the next state.', {
229
+ phase: 'invariants',
230
+ issues: safeDomainIssues(domainIssues),
231
+ });
232
+ }
233
+ const nextRevision = fromRevision + 1;
234
+ const nextHash = this.#hashing.sha256(next.canonical);
235
+ const transitionId = deriveTransitionId({
236
+ executionId: context.executionId,
237
+ operationKey: context.operationKey,
238
+ namespace: module.namespace,
239
+ entityId: context.entityId,
240
+ }, this.#hashing);
241
+ return Object.freeze({
242
+ snapshot: Object.freeze({
243
+ entityId: context.entityId,
244
+ namespace: module.namespace,
245
+ schemaVersion: module.stateSchemaVersion,
246
+ revision: nextRevision,
247
+ value: next.value,
248
+ valueHash: nextHash,
249
+ createdAt: context.now,
250
+ executionId: context.executionId,
251
+ }),
252
+ transition: Object.freeze({
253
+ transitionId,
254
+ operationKey: context.operationKey,
255
+ entityId: context.entityId,
256
+ namespace: module.namespace,
257
+ fromRevision,
258
+ toRevision: nextRevision,
259
+ deltaSchemaVersion: module.deltaSchemaVersion,
260
+ delta: validatedDelta.value,
261
+ previousHash: current?.valueHash ?? null,
262
+ nextHash,
263
+ executionId: context.executionId,
264
+ createdAt: context.now,
265
+ }),
266
+ });
267
+ }
268
+ }
269
+ export function createStateEngine(options = {}) {
270
+ return new PureStateEngine(options);
271
+ }
272
+ //# sourceMappingURL=state-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-engine.js","sourceRoot":"","sources":["../src/state-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Hashing } from './common.js';
2
+ import type { PreparedMemory } from './memory.js';
3
+ import type { ModuleResult, StateProjectionInput } from './modules.js';
4
+ export declare function buildStateProjectionInput<TDelta>(result: ModuleResult<TDelta>, preparedMemory: PreparedMemory, hashing?: Hashing): StateProjectionInput<TDelta>;
5
+ //# sourceMappingURL=state-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-projection.d.ts","sourceRoot":"","sources":["../src/state-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,aAAa,CAAC;AAGtD,OAAO,KAAK,EAIV,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAErB,MAAM,cAAc,CAAC;AAgKtB,wBAAgB,yBAAyB,CAAC,MAAM,EAC9C,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAC5B,cAAc,EAAE,cAAc,EAC9B,OAAO,GAAE,OAAqB,GAC7B,oBAAoB,CAAC,MAAM,CAAC,CAgD9B"}
@@ -0,0 +1,145 @@
1
+ import { AcmeError } from './errors.js';
2
+ import { nodeHashing } from './hashing.js';
3
+ function invalid(message, details, cause) {
4
+ const data = details === undefined
5
+ ? {
6
+ code: 'DOMAIN_INVALID_RESULT',
7
+ message,
8
+ stage: 'preparing-commit',
9
+ retryable: false,
10
+ }
11
+ : {
12
+ code: 'DOMAIN_INVALID_RESULT',
13
+ message,
14
+ stage: 'preparing-commit',
15
+ retryable: false,
16
+ details,
17
+ };
18
+ return cause === undefined
19
+ ? new AcmeError(data)
20
+ : new AcmeError(data, { cause });
21
+ }
22
+ function deepFreeze(value) {
23
+ if (value !== null && typeof value === 'object') {
24
+ for (const child of Object.values(value)) {
25
+ deepFreeze(child);
26
+ }
27
+ Object.freeze(value);
28
+ }
29
+ return value;
30
+ }
31
+ function cloneProjection(value, hashing) {
32
+ let canonical;
33
+ try {
34
+ canonical = hashing.canonicalJson(value);
35
+ }
36
+ catch (error) {
37
+ throw invalid('State projection input must contain only canonical JSON values.', undefined, error);
38
+ }
39
+ try {
40
+ return deepFreeze(JSON.parse(canonical));
41
+ }
42
+ catch (error) {
43
+ throw invalid('State projection input could not be cloned.', undefined, error);
44
+ }
45
+ }
46
+ function requireKey(value, kind, index) {
47
+ if (value === null ||
48
+ typeof value !== 'object' ||
49
+ !('key' in value || 'candidateKey' in value)) {
50
+ throw invalid(`Memory ${kind} ${index} is malformed.`, { kind, index });
51
+ }
52
+ const key = kind === 'candidate'
53
+ ? value.key
54
+ : value.candidateKey;
55
+ if (typeof key !== 'string' || key.length === 0) {
56
+ throw invalid(`Memory ${kind} ${index} key must be non-empty.`, {
57
+ kind,
58
+ index,
59
+ });
60
+ }
61
+ return key;
62
+ }
63
+ function indexCandidates(candidates) {
64
+ const indexed = new Map();
65
+ for (const [index, candidate] of candidates.entries()) {
66
+ const key = requireKey(candidate, 'candidate', index);
67
+ if (indexed.has(key)) {
68
+ throw invalid('Memory candidate keys must be unique for state projection.', {
69
+ candidateKey: key,
70
+ });
71
+ }
72
+ indexed.set(key, candidate);
73
+ }
74
+ return indexed;
75
+ }
76
+ function indexDecisions(decisions) {
77
+ const indexed = new Map();
78
+ for (const [index, decision] of decisions.entries()) {
79
+ const key = requireKey(decision, 'decision', index);
80
+ if (decision.resolution === null ||
81
+ typeof decision.resolution !== 'object' ||
82
+ decision.resolution.candidateKey !== key) {
83
+ throw invalid('Prepared memory resolution must match its decision candidate key.', { candidateKey: key });
84
+ }
85
+ if (indexed.has(key)) {
86
+ throw invalid('Prepared memory decision keys must be unique.', {
87
+ candidateKey: key,
88
+ });
89
+ }
90
+ indexed.set(key, decision);
91
+ }
92
+ return indexed;
93
+ }
94
+ function isAppliedResolution(resolution) {
95
+ return !(resolution.action === 'ignore' ||
96
+ (resolution.action === 'contradict' &&
97
+ resolution.disposition === 'reject-candidate'));
98
+ }
99
+ function appliedDecision(candidate, decision) {
100
+ if (!isAppliedResolution(decision.resolution)) {
101
+ return null;
102
+ }
103
+ return {
104
+ candidate,
105
+ identityKey: decision.identityKey,
106
+ resolution: decision.resolution,
107
+ affectedMemoryIds: decision.affectedMemoryIds,
108
+ };
109
+ }
110
+ export function buildStateProjectionInput(result, preparedMemory, hashing = nodeHashing) {
111
+ if (!Array.isArray(result.memories)) {
112
+ throw invalid('Module memory candidates must be an array.');
113
+ }
114
+ if (!Array.isArray(preparedMemory.decisions)) {
115
+ throw invalid('Prepared memory decisions must be an array.');
116
+ }
117
+ const candidates = indexCandidates(result.memories);
118
+ const decisions = indexDecisions(preparedMemory.decisions);
119
+ for (const candidateKey of candidates.keys()) {
120
+ if (!decisions.has(candidateKey)) {
121
+ throw invalid('Every memory candidate must have one prepared decision before state projection.', { candidateKey });
122
+ }
123
+ }
124
+ for (const candidateKey of decisions.keys()) {
125
+ if (!candidates.has(candidateKey)) {
126
+ throw invalid('Prepared memory decisions must not reference foreign candidates.', { candidateKey });
127
+ }
128
+ }
129
+ const memory = [];
130
+ for (const decision of preparedMemory.decisions) {
131
+ const candidate = candidates.get(decision.candidateKey);
132
+ if (candidate === undefined) {
133
+ throw invalid('Prepared memory decisions must not reference foreign candidates.', { candidateKey: decision.candidateKey });
134
+ }
135
+ const applied = appliedDecision(candidate, decision);
136
+ if (applied !== null) {
137
+ memory.push(applied);
138
+ }
139
+ }
140
+ const input = result.stateIntent === undefined
141
+ ? { memory }
142
+ : { stateIntent: result.stateIntent, memory };
143
+ return cloneProjection(input, hashing);
144
+ }
145
+ //# sourceMappingURL=state-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-projection.js","sourceRoot":"","sources":["../src/state-projection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAc3C,SAAS,OAAO,CACd,OAAe,EACf,OAAmB,EACnB,KAAe;IAEf,MAAM,IAAI,GACR,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC;YACE,IAAI,EAAE,uBAAgC;YACtC,OAAO;YACP,KAAK,EAAE,kBAA2B;YAClC,SAAS,EAAE,KAAK;SACjB;QACH,CAAC,CAAC;YACE,IAAI,EAAE,uBAAgC;YACtC,OAAO;YACP,KAAK,EAAE,kBAA2B;YAClC,SAAS,EAAE,KAAK;YAChB,OAAO;SACR,CAAC;IAER,OAAO,KAAK,KAAK,SAAS;QACxB,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC;QACrB,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAI,KAAQ;IAC7B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CACtB,KAA8B,EAC9B,OAAgB;IAEhB,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,KAA6B,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,CACX,iEAAiE,EACjE,SAAS,EACT,KAAK,CACN,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAA4B,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,CACX,6CAA6C,EAC7C,SAAS,EACT,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,KAAc,EACd,IAA8B,EAC9B,KAAa;IAEb,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,CAAC,KAAK,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,CAAC,EAC5C,CAAC;QACD,MAAM,OAAO,CAAC,UAAU,IAAI,IAAI,KAAK,gBAAgB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,GAAG,GACP,IAAI,KAAK,WAAW;QAClB,CAAC,CAAE,KAAoC,CAAC,GAAG;QAC3C,CAAC,CAAE,KAA6C,CAAC,YAAY,CAAC;IAClE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,CAAC,UAAU,IAAI,IAAI,KAAK,yBAAyB,EAAE;YAC9D,IAAI;YACJ,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,eAAe,CACtB,UAAsC;IAEtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IACnD,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,OAAO,CACX,4DAA4D,EAC5D;gBACE,YAAY,EAAE,GAAG;aAClB,CACF,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CACrB,SAA4C;IAE5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC1D,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACpD,IACE,QAAQ,CAAC,UAAU,KAAK,IAAI;YAC5B,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ;YACvC,QAAQ,CAAC,UAAU,CAAC,YAAY,KAAK,GAAG,EACxC,CAAC;YACD,MAAM,OAAO,CACX,mEAAmE,EACnE,EAAE,YAAY,EAAE,GAAG,EAAE,CACtB,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,OAAO,CAAC,+CAA+C,EAAE;gBAC7D,YAAY,EAAE,GAAG;aAClB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,mBAAmB,CAC1B,UAA4B;IAE5B,OAAO,CAAC,CACN,UAAU,CAAC,MAAM,KAAK,QAAQ;QAC9B,CAAC,UAAU,CAAC,MAAM,KAAK,YAAY;YACjC,UAAU,CAAC,WAAW,KAAK,kBAAkB,CAAC,CACjD,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,SAA0B,EAC1B,QAAgC;IAEhC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,SAAS;QACT,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;KAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,MAA4B,EAC5B,cAA8B,EAC9B,UAAmB,WAAW;IAE9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,CAAC,4CAA4C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,MAAM,OAAO,CAAC,6CAA6C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAE3D,KAAK,MAAM,YAAY,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,OAAO,CACX,iFAAiF,EACjF,EAAE,YAAY,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,KAAK,MAAM,YAAY,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,MAAM,OAAO,CACX,kEAAkE,EAClE,EAAE,YAAY,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,OAAO,CACX,kEAAkE,EAClE,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,CACxC,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GACT,MAAM,CAAC,WAAW,KAAK,SAAS;QAC9B,CAAC,CAAC,EAAE,MAAM,EAAE;QACZ,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAClD,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { EntityId, ExecutionId, IsoTimestamp, Namespace } from './common.js';
2
+ export interface StateSnapshot<TState> {
3
+ readonly entityId: EntityId;
4
+ readonly namespace: Namespace;
5
+ readonly schemaVersion: string;
6
+ readonly revision: number;
7
+ readonly value: TState;
8
+ readonly valueHash: string;
9
+ readonly createdAt: IsoTimestamp;
10
+ readonly executionId: ExecutionId;
11
+ }
12
+ export interface StateTransition<TDelta> {
13
+ readonly transitionId: string;
14
+ readonly operationKey: string;
15
+ readonly entityId: EntityId;
16
+ readonly namespace: Namespace;
17
+ readonly fromRevision: number;
18
+ readonly toRevision: number;
19
+ readonly deltaSchemaVersion: string;
20
+ readonly delta: TDelta;
21
+ readonly previousHash: string | null;
22
+ readonly nextHash: string;
23
+ readonly executionId: ExecutionId;
24
+ readonly createdAt: IsoTimestamp;
25
+ }
26
+ export interface DomainIssue {
27
+ readonly code: string;
28
+ readonly path: readonly (string | number)[];
29
+ readonly message: string;
30
+ }
31
+ export interface PreparedState<TState, TDelta> {
32
+ readonly snapshot: StateSnapshot<TState>;
33
+ readonly transition: StateTransition<TDelta>;
34
+ }
35
+ export interface StatePrepareContext {
36
+ readonly entityId: EntityId;
37
+ readonly executionId: ExecutionId;
38
+ readonly operationKey: string;
39
+ readonly now: IsoTimestamp;
40
+ }
41
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,aAAa,CAAC,MAAM;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CACnC;AAED,MAAM,WAAW,eAAe,CAAC,MAAM;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa,CAAC,MAAM,EAAE,MAAM;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;CAC5B"}
package/dist/state.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ import type { ExecutionId, IsoTimestamp } from './common.js';
2
+ import { type AcmeErrorData } from './errors.js';
3
+ import type { ExecutionStatus } from './execution-status.js';
4
+ import type { ModelCallRecord, NonCommitTerminalRecord, RepositoryEvidence } from './repository.js';
5
+ /** Versioned list document identity. */
6
+ export declare const ACME_STRANDED_LIST: "acme-stranded-list/1";
7
+ /**
8
+ * Why an execution needs a human decision rather than automatic resume.
9
+ * Aligns with ADR-0017 resume refusals and ADR-0014 terminal ambiguity.
10
+ */
11
+ export type StrandedReasonCode = 'unobserved-reservation' | 'unreadable-response' | 'recorded-failure' | 'recorded-ambiguous' | 'terminal-resume-refusal';
12
+ export type StrandedDisposition = 'open' | 'terminal';
13
+ export interface StrandedExecutionEntry {
14
+ readonly executionId: ExecutionId;
15
+ readonly disposition: StrandedDisposition;
16
+ readonly status: ExecutionStatus;
17
+ readonly namespace: string;
18
+ readonly task: string;
19
+ readonly requestKey: string;
20
+ readonly entityId: string;
21
+ readonly reasonCode: StrandedReasonCode;
22
+ readonly modelCallId?: string;
23
+ readonly modelCallStatus?: ModelCallRecord['status'];
24
+ readonly errorCode?: AcmeErrorData['code'];
25
+ readonly createdAt: IsoTimestamp;
26
+ readonly updatedAt: IsoTimestamp;
27
+ }
28
+ export interface StrandedListReport {
29
+ readonly report: typeof ACME_STRANDED_LIST;
30
+ readonly count: number;
31
+ readonly entries: readonly StrandedExecutionEntry[];
32
+ }
33
+ export interface OperatorDischargeInput {
34
+ readonly executionId: ExecutionId;
35
+ /** Non-empty operator identity (human or system account name). */
36
+ readonly dischargedBy: string;
37
+ /** Non-empty rationale for the discharge decision. */
38
+ readonly rationale: string;
39
+ readonly dischargedAt: IsoTimestamp;
40
+ }
41
+ export interface OperatorDischargeResult {
42
+ readonly executionId: ExecutionId;
43
+ readonly reasonCode: StrandedReasonCode;
44
+ readonly terminal: NonCommitTerminalRecord;
45
+ }
46
+ /**
47
+ * Inventory executions that need a human decision for resume/outcome
48
+ * (ADR-0017). Deterministic order: `executionId` ascending.
49
+ */
50
+ export declare function listStrandedExecutions(evidence: Pick<RepositoryEvidence, 'executions' | 'modelCalls'>, options?: {
51
+ readonly limit?: number;
52
+ }): StrandedListReport;
53
+ /**
54
+ * Build a non-commit terminal record for an **open** stranded execution.
55
+ * Does not write; the caller persists via `markTerminal` (and optional
56
+ * attempt append). Refuses committed, non-stranded and already-terminal rows.
57
+ */
58
+ export declare function prepareOperatorDischarge(evidence: Pick<RepositoryEvidence, 'executions' | 'modelCalls'>, input: OperatorDischargeInput): OperatorDischargeResult;
59
+ //# sourceMappingURL=stranded-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stranded-execution.d.ts","sourceRoot":"","sources":["../src/stranded-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAa,MAAM,aAAa,CAAC;AACxE,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAEV,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAEzB,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,EAAG,sBAA+B,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,GACpB,yBAAyB,CAAC;AAE9B,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC;CAC5C;AAmJD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC/D,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,kBAAkB,CA8DpB;AA+CD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC/D,KAAK,EAAE,sBAAsB,GAC5B,uBAAuB,CAuDzB"}