@forestrie/receipt-verify 2.1.0 → 3.0.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.
@@ -17,7 +17,7 @@
17
17
  import { COSE_LABEL_PEAK_RECEIPTS, COSE_LABEL_VDP, decodeCborDeterministic, encodeCborDeterministic, readProtectedTreeSize2, } from "@forestrie/encoding";
18
18
  import { calculateRoot, inclusionProof, massifIndexFromMMRIndex, openMassifNodeStore, peakIndexForLeafProof, } from "@forestrie/merklelog";
19
19
  import { requireCoseSign1, toHeaderMap, unwrapCoseSign1Tag, } from "./parse-receipt.js";
20
- import { decodeConsistencyProofFromUnprotected } from "./decode-checkpoint-consistency-proof.js";
20
+ import { decodeConsistencyProofsFromUnprotected } from "./decode-checkpoint-consistency-proof.js";
21
21
  import { SubtleHasher } from "./subtle-hasher.js";
22
22
  /** Not in scope for the shared cose-labels module (FOR-568 §4.1). */
23
23
  const DELEGATION_CERT_LABEL = 1000;
@@ -158,20 +158,24 @@ function cborBytes(value) {
158
158
  * (ADR-0066 D1 as amended, label -65933) from the PROTECTED header — not the
159
159
  * unprotected consistency proof's declared value, which a checkpoint without
160
160
  * a signing key could freely restate (ADR-0066's "keyless first checkpoint"
161
- * case). A consistency proof must still be present (an unsigned checkpoint
162
- * with no proof is not sealed at all); its declared sizes are not otherwise
163
- * used here — {@link checkpointConsistencyProof} in `checkpoint-chain.ts`
164
- * is the validating decode that requires the two to agree.
161
+ * case). At least one consistency proof must still be present (an unsigned
162
+ * checkpoint with no proof is not sealed at all) — one or more, since a
163
+ * checkpoint may relay a chain of sealed steps under one signature
164
+ * (ADR-0066 D2). Their declared sizes are not otherwise used here;
165
+ * {@link checkpointConsistencyProof} in `checkpoint-chain.ts` is the
166
+ * validating decode that requires the signed size and the last relayed
167
+ * proof's to agree.
165
168
  *
166
- * Lenient by design: an absent proof, a malformed proof, or an absent or
167
- * malformed signed tree-size-2 all yield `null` rather than a throw, so a
168
- * caller of {@link parseCheckpoint} sees exactly the same "not verifiable"
169
- * outcome either way.
169
+ * Lenient by design: an absent proof, an empty or malformed
170
+ * consistency-proofs array, or an absent or malformed signed tree-size-2
171
+ * all yield `null` rather than a throw, so a caller of
172
+ * {@link parseCheckpoint} sees exactly the same "not verifiable" outcome
173
+ * either way.
170
174
  */
171
175
  function sealedSizeFromCheckpoint(coseSign1, unprotected) {
172
176
  let declared;
173
177
  try {
174
- declared = decodeConsistencyProofFromUnprotected(unprotected);
178
+ declared = decodeConsistencyProofsFromUnprotected(unprotected);
175
179
  }
176
180
  catch {
177
181
  return null;
@@ -1,19 +1,50 @@
1
- /** Draft-bryce consistency proof embedded in a v3 checkpoint. `treeSize2` is
2
- * cross-checked against the checkpoint's SIGNED tree-size-2 (ADR-0066 D1 as
3
- * amended); `treeSize1` is unsigned prover context, not cross-checked here —
4
- * see {@link verifyCheckpointChain}, which compares it with the trusted
5
- * origin instead. */
1
+ import { EmptyConsistencyProofsError, type DecodedConsistencyProof } from "./decode-checkpoint-consistency-proof.js";
2
+ /**
3
+ * The draft-bryce consistency proofs embedded in a v3 checkpoint: one or
4
+ * more, in relay order (`consistency-proofs = [ + consistency-proof ]`,
5
+ * ADR-0066 D2). A checkpoint sealing a single step carries the chain of
6
+ * one; there is no separate single-proof shape.
7
+ *
8
+ * {@link treeSize2} — the LAST proof's — is cross-checked against the
9
+ * checkpoint's SIGNED tree-size-2 (ADR-0066 D1 as amended, D5.5).
10
+ * {@link treeSize1} — the FIRST proof's — is unsigned prover context, not
11
+ * cross-checked here; see {@link verifyCheckpointChain}, which compares it
12
+ * with the trusted origin instead. The sizes between the two are named by
13
+ * no signature: {@link computeCheckpointAccumulator} holds the chain
14
+ * together by requiring each proof to continue the one before it.
15
+ */
6
16
  export type CheckpointConsistencyProof = {
17
+ /** The relayed proofs, in chain order; never empty. */
18
+ proofs: DecodedConsistencyProof[];
19
+ /** `tree-size-1` of the FIRST proof: the size the chain continues from. */
7
20
  treeSize1: bigint;
21
+ /** `tree-size-2` of the LAST proof: the size the chain reaches. */
8
22
  treeSize2: bigint;
9
23
  /** Signed `tree-size-2` (protected header label -65933); equal to
10
24
  * {@link treeSize2} — {@link checkpointConsistencyProof} enforces this. */
11
25
  signedTreeSize2: bigint;
12
- /** One inclusion path per tree-size-1 peak, proven at tree-size-2. */
13
- paths: Uint8Array[][];
14
- /** New peaks not covered by the proven roots (draft `right-peaks`). */
15
- rightPeaks: Uint8Array[];
16
26
  };
27
+ /**
28
+ * A relayed consistency-proof chain does not join up: a proof's declared
29
+ * `tree-size-1` is not the size the fold has reached — the caller's trusted
30
+ * size for the first proof, the previous proof's `tree-size-2` after that —
31
+ * or, having applied every proof, the fold reaches a size other than the
32
+ * chain link's own declared `tree-size-2` (F3: a caller-assembled link —
33
+ * `freshenReceipt` callers build these from on-chain calldata, never
34
+ * through {@link checkpointConsistencyProof} — can set `proofs` and
35
+ * `treeSize2` independently, which `checkpointConsistencyProof` itself
36
+ * never allows to disagree). go-merklelog reuses its equivalent
37
+ * `ErrProofChainNotContiguous` for this same end-of-chain comparison
38
+ * (`checkpointverify.go:245-251`, folded size vs. signed size). Reported as
39
+ * `"size_mismatch"` by {@link verifyCheckpointChain}, the same as any other
40
+ * size disagreement, because the sizes it names are unsigned (ADR-0066 D2):
41
+ * nothing distinguishes a relay assembled in the wrong order from one
42
+ * assembled over a different log.
43
+ */
44
+ export declare class ConsistencyChainNotContiguousError extends Error {
45
+ constructor(message: string);
46
+ }
47
+ export { EmptyConsistencyProofsError };
17
48
  /**
18
49
  * The checkpoint's SIGNED `tree-size-2` (protected header, ADR-0066 D1 as
19
50
  * amended) differs from the declared `tree-size-2` of its embedded
@@ -40,12 +71,29 @@ export declare class CheckpointHighSSignatureError extends Error {
40
71
  constructor(message: string);
41
72
  }
42
73
  /**
43
- * Decode the embedded consistency proof (`vdp` 396 key -2) and require its
44
- * declared `tree-size-2` to equal the checkpoint's SIGNED `tree-size-2` from
45
- * the protected header (ADR-0066 D1 as amended, D5.5, label -65933).
46
- * `tree-size-1` is not signed and is not checked here (D2 is withdrawn); see
47
- * {@link verifyCheckpointChain} for its comparison against the trusted
48
- * origin.
74
+ * The checkpoint's protected header carries no integer `alg` (label 1).
75
+ *
76
+ * The univocity contract rejects such a header outright — the structural
77
+ * walk finds the size, and the `alg` requirement in the same call raises
78
+ * `ClaimNotFound(1)` or `UnexpectedMajorType`. Off-chain the header used to
79
+ * read as "no algorithm stated", which both turned OFF the high-s rejection
80
+ * below (gated on the algorithm being ES256) and still yielded a signed size
81
+ * to fold from — so a checkpoint the chain will never anchor verified here
82
+ * under weaker rules than a well-formed one (review finding S-1). Reported
83
+ * as `"proof_malformed"` by {@link verifyCheckpointChain}.
84
+ */
85
+ export declare class CheckpointProtectedHeaderAlgError extends Error {
86
+ constructor(message: string);
87
+ }
88
+ /**
89
+ * Decode the embedded consistency proofs (`vdp` 396 key -2, one or more in
90
+ * relay order) and require the LAST proof's declared `tree-size-2` to equal
91
+ * the checkpoint's SIGNED `tree-size-2` from the protected header (ADR-0066
92
+ * D1 as amended, D2, D5.5, label -65933). The earlier proofs' sizes are not
93
+ * signed: the fold checks them against each other
94
+ * ({@link computeCheckpointAccumulator}). `tree-size-1` is not signed
95
+ * either; see {@link verifyCheckpointChain} for its comparison against the
96
+ * trusted origin.
49
97
  *
50
98
  * Also rejects a malleable high-s ES256 signature (see
51
99
  * {@link CheckpointHighSSignatureError}) before any fold or WebCrypto verify
@@ -53,36 +101,60 @@ export declare class CheckpointHighSSignatureError extends Error {
53
101
  * subject to this check, since it does not go through the P-256 WebCrypto
54
102
  * path this guards.
55
103
  *
56
- * @throws {Error} when the protected header carries no consistency proof,
57
- * the proof is structurally malformed (see
58
- * {@link decodeConsistencyProofFromUnprotected}), or the protected header
104
+ * @throws {Error} when the unprotected header carries no consistency proof,
105
+ * a proof is structurally malformed (see
106
+ * {@link decodeConsistencyProofsFromUnprotected}), or the protected header
59
107
  * carries no signed tree-size-2 label
108
+ * @throws {EmptyConsistencyProofsError} when the consistency-proofs array is
109
+ * present but empty
60
110
  * @throws {CheckpointSignedSizeMismatchError} when the signed tree-size-2
61
- * differs from the declared proof's tree-size-2
111
+ * differs from the LAST declared proof's tree-size-2
62
112
  * @throws {CheckpointHighSSignatureError} when the checkpoint is ES256-signed
63
113
  * with a high-s (malleable) signature
114
+ * @throws {CheckpointProtectedHeaderAlgError} when the protected header
115
+ * carries no integer `alg` (label 1)
64
116
  */
65
117
  export declare function checkpointConsistencyProof(checkpointBytes: Uint8Array): CheckpointConsistencyProof;
66
118
  /**
67
- * One fold step: from the CALLER-TRUSTED accumulator at `sizeFrom`, produce
68
- * the `proof.treeSize2` accumulator via the size-driven
69
- * {@link consistentRootsForSizes} (ADR-0066 D5) — `roots` (the proven
70
- * prefix) followed by the proof's supplied right-peaks (the target peaks no
71
- * path reaches).
119
+ * Fold a checkpoint's relayed consistency proofs, in order, from the
120
+ * CALLER-TRUSTED accumulator at `sizeFrom` to the accumulator at the last
121
+ * proof's `tree-size-2` — the value the checkpoint's signature covers.
122
+ *
123
+ * Each proof is applied by the size-driven {@link consistentRootsForSizes}
124
+ * (ADR-0066 D5), which yields `roots` (the proven prefix); the proof's own
125
+ * right-peaks (the target peaks no path reaches) complete that step's
126
+ * accumulator, and it becomes the next step's input. A checkpoint sealing
127
+ * one step carries the chain of one and runs the same loop once.
128
+ *
129
+ * `sizeFrom` is a parameter, not read off the proofs, because the fold must
130
+ * start from a size the CALLER already trusts (the previous checkpoint's
131
+ * verified `treeSize2`, or the caller's anchor for a first link) — reading
132
+ * it from the relay instead would let an unsigned or substituted proof
133
+ * dictate its own starting point (ADR-0066 D5.4). Every proof after the
134
+ * first is held to the size the previous one reached for the same reason:
135
+ * only the last step's size is signed, so the intermediate sizes are worth
136
+ * no more than their agreement with each other.
72
137
  *
73
- * `sizeFrom` is a parameter, not read off `proof`, because the fold must run
74
- * against a size the CALLER already trusts (the previous link's verified
75
- * `treeSize2`, or the caller's anchor for a first link) — reading it from
76
- * the proof instead would let an unsigned or substituted proof dictate its
77
- * own starting point. `proof.treeSize1` must equal it regardless: the two
78
- * disagreeing means this proof does not continue from the state being
79
- * folded, not a mere shape defect, so it is checked before any fold work.
138
+ * `proof.proofs` must hold at least one step and, once every step has been
139
+ * applied, the fold must have reached exactly `proof.treeSize2` (F3).
140
+ * `checkpointConsistencyProof` already guarantees both — the decode rejects
141
+ * an empty `consistency-proofs` array (`EmptyConsistencyProofsError`) and
142
+ * sets `treeSize2` from the last decoded proof — but a caller-assembled
143
+ * link (`freshenReceipt` callers building from on-chain calldata) is not
144
+ * decoded through it, so both are re-checked here rather than trusted from
145
+ * the type.
80
146
  *
81
- * @throws {Error} when `proof.treeSize1 !== sizeFrom`, or when the proof
82
- * supplies a right-peaks count other than
147
+ * @throws {EmptyConsistencyProofsError} when `proof.proofs` is empty — an
148
+ * already-decoded link the caller assembled themselves rather than one
149
+ * `checkpointConsistencyProof` produced, which never returns one
150
+ * @throws {ConsistencyChainNotContiguousError} when the first proof's
151
+ * `treeSize1` is not `sizeFrom`, a later proof's `treeSize1` is not the
152
+ * previous proof's `treeSize2`, or the size the fold reaches after every
153
+ * proof is not `proof.treeSize2`
154
+ * @throws {Error} when a proof supplies a right-peaks count other than
83
155
  * {@link consistentRootsForSizes}'s `expectedRight`
84
- * @throws {ConsistencyShapeError} (`@forestrie/merklelog`) when the proof
85
- * does not have the shape MMR(sizeFrom) -> MMR(proof.treeSize2) implies
156
+ * @throws {ConsistencyShapeError} (`@forestrie/merklelog`) when a proof does
157
+ * not have the shape its two sizes imply
86
158
  */
87
159
  export declare function computeCheckpointAccumulator(proof: CheckpointConsistencyProof, accumulatorFrom: Uint8Array[], sizeFrom: bigint): Promise<Uint8Array[]>;
88
160
  /** Detached payload the checkpoint signature covers (ADR-0046): the raw
@@ -118,8 +190,10 @@ export type CheckpointChainResult = {
118
190
  * `tree-size-2` (ADR-0066 D1 as amended, D5.5), or a link's declared
119
191
  * `tree-size-1` disagrees with the size the fold starts from — the
120
192
  * caller's `trustedBase.size` (0 with no `trustedBase`) for the
121
- * first link, the previous link's `tree-size-2` after that.
122
- * `detail` names both sizes.
193
+ * first link, the previous link's `tree-size-2` after that — or a
194
+ * relayed proof WITHIN a checkpoint disagrees with the size the
195
+ * proof before it reached ({@link
196
+ * ConsistencyChainNotContiguousError}). `detail` names both sizes.
123
197
  */
124
198
  | "size_mismatch";
125
199
  /** Index of the offending checkpoint. */
@@ -136,23 +210,31 @@ export type CheckpointChainResult = {
136
210
  * as the fold's starting accumulator (a suffix chain rooted in an
137
211
  * already-trusted accumulator supplies both).
138
212
  * - A supplied `trustedBase` must describe a state an MMR can be in: its
139
- * `size` a complete MMR size, and its `accumulator` holding one peak per
140
- * peak of that size. `peaksBitmap` rounds an incomplete size DOWN to the
141
- * largest MMR below it, so without the completeness check a size of 5
142
- * folds the 4 -> N shape while every link reports a base of 5 — a node
143
- * count no MMR has. Both are `proof_malformed`.
213
+ * `size` a complete MMR size, its `accumulator` holding one peak per peak
214
+ * of that size, and every one of those peaks a 32-byte node value.
215
+ * `peaksBitmap` rounds an incomplete size DOWN to the largest MMR below
216
+ * it, so without the completeness check a size of 5 folds the 4 -> N shape
217
+ * while every link reports a base of 5 — a node count no MMR has; and
218
+ * without the byte-length check an origin peak of any length is copied
219
+ * through the empty-path branch into the detached payload. All three are
220
+ * `proof_malformed`.
144
221
  * - The first link's declared `tree-size-1` must equal that trusted
145
222
  * starting size, and every subsequent link's must equal the previous
146
223
  * link's sealed `tree-size-2`; either disagreement is `size_mismatch`.
147
- * `tree-size-1` itself is never compared with a signed value (D2 is
148
- * withdrawn): only this trusted-origin comparison applies. Because it is
224
+ * `tree-size-1` itself is never compared with a signed value (the signed
225
+ * origin ADR-0066 D2 first proposed was withdrawn): only this
226
+ * trusted-origin comparison applies. Because it is
149
227
  * unsigned, the reason it produces carries no more meaning than the size
150
228
  * disagreement itself (ADR-0066 D6: no pre-FOR-410 state is supported, so
151
229
  * there is no drift condition to fall back from).
152
- * - Each checkpoint's SIGNED `tree-size-2` (ADR-0066 D1 as amended) must
153
- * equal its declared consistency-proof `tree-size-2`
154
- * ({@link checkpointConsistencyProof}); a disagreement is
155
- * `size_mismatch`.
230
+ * - A checkpoint may relay SEVERAL consistency proofs under one signature
231
+ * (ADR-0066 D2; draft `consistency-proofs = [ + consistency-proof ]`).
232
+ * Its SIGNED `tree-size-2` (ADR-0066 D1 as amended) must equal the LAST
233
+ * proof's declared `tree-size-2` ({@link checkpointConsistencyProof}),
234
+ * and each relayed proof must continue the one before it
235
+ * ({@link computeCheckpointAccumulator}); either disagreement is
236
+ * `size_mismatch`. A checkpoint sealing one step is the relay of one and
237
+ * takes the same path.
156
238
  * - Each link's signature is checked over its computed accumulator via
157
239
  * the injected verifier (the caller owns trust resolution — genesis
158
240
  * roots, caller-known keys, or the label-1000 delegation path). A link
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-chain.d.ts","sourceRoot":"","sources":["../src/checkpoint-chain.ts"],"names":[],"mappings":"AAwDA;;;;qBAIqB;AACrB,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;+EAC2E;IAC3E,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC;IACtB,uEAAuE;IACvE,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;gBAC9C,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,UAAU,GAC1B,0BAA0B,CAgC5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,0BAA0B,EACjC,eAAe,EAAE,UAAU,EAAE,EAC7B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CAoBvB;AAED;+DAC+D;AAC/D,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,UAAU,CAQxE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;mBACe;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,GACrE;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACF,aAAa,GACb,WAAW;IACb;;;;;OAKG;OACD,qBAAqB,GACrB,iBAAiB;IACnB;;;;;;;;OAQG;OACD,eAAe,CAAC;IACpB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,CACf,eAAe,EAAE,UAAU,EAC3B,eAAe,EAAE,UAAU,KACxB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB;+EAC2E;IAC3E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;CAC3D,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAoIjC"}
1
+ {"version":3,"file":"checkpoint-chain.d.ts","sourceRoot":"","sources":["../src/checkpoint-chain.ts"],"names":[],"mappings":"AA2DA,OAAO,EAEL,2BAA2B,EAC3B,KAAK,uBAAuB,EAC7B,MAAM,0CAA0C,CAAC;AAElD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,uDAAuD;IACvD,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB;+EAC2E;IAC3E,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kCAAmC,SAAQ,KAAK;gBAC/C,OAAO,EAAE,MAAM;CAI5B;AAED,OAAO,EAAE,2BAA2B,EAAE,CAAC;AAEvC;;;;;;GAMG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;gBAC9C,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;gBAC9C,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,UAAU,GAC1B,0BAA0B,CAgD5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,0BAA0B,EACjC,eAAe,EAAE,UAAU,EAAE,EAC7B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CA+CvB;AAED;+DAC+D;AAC/D,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,UAAU,CAQxE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;mBACe;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,2EAA2E;IAC3E,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAAC,WAAW,EAAE,UAAU,EAAE,CAAA;CAAE,GACrE;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACF,aAAa,GACb,WAAW;IACb;;;;;OAKG;OACD,qBAAqB,GACrB,iBAAiB;IACnB;;;;;;;;;;OAUG;OACD,eAAe,CAAC;IACpB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,CACf,eAAe,EAAE,UAAU,EAC3B,eAAe,EAAE,UAAU,KACxB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB;+EAC2E;IAC3E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;CAC3D,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6JjC"}