@gnolith/taproot 0.2.0 → 0.3.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/CHANGELOG.md +53 -0
- package/COMPATIBILITY.md +5 -3
- package/README.md +106 -33
- package/SECURITY.md +6 -3
- package/dist/authorization-maintenance.d.ts +55 -0
- package/dist/authorization-maintenance.d.ts.map +1 -0
- package/dist/authorization-maintenance.js +686 -0
- package/dist/authorization-maintenance.js.map +1 -0
- package/dist/authorization.d.ts +98 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +1137 -0
- package/dist/authorization.js.map +1 -0
- package/dist/canonical.d.ts +2 -1
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +9 -1
- package/dist/canonical.js.map +1 -1
- package/dist/errors.d.ts +4 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +125 -49
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +351 -44
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts +9 -3
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +77 -5
- package/dist/migrations.js.map +1 -1
- package/dist/repository.d.ts +20 -9
- package/dist/repository.d.ts.map +1 -1
- package/dist/repository.js +593 -48
- package/dist/repository.js.map +1 -1
- package/dist/schema.d.ts +14 -5
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +461 -18
- package/dist/schema.js.map +1 -1
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/api.md +56 -18
- package/docs/architecture.md +19 -7
- package/docs/authorization.md +82 -0
- package/docs/completion-audit.md +15 -15
- package/docs/operations.md +28 -5
- package/docs/product-scope.md +5 -3
- package/docs/testing.md +18 -1
- package/docs/threat-model.md +30 -3
- package/examples/d1-diamond-interop/README.md +2 -1
- package/examples/d1-diamond-interop/demo.ts +150 -21
- package/migrations/0003_canonical_statement_text.sql +31 -0
- package/migrations/0004_canonical_authorization_policy.sql +213 -0
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- **Breaking 0.3 API:** removed `TaprootRepository`, `createTaproot`, and every
|
|
6
|
+
unscoped canonical read helper from the normal package export. Canonical
|
|
7
|
+
entity, history, list, term-search, audit, export, integrity, and repair
|
|
8
|
+
access now exists only through mandatory `AuthorizedTaprootReader` context.
|
|
9
|
+
- Added host-issued non-extractable AES-GCM cursor capability, authenticated
|
|
10
|
+
cursors bound to caller/grants/query/filter/auth revision/data generation,
|
|
11
|
+
fixed-size plaintext padding, identifier-only candidate scans, denied-heavy
|
|
12
|
+
page filling, and final authorization rechecks. Revision and audit generation
|
|
13
|
+
invalidate cursors after writes and repair. Stale, tampered, and cross-context
|
|
14
|
+
cursors fail generically.
|
|
15
|
+
- Public mutation helpers now return minimal receipts and reject validator/RDF
|
|
16
|
+
factory callbacks and configurable entity-size probes, so write configuration
|
|
17
|
+
cannot observe preexisting canonical content. They require a process-local
|
|
18
|
+
opaque installation authorization guard bound to the exact database object
|
|
19
|
+
and installation base IRI. Normal writes require current `knowledge:write`;
|
|
20
|
+
policy changes require orthogonal `knowledge:policy`. Raw repository
|
|
21
|
+
internals are not package-exported.
|
|
22
|
+
- Added host-created authorization contexts, canonical CNF visibility scopes,
|
|
23
|
+
lossless scope intersection, portable fingerprints, explicit `search:admin`
|
|
24
|
+
checks, and fail-closed pre/post-hydration canonical reads.
|
|
25
|
+
- Added checksummed migration 4 with immutable installation authorization
|
|
26
|
+
state, current and per-revision entity/statement policy, atomic projection
|
|
27
|
+
outbox and counter advances, fail-closed legacy quarantine, and bounded
|
|
28
|
+
hash-attested `search:admin` backfill. Unique durable advance IDs prevent
|
|
29
|
+
same-target ABA races for canonical and cross-package ordered batches.
|
|
30
|
+
- Runtime JavaScript writes now fail closed when authorization metadata is
|
|
31
|
+
omitted, authorize before loading existing canonical state, validate redirect
|
|
32
|
+
targets and historical reverts against current policy, and preserve generic
|
|
33
|
+
denial behavior for missing, stale, or inaccessible targets.
|
|
34
|
+
- Cross-package authorization fencing is guard-executed and inseparable from
|
|
35
|
+
the ordered database batch. Authorization singleton/audit rows reject
|
|
36
|
+
replacement, readiness verifies current and historical statement-policy
|
|
37
|
+
coverage, and authorized bulk import advances its context between entities.
|
|
38
|
+
- Added host-issued fence-only domain guards bound to one exact non-Knowledge
|
|
39
|
+
capability. Task/Memory-style writes can share the installation revision
|
|
40
|
+
without borrowing Knowledge authority or advancing counters; Knowledge
|
|
41
|
+
advances require orthogonal policy authority and bind the prior durable
|
|
42
|
+
advance ID.
|
|
43
|
+
- Authorization readiness and persisted sources now require exact parity
|
|
44
|
+
between mutable current policy and its immutable matching revision, and
|
|
45
|
+
recompute historical statement coverage/effective visibility before use.
|
|
46
|
+
Operational inspection also validates exact trigger definitions.
|
|
47
|
+
|
|
48
|
+
- Added required, explicitly authored nonblank `Statement.text` to canonical
|
|
49
|
+
JSON and to every logical statement mutation.
|
|
50
|
+
- Added canonical JSON migration 3. Existing databases with no unauthored
|
|
51
|
+
statements upgrade atomically; persisted statements without text fail closed
|
|
52
|
+
rather than receiving inferred fallback prose.
|
|
53
|
+
- Whole-entity replacement and historical revert now require an exact
|
|
54
|
+
statement-ID-to-text resupply map, preventing silent stale-text carry.
|
|
55
|
+
|
|
3
56
|
## 0.2.0
|
|
4
57
|
|
|
5
58
|
- Added a runtime-neutral SQLite persistence surface while retaining D1
|
package/COMPATIBILITY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Wikibase compatibility target
|
|
2
2
|
|
|
3
|
-
Taproot 0.
|
|
3
|
+
Taproot 0.3.x requires `@gnolith/diamond` 0.4.0 exactly. Existing Cloudflare D1
|
|
4
4
|
objects remain compatible with the exported `D1DatabaseLike` surface. New
|
|
5
5
|
embedders may use the equivalent `SqliteDatabaseLike`; both require one
|
|
6
6
|
adapter/connection with ordered atomic batch semantics.
|
|
@@ -25,8 +25,10 @@ Intentional differences:
|
|
|
25
25
|
lifecycle RDF; deleted content remains available in immutable revisions.
|
|
26
26
|
- Search is a deterministic D1 term projection using case-insensitive
|
|
27
27
|
substring matching. FTS5 is not required.
|
|
28
|
-
- Taproot stores attribution claims but does not authenticate them.
|
|
29
|
-
|
|
28
|
+
- Taproot stores attribution claims but does not authenticate them. Normal
|
|
29
|
+
canonical reads require a host-created authorization context and use
|
|
30
|
+
Taproot's persisted canonical policy. Authentication, principals,
|
|
31
|
+
memberships, sessions, and agent/MCP transport remain host concerns.
|
|
30
32
|
- The compatibility target is Wikibase core Items and Properties. Lexemes,
|
|
31
33
|
Forms, Senses, EntitySchemas, MediaInfo, MediaWiki page metadata, and
|
|
32
34
|
normalized external-ID formatter URLs are not claimed as supported entity
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ editing commands, term search, repairable projections, and a deterministic RDF p
|
|
|
12
12
|
|
|
13
13
|
## Status
|
|
14
14
|
|
|
15
|
-
Version `0.
|
|
15
|
+
Version `0.3.0` supports Node 22 and 24 and depends exactly on Diamond `0.4.0`,
|
|
16
16
|
which exposes transaction-composable RDF patches, a runtime-neutral SQLite
|
|
17
17
|
capability, and a process-local `node:sqlite` adapter.
|
|
18
18
|
|
|
@@ -21,6 +21,8 @@ capability, and a process-local `node:sqlite` adapter.
|
|
|
21
21
|
- Items and Properties with Wikibase-style canonical JSON.
|
|
22
22
|
- Labels, descriptions, aliases, sitelinks, statements, qualifiers,
|
|
23
23
|
references, ranks, and all three snak types.
|
|
24
|
+
- Nonblank, explicitly authored text for every logical statement revision;
|
|
25
|
+
Taproot never generates prose from properties or values.
|
|
24
26
|
- Item, Property, Lexeme, Form, Sense, and EntitySchema links; string,
|
|
25
27
|
external ID, URL, Commons media, monolingual text, time,
|
|
26
28
|
quantity, coordinate, math, musical notation, geo-shape, and tabular-data
|
|
@@ -46,25 +48,57 @@ tables idempotently. First initialization requires the database's permanent
|
|
|
46
48
|
identity:
|
|
47
49
|
|
|
48
50
|
```ts
|
|
49
|
-
import {
|
|
51
|
+
import {
|
|
52
|
+
createAuthorizationCursorCodec,
|
|
53
|
+
createAuthorizedTaproot,
|
|
54
|
+
createItem,
|
|
55
|
+
bootstrapTaprootAuthorization,
|
|
56
|
+
createInstallationAuthorizationGuard,
|
|
57
|
+
createTaprootHostWriteCapability,
|
|
58
|
+
initializeTaproot,
|
|
59
|
+
setLabel,
|
|
60
|
+
} from '@gnolith/taproot';
|
|
50
61
|
|
|
51
62
|
await initializeTaproot(env.DB, { baseIri: 'https://knowledge.example' });
|
|
52
|
-
const
|
|
63
|
+
const options = {
|
|
53
64
|
baseIri: 'https://knowledge.example',
|
|
65
|
+
};
|
|
66
|
+
const writeCapability = createTaprootHostWriteCapability(
|
|
67
|
+
env.DB,
|
|
68
|
+
options,
|
|
69
|
+
nonExtractableHmacSha256Key,
|
|
70
|
+
);
|
|
71
|
+
await bootstrapTaprootAuthorization(
|
|
72
|
+
env.DB,
|
|
73
|
+
options,
|
|
74
|
+
writeCapability,
|
|
75
|
+
'installation-1',
|
|
76
|
+
);
|
|
77
|
+
const guard = await createInstallationAuthorizationGuard(
|
|
78
|
+
env.DB,
|
|
79
|
+
options,
|
|
80
|
+
writeCapability,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const item = await createItem(env.DB, options, guard, writeContext, {
|
|
84
|
+
labels: { en: { language: 'en', value: 'Ada Lovelace' } },
|
|
85
|
+
authorization: canonicalPolicy,
|
|
54
86
|
});
|
|
55
87
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const item = await knowledge.createItem({
|
|
61
|
-
labels: { en: { language: 'en', value: 'Ada Lovelace' } },
|
|
88
|
+
// The host derives context only from authenticated state. Taproot loads its
|
|
89
|
+
// persisted canonical policy itself. The cursor key is durable and host-held.
|
|
90
|
+
const knowledge = createAuthorizedTaproot(env.DB, options, readContext, {
|
|
91
|
+
cursorCodec: createAuthorizationCursorCodec(nonExtractableAesGcmKey),
|
|
62
92
|
});
|
|
93
|
+
const canonical = await knowledge.getEntity(item.entityId);
|
|
63
94
|
```
|
|
64
95
|
|
|
96
|
+
Never accept either host key, host capability, authorization guard, context, or
|
|
97
|
+
policy from a request, MCP argument, prompt, or query.
|
|
98
|
+
|
|
65
99
|
Use Taproot's `planTaprootMigrations`, `applyTaprootMigrations`, and
|
|
66
100
|
`initializeTaproot` APIs for schema changes. The numbered SQL files document
|
|
67
|
-
the historical 0.1 layout and are not an operator migration interface in 0.
|
|
101
|
+
the historical 0.1 layout and are not an operator migration interface in 0.3.
|
|
68
102
|
The package APIs own checksums, conservative adoption, application-level
|
|
69
103
|
SHA-256 backfills, and RDF reprojection.
|
|
70
104
|
|
|
@@ -78,35 +112,72 @@ Diamond patch together. A stale guard or any SQL/RDF failure rolls the whole
|
|
|
78
112
|
batch back.
|
|
79
113
|
|
|
80
114
|
```ts
|
|
81
|
-
const edited = await
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
115
|
+
const edited = await setLabel(
|
|
116
|
+
env.DB,
|
|
117
|
+
options,
|
|
118
|
+
guard,
|
|
119
|
+
currentWriteContext,
|
|
120
|
+
item.entityId,
|
|
121
|
+
'fr',
|
|
122
|
+
'Ada Lovelace',
|
|
123
|
+
{
|
|
124
|
+
expectedRevision: item.newRevision,
|
|
125
|
+
attribution: {
|
|
126
|
+
id: 'agent:cataloguer',
|
|
127
|
+
kind: 'agent',
|
|
128
|
+
tool: 'gnolith-mcp',
|
|
129
|
+
},
|
|
130
|
+
editSummary: 'add French label',
|
|
131
|
+
tags: ['agent'],
|
|
132
|
+
requestId: 'mcp-request-123',
|
|
133
|
+
authorization: currentCanonicalPolicy,
|
|
87
134
|
},
|
|
88
|
-
|
|
89
|
-
tags: ['agent'],
|
|
90
|
-
requestId: 'mcp-request-123',
|
|
91
|
-
});
|
|
135
|
+
);
|
|
92
136
|
```
|
|
93
137
|
|
|
94
|
-
The public API
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
`
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
The public API exposes canonical reads only on `AuthorizedTaprootReader`.
|
|
139
|
+
Entity/history/list/term-search/audit/export and integrity operations require a
|
|
140
|
+
host-created authorization context and Taproot's persisted policy source.
|
|
141
|
+
Public mutation helpers require the DB/installation-bound opaque authorization
|
|
142
|
+
guard, a current context with exact `knowledge:write`, and canonical policy
|
|
143
|
+
input. Policy changes additionally require exact `knowledge:policy`. They
|
|
144
|
+
return only entity ID, previous/new revision, authorization/search generation,
|
|
145
|
+
and committed status;
|
|
146
|
+
they do not return canonical JSON, text, RDF counts, hashes, or audit bodies.
|
|
147
|
+
`TaprootRepository` and raw read helpers are intentionally absent from package
|
|
148
|
+
exports in the breaking 0.3 line.
|
|
149
|
+
|
|
150
|
+
The opaque guard also owns execution of ordered cross-package batches that
|
|
151
|
+
need an exact authorization-revision fence or advance. It does not expose raw
|
|
152
|
+
counter-update statements that a caller could separate from the corresponding
|
|
153
|
+
audit, assertion, or domain writes.
|
|
154
|
+
Hosts issue a distinct fence-only domain guard for each exact non-Knowledge
|
|
155
|
+
domain capability, such as Task or Memory writes. The capability is bound at
|
|
156
|
+
issuance, cannot be supplied at the call site, and an ordinary domain fence
|
|
157
|
+
does not advance authorization or search counters. Knowledge authorization
|
|
158
|
+
advances additionally require `knowledge:policy`.
|
|
159
|
+
|
|
160
|
+
Statement creation and replacement include `text` on the `Statement` itself.
|
|
161
|
+
Rank, qualifier, and reference mutation methods require authored text for the
|
|
162
|
+
new logical statement revision. `replaceEntity` and `revertEntity` require an
|
|
163
|
+
exact `statementTexts` map for every statement they carry forward. Reusing old
|
|
164
|
+
wording is allowed only when the caller deliberately supplies it again.
|
|
165
|
+
|
|
166
|
+
Set `requireAttribution: true` to reject unattributed writes. `observe` receives
|
|
167
|
+
isolated success/error timing records. Public write options cannot install
|
|
168
|
+
validators or RDF factories over canonical state and cannot vary the canonical
|
|
169
|
+
entity-size limit; hosts perform domain validation before invoking the write
|
|
170
|
+
using separately authorized input.
|
|
103
171
|
|
|
104
172
|
## SPARQL prefixes
|
|
105
173
|
|
|
106
174
|
`wikibasePrefixes(baseIri)` returns site-owned `wd:`, `wds:`, `wdv:`,
|
|
107
175
|
`wdref:`, `wdt:`, `p:`, `ps:`, `psv:`, `pq:`, `pqv:`, `pr:`, `prv:`, and
|
|
108
|
-
`wdno:` namespaces.
|
|
109
|
-
|
|
176
|
+
`wdno:` namespaces. Diamond's database-level SPARQL handler can query them, but
|
|
177
|
+
it sees the complete graph and is privileged host maintenance/debug
|
|
178
|
+
infrastructure. Do not expose it to a user, agent, MCP, or search caller.
|
|
179
|
+
Normal SPARQL needs an authorization-scoped dataset and final canonical policy
|
|
180
|
+
recheck in the owning host.
|
|
110
181
|
|
|
111
182
|
## Limits
|
|
112
183
|
|
|
@@ -116,8 +187,10 @@ that as `QuadPatchTooLargeError`. Store PDFs, images, audio, OCR, transcripts,
|
|
|
116
187
|
and article bodies externally and represent them as knowledge Items.
|
|
117
188
|
|
|
118
189
|
Bulk imports default to create-only, can opt into `upsert`, are capped at 100
|
|
119
|
-
entities by default, and commit one entity atomically at a time.
|
|
120
|
-
|
|
190
|
+
entities by default, and commit one entity atomically at a time. Authorized
|
|
191
|
+
bulk policies use sequential expected authorization revisions; Taproot carries
|
|
192
|
+
each successful advance into the next entity's context. Multi-command edits
|
|
193
|
+
apply up to 100 commands in one revision. All list limits are capped at 500.
|
|
121
194
|
|
|
122
195
|
See the [local D1 and Diamond interoperability example](examples/d1-diamond-interop/README.md),
|
|
123
196
|
[`COMPATIBILITY.md`](COMPATIBILITY.md), and the architecture, API, operations,
|
package/SECURITY.md
CHANGED
|
@@ -11,9 +11,12 @@ canonical history or RDF query results, and whether untrusted JSON or SPARQL
|
|
|
11
11
|
input is required. Do not include production data or credentials.
|
|
12
12
|
|
|
13
13
|
Taproot records attribution claims but does not authenticate identities or
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
persist principals, memberships, or sessions. It does persist canonical entity
|
|
15
|
+
authorization policy and requires a host-created current context plus an
|
|
16
|
+
opaque DB-bound guard for normal writes. Canonical JSON, authorization policy,
|
|
17
|
+
revision/audit immutability, size limits, optimistic revision/authorization
|
|
18
|
+
guards, and read-only Diamond SPARQL are security boundaries; rebuildable
|
|
19
|
+
projection content is not authoritative.
|
|
17
20
|
|
|
18
21
|
The threat model and host responsibilities are documented in
|
|
19
22
|
`docs/threat-model.md`.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { SqliteDatabaseLike } from '@gnolith/diamond';
|
|
2
|
+
import type { EntityId, VisibilityScopeV1, AuthorizationContext } from './types.js';
|
|
3
|
+
export type AuthorizationReadinessCode = 'missing-current-policy' | 'current-revision-mismatch' | 'cross-installation-policy' | 'authorization-revision-invalid' | 'entity-policy-mismatch' | 'missing-revision-policy' | 'statement-policy-mismatch';
|
|
4
|
+
export interface AuthorizationReadinessIssue {
|
|
5
|
+
entityId: EntityId;
|
|
6
|
+
currentRevision: number;
|
|
7
|
+
codes: AuthorizationReadinessCode[];
|
|
8
|
+
}
|
|
9
|
+
export interface AuthorizationReadinessInspection {
|
|
10
|
+
installationId: string;
|
|
11
|
+
authorizationRevision: number;
|
|
12
|
+
searchGeneration: number;
|
|
13
|
+
counts: {
|
|
14
|
+
canonicalEntities: number;
|
|
15
|
+
canonicalRevisions: number;
|
|
16
|
+
currentPolicies: number;
|
|
17
|
+
revisionPolicies: number;
|
|
18
|
+
quarantinedEntities: number;
|
|
19
|
+
revisionPolicyMismatches: number;
|
|
20
|
+
entityPolicyMismatches: number;
|
|
21
|
+
statementPolicyMismatches: number;
|
|
22
|
+
currentHistoryParityMismatches: number;
|
|
23
|
+
};
|
|
24
|
+
ready: boolean;
|
|
25
|
+
issues: AuthorizationReadinessIssue[];
|
|
26
|
+
cursor: EntityId | null;
|
|
27
|
+
}
|
|
28
|
+
export interface AuthorizationBackfillRevisionInput {
|
|
29
|
+
revision: number;
|
|
30
|
+
contentHash: string;
|
|
31
|
+
workspaceId: string | null;
|
|
32
|
+
ownerPrincipalId: string;
|
|
33
|
+
visibility: VisibilityScopeV1;
|
|
34
|
+
statementRestrictions: Readonly<Record<string, readonly VisibilityScopeV1[]>>;
|
|
35
|
+
}
|
|
36
|
+
export interface AuthorizationBackfillEntityInput {
|
|
37
|
+
entityId: EntityId;
|
|
38
|
+
revisions: readonly AuthorizationBackfillRevisionInput[];
|
|
39
|
+
}
|
|
40
|
+
export interface AuthorizationBackfillPlan {
|
|
41
|
+
planId: string;
|
|
42
|
+
installationId: string;
|
|
43
|
+
baseAuthorizationRevision: number;
|
|
44
|
+
manifestHash: string;
|
|
45
|
+
entityCount: number;
|
|
46
|
+
revisionCount: number;
|
|
47
|
+
status: 'planned' | 'complete';
|
|
48
|
+
}
|
|
49
|
+
export declare function inspectAuthorizationReadiness(db: SqliteDatabaseLike, rawContext: AuthorizationContext, options?: {
|
|
50
|
+
limit?: number;
|
|
51
|
+
cursor?: EntityId;
|
|
52
|
+
}): Promise<AuthorizationReadinessInspection>;
|
|
53
|
+
export declare function planAuthorizationBackfill(db: SqliteDatabaseLike, rawContext: AuthorizationContext, inputs: readonly AuthorizationBackfillEntityInput[], now?: string): Promise<AuthorizationBackfillPlan>;
|
|
54
|
+
export declare function applyAuthorizationBackfill(db: SqliteDatabaseLike, rawContext: AuthorizationContext, planId: string, now?: string): Promise<AuthorizationBackfillPlan>;
|
|
55
|
+
//# sourceMappingURL=authorization-maintenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization-maintenance.d.ts","sourceRoot":"","sources":["../src/authorization-maintenance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAc1B,OAAO,KAAK,EACV,QAAQ,EACR,iBAAiB,EAEjB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAOpB,MAAM,MAAM,0BAA0B,GAClC,wBAAwB,GACxB,2BAA2B,GAC3B,2BAA2B,GAC3B,gCAAgC,GAChC,wBAAwB,GACxB,yBAAyB,GACzB,2BAA2B,CAAC;AAEhC,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,QAAQ,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,0BAA0B,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,gCAAgC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE;QACN,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,wBAAwB,EAAE,MAAM,CAAC;QACjC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,yBAAyB,EAAE,MAAM,CAAC;QAClC,8BAA8B,EAAE,MAAM,CAAC;KACxC,CAAC;IACF,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,SAAS,kCAAkC,EAAE,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC;AAoCD,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,oBAAoB,EAChC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAAO,GAClD,OAAO,CAAC,gCAAgC,CAAC,CAoK3C;AA4JD,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,SAAS,gCAAgC,EAAE,EACnD,GAAG,GAAE,MAAiC,GACrC,OAAO,CAAC,yBAAyB,CAAC,CA8KpC;AAED,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,MAAiC,GACrC,OAAO,CAAC,yBAAyB,CAAC,CA+OpC"}
|