@certrev/cert-block 0.1.0 → 0.1.2
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/dist/builder/index.d.ts +73 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +63 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/contract/fixtures.d.ts +1 -1
- package/dist/contract/fixtures.d.ts.map +1 -1
- package/dist/contract/fixtures.js +8 -4
- package/dist/contract/fixtures.js.map +1 -1
- package/dist/contract/kernel.d.ts +2 -2
- package/dist/contract/kernel.js +2 -2
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/verify/get-verified-envelope.d.ts.map +1 -1
- package/dist/verify/get-verified-envelope.js +28 -4
- package/dist/verify/get-verified-envelope.js.map +1 -1
- package/dist/verify/resolve-kid.d.ts.map +1 -1
- package/dist/verify/resolve-kid.js +3 -1
- package/dist/verify/resolve-kid.js.map +1 -1
- package/package.json +77 -69
- package/src/__tests__/verify.test.ts +36 -0
- package/src/builder/__tests__/builder.test.tsx +81 -0
- package/src/builder/index.tsx +100 -0
- package/src/contract/fixtures.ts +13 -9
- package/src/contract/kernel.ts +2 -2
- package/src/index.ts +11 -6
- package/src/verify/get-verified-envelope.ts +29 -4
- package/src/verify/resolve-kid.ts +3 -1
- package/dist/contract/kernel-contract.d.ts +0 -154
- package/dist/contract/kernel-contract.d.ts.map +0 -1
- package/dist/contract/kernel-contract.js +0 -35
- package/dist/contract/kernel-contract.js.map +0 -1
- package/dist/contract/kernel-stub.d.ts +0 -44
- package/dist/contract/kernel-stub.d.ts.map +0 -1
- package/dist/contract/kernel-stub.js +0 -163
- package/dist/contract/kernel-stub.js.map +0 -1
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
-
* VerdictKernel — LOCAL STUB (delete on publish; mirrors @certrev/cert-contract)
|
|
4
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
-
*
|
|
6
|
-
* A faithful, self-contained implementation of the cert-contract VerdictKernel so the
|
|
7
|
-
* SDK's verify layer + tests run NOW, before `@certrev/cert-contract` publishes to a
|
|
8
|
-
* registry this workspace installs from. The behavior is identical to the real kernel:
|
|
9
|
-
* • Ed25519 detached signature verified over the RFC-8785 (JCS) canonical bytes of
|
|
10
|
-
* `payload` (lexicographic key order, minimal whitespace, UTF-8).
|
|
11
|
-
* • Fail-closed pipeline: shape → alg → kid → signature → platform → subject →
|
|
12
|
-
* revoked → expired → drift → render. Any failure short-circuits to `suppress`.
|
|
13
|
-
* • Never throws on a bad envelope — a malformed input / throwing resolver fails
|
|
14
|
-
* closed to `suppress`, not to an exception a caller might swallow into a render.
|
|
15
|
-
*
|
|
16
|
-
* The byte-identical canonicalization across PHP / Node is what makes the credential
|
|
17
|
-
* portable; here we hand-roll a deterministic JCS serializer (sufficient for the
|
|
18
|
-
* envelope's all-string/number/bool/array/object shape — no exotic numbers) so the SDK
|
|
19
|
-
* carries no production crypto-canonicalization of its own that could DRIFT from the
|
|
20
|
-
* contract. On publish, the real `canonicalize` (RFC 8785) from cert-contract is used.
|
|
21
|
-
*
|
|
22
|
-
* INTEGRATION: delete this file + `./kernel-contract.ts`; import `verifyEnvelope`,
|
|
23
|
-
* `renderVerdict`, `verifySignatureOnly`, `toEd25519PublicKey` from
|
|
24
|
-
* `@certrev/cert-contract`. See README "Integration TODOs".
|
|
25
|
-
*/
|
|
26
|
-
import { createPublicKey, verify as nodeVerify } from 'node:crypto';
|
|
27
|
-
import { CONTRACT_VERSION, SIGNATURE_ALG } from './kernel-contract.js';
|
|
28
|
-
// ── RFC-8785 (JCS) canonicalization — minimal, deterministic, envelope-shaped ─────
|
|
29
|
-
/**
|
|
30
|
-
* Serialize a JSON value to its RFC-8785 canonical string form: object keys sorted by
|
|
31
|
-
* UTF-16 code unit, no insignificant whitespace, JSON string escaping. The payload is
|
|
32
|
-
* all strings / finite numbers / booleans / null / arrays / objects, so we do NOT need
|
|
33
|
-
* the full ECMAScript number-formatting machinery the production `canonicalize` package
|
|
34
|
-
* implements — integers + ISO strings serialize identically either way. This stub
|
|
35
|
-
* exists only so tests run; the published path uses cert-contract's vetted JCS.
|
|
36
|
-
*/
|
|
37
|
-
function jcs(value) {
|
|
38
|
-
if (value === null)
|
|
39
|
-
return 'null';
|
|
40
|
-
const t = typeof value;
|
|
41
|
-
if (t === 'string')
|
|
42
|
-
return JSON.stringify(value);
|
|
43
|
-
if (t === 'number') {
|
|
44
|
-
if (!Number.isFinite(value))
|
|
45
|
-
throw new Error('jcs: non-finite number');
|
|
46
|
-
return JSON.stringify(value);
|
|
47
|
-
}
|
|
48
|
-
if (t === 'boolean')
|
|
49
|
-
return value ? 'true' : 'false';
|
|
50
|
-
if (Array.isArray(value)) {
|
|
51
|
-
return `[${value.map((v) => jcs(v)).join(',')}]`;
|
|
52
|
-
}
|
|
53
|
-
if (t === 'object') {
|
|
54
|
-
const obj = value;
|
|
55
|
-
const keys = Object.keys(obj)
|
|
56
|
-
.filter((k) => obj[k] !== undefined)
|
|
57
|
-
.sort();
|
|
58
|
-
return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(obj[k])}`).join(',')}}`;
|
|
59
|
-
}
|
|
60
|
-
throw new Error(`jcs: unsupported value type ${t}`);
|
|
61
|
-
}
|
|
62
|
-
function canonicalPayloadBytes(payload) {
|
|
63
|
-
return new TextEncoder().encode(jcs(payload));
|
|
64
|
-
}
|
|
65
|
-
function base64urlDecode(s) {
|
|
66
|
-
return new Uint8Array(Buffer.from(s, 'base64url'));
|
|
67
|
-
}
|
|
68
|
-
const RAW_SPKI_PREFIX = Uint8Array.from([0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00]);
|
|
69
|
-
/** Mirror of cert-contract's `toEd25519PublicKey` for the input encodings the SDK uses. */
|
|
70
|
-
function toEd25519PublicKey(input) {
|
|
71
|
-
switch (input.format) {
|
|
72
|
-
case 'pem':
|
|
73
|
-
return createPublicKey({ key: input.pem, format: 'pem' });
|
|
74
|
-
case 'spki-base64':
|
|
75
|
-
return createPublicKey({ key: Buffer.from(input.base64, 'base64'), format: 'der', type: 'spki' });
|
|
76
|
-
case 'spki-der':
|
|
77
|
-
return createPublicKey({ key: Buffer.from(input.bytes), format: 'der', type: 'spki' });
|
|
78
|
-
case 'raw': {
|
|
79
|
-
if (input.bytes.length !== 32) {
|
|
80
|
-
throw new Error(`ed25519 raw public key must be 32 bytes, got ${input.bytes.length}`);
|
|
81
|
-
}
|
|
82
|
-
const spki = new Uint8Array(RAW_SPKI_PREFIX.length + 32);
|
|
83
|
-
spki.set(RAW_SPKI_PREFIX, 0);
|
|
84
|
-
spki.set(input.bytes, RAW_SPKI_PREFIX.length);
|
|
85
|
-
return createPublicKey({ key: Buffer.from(spki), format: 'der', type: 'spki' });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function verifyDetached(payload, sigBase64url, publicKey) {
|
|
90
|
-
try {
|
|
91
|
-
return nodeVerify(null, canonicalPayloadBytes(payload), publicKey, base64urlDecode(sigBase64url));
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
async function verifyCryptographic(envelope, resolveKid) {
|
|
98
|
-
const { payload, signature } = envelope ?? {};
|
|
99
|
-
if (!payload || !signature || payload.contractVersion !== CONTRACT_VERSION) {
|
|
100
|
-
return { ok: false, reason: 'unsupported_contract_version' };
|
|
101
|
-
}
|
|
102
|
-
if (signature.alg !== SIGNATURE_ALG) {
|
|
103
|
-
return { ok: false, reason: 'unsupported_alg' };
|
|
104
|
-
}
|
|
105
|
-
const resolved = await resolveKid(signature.kid);
|
|
106
|
-
if (!resolved) {
|
|
107
|
-
return { ok: false, reason: 'unknown_key' };
|
|
108
|
-
}
|
|
109
|
-
let key;
|
|
110
|
-
try {
|
|
111
|
-
key = toEd25519PublicKey(resolved);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
return { ok: false, reason: 'unknown_key' };
|
|
115
|
-
}
|
|
116
|
-
if (!verifyDetached(payload, signature.sig, key)) {
|
|
117
|
-
return { ok: false, reason: 'invalid_signature' };
|
|
118
|
-
}
|
|
119
|
-
return { ok: true };
|
|
120
|
-
}
|
|
121
|
-
/** Phase-2-only policy verdict over an already-authentic payload. Pure + synchronous. */
|
|
122
|
-
export function renderVerdict(payload, ctx) {
|
|
123
|
-
const now = ctx.now ?? new Date();
|
|
124
|
-
if (payload.subject.platform !== ctx.platform) {
|
|
125
|
-
return { decision: 'suppress', reason: 'platform_mismatch' };
|
|
126
|
-
}
|
|
127
|
-
if (payload.subject.externalId !== ctx.externalId) {
|
|
128
|
-
return { decision: 'suppress', reason: 'subject_mismatch' };
|
|
129
|
-
}
|
|
130
|
-
if (payload.lifecycle.revokedAt !== null) {
|
|
131
|
-
return { decision: 'suppress', reason: 'revoked' };
|
|
132
|
-
}
|
|
133
|
-
if (now.getTime() >= Date.parse(payload.lifecycle.expiresAt)) {
|
|
134
|
-
return { decision: 'suppress', reason: 'expired' };
|
|
135
|
-
}
|
|
136
|
-
const bound = payload.subject.contentDigest;
|
|
137
|
-
const live = ctx.liveContentHash;
|
|
138
|
-
if (bound !== null && live != null && bound !== live) {
|
|
139
|
-
return { decision: 'suppress', reason: 'content_drift' };
|
|
140
|
-
}
|
|
141
|
-
return { decision: 'render', payload };
|
|
142
|
-
}
|
|
143
|
-
/** Phase-1-only cryptographic verification. */
|
|
144
|
-
export async function verifySignatureOnly(envelope, resolveKid) {
|
|
145
|
-
return verifyCryptographic(envelope, resolveKid);
|
|
146
|
-
}
|
|
147
|
-
/** Full kernel: verify signature, then apply policy. Fail-closed, never throws. */
|
|
148
|
-
export async function verifyEnvelope(envelope, resolveKid, ctx) {
|
|
149
|
-
let crypto;
|
|
150
|
-
try {
|
|
151
|
-
crypto = await verifyCryptographic(envelope, resolveKid);
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
return { decision: 'suppress', reason: 'unknown_key' };
|
|
155
|
-
}
|
|
156
|
-
if (!crypto.ok) {
|
|
157
|
-
return { decision: 'suppress', reason: crypto.reason };
|
|
158
|
-
}
|
|
159
|
-
return renderVerdict(envelope.payload, ctx);
|
|
160
|
-
}
|
|
161
|
-
/** Re-export for tests that need to build a public key from raw/spki bytes. */
|
|
162
|
-
export { toEd25519PublicKey };
|
|
163
|
-
//# sourceMappingURL=kernel-stub.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kernel-stub.js","sourceRoot":"","sources":["../../src/contract/kernel-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,UAAU,EAAE,MAAM,aAAa,CAAA;AAUnF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEtE,qFAAqF;AACrF;;;;;;;GAOG;AACH,SAAS,GAAG,CAAC,KAAc;IAC1B,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IACjC,MAAM,CAAC,GAAG,OAAO,KAAK,CAAA;IACtB,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAChD,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAe,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAChF,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;IACD,IAAI,CAAC,KAAK,SAAS;QAAE,OAAQ,KAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;IACjD,CAAC;IACD,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,KAAgC,CAAA;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;aAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;aACnC,IAAI,EAAE,CAAA;QACR,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;IAC/E,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAA;AACpD,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAoB;IAClD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;AAC9C,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IACjC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AAEjH,2FAA2F;AAC3F,SAAS,kBAAkB,CAAC,KAA4B;IACvD,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,KAAK;YACT,OAAO,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1D,KAAK,aAAa;YACjB,OAAO,eAAe,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QAClG,KAAK,UAAU;YACd,OAAO,eAAe,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACvF,KAAK,KAAK,CAAC,CAAC,CAAC;YACZ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,gDAAgD,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;YACtF,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,eAAe,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;YACxD,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;YAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;YAC7C,OAAO,eAAe,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QAChF,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,cAAc,CAAC,OAAoB,EAAE,YAAoB,EAAE,SAAoB;IACvF,IAAI,CAAC;QACJ,OAAO,UAAU,CAAC,IAAI,EAAE,qBAAqB,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC,CAAA;IAClG,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC;AAID,KAAK,UAAU,mBAAmB,CACjC,QAA8B,EAC9B,UAAiC;IAEjC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,IAAK,EAA2B,CAAA;IACvE,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,eAAe,KAAK,gBAAgB,EAAE,CAAC;QAC5E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAA;IAC7D,CAAC;IACD,IAAI,SAAS,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;QACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAChD,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;IAC5C,CAAC;IACD,IAAI,GAAc,CAAA;IAClB,IAAI,CAAC;QACJ,GAAG,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;IAC5C,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAA;IAClD,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AACpB,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,aAAa,CAAC,OAAoB,EAAE,GAAkB;IACrE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;IACjC,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC/C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAA;IAC7D,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC;QACnD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAC5D,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACnD,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACnD,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAA;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAA;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;IACzD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AACvC,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,QAA8B,EAC9B,UAAiC;IAEjC,OAAO,mBAAmB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;AACjD,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,QAA8B,EAC9B,UAAiC,EACjC,GAAkB;IAElB,IAAI,MAAoB,CAAA;IACxB,IAAI,CAAC;QACJ,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACzD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAA;IACvD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IACvD,CAAC;IACD,OAAO,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAC5C,CAAC;AAED,+EAA+E;AAC/E,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|