@drift-labs/sdk 0.1.29-master.0 → 0.1.29-master.1
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/lib/accounts/bulkAccountLoader.js +5 -0
- package/lib/idl/clearing_house.json +12 -2
- package/lib/math/amm.d.ts +0 -18
- package/lib/math/amm.js +1 -88
- package/lib/math/repeg.d.ts +32 -0
- package/lib/math/repeg.js +178 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +4 -0
- package/src/idl/clearing_house.json +12 -2
- package/src/math/amm.ts +2 -127
- package/src/math/repeg.ts +253 -0
- package/src/addresses.js +0 -59
- package/src/addresses.js.map +0 -1
- package/src/admin.js +0 -443
- package/src/admin.js.map +0 -1
- package/src/clearingHouseUser.js +0 -581
- package/src/clearingHouseUser.js.map +0 -1
- package/src/config.js +0 -37
- package/src/config.js.map +0 -1
- package/src/index.js +0 -56
- package/src/index.js.map +0 -1
- package/src/mockUSDCFaucet.js +0 -143
- package/src/mockUSDCFaucet.js.map +0 -1
- package/src/orderParams.js +0 -109
- package/src/orderParams.js.map +0 -1
- package/src/orders.js +0 -172
- package/src/orders.js.map +0 -1
- package/src/types.js +0 -61
- package/src/types.js.map +0 -1
- package/src/wallet.js +0 -23
- package/src/wallet.js.map +0 -1
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { BN } from '@project-serum/anchor';
|
|
2
|
+
import {
|
|
3
|
+
MARK_PRICE_PRECISION,
|
|
4
|
+
AMM_RESERVE_PRECISION,
|
|
5
|
+
PEG_PRECISION,
|
|
6
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
7
|
+
QUOTE_PRECISION,
|
|
8
|
+
ZERO,
|
|
9
|
+
} from '../constants/numericConstants';
|
|
10
|
+
import { calculateBaseAssetValue } from './position';
|
|
11
|
+
import { calculateTerminalPrice } from './amm';
|
|
12
|
+
|
|
13
|
+
import { Market } from '../types';
|
|
14
|
+
import { calculatePositionPNL, calculateMarkPrice, convertToNumber } from '..';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Helper function calculating adjust k cost
|
|
18
|
+
* @param market
|
|
19
|
+
* @param marketIndex
|
|
20
|
+
* @param numerator
|
|
21
|
+
* @param denomenator
|
|
22
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
23
|
+
*/
|
|
24
|
+
export function calculateAdjustKCost(
|
|
25
|
+
market: Market,
|
|
26
|
+
marketIndex: BN,
|
|
27
|
+
numerator: BN,
|
|
28
|
+
denomenator: BN
|
|
29
|
+
): BN {
|
|
30
|
+
const netUserPosition = {
|
|
31
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
32
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
33
|
+
marketIndex: new BN(marketIndex),
|
|
34
|
+
quoteAssetAmount: ZERO,
|
|
35
|
+
openOrders: ZERO,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
39
|
+
|
|
40
|
+
const marketNewK = Object.assign({}, market);
|
|
41
|
+
marketNewK.amm = Object.assign({}, market.amm);
|
|
42
|
+
|
|
43
|
+
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
44
|
+
.mul(numerator)
|
|
45
|
+
.div(denomenator);
|
|
46
|
+
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
47
|
+
.mul(numerator)
|
|
48
|
+
.div(denomenator);
|
|
49
|
+
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
50
|
+
|
|
51
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
52
|
+
|
|
53
|
+
const cost = calculatePositionPNL(marketNewK, netUserPosition);
|
|
54
|
+
|
|
55
|
+
return cost;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
60
|
+
*
|
|
61
|
+
* @param market
|
|
62
|
+
* @param marketIndex
|
|
63
|
+
* @param newPeg
|
|
64
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
65
|
+
*/
|
|
66
|
+
export function calculateRepegCost(
|
|
67
|
+
market: Market,
|
|
68
|
+
marketIndex: BN,
|
|
69
|
+
newPeg: BN
|
|
70
|
+
): BN {
|
|
71
|
+
const netUserPosition = {
|
|
72
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
73
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
74
|
+
marketIndex: new BN(marketIndex),
|
|
75
|
+
quoteAssetAmount: new BN(0),
|
|
76
|
+
openOrders: ZERO,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
80
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
81
|
+
const prevMarketPrice = calculateMarkPrice(market);
|
|
82
|
+
const marketNewPeg = Object.assign({}, market);
|
|
83
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
84
|
+
|
|
85
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
86
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
87
|
+
|
|
88
|
+
console.log(
|
|
89
|
+
'Price moves from',
|
|
90
|
+
convertToNumber(prevMarketPrice),
|
|
91
|
+
'to',
|
|
92
|
+
convertToNumber(calculateMarkPrice(marketNewPeg))
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
|
|
96
|
+
|
|
97
|
+
return cost;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
102
|
+
*
|
|
103
|
+
* @param market
|
|
104
|
+
* @param marketIndex
|
|
105
|
+
* @param newPeg
|
|
106
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
107
|
+
*/
|
|
108
|
+
export function calculateReserveRebalanceCost(
|
|
109
|
+
market: Market,
|
|
110
|
+
marketIndex: BN
|
|
111
|
+
): BN {
|
|
112
|
+
const netUserPosition = {
|
|
113
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
114
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
115
|
+
marketIndex: new BN(marketIndex),
|
|
116
|
+
quoteAssetAmount: new BN(0),
|
|
117
|
+
openOrders: ZERO,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
121
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
122
|
+
const prevMarketPrice = calculateMarkPrice(market);
|
|
123
|
+
const marketNewPeg = Object.assign({}, market);
|
|
124
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
125
|
+
|
|
126
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
127
|
+
const newPeg = calculateTerminalPrice(market)
|
|
128
|
+
.mul(PEG_PRECISION)
|
|
129
|
+
.div(MARK_PRICE_PRECISION);
|
|
130
|
+
// const newPeg = prevMarketPrice.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION);
|
|
131
|
+
|
|
132
|
+
const newBaseReserve = market.amm.baseAssetReserve.add(
|
|
133
|
+
market.baseAssetAmount
|
|
134
|
+
);
|
|
135
|
+
const newQuoteReserve = market.amm.sqrtK
|
|
136
|
+
.mul(market.amm.sqrtK)
|
|
137
|
+
.div(newBaseReserve);
|
|
138
|
+
console.log(
|
|
139
|
+
'current reserves on close, quote:',
|
|
140
|
+
convertToNumber(newQuoteReserve, AMM_RESERVE_PRECISION),
|
|
141
|
+
'base:',
|
|
142
|
+
convertToNumber(newBaseReserve, AMM_RESERVE_PRECISION)
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
let newSqrtK;
|
|
146
|
+
if (newPeg.lt(market.amm.pegMultiplier)) {
|
|
147
|
+
newSqrtK = newBaseReserve;
|
|
148
|
+
} else {
|
|
149
|
+
newSqrtK = newQuoteReserve;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
marketNewPeg.amm.baseAssetReserve = newSqrtK.sub(market.baseAssetAmount); // newSqrtK.sub(market.baseAssetAmount);
|
|
153
|
+
marketNewPeg.amm.quoteAssetReserve = newSqrtK
|
|
154
|
+
.mul(newSqrtK)
|
|
155
|
+
.div(marketNewPeg.amm.baseAssetReserve);
|
|
156
|
+
marketNewPeg.amm.sqrtK = newSqrtK;
|
|
157
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
158
|
+
|
|
159
|
+
console.log(
|
|
160
|
+
'Price moves from',
|
|
161
|
+
convertToNumber(prevMarketPrice),
|
|
162
|
+
'to',
|
|
163
|
+
convertToNumber(calculateMarkPrice(marketNewPeg))
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
|
|
167
|
+
|
|
168
|
+
return cost;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
|
|
172
|
+
// wolframalpha.com
|
|
173
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
174
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
175
|
+
|
|
176
|
+
// todo: assumes k = x * y
|
|
177
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
178
|
+
|
|
179
|
+
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
180
|
+
const x = market.amm.baseAssetReserve;
|
|
181
|
+
const y = market.amm.quoteAssetReserve;
|
|
182
|
+
|
|
183
|
+
const d = market.baseAssetAmount;
|
|
184
|
+
const Q = market.amm.pegMultiplier;
|
|
185
|
+
|
|
186
|
+
const C = cost.mul(new BN(-1));
|
|
187
|
+
|
|
188
|
+
const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
|
|
189
|
+
const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
|
|
190
|
+
const denom1 = C.mul(x)
|
|
191
|
+
.mul(x.add(d))
|
|
192
|
+
.div(AMM_RESERVE_PRECISION)
|
|
193
|
+
.div(QUOTE_PRECISION);
|
|
194
|
+
const denom2 = y
|
|
195
|
+
.mul(d)
|
|
196
|
+
.mul(d)
|
|
197
|
+
.mul(Q)
|
|
198
|
+
.div(AMM_RESERVE_PRECISION)
|
|
199
|
+
.div(AMM_RESERVE_PRECISION)
|
|
200
|
+
.div(PEG_PRECISION);
|
|
201
|
+
|
|
202
|
+
const numerator = d
|
|
203
|
+
.mul(numer1.add(numer2))
|
|
204
|
+
.div(AMM_RESERVE_PRECISION)
|
|
205
|
+
.div(AMM_RESERVE_PRECISION)
|
|
206
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
207
|
+
const denominator = denom1
|
|
208
|
+
.add(denom2)
|
|
209
|
+
.div(AMM_RESERVE_PRECISION)
|
|
210
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
211
|
+
console.log(numerator, denominator);
|
|
212
|
+
// const p = (numerator).div(denominator);
|
|
213
|
+
|
|
214
|
+
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
215
|
+
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
216
|
+
|
|
217
|
+
return [numerator, denominator];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function calculateBudgetedPeg(market: Market, cost: BN): BN {
|
|
221
|
+
// wolframalpha.com
|
|
222
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
223
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
224
|
+
|
|
225
|
+
// todo: assumes k = x * y
|
|
226
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
227
|
+
|
|
228
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
229
|
+
const x = market.amm.baseAssetReserve;
|
|
230
|
+
const y = market.amm.quoteAssetReserve;
|
|
231
|
+
|
|
232
|
+
const d = market.baseAssetAmount;
|
|
233
|
+
const Q = market.amm.pegMultiplier;
|
|
234
|
+
|
|
235
|
+
const C = cost.mul(new BN(-1));
|
|
236
|
+
|
|
237
|
+
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
238
|
+
const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION).div(
|
|
239
|
+
deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO)
|
|
240
|
+
);
|
|
241
|
+
// .mul(PEG_PRECISION)
|
|
242
|
+
// .div(QUOTE_PRECISION);
|
|
243
|
+
console.log(
|
|
244
|
+
Q.toNumber(),
|
|
245
|
+
'change by',
|
|
246
|
+
deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
|
|
247
|
+
);
|
|
248
|
+
const newPeg = Q.sub(
|
|
249
|
+
deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
return newPeg;
|
|
253
|
+
}
|
package/src/addresses.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.getUserOrdersAccountPublicKey = exports.getUserOrdersAccountPublicKeyAndNonce = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getClearingHouseStateAccountPublicKey = exports.getOrderStateAccountPublicKeyAndNonce = exports.getOrderStateAccountPublicKey = exports.getClearingHouseStateAccountPublicKeyAndNonce = void 0;
|
|
23
|
-
const anchor = __importStar(require("@project-serum/anchor"));
|
|
24
|
-
async function getClearingHouseStateAccountPublicKeyAndNonce(programId) {
|
|
25
|
-
return anchor.web3.PublicKey.findProgramAddress([Buffer.from(anchor.utils.bytes.utf8.encode('clearing_house'))], programId);
|
|
26
|
-
}
|
|
27
|
-
exports.getClearingHouseStateAccountPublicKeyAndNonce = getClearingHouseStateAccountPublicKeyAndNonce;
|
|
28
|
-
async function getOrderStateAccountPublicKey(programId) {
|
|
29
|
-
return (await getOrderStateAccountPublicKeyAndNonce(programId))[0];
|
|
30
|
-
}
|
|
31
|
-
exports.getOrderStateAccountPublicKey = getOrderStateAccountPublicKey;
|
|
32
|
-
async function getOrderStateAccountPublicKeyAndNonce(programId) {
|
|
33
|
-
return anchor.web3.PublicKey.findProgramAddress([Buffer.from(anchor.utils.bytes.utf8.encode('order_state'))], programId);
|
|
34
|
-
}
|
|
35
|
-
exports.getOrderStateAccountPublicKeyAndNonce = getOrderStateAccountPublicKeyAndNonce;
|
|
36
|
-
async function getClearingHouseStateAccountPublicKey(programId) {
|
|
37
|
-
return (await getClearingHouseStateAccountPublicKeyAndNonce(programId))[0];
|
|
38
|
-
}
|
|
39
|
-
exports.getClearingHouseStateAccountPublicKey = getClearingHouseStateAccountPublicKey;
|
|
40
|
-
async function getUserAccountPublicKeyAndNonce(programId, authority) {
|
|
41
|
-
return anchor.web3.PublicKey.findProgramAddress([Buffer.from(anchor.utils.bytes.utf8.encode('user')), authority.toBuffer()], programId);
|
|
42
|
-
}
|
|
43
|
-
exports.getUserAccountPublicKeyAndNonce = getUserAccountPublicKeyAndNonce;
|
|
44
|
-
async function getUserAccountPublicKey(programId, authority) {
|
|
45
|
-
return (await getUserAccountPublicKeyAndNonce(programId, authority))[0];
|
|
46
|
-
}
|
|
47
|
-
exports.getUserAccountPublicKey = getUserAccountPublicKey;
|
|
48
|
-
async function getUserOrdersAccountPublicKeyAndNonce(programId, userAccount) {
|
|
49
|
-
return anchor.web3.PublicKey.findProgramAddress([
|
|
50
|
-
Buffer.from(anchor.utils.bytes.utf8.encode('user_orders')),
|
|
51
|
-
userAccount.toBuffer(),
|
|
52
|
-
], programId);
|
|
53
|
-
}
|
|
54
|
-
exports.getUserOrdersAccountPublicKeyAndNonce = getUserOrdersAccountPublicKeyAndNonce;
|
|
55
|
-
async function getUserOrdersAccountPublicKey(programId, userAccount) {
|
|
56
|
-
return (await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount))[0];
|
|
57
|
-
}
|
|
58
|
-
exports.getUserOrdersAccountPublicKey = getUserOrdersAccountPublicKey;
|
|
59
|
-
//# sourceMappingURL=addresses.js.map
|
package/src/addresses.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"addresses.js","sourceRoot":"","sources":["addresses.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,8DAAgD;AAEzC,KAAK,UAAU,6CAA6C,CAClE,SAAoB;IAEpB,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAC9C,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAC/D,SAAS,CACT,CAAC;AACH,CAAC;AAPD,sGAOC;AAEM,KAAK,UAAU,6BAA6B,CAClD,SAAoB;IAEpB,OAAO,CAAC,MAAM,qCAAqC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAJD,sEAIC;AAEM,KAAK,UAAU,qCAAqC,CAC1D,SAAoB;IAEpB,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAC9C,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAC5D,SAAS,CACT,CAAC;AACH,CAAC;AAPD,sFAOC;AAEM,KAAK,UAAU,qCAAqC,CAC1D,SAAoB;IAEpB,OAAO,CAAC,MAAM,6CAA6C,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAJD,sFAIC;AAEM,KAAK,UAAU,+BAA+B,CACpD,SAAoB,EACpB,SAAoB;IAEpB,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAC9C,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EAC3E,SAAS,CACT,CAAC;AACH,CAAC;AARD,0EAQC;AAEM,KAAK,UAAU,uBAAuB,CAC5C,SAAoB,EACpB,SAAoB;IAEpB,OAAO,CAAC,MAAM,+BAA+B,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AALD,0DAKC;AAEM,KAAK,UAAU,qCAAqC,CAC1D,SAAoB,EACpB,WAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAC9C;QACC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1D,WAAW,CAAC,QAAQ,EAAE;KACtB,EACD,SAAS,CACT,CAAC;AACH,CAAC;AAXD,sFAWC;AAEM,KAAK,UAAU,6BAA6B,CAClD,SAAoB,EACpB,WAAsB;IAEtB,OAAO,CACN,MAAM,qCAAqC,CAAC,SAAS,EAAE,WAAW,CAAC,CACnE,CAAC,CAAC,CAAC,CAAC;AACN,CAAC;AAPD,sEAOC"}
|