attenu-guard 0.1.1 → 0.2.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 +29 -0
- package/README.md +12 -4
- package/dist/cjs/audit.d.ts +1 -0
- package/dist/cjs/audit.d.ts.map +1 -1
- package/dist/cjs/audit.js +9 -5
- package/dist/cjs/audit.js.map +1 -1
- package/dist/cjs/canonical.d.ts +21 -69
- package/dist/cjs/canonical.d.ts.map +1 -1
- package/dist/cjs/canonical.js +198 -171
- package/dist/cjs/canonical.js.map +1 -1
- package/dist/cjs/evidence.d.ts +1 -0
- package/dist/cjs/evidence.d.ts.map +1 -1
- package/dist/cjs/evidence.js +8 -3
- package/dist/cjs/evidence.js.map +1 -1
- package/dist/cjs/index.d.ts +4 -4
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/wire.d.ts +136 -1
- package/dist/cjs/wire.d.ts.map +1 -1
- package/dist/cjs/wire.js +405 -2
- package/dist/cjs/wire.js.map +1 -1
- package/dist/esm/audit.d.ts +1 -0
- package/dist/esm/audit.d.ts.map +1 -1
- package/dist/esm/audit.js +10 -6
- package/dist/esm/audit.js.map +1 -1
- package/dist/esm/canonical.d.ts +21 -69
- package/dist/esm/canonical.d.ts.map +1 -1
- package/dist/esm/canonical.js +192 -168
- package/dist/esm/canonical.js.map +1 -1
- package/dist/esm/evidence.d.ts +1 -0
- package/dist/esm/evidence.d.ts.map +1 -1
- package/dist/esm/evidence.js +8 -3
- package/dist/esm/evidence.js.map +1 -1
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/wire.d.ts +136 -1
- package/dist/esm/wire.d.ts.map +1 -1
- package/dist/esm/wire.js +400 -2
- package/dist/esm/wire.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to this package are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this package
|
|
5
5
|
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.2.0] — 2026-08-29
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **RFC 8785 JCS is the only canonicalization format.** Delegation Tokens must
|
|
11
|
+
declare `c14n: JCS` and already carry canonical header and payload bytes.
|
|
12
|
+
Ledger entries, anchors and evidence bundles now carry the same marker and
|
|
13
|
+
use JCS for every hash and signature. There is no legacy or dual-format reader.
|
|
14
|
+
- The canonicalizer now uses ECMAScript number serialization, raw Unicode and
|
|
15
|
+
UTF-16 code-unit member ordering, and rejects non-finite numbers, duplicate
|
|
16
|
+
members, lone surrogates, unsupported values and cyclic structures.
|
|
17
|
+
- Cross-language fixtures now target Python `attenu-guard` 0.7 and include all
|
|
18
|
+
17 published interop vectors. The new reason codes are `non_finite`,
|
|
19
|
+
`duplicate_member`, `canonicalization_required` and `non_canonical`.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- **Delegation-chain verification.** `load(tokens, signer, {rootKeyIds, now})` runs the
|
|
23
|
+
Internet-Draft's Offline Verification Algorithm over a chain of Delegation Tokens and
|
|
24
|
+
returns a `VerifiedChain` whose `permits` authorises against the leaf authority. All
|
|
25
|
+
five in-scope steps are checked in the draft's order — JWS signatures with an
|
|
26
|
+
alg-confusion guard, the `par_hash` byte commitment compared in constant time,
|
|
27
|
+
`del_depth`/`del_max_depth` bounds, subsumption via `Authority.isNarrowerThan`, and the
|
|
28
|
+
time claims including `exp` monotonicity along the chain — denying on the first failure
|
|
29
|
+
with a `WireError` carrying a `WireReasonCode`. Holder binding (`cnf`/DPoP) and status-list
|
|
30
|
+
revocation, the draft's steps 6 and 7, are out of scope in both implementations.
|
|
31
|
+
`b64urlEncode`/`b64urlDecode` are exported alongside it.
|
|
32
|
+
- The 17 language-independent interop vectors from the Python repository are generated
|
|
33
|
+
into `test/fixtures/vectors/` and asserted here: the valid chain verifies and yields the
|
|
34
|
+
leaf authority, and each adversarial chain is rejected for exactly the reason it declares.
|
|
35
|
+
|
|
7
36
|
## [0.1.1] — 2026-08-28
|
|
8
37
|
|
|
9
38
|
### Changed
|
package/README.md
CHANGED
|
@@ -159,10 +159,18 @@ ledger, and one bundle per tamper mode with the report Python produces for each.
|
|
|
159
159
|
The suite reproduces all of it, and a separate test writes a ledger and bundle
|
|
160
160
|
here and has the Python CLI verify them, so both directions are covered.
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
Version 0.2 uses [RFC 8785 JCS](https://www.rfc-editor.org/rfc/rfc8785) for every
|
|
163
|
+
signed or hashed JSON surface: Delegation Tokens, ledger entries, anchors and
|
|
164
|
+
evidence bundles. Tokens must declare `"c14n":"JCS"` in the protected header,
|
|
165
|
+
and their decoded header and payload bytes must already be canonical. Ledger
|
|
166
|
+
entries, anchors and bundles carry the same marker. Duplicate object members,
|
|
167
|
+
non-finite numbers, lone UTF-16 surrogates, unmarked tokens and non-canonical
|
|
168
|
+
spellings are rejected instead of being normalized after verification.
|
|
169
|
+
|
|
170
|
+
This is the only supported format. There is no 0.1 compatibility reader or
|
|
171
|
+
dual-signing mode. The 17 committed interop vectors include the separating cases
|
|
172
|
+
for number spelling, raw Unicode, UTF-16 member ordering, large integers,
|
|
173
|
+
duplicates, non-finite values and the required marker.
|
|
166
174
|
|
|
167
175
|
## What it does not do
|
|
168
176
|
|
package/dist/cjs/audit.d.ts
CHANGED
package/dist/cjs/audit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAKL,KAAK,KAAK,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,OAAO,QAAiB,CAAC;AAEtC,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEhD,0EAA0E;AAC1E,MAAM,WAAW,IAAI;IACnB,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC;AAED,oDAAoD;AACpD,MAAM,WAAW,MAAM;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAKxE;AAeD,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;CACzB;AAED,8CAA8C;AAC9C,qBAAa,QAAQ;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAE9C;;;;OAIG;gBACS,IAAI,GAAE,YAAY,GAAG,MAAM,GAAG,IAAS;IAUnD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,GAAE,WAAgB,GAAG,WAAW;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/audit.js
CHANGED
|
@@ -64,6 +64,7 @@ class AuditLog {
|
|
|
64
64
|
append(event, ts, fields = {}) {
|
|
65
65
|
const payload = {
|
|
66
66
|
v: exports.SCHEMA_VERSION,
|
|
67
|
+
c14n: "JCS",
|
|
67
68
|
seq: this.seq,
|
|
68
69
|
ts,
|
|
69
70
|
event,
|
|
@@ -75,9 +76,7 @@ class AuditLog {
|
|
|
75
76
|
this.seq += 1;
|
|
76
77
|
this._entries.push(payload);
|
|
77
78
|
if (this.path) {
|
|
78
|
-
|
|
79
|
-
// its DEFAULT separators, not the compact pair the hash is taken over.
|
|
80
|
-
(0, node_fs_1.appendFileSync)(this.path, (0, canonical_js_1.pyJsonDumps)(payload) + "\n");
|
|
79
|
+
(0, node_fs_1.appendFileSync)(this.path, (0, canonical_js_1.canonicalJson)(payload) + "\n");
|
|
81
80
|
}
|
|
82
81
|
for (const sink of this.sinks)
|
|
83
82
|
sink.write(payload);
|
|
@@ -111,7 +110,7 @@ class AuditLog {
|
|
|
111
110
|
*/
|
|
112
111
|
anchor(signer, ts = 0) {
|
|
113
112
|
const [seq, head] = this.head();
|
|
114
|
-
const body = { v: exports.SCHEMA_VERSION, chain_id: this.chainIdHint(), seq, head, ts };
|
|
113
|
+
const body = { v: exports.SCHEMA_VERSION, c14n: "JCS", chain_id: this.chainIdHint(), seq, head, ts };
|
|
115
114
|
return {
|
|
116
115
|
...body,
|
|
117
116
|
kid: signer.kid ?? null,
|
|
@@ -121,8 +120,10 @@ class AuditLog {
|
|
|
121
120
|
/** The chain reproduces AND its head matches a SIGNED anchor. */
|
|
122
121
|
static verifyAnchor(entries, anchor, signer) {
|
|
123
122
|
const a = anchor ?? {};
|
|
123
|
+
if ((0, canonical_js_1.toPlain)(a["c14n"]) !== "JCS")
|
|
124
|
+
return [false, "anchor canonicalization is not JCS"];
|
|
124
125
|
const body = {};
|
|
125
|
-
for (const k of ["v", "chain_id", "seq", "head", "ts"])
|
|
126
|
+
for (const k of ["v", "c14n", "chain_id", "seq", "head", "ts"])
|
|
126
127
|
body[k] = a[k] ?? null;
|
|
127
128
|
const sigHex = (0, canonical_js_1.toPlain)(a["sig"]) ?? "";
|
|
128
129
|
if (typeof sigHex !== "string" || !/^(?:[0-9a-fA-F]{2})*$/.test(sigHex)) {
|
|
@@ -149,6 +150,9 @@ class AuditLog {
|
|
|
149
150
|
let prev = exports.GENESIS;
|
|
150
151
|
let expectedSeq = 0;
|
|
151
152
|
for (const e of entries) {
|
|
153
|
+
if ((0, canonical_js_1.toPlain)(e["c14n"]) !== "JCS") {
|
|
154
|
+
return [false, `canonicalization is not JCS at seq ${expectedSeq}`];
|
|
155
|
+
}
|
|
152
156
|
const seq = asNumber(e["seq"]);
|
|
153
157
|
if (seq !== expectedSeq) {
|
|
154
158
|
return [false, `seq gap at ${expectedSeq} (got ${formatSeq(e["seq"])})`];
|
package/dist/cjs/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/audit.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/canonical.d.ts
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* (1) and (2) are handled by `canonicalJson` below. (3) cannot be solved by a
|
|
18
|
-
* serialiser alone, because a JavaScript `number` has forgotten whether the
|
|
19
|
-
* document said `100` or `100.0`. So a document that is going to be re-hashed —
|
|
20
|
-
* a ledger or a bundle produced elsewhere — is read with `parseJson`, which
|
|
21
|
-
* keeps each number's original literal alongside its value as a `RawNumber`.
|
|
22
|
-
* `canonicalJson` re-emits that literal verbatim, so a Python-written entry
|
|
23
|
-
* hashes to the byte-identical digest here. Values created in this library are
|
|
24
|
-
* plain numbers, and `pyNumber` formats them the way Python's `json` would, so
|
|
25
|
-
* the reverse direction round-trips too.
|
|
26
|
-
*/
|
|
27
|
-
/** A number as it was written in the source document, plus its parsed value. */
|
|
1
|
+
/** RFC 8785 JSON Canonicalization Scheme (JCS), with no runtime dependencies. */
|
|
2
|
+
export declare class CanonicalizationError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class NonFiniteNumberError extends CanonicalizationError {
|
|
6
|
+
}
|
|
7
|
+
export declare class LoneSurrogateError extends CanonicalizationError {
|
|
8
|
+
}
|
|
9
|
+
export declare class UnsupportedTypeError extends CanonicalizationError {
|
|
10
|
+
}
|
|
11
|
+
/** Raised while parsing when an object repeats a member name. */
|
|
12
|
+
export declare class DuplicateMemberError extends SyntaxError {
|
|
13
|
+
readonly member: string;
|
|
14
|
+
constructor(member: string);
|
|
15
|
+
}
|
|
16
|
+
/** A parsed JSON number, retaining its source spelling for syntax-sensitive checks. */
|
|
28
17
|
export declare class RawNumber {
|
|
29
18
|
readonly raw: string;
|
|
30
19
|
readonly value: number;
|
|
@@ -32,60 +21,23 @@ export declare class RawNumber {
|
|
|
32
21
|
valueOf(): number;
|
|
33
22
|
toJSON(): number;
|
|
34
23
|
}
|
|
35
|
-
/** A JSON value that may still carry original number literals. */
|
|
36
24
|
export type CJson = null | boolean | number | string | RawNumber | CJson[] | {
|
|
37
25
|
[key: string]: CJson;
|
|
38
26
|
};
|
|
39
|
-
/** A plain JSON value — what the rest of the library works with. */
|
|
40
27
|
export type Json = null | boolean | number | string | Json[] | {
|
|
41
28
|
[key: string]: Json;
|
|
42
29
|
};
|
|
43
|
-
/** Compare
|
|
30
|
+
/** Compare by Unicode code point for semantic lists that mirror Python `sorted`. */
|
|
44
31
|
export declare function compareCodePoints(a: string, b: string): number;
|
|
45
|
-
/** Sort strings by code point (Python's `sorted(list_of_str)`). */
|
|
46
32
|
export declare function sortedStrings(values: Iterable<string>): string[];
|
|
47
|
-
/**
|
|
48
|
-
* Format a number the way Python's `json.dumps` would.
|
|
49
|
-
*
|
|
50
|
-
* Integral values are emitted without a decimal point, matching a Python `int`.
|
|
51
|
-
* A TypeScript number cannot record that it was meant to be the float `100.0`,
|
|
52
|
-
* so such a value serialises as `100`; Python reads that back as an `int` and
|
|
53
|
-
* re-emits `100`, which keeps the chain verifiable in both directions. Values
|
|
54
|
-
* with a fractional part follow CPython's `repr`: shortest round-tripping
|
|
55
|
-
* digits, exponential notation when the decimal exponent is below -4 or at
|
|
56
|
-
* least 16, a two-digit signed exponent, and always a decimal point otherwise.
|
|
57
|
-
*/
|
|
33
|
+
/** Python-style numeric display used only in human-readable ceiling descriptions. */
|
|
58
34
|
export declare function pyNumber(n: number): string;
|
|
59
|
-
/**
|
|
60
|
-
export declare function pyString(s: string): string;
|
|
61
|
-
/**
|
|
62
|
-
* Serialise to the exact bytes Python's
|
|
63
|
-
* `json.dumps(obj, sort_keys=True, separators=(",", ":"))` produces:
|
|
64
|
-
* sorted keys, no incidental whitespace, ASCII-escaped strings.
|
|
65
|
-
*
|
|
66
|
-
* Object entries whose value is `undefined` are omitted, matching a Python dict
|
|
67
|
-
* that simply never held the key. `null` is kept — it is a value.
|
|
68
|
-
*/
|
|
35
|
+
/** Return an RFC 8785 canonical JSON string. */
|
|
69
36
|
export declare function canonicalJson(value: CJson | undefined): string;
|
|
70
|
-
/**
|
|
71
|
-
* Serialise with sorted keys and ASCII escaping, choosing the separators.
|
|
72
|
-
*
|
|
73
|
-
* `canonicalJson` uses the compact `(",", ":")` pair every hash is taken over.
|
|
74
|
-
* The `.jsonl` ledger on disk is written with Python's DEFAULT separators
|
|
75
|
-
* (`", "` and `": "`), so a line read back by either language re-serialises to
|
|
76
|
-
* the same bytes its writer produced.
|
|
77
|
-
*/
|
|
78
|
-
export declare function pyJsonDumps(value: CJson | undefined, itemSeparator?: string, keySeparator?: string): string;
|
|
79
|
-
/** The canonical bytes — what every hash, seal and signature is taken over. */
|
|
37
|
+
/** The canonical UTF-8 bytes used by every hash, seal, and signature. */
|
|
80
38
|
export declare function canonicalBytes(value: CJson | undefined): Buffer;
|
|
81
39
|
/** Strip `RawNumber` wrappers, yielding ordinary JavaScript values. */
|
|
82
40
|
export declare function toPlain<T = Json>(value: CJson | undefined): T;
|
|
83
|
-
/**
|
|
84
|
-
* Parse JSON, keeping every number's original literal.
|
|
85
|
-
*
|
|
86
|
-
* `JSON.parse` is not used: it discards the literal, and with it the ability to
|
|
87
|
-
* reproduce the bytes the writer hashed. Objects preserve their key order for
|
|
88
|
-
* readability; canonical serialisation sorts them anyway.
|
|
89
|
-
*/
|
|
41
|
+
/** Parse JSON without losing number spellings, while rejecting duplicates. */
|
|
90
42
|
export declare function parseJson(text: string): CJson;
|
|
91
43
|
//# sourceMappingURL=canonical.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,oBAAqB,SAAQ,qBAAqB;CAAG;AAClE,qBAAa,kBAAmB,SAAQ,qBAAqB;CAAG;AAChE,qBAAa,oBAAqB,SAAQ,qBAAqB;CAAG;AAElE,iEAAiE;AACjE,qBAAa,oBAAqB,SAAQ,WAAW;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;CAIpC;AAED,uFAAuF;AACvF,qBAAa,SAAS;IAElB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM;gBADb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM;IAExB,OAAO,IAAI,MAAM;IAGjB,MAAM,IAAI,MAAM;CAGjB;AAED,MAAM,MAAM,KAAK,GACb,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,KAAK,EAAE,GACP;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,CAAC;AAE7B,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEvF,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAEhE;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB1C;AAuGD,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAE/D;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,CAAC,CAgB7D;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAO7C"}
|