@the-situation/collateral 0.5.0-alpha.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.
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Off-chain collateral computation for trading between normal distributions.
3
+ *
4
+ * Computes the collateral requirement for transitioning from distribution f to g:
5
+ * C = max(0, sup_x[f(x) - g(x)]) = max(0, -inf_x[g(x) - f(x)])
6
+ *
7
+ * Uses Newton-Raphson minimization to find x* where d(x) = g(x) - f(x) achieves
8
+ * its infimum. The smart contracts verify but don't compute - this computation
9
+ * must be done locally.
10
+ *
11
+ * @module
12
+ */
13
+ import { NormalDistribution, SQ128x128 } from '@the-situation/core';
14
+ /**
15
+ * sqrt(π) ≈ 1.7724538509055159
16
+ *
17
+ * Used for L2 norm and lambda computation.
18
+ */
19
+ export declare const SQRT_PI: number;
20
+ /**
21
+ * Computes the L2 norm of a normal distribution's PDF.
22
+ *
23
+ * For a normal PDF with standard deviation σ:
24
+ * ||p||_2 = 1 / sqrt(2 * σ * sqrt(π))
25
+ *
26
+ * @param sigma - The standard deviation (as number)
27
+ * @returns The L2 norm
28
+ */
29
+ export declare function computeL2NormNumber(sigma: number): number;
30
+ /**
31
+ * Computes the lambda scaling factor for a distribution.
32
+ *
33
+ * lambda = k / ||p||_2 = k * sqrt(2 * σ * sqrt(π))
34
+ *
35
+ * @param sigma - The distribution's standard deviation (as number)
36
+ * @param k - The AMM invariant parameter (as number)
37
+ * @returns The lambda scaling factor
38
+ */
39
+ export declare function computeLambdaNumber(sigma: number, k: number): number;
40
+ /**
41
+ * Computes the L2 norm of a normal distribution's PDF.
42
+ *
43
+ * For a normal PDF with standard deviation σ:
44
+ * ||p||_2 = 1 / sqrt(2 * σ * sqrt(π))
45
+ *
46
+ * @param sigma - The standard deviation
47
+ * @returns The L2 norm, or null if computation fails
48
+ */
49
+ export declare function computeL2Norm(sigma: SQ128x128): SQ128x128 | null;
50
+ /**
51
+ * Computes the lambda scaling factor for a distribution.
52
+ *
53
+ * lambda = k / ||p||_2 = k * sqrt(2 * σ * sqrt(π))
54
+ *
55
+ * This is the multiplier applied to the base PDF to create a scaled position
56
+ * that satisfies the AMM invariant ||f||_2 = k.
57
+ *
58
+ * @param sigma - The distribution's standard deviation
59
+ * @param k - The AMM invariant parameter
60
+ * @returns The lambda scaling factor, or null if computation fails
61
+ */
62
+ export declare function computeLambda(sigma: SQ128x128, k: SQ128x128): SQ128x128 | null;
63
+ /**
64
+ * Policy parameters for the minimization algorithm.
65
+ *
66
+ * These define the "safe operating envelope" where Newton-Raphson
67
+ * is expected to produce correct results.
68
+ */
69
+ export interface MinimizationPolicy {
70
+ /** Maximum allowed sigma ratio (σ_large / σ_small). Default: 4.0 */
71
+ maxSigmaRatio: SQ128x128;
72
+ /** Maximum mean separation in units of the narrower σ. Default: 4.0 */
73
+ maxMeanSepSigmas: SQ128x128;
74
+ /** Maximum absolute value of mean. Default: 2^20 */
75
+ maxAbsoluteMean: SQ128x128;
76
+ }
77
+ /**
78
+ * Returns the default minimization policy.
79
+ */
80
+ export declare function defaultPolicy(): MinimizationPolicy;
81
+ /**
82
+ * Returns a relaxed minimization policy for close position scenarios.
83
+ *
84
+ * The default policy (4σ limits) may be too restrictive for closing positions
85
+ * when the market has moved significantly. This relaxed policy allows the
86
+ * offchain solver to attempt computation for larger separations.
87
+ *
88
+ * The actual validation is done by calling `check_close_position` on-chain,
89
+ * which validates the computed x* without the artificial solver limits.
90
+ */
91
+ export declare function relaxedPolicy(): MinimizationPolicy;
92
+ /** Method used to find the minimum. */
93
+ export type MinimizationMethod = 'closed-form' | 'newton';
94
+ /**
95
+ * A verified minimum that passed all validation checks.
96
+ *
97
+ * This is a self-contained certificate that includes all context needed
98
+ * for verification.
99
+ */
100
+ export interface VerifiedMinimum {
101
+ /** The x-coordinate where the minimum occurs */
102
+ xMin: SQ128x128;
103
+ /** The minimum value d(xMin) = g(xMin) - f(xMin) */
104
+ dMin: SQ128x128;
105
+ /** The computed collateral: max(0, -dMin) */
106
+ collateral: SQ128x128;
107
+ /** The tolerance used for stationary validation */
108
+ tolerance: SQ128x128;
109
+ /** Number of iterations (0 for closed-form) */
110
+ iterations: number;
111
+ /** Method used to find the minimum */
112
+ method: MinimizationMethod;
113
+ }
114
+ /**
115
+ * A candidate minimum that has not been verified.
116
+ */
117
+ export interface CandidateMinimum {
118
+ /** The x-coordinate of the candidate */
119
+ x: SQ128x128;
120
+ /** The function value at x */
121
+ d: SQ128x128;
122
+ /** Tentative collateral (may be incorrect) */
123
+ collateral: SQ128x128;
124
+ /** Number of iterations */
125
+ iterations: number;
126
+ /** Method used */
127
+ method: MinimizationMethod;
128
+ }
129
+ /** Reason why the minimum could not be verified or was rejected. */
130
+ export type NotVerifiedReason = 'degenerate_distribution' | 'sigma_ratio_too_high' | 'mean_separation_too_large' | 'mean_magnitude_too_large' | 'newton_did_not_converge' | 'not_stationary' | 'curvature_not_positive' | 'wrong_side' | 'computation_failed';
131
+ /** Result of attempting to find the minimum. */
132
+ export type FindMinimumResult = {
133
+ type: 'verified';
134
+ result: VerifiedMinimum;
135
+ } | {
136
+ type: 'not_verified';
137
+ reason: NotVerifiedReason;
138
+ candidate?: CandidateMinimum;
139
+ } | {
140
+ type: 'rejected';
141
+ reason: NotVerifiedReason;
142
+ };
143
+ /**
144
+ * Computes the pointwise PDF difference d(x) = g(x) - f(x).
145
+ *
146
+ * @param f - The "from" distribution
147
+ * @param g - The "to" distribution
148
+ * @param x - The point at which to evaluate
149
+ * @returns The difference g(x) - f(x), or null if computation fails
150
+ */
151
+ export declare function pdfDifference(f: NormalDistribution, g: NormalDistribution, x: SQ128x128): SQ128x128 | null;
152
+ /**
153
+ * Computes d'(x) = g'(x) - f'(x), the derivative of the PDF difference.
154
+ *
155
+ * At a stationary point x*, d'(x*) = 0.
156
+ *
157
+ * @param f - The "from" distribution
158
+ * @param g - The "to" distribution
159
+ * @param x - The point at which to evaluate
160
+ * @returns The derivative difference, or null if computation fails
161
+ */
162
+ export declare function pdfDifferenceDerivative(f: NormalDistribution, g: NormalDistribution, x: SQ128x128): SQ128x128 | null;
163
+ /**
164
+ * Computes d''(x) = g''(x) - f''(x), the second derivative of the PDF difference.
165
+ *
166
+ * At a minimum x*, d''(x*) > 0.
167
+ *
168
+ * @param f - The "from" distribution
169
+ * @param g - The "to" distribution
170
+ * @param x - The point at which to evaluate
171
+ * @returns The second derivative difference, or null if computation fails
172
+ */
173
+ export declare function pdfDifferenceSecondDerivative(f: NormalDistribution, g: NormalDistribution, x: SQ128x128): SQ128x128 | null;
174
+ /**
175
+ * Suggests an initial guess for Newton-Raphson minimization.
176
+ *
177
+ * The minimum of d(x) = g(x) - f(x) depends on the relationship between f and g:
178
+ *
179
+ * 1. Different means: minimum is on the side of f opposite to g, close to f's mean
180
+ * 2. Same mean (or nearly equal), narrow to wide (σ_f < σ_g): minimum is at the mean
181
+ * 3. Same mean (or nearly equal), wide to narrow (σ_f > σ_g): minimum is in the tails
182
+ *
183
+ * @param f - The "from" distribution
184
+ * @param g - The "to" distribution
185
+ * @returns The suggested initial guess
186
+ */
187
+ export declare function suggestInitialGuess(f: NormalDistribution, g: NormalDistribution): SQ128x128;
188
+ /**
189
+ * Computes collateral from the minimum value of d(x).
190
+ *
191
+ * C = max(0, -d_min) = max(0, f(x*) - g(x*))
192
+ *
193
+ * @param dMin - The minimum value of d(x) = g(x) - f(x)
194
+ * @returns The collateral requirement
195
+ */
196
+ export declare function collateralFromMinimum(dMin: SQ128x128): SQ128x128;
197
+ /**
198
+ * Checks if x is on the correct side of μ_f relative to μ_g.
199
+ *
200
+ * The minimum of d(x) = g(x) - f(x) occurs on the side of f opposite to g:
201
+ * - If μ_g > μ_f, then x should be < μ_f (left of f, away from g)
202
+ * - If μ_g < μ_f, then x should be > μ_f (right of f, away from g)
203
+ * - If μ_g = μ_f, any side is valid (symmetric case)
204
+ *
205
+ * @param f - The "from" distribution
206
+ * @param g - The "to" distribution
207
+ * @param x - The point to check
208
+ * @returns True if x is on the correct side
209
+ */
210
+ export declare function isOnCorrectSide(f: NormalDistribution, g: NormalDistribution, x: SQ128x128): boolean;
211
+ /** Default convergence tolerance */
212
+ export declare const DEFAULT_TOLERANCE: SQ128x128;
213
+ /** Default maximum iterations */
214
+ export declare const DEFAULT_MAX_ITERATIONS = 50;
215
+ /**
216
+ * Finds the minimum of d(x) = g(x) - f(x) using Newton-Raphson.
217
+ *
218
+ * This is the primary entry point for collateral computation.
219
+ *
220
+ * @param f - The "from" distribution
221
+ * @param g - The "to" distribution
222
+ * @param x0 - Optional initial guess (will be computed if not provided)
223
+ * @param tolerance - Convergence threshold (default: 1e-10)
224
+ * @param maxIterations - Maximum Newton iterations (default: 50)
225
+ * @param policy - Safe envelope policy (default: defaultPolicy())
226
+ * @returns The minimization result
227
+ */
228
+ export declare function findMinimum(f: NormalDistribution, g: NormalDistribution, x0?: SQ128x128, tolerance?: SQ128x128, maxIterations?: number, policy?: MinimizationPolicy): FindMinimumResult;
229
+ /**
230
+ * Convenience function to compute collateral directly.
231
+ *
232
+ * Returns the verified collateral amount, or null if verification fails.
233
+ *
234
+ * @param f - The "from" distribution
235
+ * @param g - The "to" distribution
236
+ * @returns The collateral requirement, or null if computation fails
237
+ */
238
+ export declare function computeCollateral(f: NormalDistribution, g: NormalDistribution): SQ128x128 | null;
239
+ /**
240
+ * Extracts the verified minimum from a result, if available.
241
+ *
242
+ * @param result - The FindMinimumResult
243
+ * @returns The VerifiedMinimum if verified, null otherwise
244
+ */
245
+ export declare function getVerifiedMinimum(result: FindMinimumResult): VerifiedMinimum | null;
246
+ /**
247
+ * Checks if a FindMinimumResult is verified.
248
+ *
249
+ * @param result - The FindMinimumResult
250
+ * @returns True if the result is verified
251
+ */
252
+ export declare function isVerified(result: FindMinimumResult): boolean;
253
+ /**
254
+ * Result of scaled collateral computation.
255
+ */
256
+ export interface ScaledCollateralResult {
257
+ /** The unscaled collateral (before lambda multiplication) */
258
+ readonly unscaledCollateral: SQ128x128;
259
+ /** The scaled collateral (lambda * unscaledCollateral) */
260
+ readonly scaledCollateral: SQ128x128;
261
+ /** The lambda scaling factor */
262
+ readonly lambda: SQ128x128;
263
+ /** The minimum point x* */
264
+ readonly xStar: SQ128x128;
265
+ /** Number of iterations used */
266
+ readonly iterations: number;
267
+ /** Lambda for the "from" distribution */
268
+ readonly lambdaF: SQ128x128;
269
+ /** Lambda for the "to" distribution */
270
+ readonly lambdaG: SQ128x128;
271
+ }
272
+ /**
273
+ * Extended result for scaled collateral with both lambdas.
274
+ * @deprecated Use ScaledCollateralResult which now includes both lambdas
275
+ */
276
+ export interface ScaledCollateralResultExtended extends ScaledCollateralResult {
277
+ }
278
+ /**
279
+ * Computes the scaled PDF difference: d_s(x) = lambda_g * g(x) - lambda_f * f(x)
280
+ *
281
+ * When variances differ, finding the minimum of this scaled difference
282
+ * is necessary for correct collateral computation.
283
+ */
284
+ export declare function scaledPdfDifference(f: NormalDistribution, g: NormalDistribution, lambdaF: number, lambdaG: number, x: SQ128x128): number | null;
285
+ /**
286
+ * Computes the derivative of scaled PDF difference:
287
+ * d_s'(x) = lambda_g * g'(x) - lambda_f * f'(x)
288
+ */
289
+ export declare function scaledPdfDifferenceDerivative(f: NormalDistribution, g: NormalDistribution, lambdaF: number, lambdaG: number, x: SQ128x128): number | null;
290
+ /**
291
+ * Computes the second derivative of scaled PDF difference:
292
+ * d_s''(x) = lambda_g * g''(x) - lambda_f * f''(x)
293
+ */
294
+ export declare function scaledPdfDifferenceSecondDerivative(f: NormalDistribution, g: NormalDistribution, lambdaF: number, lambdaG: number, x: SQ128x128): number | null;
295
+ /**
296
+ * Computes the scaled collateral for AMM trading.
297
+ *
298
+ * The AMM uses lambda-scaled PDFs where lambda = k / ||p||_2.
299
+ *
300
+ * For distributions with the same variance, lambda_f = lambda_g and we can
301
+ * use the unscaled minimum.
302
+ *
303
+ * For distributions with different variances, we find x* by minimizing
304
+ * the scaled difference: d_s(x) = lambda_g * g(x) - lambda_f * f(x)
305
+ *
306
+ * Collateral = max(0, lambda_f * f(x*) - lambda_g * g(x*)) = max(0, -d_s(x*))
307
+ *
308
+ * @param f - The "from" distribution (current market)
309
+ * @param g - The "to" distribution (candidate)
310
+ * @param k - The AMM invariant parameter (default: 1)
311
+ * @param policy - The minimization policy (default: defaultPolicy())
312
+ * @returns The scaled collateral result, or null if computation fails
313
+ *
314
+ * @example
315
+ * ```typescript
316
+ * const f = NormalDistribution.create(mean100, variance100);
317
+ * const g = NormalDistribution.create(mean105, variance100);
318
+ * const result = computeScaledCollateral(f, g, SQ128x128.fromNumber(1));
319
+ * if (result) {
320
+ * console.log('Collateral:', result.scaledCollateral.toNumber());
321
+ * console.log('x*:', result.xStar.toNumber());
322
+ * }
323
+ * ```
324
+ */
325
+ export declare function computeScaledCollateral(f: NormalDistribution, g: NormalDistribution, k?: SQ128x128, policy?: MinimizationPolicy): ScaledCollateralResult | null;
326
+ //# sourceMappingURL=compute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../src/compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,kBAAkB,EAAO,SAAS,EAAQ,MAAM,qBAAqB,CAAC;AAMrF;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,MAA2B,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAShE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAM9E;AAMD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,aAAa,EAAE,SAAS,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,EAAE,SAAS,CAAC;IAC5B,oDAAoD;IACpD,eAAe,EAAE,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,CAQlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,CAQlD;AAMD,uCAAuC;AACvC,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,QAAQ,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,IAAI,EAAE,SAAS,CAAC;IAChB,oDAAoD;IACpD,IAAI,EAAE,SAAS,CAAC;IAChB,6CAA6C;IAC7C,UAAU,EAAE,SAAS,CAAC;IACtB,mDAAmD;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,CAAC,EAAE,SAAS,CAAC;IACb,8BAA8B;IAC9B,CAAC,EAAE,SAAS,CAAC;IACb,8CAA8C;IAC9C,UAAU,EAAE,SAAS,CAAC;IACtB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GACzB,yBAAyB,GACzB,sBAAsB,GACtB,2BAA2B,GAC3B,0BAA0B,GAC1B,yBAAyB,GACzB,gBAAgB,GAChB,wBAAwB,GACxB,YAAY,GACZ,oBAAoB,CAAC;AAEzB,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,SAAS,GACX,SAAS,GAAG,IAAI,CASlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,SAAS,GACX,SAAS,GAAG,IAAI,CASlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,SAAS,GACX,SAAS,GAAG,IAAI,CASlB;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,GAAG,SAAS,CA6D3F;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAMhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,SAAS,GACX,OAAO,CAYT;AAkED,oCAAoC;AACpC,eAAO,MAAM,iBAAiB,EAAkC,SAAS,CAAC;AAE1E,iCAAiC;AACjC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAkGzC;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,EAAE,CAAC,EAAE,SAAS,EACd,SAAS,GAAE,SAA6B,EACxC,aAAa,GAAE,MAA+B,EAC9C,MAAM,GAAE,kBAAoC,GAC3C,iBAAiB,CA0FnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,GACpB,SAAS,GAAG,IAAI,CAMlB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,GAAG,IAAI,CAKpF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAE7D;AAMD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,QAAQ,CAAC,kBAAkB,EAAE,SAAS,CAAC;IACvC,0DAA0D;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACrC,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,8BAA+B,SAAQ,sBAAsB;CAAG;AAMjF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,CAAC,EAAE,SAAS,GACX,MAAM,GAAG,IAAI,CAKf;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,CAAC,EAAE,SAAS,GACX,MAAM,GAAG,IAAI,CAKf;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,CAAC,EAAE,SAAS,GACX,MAAM,GAAG,IAAI,CAKf;AAuHD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,EACrB,CAAC,GAAE,SAAe,EAClB,MAAM,GAAE,kBAAoC,GAC3C,sBAAsB,GAAG,IAAI,CAqF/B"}