@sig-net/midnight 0.22.0-rc.1 → 0.22.0-rc.3
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 +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mpc-output-cache.d.ts +48 -0
- package/dist/mpc-output-cache.d.ts.map +1 -0
- package/dist/mpc-output-cache.js +57 -0
- package/dist/mpc-output-cache.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ What clients import from `@sig-net/midnight`:
|
|
|
72
72
|
| Compose expected calldata words off chain (UIs, expected-record builders, tests) | The builders `numericAbiWord`, `evmAddressAbiWord` and `boolAbiWord`, and the readers `abiWordToUint128` and `abiWordToBool`: TS twins of the circuits under identical names. |
|
|
73
73
|
| Convert a foreign execution output into respond bytes | `deserializeEvmOutput` (raw EVM return data to named values) and `serializeRespondOutput` (named values to the packed respond payload the MPC attests): together they rebuild the `serializedOutput` of steps 4 and 5. |
|
|
74
74
|
| Recognise a failed remote execution | `MPC_FAILURE_OUTPUT` and `isMpcFailureOutput`: the MPC's fixed 5-byte failure payload for reverted or replaced transactions (see [Handling Failure](https://github.com/sig-net/midnight-integration/blob/main/README.md#handling-failure)). |
|
|
75
|
+
| Read the attested output bytes from the MPC's output cache | `MpcOutputCacheReader`: one reader per network and Signet singleton pair, over the public bucket an MPC configured with output storage writes each request's exact attested bytes to before posting. `fetchSerializedOutput` yields the bytes step 5 verifies, `undefined` while the object is not written yet. |
|
|
75
76
|
| Verify attestations without the reader | `verifyRespondBidirectionalSignature`: the check the reader runs internally, exposed for custom pipelines. |
|
|
76
77
|
| Mint attestations in your contract's unit tests | The `@sig-net/midnight/testing` entry point, see [Testing entry point](#testing-entry-point). |
|
|
77
78
|
| Discover requests MPC-side (responders, background workers) | The discovery primitives: decode the signet contract's emitted notification events with `decodeSignBidirectionalEventNotificationPayload` and `decodeSignBidirectionalNotification`, then resolve each pointer against the named caller's own request map with `lookupSignetRequestAt` (the authenticated read). The polling loop belongs to the responder. |
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./abi-serde.ts";
|
|
|
2
2
|
export { bigintToBytes32, bigintToBytes32BE, BLS_ORDER, bytesToBigint, bytesToBigintBE, bytesToHex, hexToBytes, stripHexPrefix, } from "./byte-codecs.ts";
|
|
3
3
|
export * from "./constants.ts";
|
|
4
4
|
export { deriveEpsilon, deriveEvmAddress, deriveMidnightResponseKey, EPSILON_DERIVATION_PREFIX, MIDNIGHT_CAIP2_ID, MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH, } from "./epsilon-derivation.ts";
|
|
5
|
+
export * from "./mpc-output-cache.ts";
|
|
5
6
|
export { type RawContractState, signetFieldNodeByPath } from "./raw-contract-state.ts";
|
|
6
7
|
export * from "./signature-requests-state-reader.ts";
|
|
7
8
|
export * from "./signature-response-verification.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAI1B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACvF,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,KAAK,kBAAkB,EACvB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,cAAc,EACd,4CAA4C,EAC5C,8CAA8C,GAC/C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,cAAc,qCAAqC,CAAC;AACpD,OAAO,EACL,KAAK,eAAe,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,KAAK,SAAS,EACd,cAAc,EACd,KAAK,YAAY,EACjB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,6BAA6B,EAC7B,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,uCAAuC,EACvC,eAAe,EACf,KAAK,cAAc,EACnB,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAEhC;;;;GAIG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAI1B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,KAAK,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACvF,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,KAAK,kBAAkB,EACvB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,cAAc,EACd,4CAA4C,EAC5C,8CAA8C,GAC/C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,cAAc,qCAAqC,CAAC;AACpD,OAAO,EACL,KAAK,eAAe,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,KAAK,SAAS,EACd,cAAc,EACd,KAAK,YAAY,EACjB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,6BAA6B,EAC7B,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,uCAAuC,EACvC,eAAe,EACf,KAAK,cAAc,EACnB,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAEhC;;;;GAIG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./constants.js";
|
|
|
10
10
|
// Selective: deriveMidnightResponseSecretKey takes the MPC root secret, so
|
|
11
11
|
// it is exported through ./testing with the other secret-taking helpers.
|
|
12
12
|
export { deriveEpsilon, deriveEvmAddress, deriveMidnightResponseKey, EPSILON_DERIVATION_PREFIX, MIDNIGHT_CAIP2_ID, MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH, } from "./epsilon-derivation.js";
|
|
13
|
+
export * from "./mpc-output-cache.js";
|
|
13
14
|
export { signetFieldNodeByPath } from "./raw-contract-state.js";
|
|
14
15
|
export * from "./signature-requests-state-reader.js";
|
|
15
16
|
export * from "./signature-response-verification.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,sEAAsE;AACtE,wEAAwE;AAExE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,uEAAuE;AACvE,4EAA4E;AAC5E,4EAA4E;AAC5E,cAAc,gBAAgB,CAAC;AAC/B,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAyB,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACvF,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAEX,iBAAiB,EAGjB,cAAc,EACd,4CAA4C,EAC5C,8CAA8C,GAC/C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,cAAc,qCAAqC,CAAC;AACpD,OAAO,EAEL,sBAAsB,EAEtB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EAEV,cAAc,EAEd,YAAY,EAIZ,6BAA6B,EAC7B,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,2EAA2E;AAC3E,2EAA2E;AAC3E,2EAA2E;AAC3E,8DAA8D;AAC9D,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,uCAAuC,EACvC,eAAe,EAEf,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAEhC;;;;GAIG;AACH,OAAO,EAAqB,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,sEAAsE;AACtE,wEAAwE;AAExE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,uEAAuE;AACvE,4EAA4E;AAC5E,4EAA4E;AAC5E,cAAc,gBAAgB,CAAC;AAC/B,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAyB,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACvF,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAEX,iBAAiB,EAGjB,cAAc,EACd,4CAA4C,EAC5C,8CAA8C,GAC/C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,cAAc,qCAAqC,CAAC;AACpD,OAAO,EAEL,sBAAsB,EAEtB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EAEV,cAAc,EAEd,YAAY,EAIZ,6BAA6B,EAC7B,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,2EAA2E;AAC3E,2EAA2E;AAC3E,2EAA2E;AAC3E,8DAA8D;AAC9D,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,uCAAuC,EACvC,eAAe,EAEf,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAEhC;;;;GAIG;AACH,OAAO,EAAqB,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RequestIdHex } from "./signet-requests.ts";
|
|
2
|
+
/** Where the MPC's output cache lives and which of its namespaces to read. */
|
|
3
|
+
export interface MpcOutputCacheConfig {
|
|
4
|
+
/**
|
|
5
|
+
* The cache's public URL down to the MPC's configured object prefix, e.g.
|
|
6
|
+
* `https://storage.googleapis.com/<bucket>/<prefix>`. A trailing slash is
|
|
7
|
+
* tolerated.
|
|
8
|
+
*/
|
|
9
|
+
readonly cacheUrl: string;
|
|
10
|
+
/** The Midnight network id the MPC serves: the path segment after the prefix. */
|
|
11
|
+
readonly networkId: string;
|
|
12
|
+
/** The signet singleton the MPC publishes through, 64 hex chars: the segment after the network. */
|
|
13
|
+
readonly signetContractAddress: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Reads attested serialised outputs out of the MPC's output cache. The MPC
|
|
17
|
+
* writes a request's bytes to
|
|
18
|
+
* `<prefix>/<networkId>/<signetContractAddress>/<requestId>.bin` before it
|
|
19
|
+
* posts the matching attestation, so once an attestation is on chain a
|
|
20
|
+
* missing object is the MPC's cache write being lost, and an object found
|
|
21
|
+
* before any attestation is still unverified.
|
|
22
|
+
*/
|
|
23
|
+
export declare class MpcOutputCacheReader {
|
|
24
|
+
private readonly namespaceUrl;
|
|
25
|
+
/**
|
|
26
|
+
* @param config - The cache location and the namespace to read.
|
|
27
|
+
*/
|
|
28
|
+
constructor(config: MpcOutputCacheConfig);
|
|
29
|
+
/**
|
|
30
|
+
* The URL of the object holding `requestId`'s attested output.
|
|
31
|
+
*
|
|
32
|
+
* @param requestId - The request whose output object to locate.
|
|
33
|
+
* @returns The object's public URL.
|
|
34
|
+
*/
|
|
35
|
+
objectUrl(requestId: RequestIdHex): string;
|
|
36
|
+
/**
|
|
37
|
+
* Download the serialised output the MPC cached for `requestId`, verbatim.
|
|
38
|
+
* UNTRUSTED: verify the attestation signature over the returned bytes.
|
|
39
|
+
*
|
|
40
|
+
* @param requestId - The request whose attested output to fetch.
|
|
41
|
+
* @returns The cached bytes, or `undefined` when the cache holds no object
|
|
42
|
+
* for the request (the MPC has not written it yet).
|
|
43
|
+
* @throws {Error} If the cache cannot be reached or answers with a status
|
|
44
|
+
* other than 200 or 404.
|
|
45
|
+
*/
|
|
46
|
+
fetchSerializedOutput(requestId: RequestIdHex): Promise<Uint8Array | undefined>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=mpc-output-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpc-output-cache.d.ts","sourceRoot":"","sources":["../src/mpc-output-cache.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mGAAmG;IACnG,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC;;OAEG;IACH,YAAY,MAAM,EAAE,oBAAoB,EAGvC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED;;;;;;;;;OASG;IACG,qBAAqB,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAYpF;CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Reader over the MPC's output cache: the exact serialised output bytes the
|
|
2
|
+
// MPC attests for a bidirectional request, stored as one object per request
|
|
3
|
+
// id in a public bucket BEFORE the attestation is posted on chain. A Compact
|
|
4
|
+
// circuit fixes its byte-payload width at compile time while serialised
|
|
5
|
+
// outputs vary in size across requests, so the signet contract carries the
|
|
6
|
+
// signature alone and the cache carries the bytes. An object holds nothing
|
|
7
|
+
// but the packed output, and is UNTRUSTED until the attestation signature
|
|
8
|
+
// verifies over it (`verifyRespondBidirectionalSignature`).
|
|
9
|
+
/**
|
|
10
|
+
* Reads attested serialised outputs out of the MPC's output cache. The MPC
|
|
11
|
+
* writes a request's bytes to
|
|
12
|
+
* `<prefix>/<networkId>/<signetContractAddress>/<requestId>.bin` before it
|
|
13
|
+
* posts the matching attestation, so once an attestation is on chain a
|
|
14
|
+
* missing object is the MPC's cache write being lost, and an object found
|
|
15
|
+
* before any attestation is still unverified.
|
|
16
|
+
*/
|
|
17
|
+
export class MpcOutputCacheReader {
|
|
18
|
+
namespaceUrl;
|
|
19
|
+
/**
|
|
20
|
+
* @param config - The cache location and the namespace to read.
|
|
21
|
+
*/
|
|
22
|
+
constructor(config) {
|
|
23
|
+
const prefixUrl = config.cacheUrl.replace(/\/+$/u, "");
|
|
24
|
+
this.namespaceUrl = `${prefixUrl}/${config.networkId}/${config.signetContractAddress}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The URL of the object holding `requestId`'s attested output.
|
|
28
|
+
*
|
|
29
|
+
* @param requestId - The request whose output object to locate.
|
|
30
|
+
* @returns The object's public URL.
|
|
31
|
+
*/
|
|
32
|
+
objectUrl(requestId) {
|
|
33
|
+
return `${this.namespaceUrl}/${requestId}.bin`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Download the serialised output the MPC cached for `requestId`, verbatim.
|
|
37
|
+
* UNTRUSTED: verify the attestation signature over the returned bytes.
|
|
38
|
+
*
|
|
39
|
+
* @param requestId - The request whose attested output to fetch.
|
|
40
|
+
* @returns The cached bytes, or `undefined` when the cache holds no object
|
|
41
|
+
* for the request (the MPC has not written it yet).
|
|
42
|
+
* @throws {Error} If the cache cannot be reached or answers with a status
|
|
43
|
+
* other than 200 or 404.
|
|
44
|
+
*/
|
|
45
|
+
async fetchSerializedOutput(requestId) {
|
|
46
|
+
const url = this.objectUrl(requestId);
|
|
47
|
+
const response = await fetch(url);
|
|
48
|
+
if (response.status === 404) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`MPC output cache answered HTTP ${String(response.status)} for ${url}: ${await response.text()}`);
|
|
53
|
+
}
|
|
54
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=mpc-output-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpc-output-cache.js","sourceRoot":"","sources":["../src/mpc-output-cache.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,wEAAwE;AACxE,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,4DAA4D;AAkB5D;;;;;;;GAOG;AACH,MAAM,OAAO,oBAAoB;IACd,YAAY,CAAS;IAEtC;;OAEG;IACH,YAAY,MAA4B;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,GAAG,GAAG,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;IACzF,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAuB;QAC/B,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;IACjD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,qBAAqB,CAAC,SAAuB;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,kCAAkC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,GAAG,KAAK,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CACjG,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,CAAC;CACF"}
|