@x12i/memorix-retrieval 1.6.4 → 1.8.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.
- package/README.md +115 -59
- package/dist/client/types.d.ts +2 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/data/collection-parser.d.ts +14 -0
- package/dist/data/collection-parser.d.ts.map +1 -0
- package/dist/data/collection-parser.js +31 -0
- package/dist/data/collection-parser.js.map +1 -0
- package/dist/data/identity.d.ts +15 -4
- package/dist/data/identity.d.ts.map +1 -1
- package/dist/data/identity.js +22 -12
- package/dist/data/identity.js.map +1 -1
- package/dist/data/memorix-read.d.ts.map +1 -1
- package/dist/data/memorix-read.js +1 -0
- package/dist/data/memorix-read.js.map +1 -1
- package/dist/data/record-identity.d.ts +11 -0
- package/dist/data/record-identity.d.ts.map +1 -0
- package/dist/data/record-identity.js +50 -0
- package/dist/data/record-identity.js.map +1 -0
- package/dist/data/target-read.d.ts +19 -0
- package/dist/data/target-read.d.ts.map +1 -0
- package/dist/data/target-read.js +85 -0
- package/dist/data/target-read.js.map +1 -0
- package/dist/descriptors/descriptor-types.d.ts +22 -6
- package/dist/descriptors/descriptor-types.d.ts.map +1 -1
- package/dist/descriptors/discover-entities.d.ts +1 -1
- package/dist/descriptors/discover-entities.d.ts.map +1 -1
- package/dist/descriptors/load-slice-descriptor.d.ts +6 -0
- package/dist/descriptors/load-slice-descriptor.d.ts.map +1 -0
- package/dist/descriptors/load-slice-descriptor.js +20 -0
- package/dist/descriptors/load-slice-descriptor.js.map +1 -0
- package/dist/descriptors/validate-descriptor.d.ts.map +1 -1
- package/dist/descriptors/validate-descriptor.js +5 -2
- package/dist/descriptors/validate-descriptor.js.map +1 -1
- package/dist/explorer/collection-inventory.d.ts +1 -0
- package/dist/explorer/collection-inventory.d.ts.map +1 -1
- package/dist/explorer/collection-inventory.js +20 -13
- package/dist/explorer/collection-inventory.js.map +1 -1
- package/dist/explorer/collection-records.d.ts +46 -0
- package/dist/explorer/collection-records.d.ts.map +1 -0
- package/dist/explorer/collection-records.js +106 -0
- package/dist/explorer/collection-records.js.map +1 -0
- package/dist/explorer/entity-graph.d.ts +21 -0
- package/dist/explorer/entity-graph.d.ts.map +1 -1
- package/dist/explorer/entity-graph.js +124 -12
- package/dist/explorer/entity-graph.js.map +1 -1
- package/dist/explorer/health.d.ts +43 -10
- package/dist/explorer/health.d.ts.map +1 -1
- package/dist/explorer/health.js +216 -102
- package/dist/explorer/health.js.map +1 -1
- package/dist/explorer/inventory-policy.d.ts +10 -0
- package/dist/explorer/inventory-policy.d.ts.map +1 -0
- package/dist/explorer/inventory-policy.js +20 -0
- package/dist/explorer/inventory-policy.js.map +1 -0
- package/dist/explorer/raw-collection-records.d.ts +62 -0
- package/dist/explorer/raw-collection-records.d.ts.map +1 -0
- package/dist/explorer/raw-collection-records.js +218 -0
- package/dist/explorer/raw-collection-records.js.map +1 -0
- package/dist/explorer/unified-inventory.d.ts +82 -0
- package/dist/explorer/unified-inventory.d.ts.map +1 -0
- package/dist/explorer/unified-inventory.js +544 -0
- package/dist/explorer/unified-inventory.js.map +1 -0
- package/dist/index.d.ts +16 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/mongo/env.d.ts +1 -0
- package/dist/mongo/env.d.ts.map +1 -1
- package/dist/mongo/env.js +14 -0
- package/dist/mongo/env.js.map +1 -1
- package/dist/mongo/resolve-db.d.ts +2 -0
- package/dist/mongo/resolve-db.d.ts.map +1 -1
- package/dist/mongo/resolve-db.js +2 -0
- package/dist/mongo/resolve-db.js.map +1 -1
- package/dist/mongo/target-config.d.ts +28 -0
- package/dist/mongo/target-config.d.ts.map +1 -0
- package/dist/mongo/target-config.js +31 -0
- package/dist/mongo/target-config.js.map +1 -0
- package/dist/mongo/types.d.ts +1 -1
- package/dist/mongo/types.d.ts.map +1 -1
- package/dist/retrieval/batch-fetch.d.ts +6 -4
- package/dist/retrieval/batch-fetch.d.ts.map +1 -1
- package/dist/retrieval/batch-fetch.js +1 -1
- package/dist/retrieval/batch-fetch.js.map +1 -1
- package/dist/retrieval/fetch-item.d.ts.map +1 -1
- package/dist/retrieval/fetch-item.js +4 -2
- package/dist/retrieval/fetch-item.js.map +1 -1
- package/dist/retrieval/fetch-list.d.ts.map +1 -1
- package/dist/retrieval/fetch-list.js +5 -1
- package/dist/retrieval/fetch-list.js.map +1 -1
- package/dist/retrieval/fetch-slices.d.ts +85 -0
- package/dist/retrieval/fetch-slices.d.ts.map +1 -0
- package/dist/retrieval/fetch-slices.js +332 -0
- package/dist/retrieval/fetch-slices.js.map +1 -0
- package/dist/retrieval/resolve-fields.js +1 -1
- package/dist/retrieval/resolve-fields.js.map +1 -1
- package/dist/retrieval/runtime-filters.d.ts +9 -0
- package/dist/retrieval/runtime-filters.d.ts.map +1 -0
- package/dist/retrieval/runtime-filters.js +139 -0
- package/dist/retrieval/runtime-filters.js.map +1 -0
- package/dist/retrieval/slice-filters.d.ts +12 -0
- package/dist/retrieval/slice-filters.d.ts.map +1 -0
- package/dist/retrieval/slice-filters.js +153 -0
- package/dist/retrieval/slice-filters.js.map +1 -0
- package/dist/tests/collection-inventory.test.js +1 -0
- package/dist/tests/collection-inventory.test.js.map +1 -1
- package/dist/tests/collection-parser.test.d.ts +2 -0
- package/dist/tests/collection-parser.test.d.ts.map +1 -0
- package/dist/tests/collection-parser.test.js +77 -0
- package/dist/tests/collection-parser.test.js.map +1 -0
- package/dist/tests/entity-graph.test.js +2 -1
- package/dist/tests/entity-graph.test.js.map +1 -1
- package/dist/tests/fetch-list.test.js +1 -0
- package/dist/tests/fetch-list.test.js.map +1 -1
- package/dist/tests/load-slice-descriptor.test.d.ts +2 -0
- package/dist/tests/load-slice-descriptor.test.d.ts.map +1 -0
- package/dist/tests/load-slice-descriptor.test.js +58 -0
- package/dist/tests/load-slice-descriptor.test.js.map +1 -0
- package/dist/tests/slice-filters.test.d.ts +2 -0
- package/dist/tests/slice-filters.test.d.ts.map +1 -0
- package/dist/tests/slice-filters.test.js +36 -0
- package/dist/tests/slice-filters.test.js.map +1 -0
- package/docs/DATA-TIER-CONTRACT.md +34 -7
- package/docs/EXPLORER-HOST-APIS.md +13 -10
- package/docs/MEMORIX-CATALOX-CONTRACTS.md +5 -3
- package/docs/MEMORIX-DATABASE-CONVENTIONS.md +24 -2
- package/package.json +4 -2
- package/dist/data/xronox-read.d.ts +0 -13
- package/dist/data/xronox-read.d.ts.map +0 -1
- package/dist/data/xronox-read.js +0 -34
- package/dist/data/xronox-read.js.map +0 -1
|
@@ -136,7 +136,7 @@ Types below mirror `MemorixEntityDescriptor`, `MemorixListDescriptor`, and `Memo
|
|
|
136
136
|
|
|
137
137
|
| Field | Type | Default |
|
|
138
138
|
|-------|------|---------|
|
|
139
|
-
| `target` | `"entity"` \| `"event"` | `"entity"` — selects
|
|
139
|
+
| `target` | `"entity"` \| `"event"` \| `"knowledge"` | `"entity"` — selects memorix-entities / memorix-events / memorix-knowledge |
|
|
140
140
|
| `contentDefaults` | object | Default content-object storage/format |
|
|
141
141
|
| `relations` | object | Cross-entity joins declared on this entity |
|
|
142
142
|
|
|
@@ -144,7 +144,7 @@ Types below mirror `MemorixEntityDescriptor`, `MemorixListDescriptor`, and `Memo
|
|
|
144
144
|
|
|
145
145
|
```json
|
|
146
146
|
{
|
|
147
|
-
"allowedIdFields": ["entityId", "eventId"],
|
|
147
|
+
"allowedIdFields": ["entityId", "eventId", "knowledgeId"],
|
|
148
148
|
"requiredExactlyOne": true,
|
|
149
149
|
"defaultIdField": "entityId"
|
|
150
150
|
}
|
|
@@ -210,6 +210,7 @@ List descriptors are a **discriminated union** by `kind`:
|
|
|
210
210
|
| Kind | When | Key fields |
|
|
211
211
|
|------|------|------------|
|
|
212
212
|
| *(omit or `"entity"`)* | Per-entity tabular list | `entity`, `leadingContentType`, `fields[]` |
|
|
213
|
+
| `"slice"` | Saved Explorer view / executable slice | Same as entity list + optional `group`, `contentType`, `itemDescriptorId` |
|
|
213
214
|
| `"workspace"` | Cross-entity workspace merge | `fields[]` (column hints), optional `entities`, `listDescriptorByEntity` |
|
|
214
215
|
|
|
215
216
|
#### 3.2.1 Entity list (`kind` omitted or `"entity"`)
|
|
@@ -386,6 +387,7 @@ Documents in Memorix target databases follow [MEMORIX-DATABASE-CONVENTIONS](./ME
|
|
|
386
387
|
"recordId": "<optional>",
|
|
387
388
|
"entityId": "<for entity-targeted records>",
|
|
388
389
|
"eventId": "<for event-targeted records>",
|
|
390
|
+
"knowledgeId": "<for knowledge-targeted records>",
|
|
389
391
|
"capturedAt": "<ISO-8601>",
|
|
390
392
|
"data": { "... domain fields referenced by descriptor paths ..." }
|
|
391
393
|
}
|
|
@@ -395,7 +397,7 @@ Documents in Memorix target databases follow [MEMORIX-DATABASE-CONVENTIONS](./ME
|
|
|
395
397
|
|
|
396
398
|
- Domain payload lives under **`data`** (or content-type-specific `dataRoot`, almost always `data`).
|
|
397
399
|
- Descriptor `source.path` values are **dot paths from the document root** (e.g. `data.assetIp`, not `assetIp` alone).
|
|
398
|
-
- Identity for list pagination and item fetch: **`entityId
|
|
400
|
+
- Identity for list pagination and item fetch: **`entityId`**, **`eventId`**, or **`knowledgeId`** as declared on the item descriptor.
|
|
399
401
|
- Legacy `snapshotId` may be read as `recordId` fallback; do not write it in new code.
|
|
400
402
|
|
|
401
403
|
### 4.2 Shipped entity ↔ database mapping
|
|
@@ -85,7 +85,18 @@ Resolution order matters: **first non-empty value wins**.
|
|
|
85
85
|
| 4 | `MEMORIX_DB` *(legacy fallback)* |
|
|
86
86
|
| 5 | **Default:** `memorix-events` |
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
#### Knowledge database (`memorix-knowledge`)
|
|
89
|
+
|
|
90
|
+
| Priority | Variable |
|
|
91
|
+
|----------|----------|
|
|
92
|
+
| 1 | `MEMORIX_KNOWLEDGE_DB` |
|
|
93
|
+
| 2 | `MEMORIX_DB_KNOWLEDGE` |
|
|
94
|
+
| 3 | `memorix_knowledge_db` |
|
|
95
|
+
| 4 | **Default:** `memorix-knowledge` |
|
|
96
|
+
|
|
97
|
+
Identity field: `knowledgeId`.
|
|
98
|
+
|
|
99
|
+
> **Peer rule:** Prefer `MEMORIX_ENTITIES_DB`, `MEMORIX_EVENTS_DB`, and `MEMORIX_KNOWLEDGE_DB`. Treat `MEMORIX_DB` as a legacy single-database override only.
|
|
89
100
|
|
|
90
101
|
#### Neo / non-default deployments
|
|
91
102
|
|
|
@@ -120,6 +131,17 @@ Normalize `entityType` by replacing `-` with `_` and uppercasing.
|
|
|
120
131
|
|--------|-----------------|----------------------------------------|
|
|
121
132
|
| `entity` | `MEMORIX_ENTITIES_COLLECTION_<ENTITY_TYPE>` | `MEMORIX_ENTITIES_COLLECTION_VULNERABILITY` |
|
|
122
133
|
| `event` | `MEMORIX_EVENTS_COLLECTION_<ENTITY_TYPE>` | `MEMORIX_EVENTS_COLLECTION_VULNERABILITY` |
|
|
134
|
+
| `knowledge` | `MEMORIX_KNOWLEDGE_COLLECTION_<ENTITY_TYPE>` | `MEMORIX_KNOWLEDGE_COLLECTION_PLAYBOOK` |
|
|
135
|
+
|
|
136
|
+
### Content-type collection naming (retrieval / Explorer)
|
|
137
|
+
|
|
138
|
+
When content types do not set an explicit `collection`, retrieval uses:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
<objectName>-<contentType>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The **last dash** separates object name from content type (object names may contain dashes). See `parseMemorixCollectionName` in `@x12i/memorix-retrieval`.
|
|
123
145
|
|
|
124
146
|
## Collection naming
|
|
125
147
|
|
|
@@ -315,7 +337,7 @@ MEMORIX_EVENTS_COLLECTION_VULNERABILITY=vulnerability-events
|
|
|
315
337
|
When building a new service or tool that touches Memorix:
|
|
316
338
|
|
|
317
339
|
- [ ] Connect with `MONGO_URI` / `MONGO_CONNECTION_STRING`
|
|
318
|
-
- [ ] Select database via `target`: `entity` → `memorix-entities`, `event` → `memorix-events`
|
|
340
|
+
- [ ] Select database via `target`: `entity` → `memorix-entities`, `event` → `memorix-events`, `knowledge` → `memorix-knowledge`
|
|
319
341
|
- [ ] Respect env precedence documented above
|
|
320
342
|
- [ ] Use recommended collection names or set explicit env overrides
|
|
321
343
|
- [ ] Store domain payload under `data`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x12i/memorix-retrieval",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.8.0",
|
|
4
|
+
"description": "Read-side runtime data tier for Memorix: inventory, lists, items, slices, graph, and health",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"catalox:seed:memorix-retrieval:apply": "npm run build && node scripts/apply-seed-manifest.mjs",
|
|
25
25
|
"catalox:seed:ensure": "npm run build && node scripts/ensure-catalox-seed.mjs",
|
|
26
26
|
"mongo:check-collections": "node scripts/check-mongo-collections.mjs",
|
|
27
|
+
"mongo:inventory": "npm run build && node scripts/mongo-inventory.mjs",
|
|
27
28
|
"smoke:retrieval": "npm run build && node scripts/smoke-retrieval.mjs"
|
|
28
29
|
},
|
|
29
30
|
"engines": {
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@x12i/catalox": "^5.0.0",
|
|
34
35
|
"@x12i/helpers": "^1.7.0",
|
|
36
|
+
"@x12i/memorix-descriptors": "^1.3.0",
|
|
35
37
|
"@x12i/xronox": "^3.9.0"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { MemorixRetrievalClient } from "../client/types.js";
|
|
2
|
-
import type { XronoxReadParams } from "../client/xronox-like.js";
|
|
3
|
-
import type { MemorixEntityDescriptor } from "../descriptors/descriptor-types.js";
|
|
4
|
-
import type { MemorixTarget } from "../mongo/types.js";
|
|
5
|
-
/** Default Xronox role names for Memorix entity/event databases (see README). */
|
|
6
|
-
export declare const DEFAULT_MEMORIX_XRONOX_ROLES: Record<MemorixTarget, string>;
|
|
7
|
-
export declare function resolveMemorixXronoxRole(entity: MemorixEntityDescriptor, client: MemorixRetrievalClient): string;
|
|
8
|
-
export declare function memorixXronoxRead(client: MemorixRetrievalClient, params: Omit<XronoxReadParams, "dataType" | "sourceType" | "subSourceType"> & {
|
|
9
|
-
source: string;
|
|
10
|
-
entity: MemorixEntityDescriptor;
|
|
11
|
-
role?: string;
|
|
12
|
-
}): Promise<Record<string, unknown>[]>;
|
|
13
|
-
//# sourceMappingURL=xronox-read.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xronox-read.d.ts","sourceRoot":"","sources":["../../src/data/xronox-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAElF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,iFAAiF;AACjF,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAGtE,CAAC;AAEF,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,sBAAsB,GAC7B,MAAM,CAGR;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,YAAY,GAAG,eAAe,CAAC,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,uBAAuB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAyBpC"}
|
package/dist/data/xronox-read.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { resolveEntityTarget } from "../mongo/resolve-db.js";
|
|
2
|
-
/** Default Xronox role names for Memorix entity/event databases (see README). */
|
|
3
|
-
export const DEFAULT_MEMORIX_XRONOX_ROLES = {
|
|
4
|
-
entity: "operational",
|
|
5
|
-
event: "logs",
|
|
6
|
-
};
|
|
7
|
-
export function resolveMemorixXronoxRole(entity, client) {
|
|
8
|
-
const target = resolveEntityTarget(entity);
|
|
9
|
-
return client.xronoxRoles?.[target] ?? DEFAULT_MEMORIX_XRONOX_ROLES[target];
|
|
10
|
-
}
|
|
11
|
-
export async function memorixXronoxRead(client, params) {
|
|
12
|
-
const { entity, role: roleOverride, ...readParams } = params;
|
|
13
|
-
const fullParams = {
|
|
14
|
-
dataType: "metadata",
|
|
15
|
-
sourceType: "database",
|
|
16
|
-
subSourceType: "mongo",
|
|
17
|
-
role: roleOverride ?? resolveMemorixXronoxRole(entity, client),
|
|
18
|
-
...readParams,
|
|
19
|
-
};
|
|
20
|
-
if (client.xronox.readArray) {
|
|
21
|
-
const rows = await client.xronox.readArray(fullParams);
|
|
22
|
-
return rows.map((r) => r);
|
|
23
|
-
}
|
|
24
|
-
const result = await client.xronox.read(fullParams);
|
|
25
|
-
if (Array.isArray(result)) {
|
|
26
|
-
return result.map((r) => r);
|
|
27
|
-
}
|
|
28
|
-
const rows = [];
|
|
29
|
-
for await (const row of result) {
|
|
30
|
-
rows.push(row);
|
|
31
|
-
}
|
|
32
|
-
return rows;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=xronox-read.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xronox-read.js","sourceRoot":"","sources":["../../src/data/xronox-read.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,iFAAiF;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAkC;IACzE,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,MAAM;CACd,CAAC;AAEF,MAAM,UAAU,wBAAwB,CACtC,MAA+B,EAC/B,MAA8B;IAE9B,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,4BAA4B,CAAC,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAA8B,EAC9B,MAIC;IAED,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;IAE7D,MAAM,UAAU,GAAqB;QACnC,QAAQ,EAAE,UAAU;QACpB,UAAU,EAAE,UAAU;QACtB,aAAa,EAAE,OAAO;QACtB,IAAI,EAAE,YAAY,IAAI,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC;QAC9D,GAAG,UAAU;KACd,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAA4B,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAA4B,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,IAAI,GAA8B,EAAE,CAAC;IAC3C,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,GAA8B,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|