@sundaeswap/math 0.5.0 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ConcentratedLiquidityPool.js","names":["AssetAmount","Fraction","ConstantProductPool","asFeeParts","fee","f","asFraction","lt","ZERO","gte","ONE","Error","BigInt","numerator","denominator","rawSwapOutput","dx","aReserve","bReserve","totalLp","spaNum","spaDen","spbNum","spbDen","feeNum","feeDen","isAInput","dxEff","va0","vb0","dvaEff","denom","dvbEff","getSwapOutput","inputMetadata","input","sqrtPriceA","sqrtPriceB","inputReserve","outputReserve","output","inputLpFee","nextInputReserve","nextOutputReserve","priceImpact","idealPrice","actualPrice","subtract","divide","lpFee","getSwapInput","feeDiff","ceilDiv","n","d","effMin","dvaEffMin","dvbEffMin","fwd","guard","calculateLiquidity","a","b"],"sources":["../../../src/PoolMath/ConcentratedLiquidityPool.ts"],"sourcesContent":["import { AssetAmount, IAssetAmountMetadata } from \"@sundaeswap/asset\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\n\nimport * as ConstantProductPool from \"./ConstantProductPool.js\";\n\n/**\n * Holds the calculated outcome of a concentrated-liquidity swap. Mirrors\n * {@link ConstantProductPool.TSwapOutcome} so it flows through the same generic\n * swap-outcome consumers.\n */\nexport type TSwapOutcome = {\n input: bigint;\n output: bigint;\n lpFee: AssetAmount<IAssetAmountMetadata>;\n nextInputReserve: bigint;\n nextOutputReserve: bigint;\n priceImpact: Fraction;\n};\n\n/** A sqrt-price bound from the CL config, as an exact rational `[num, den]`. */\nexport type TSqrtPrice = [bigint, bigint];\n\n/**\n * Concentrated liquidity is Sundae v4's single-range invariant. Unlike Uniswap\n * v3 there are no per-position ranges or ticks: the whole pool shares ONE\n * immutable price range `[sqrtPriceA, sqrtPriceB]` (a < b) set at creation, and\n * LP is a single fungible token. Swaps run on *virtual* reserves that fold the\n * pool's liquidity `L` (its total LP supply) into each side:\n *\n * VA = a·spbNum + L·spbDen\n * VB = b·spaDen + L·spaNum\n *\n * where `a`/`b` are the raw assetA/assetB reserves. This is a direct port of the\n * scooper's `cl_swap_result` (scooper-v2/src/sundaev4/swap_math.rs) and the\n * on-chain `cl_check_swap` (sundae-v4/lib/modules/cl_check.ak) — those are the\n * source of truth; keep this in lockstep with them.\n */\n\nconst asFeeParts = (fee: TFractionLike): [bigint, bigint] => {\n const f = Fraction.asFraction(fee);\n if (f.lt(Fraction.ZERO) || f.gte(Fraction.ONE))\n throw new Error(\"fee must be in [0, 1)\");\n return [BigInt(f.numerator), BigInt(f.denominator)];\n};\n\n/**\n * The raw forward swap: given a pre-fee input `dx`, return the output amount.\n * A→B and B→A use different virtual-reserve scalings (see `cl_check_swap`).\n * All quantities are non-negative so integer division floors, matching chain.\n */\nconst rawSwapOutput = (\n dx: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n spaNum: bigint,\n spaDen: bigint,\n spbNum: bigint,\n spbDen: bigint,\n feeNum: bigint,\n feeDen: bigint,\n isAInput: boolean,\n): bigint => {\n const fee = (dx * feeNum) / feeDen;\n const dxEff = dx - fee;\n const va0 = aReserve * spbNum + totalLp * spbDen;\n const vb0 = bReserve * spaDen + totalLp * spaNum;\n if (isAInput) {\n const dvaEff = dxEff * spbNum;\n const denom = (va0 + dvaEff) * spaDen;\n if (denom <= 0n) return 0n;\n return (vb0 * dvaEff) / denom;\n }\n const dvbEff = dxEff * spaNum;\n const denom = (vb0 + dvbEff) * spbNum;\n if (denom <= 0n) return 0n;\n return (va0 * dvbEff) / denom;\n};\n\n/**\n * Calculate the swap outcome for a concentrated-liquidity pool.\n *\n * @param inputMetadata Metadata for the supplied (input) asset — used for the fee AssetAmount.\n * @param input The pre-fee amount of the input asset being swapped.\n * @param aReserve The pool's raw reserve of asset A.\n * @param bReserve The pool's raw reserve of asset B.\n * @param totalLp The pool's total LP supply (the virtual liquidity `L`).\n * @param sqrtPriceA The lower sqrt-price bound `[num, den]` from the CL config.\n * @param sqrtPriceB The upper sqrt-price bound `[num, den]` from the CL config.\n * @param fee The liquidity-provider fee (plus protocol fee) as a fraction.\n * @param isAInput True when asset A is the supplied asset (A→B swap).\n * @returns The swap details in the shared {@link TSwapOutcome} shape.\n */\nexport const getSwapOutput = (\n inputMetadata: IAssetAmountMetadata,\n input: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n sqrtPriceA: TSqrtPrice,\n sqrtPriceB: TSqrtPrice,\n fee: TFractionLike,\n isAInput: boolean,\n): TSwapOutcome => {\n if (input <= 0n || aReserve <= 0n || bReserve <= 0n || totalLp <= 0n)\n throw new Error(\"Input, reserves and liquidity must be positive\");\n const [spaNum, spaDen] = sqrtPriceA;\n const [spbNum, spbDen] = sqrtPriceB;\n if (spaNum <= 0n || spaDen <= 0n || spbNum <= 0n || spbDen <= 0n)\n throw new Error(\"sqrt prices must be positive\");\n const [feeNum, feeDen] = asFeeParts(fee);\n\n const inputReserve = isAInput ? aReserve : bReserve;\n const outputReserve = isAInput ? bReserve : aReserve;\n\n let output = rawSwapOutput(\n input,\n aReserve,\n bReserve,\n totalLp,\n spaNum,\n spaDen,\n spbNum,\n spbDen,\n feeNum,\n feeDen,\n isAInput,\n );\n // Can't take more than the pool actually holds (virtual reserves can\n // otherwise let the formula exceed the real reserve near the boundary).\n if (output > outputReserve) output = outputReserve;\n\n const inputLpFee = (input * feeNum) / feeDen;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output;\n\n // Price impact vs the marginal (dx→0) rate. Marginal output-per-effective-\n // input is vb0·spbNum/(va0·spaDen) for A→B (symmetric for B→A), so the ideal\n // input-per-output is its reciprocal. Display-only.\n const va0 = aReserve * spbNum + totalLp * spbDen;\n const vb0 = bReserve * spaDen + totalLp * spaNum;\n let priceImpact = Fraction.ZERO;\n if (output > 0n) {\n const idealPrice = isAInput\n ? new Fraction(va0 * spaDen, vb0 * spbNum)\n : new Fraction(vb0 * spbNum, va0 * spaDen);\n const actualPrice = new Fraction(input - inputLpFee, output);\n priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n }\n\n return {\n input,\n output,\n lpFee: new AssetAmount(inputLpFee, inputMetadata),\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Calculate the minimal input required to receive a given output — the inverse\n * of {@link getSwapOutput}. The forward swap is linear-fractional in the\n * effective input, so it inverts in closed form; a short correction loop\n * absorbs the fee floor and integer rounding so the result is the exact minimal\n * input whose forward swap yields at least `output`.\n */\nexport const getSwapInput = (\n inputMetadata: IAssetAmountMetadata,\n output: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n sqrtPriceA: TSqrtPrice,\n sqrtPriceB: TSqrtPrice,\n fee: TFractionLike,\n isAInput: boolean,\n): TSwapOutcome => {\n if (output <= 0n || aReserve <= 0n || bReserve <= 0n || totalLp <= 0n)\n throw new Error(\"Output, reserves and liquidity must be positive\");\n const [spaNum, spaDen] = sqrtPriceA;\n const [spbNum, spbDen] = sqrtPriceB;\n if (spaNum <= 0n || spaDen <= 0n || spbNum <= 0n || spbDen <= 0n)\n throw new Error(\"sqrt prices must be positive\");\n const outputReserve = isAInput ? bReserve : aReserve;\n if (output > outputReserve)\n throw new Error(\"Output must not exceed the output reserve\");\n\n const [feeNum, feeDen] = asFeeParts(fee);\n const feeDiff = feeDen - feeNum;\n\n const va0 = aReserve * spbNum + totalLp * spbDen;\n const vb0 = bReserve * spaDen + totalLp * spaNum;\n\n const ceilDiv = (n: bigint, d: bigint) => (n + d - 1n) / d;\n\n // Closed-form minimal effective input, then gross up for the fee floor.\n let effMin: bigint;\n if (isAInput) {\n // dvaEff ≥ output·spaDen·va0 / (vb0 − output·spaDen)\n const denom = vb0 - output * spaDen;\n if (denom <= 0n)\n throw new Error(\"Output not reachable within the pool's range\");\n const dvaEffMin = ceilDiv(output * spaDen * va0, denom);\n effMin = ceilDiv(dvaEffMin, spbNum);\n } else {\n const denom = va0 - output * spbNum;\n if (denom <= 0n)\n throw new Error(\"Output not reachable within the pool's range\");\n const dvbEffMin = ceilDiv(output * spbNum * vb0, denom);\n effMin = ceilDiv(dvbEffMin, spaNum);\n }\n let input = feeDiff > 0n ? ceilDiv(effMin * feeDen, feeDiff) : effMin;\n\n // Correct for floor interactions: nudge up until the forward swap clears the\n // target, then trim any over-shoot. Bounded — a couple of iterations at most.\n const fwd = (dx: bigint) =>\n rawSwapOutput(\n dx,\n aReserve,\n bReserve,\n totalLp,\n spaNum,\n spaDen,\n spbNum,\n spbDen,\n feeNum,\n feeDen,\n isAInput,\n );\n let guard = 0;\n while (fwd(input) < output && guard++ < 64) input += 1n;\n while (input > 1n && fwd(input - 1n) >= output) input -= 1n;\n\n const inputLpFee = (input * feeNum) / feeDen;\n const inputReserve = isAInput ? aReserve : bReserve;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output;\n\n let priceImpact = Fraction.ZERO;\n if (output > 0n) {\n const idealPrice = isAInput\n ? new Fraction(va0 * spaDen, vb0 * spbNum)\n : new Fraction(vb0 * spbNum, va0 * spaDen);\n const actualPrice = new Fraction(input - inputLpFee, output);\n priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n }\n\n return {\n input,\n output,\n lpFee: new AssetAmount(inputLpFee, inputMetadata),\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Deposit LP estimate for a concentrated-liquidity pool. CL deposits reuse the\n * constant-product *proportional* pinning: minting by the scarcest offered\n * asset and ceil-pinning the reserve deltas gives, per asset,\n * `a1·L0 ≥ a0·L1` and `b1·L0 ≥ b0·L1` — and those two bounds multiply to\n * exactly the on-chain CL non-swap invariant `va1·vb1·L0² ≥ va0·vb0·L1²`\n * (`cl_check.ak`). So the proportional deposit is always chain-valid; excess of\n * either asset is refunded via aChange/bChange. This mirrors the scooper's\n * `resolve_cl_deposit` (which likewise reuses the CP pinning).\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n) => ConstantProductPool.calculateLiquidity(a, b, aReserve, bReserve, totalLp);\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ConcentratedLiquidityPool.js","names":["AssetAmount","Fraction","FIXED_ONE","MIN_COUNTER_PER_WEIGHT","minCreateCounter","ladder","weightTotal","ceilDiv","n","d","upperEdge","l","i","bands","length","start","closing","delta","lo","hi","num","den","aSat","x","weight","bSat","liquidityOf","k","coeffA","coeffB","buildIndex","a","Array","from","_","b","out","ca","cb","push","indexLadder","isArray","index","prefixes","e","fAt","L","gAt","A","B","ra","rb","curve","bandProof","SCAN","CAP","findWitnessInBand","hint","ok","search","span","m","undefined","w","findWitness","bandView","band","feeBuy","feeSell","feeFor","v","isAInput","bandFee","dx","fee","bandOutput","dxEff","va0","vb0","dva","dvb","pn","pd","bandCapacity","maxDxInBand","cap","fits","guard","nextBand","swapSteps","remaining","steps","known","prefer","hintX","before","view","capDx","stepDx","dy","kNext","na","nb","crossing","after","input","output","getSwapOutput","inputMetadata","aReserve","bReserve","Error","lpFee","s","inputReserve","outputReserve","w0","v0","priceImpact","ZERO","ideal","actual","ONE","subtract","divide","nextInputReserve","nextOutputReserve","bandStates","restA","restB","liquidity","quantities","active","bandOf","reservesAt","K","frac","reduceFrac","f","gcd","g","uniformLadder","curves","commonDen","BigInt","bandWeights","shape","opts","peak","Number","tail","centre","sigma","Math","max","bell","c","exp","profile","round","shapedLadder","base","weights","cs","Set","csBands","map","feeAt","has","reduce"],"sources":["../../../src/PoolMath/ConcentratedLiquidityPool.ts"],"sourcesContent":["import { AssetAmount, IAssetAmountMetadata } from \"@sundaeswap/asset\";\nimport { Fraction } from \"@sundaeswap/fraction\";\n\n/**\n * Holds the calculated outcome of a concentrated-liquidity swap. It has the\n * same shape as `ConstantProductPool.TSwapOutcome`, so the generic\n * swap-outcome consumers accept it.\n */\nexport type TSwapOutcome = {\n input: bigint;\n output: bigint;\n lpFee: AssetAmount<IAssetAmountMetadata>;\n nextInputReserve: bigint;\n nextOutputReserve: bigint;\n priceImpact: Fraction;\n};\n\n/**\n * Concentrated liquidity: Sundae v4's ladder invariant.\n *\n * A pool is a ladder of bands in ascending sqrt-price order. Each band is a\n * concentrated-liquidity arc (`curve` 0) or a constant-sum bin (`curve` 1)\n * with its own share of the pool's liquidity (`weight / weightTotal`) and\n * its own two fees. LP is one fungible token for the whole ladder; a\n * deposit or withdrawal scales every band.\n *\n * The chain never stores the price. It stores reserves, and the state is a\n * WITNESS `(X, k)`: the ladder counter `X` (the pool's `total_lp`, spec V12)\n * and the active band `k`, which the reserves must prove. Everything here\n * mirrors `lib/modules/cl_check.ak` and the scooper's ladder\n * math, rounding included; where they disagree the chain wins\n * and the transaction fails. The rounding is not negotiable:\n *\n * - `L_k` floors; saturation ceils, in ONE division;\n * - the band fee ceils, per step, on the step's real input;\n * - the prefix sums come from the LADDER INDEX (cumulative coefficients\n * in fixed point at 2^64, spec §2.3), multiplied by the counter and\n * ceiled ONCE. A per-band sum of ceilings is a different number and the\n * chain rejects it.\n */\n\n/** An exact rational `num / den`. */\nexport type TFrac = { num: bigint; den: bigint };\n\n/** One band of the ladder. */\nexport type TBand = {\n /** The band's LOWER sqrt-price edge. The next band's `start` is its upper edge. */\n start: TFrac;\n /** The band's share of the ladder's liquidity counter. */\n weight: bigint;\n /** 0 = concentrated-liquidity arc, 1 = constant-sum bin. */\n curve: 0 | 1;\n /** Fee on swaps that buy the pool's first asset (B in). */\n feeBuy: TFrac;\n /** Fee on swaps that sell the pool's first asset (A in). */\n feeSell: TFrac;\n};\n\n/** A ladder: bands, the top edge, and the sum of the weights. */\nexport type TLadder = {\n bands: TBand[];\n /** The last band's UPPER sqrt-price edge. */\n closing: TFrac;\n weightTotal: bigint;\n};\n\n/** The witness the chain checks: the ladder counter and the active band. */\nexport type TWitness = { x: bigint; k: number };\n\n/** 2^64, the fixed-point scale of the ladder index. */\nexport const FIXED_ONE = 1n << 64n;\n\n/**\n * The least counter per unit of weight a ladder may be created with.\n * Mirrors `cl_check.min_counter_per_weight` (sundae-v4 #229, SV4-007):\n * Create requires `total_lp >= MIN_COUNTER_PER_WEIGHT * weightTotal`.\n */\nexport const MIN_COUNTER_PER_WEIGHT = 1000n;\n\n/** The least counter (initial `total_lp`) the chain accepts at Create for `ladder`. */\nexport const minCreateCounter = (ladder: TLadder): bigint =>\n MIN_COUNTER_PER_WEIGHT * ladder.weightTotal;\n\nconst ceilDiv = (n: bigint, d: bigint): bigint => (n + d - 1n) / d;\n\n/** Band i's upper sqrt-price edge. */\nexport const upperEdge = (l: TLadder, i: number): TFrac =>\n i + 1 < l.bands.length ? l.bands[i + 1]!.start : l.closing;\n\n/** `D_i = hi.num·lo.den − lo.num·hi.den`: positive exactly when the edges increase. */\nexport const delta = (lo: TFrac, hi: TFrac): bigint =>\n hi.num * lo.den - lo.num * hi.den;\n\n/** `a_sat_i = ceil(w_i·X·D_i / (W·lo.num·hi.num))`: the A a band above the price holds. */\nexport const aSat = (l: TLadder, x: bigint, i: number): bigint => {\n const lo = l.bands[i]!.start;\n const hi = upperEdge(l, i);\n return ceilDiv(\n l.bands[i]!.weight * x * delta(lo, hi),\n l.weightTotal * lo.num * hi.num,\n );\n};\n\n/** `b_sat_i = ceil(w_i·X·D_i / (W·lo.den·hi.den))`: the B a band below the price holds. */\nexport const bSat = (l: TLadder, x: bigint, i: number): bigint => {\n const lo = l.bands[i]!.start;\n const hi = upperEdge(l, i);\n return ceilDiv(\n l.bands[i]!.weight * x * delta(lo, hi),\n l.weightTotal * lo.den * hi.den,\n );\n};\n\n/** `L_k = floor(w_k·X / W)`. */\nexport const liquidityOf = (l: TLadder, x: bigint, k: number): bigint =>\n (l.bands[k]!.weight * x) / l.weightTotal;\n\n/** Band i's A-side saturation coefficient: the part of `a_sat_i` independent of X, rounded up. */\nexport const coeffA = (l: TLadder, i: number): bigint => {\n const lo = l.bands[i]!.start;\n const hi = upperEdge(l, i);\n return ceilDiv(\n l.bands[i]!.weight * delta(lo, hi) * FIXED_ONE,\n l.weightTotal * lo.num * hi.num,\n );\n};\n\n/** The same on the B side. */\nexport const coeffB = (l: TLadder, i: number): bigint => {\n const lo = l.bands[i]!.start;\n const hi = upperEdge(l, i);\n return ceilDiv(\n l.bands[i]!.weight * delta(lo, hi) * FIXED_ONE,\n l.weightTotal * lo.den * hi.den,\n );\n};\n\n/** One index entry: the cumulative coefficients above and below band k. */\nexport type TIndexEntry = { ca: bigint; cb: bigint };\n\n/**\n * The ladder index `Create` pins and every spend reads: entry k is the pair\n * of cumulative coefficients for the bands strictly above and strictly\n * below band k. `cl_check.build_index`, to the digit.\n */\nexport const buildIndex = (l: TLadder): TIndexEntry[] => {\n const n = l.bands.length;\n const a = Array.from({ length: n }, (_, i) => coeffA(l, i));\n const b = Array.from({ length: n }, (_, i) => coeffB(l, i));\n const out: TIndexEntry[] = [];\n for (let k = 0; k < n; k++) {\n let ca = 0n;\n let cb = 0n;\n for (let i = 0; i < n; i++) {\n if (i > k) ca += a[i]!;\n if (i < k) cb += b[i]!;\n }\n out.push({ ca, cb });\n }\n return out;\n};\n\n/**\n * A ladder with its index built once. Every probe of the witness search\n * reads the index for every band, and rebuilding it per probe is most of\n * the cost of a quote.\n */\nexport type TIndexedLadder = TLadder & { index: TIndexEntry[] };\n\nexport const indexLadder = (l: TLadder): TIndexedLadder =>\n \"index\" in l && Array.isArray((l as TIndexedLadder).index)\n ? (l as TIndexedLadder)\n : { ...l, index: buildIndex(l) };\n\n/** `C_A`, `C_B` at (X, k) from the index: one ceiling after the multiply by X. */\nexport const prefixes = (\n l: TIndexedLadder,\n x: bigint,\n k: number,\n): { ca: bigint; cb: bigint } => {\n const e = l.index[k]!;\n return { ca: ceilDiv(e.ca * x, FIXED_ONE), cb: ceilDiv(e.cb * x, FIXED_ONE) };\n};\n\n/** `cl_check.f_at_raw`: the CL arc, cross-multiplied. */\nconst fAt = (a: bigint, b: bigint, L: bigint, lo: TFrac, hi: TFrac): bigint =>\n (a * hi.num + L * hi.den) * (b * lo.den + L * lo.num) -\n L * L * hi.num * lo.den;\n\n/** G at a witness, on whichever curve the active band carries. */\nconst gAt = (\n l: TIndexedLadder,\n A: bigint,\n B: bigint,\n x: bigint,\n k: number,\n): bigint => {\n const { ca, cb } = prefixes(l, x, k);\n const lo = l.bands[k]!.start;\n const hi = upperEdge(l, k);\n const ra = A - ca;\n const rb = B - cb;\n const L = liquidityOf(l, x, k);\n return l.bands[k]!.curve === 0\n ? fAt(ra, rb, L, lo, hi)\n : ra * (lo.num * hi.num) + rb * (lo.den * hi.den) - L * delta(lo, hi);\n};\n\n/** The band proof, P1 through P7. The chain runs exactly this. */\nexport const bandProof = (\n l: TIndexedLadder,\n A: bigint,\n B: bigint,\n x: bigint,\n k: number,\n): boolean => {\n if (x < l.weightTotal) return false; // P1\n const { ca, cb } = prefixes(l, x, k);\n const ra = A - ca;\n const rb = B - cb;\n if (ra < 0n || rb < 0n) return false; // P2, P3\n if (ra > aSat(l, x, k) || rb > bSat(l, x, k)) return false; // P4, P5\n if (gAt(l, A, B, x, k) < 0n) return false; // P6\n return gAt(l, A, B, x + 1n, k) < 0n; // P7\n};\n\nconst SCAN = 400n;\nconst CAP = 1n << 80n;\n\n/**\n * The witness in band k, seeded at `hint` when given: the counter only\n * grows along a swap, so the doubling search starts from the previous\n * witness. `lo` is the largest x with non-negative residuals and G ≥ 0,\n * and a witness is such an x whose successor fails G, so the scan walks\n * DOWN from `lo` first. Mirrors the scooper's `find_witness_in_band_from`.\n */\nexport const findWitnessInBand = (\n l: TIndexedLadder,\n A: bigint,\n B: bigint,\n k: number,\n hint?: bigint,\n): TWitness | null => {\n const ok = (x: bigint): boolean => {\n const { ca, cb } = prefixes(l, x, k);\n return A - ca >= 0n && B - cb >= 0n && gAt(l, A, B, x, k) >= 0n;\n };\n const search = (start: bigint): TWitness | null => {\n let lo = start;\n let span = 1n;\n let hi = lo + span;\n while (ok(hi) && hi < CAP) {\n lo = hi;\n span *= 2n;\n hi = lo + span;\n }\n while (lo + 1n < hi) {\n const m = (lo + hi) / 2n;\n if (ok(m)) lo = m;\n else hi = m;\n }\n const from = lo > SCAN ? lo - SCAN : 1n;\n for (let x = lo; x >= from; x--) {\n if (bandProof(l, A, B, x, k)) return { x, k };\n }\n for (let x = lo + 1n; x <= lo + SCAN; x++) {\n if (bandProof(l, A, B, x, k)) return { x, k };\n }\n return null;\n };\n if (hint !== undefined && hint > 0n && ok(hint)) {\n const w = search(hint);\n if (w) return w;\n }\n if (!ok(1n)) return null;\n return search(1n);\n};\n\n/**\n * The witness `(X, k)` for a pool's reserves. A hint (the indexed\n * `bandCounter` / `activeBand`) is checked first and seeds the search in\n * its band; a stale hint falls back to every band. Null when the reserves\n * sit on no point of the ladder — the chain would reject them too.\n */\nexport const findWitness = (\n ladder: TLadder,\n A: bigint,\n B: bigint,\n hint?: TWitness,\n): TWitness | null => {\n const l = indexLadder(ladder);\n if (hint && hint.k >= 0 && hint.k < l.bands.length) {\n if (bandProof(l, A, B, hint.x, hint.k)) return hint;\n const w = findWitnessInBand(l, A, B, hint.k, hint.x);\n if (w) return w;\n }\n for (let k = 0; k < l.bands.length; k++) {\n const w = findWitnessInBand(l, A, B, k);\n if (w) return w;\n }\n return null;\n};\n\n/** The active band's view at a witness: its residual reserves and liquidity. */\nexport type TBandView = {\n ra: bigint;\n rb: bigint;\n l: bigint;\n lo: TFrac;\n hi: TFrac;\n curve: 0 | 1;\n feeBuy: TFrac;\n feeSell: TFrac;\n};\n\nexport const bandView = (\n l: TIndexedLadder,\n A: bigint,\n B: bigint,\n w: TWitness,\n): TBandView => {\n const { ca, cb } = prefixes(l, w.x, w.k);\n const band = l.bands[w.k]!;\n return {\n ra: A - ca,\n rb: B - cb,\n l: liquidityOf(l, w.x, w.k),\n lo: band.start,\n hi: upperEdge(l, w.k),\n curve: band.curve,\n feeBuy: band.feeBuy,\n feeSell: band.feeSell,\n };\n};\n\n/** The band's fee for a direction: `feeSell` when A is sold, `feeBuy` when A is bought. */\nexport const feeFor = (v: TBandView, isAInput: boolean): TFrac =>\n isAInput ? v.feeSell : v.feeBuy;\n\n/**\n * The band fee on a step's real input `dx`: `ceil(dx * num / den)`.\n * Mirrors `cl_check.band_fee` (sundae-v4 #228, SV4-006). The chain charges\n * it per transcript step and rounds it UP, so a step below `den / num`\n * units still pays one unit. A zero rate charges nothing.\n */\nexport const bandFee = (dx: bigint, fee: TFrac): bigint =>\n (dx * fee.num + fee.den - 1n) / fee.den;\n\n/** The output one band pays for `dx` within itself. Mirrors the scooper's `band_output`. */\nexport const bandOutput = (\n v: TBandView,\n isAInput: boolean,\n dx: bigint,\n): bigint => {\n const fee = feeFor(v, isAInput);\n if (fee.den <= 0n) return 0n;\n const dxEff = dx - bandFee(dx, fee);\n if (dxEff <= 0n) return 0n;\n if (v.curve === 0) {\n const va0 = v.ra * v.hi.num + v.l * v.hi.den;\n const vb0 = v.rb * v.lo.den + v.l * v.lo.num;\n if (isAInput) {\n const dva = dxEff * v.hi.num;\n const den = (va0 + dva) * v.lo.den;\n return den === 0n ? 0n : (vb0 * dva) / den;\n }\n const dvb = dxEff * v.lo.den;\n const den = (vb0 + dvb) * v.hi.num;\n return den === 0n ? 0n : (va0 * dvb) / den;\n }\n const pn = v.lo.num * v.hi.num;\n const pd = v.lo.den * v.hi.den;\n return isAInput ? (dxEff * pn) / pd : (dxEff * pd) / pn;\n};\n\n/** What the band can pay out in a direction: its residual of the output asset. */\nexport const bandCapacity = (v: TBandView, isAInput: boolean): bigint =>\n isAInput ? v.rb : v.ra;\n\n/** The largest input whose output stays within the band. */\nexport const maxDxInBand = (v: TBandView, isAInput: boolean): bigint => {\n const cap = bandCapacity(v, isAInput);\n if (cap <= 0n) return 0n;\n const fits = (dx: bigint) => bandOutput(v, isAInput, dx) <= cap;\n let hi = 1n;\n for (let guard = 0; fits(hi); guard++) {\n hi *= 2n;\n if (guard > 200) return hi;\n }\n let lo = 0n;\n while (lo + 1n < hi) {\n const m = (lo + hi) / 2n;\n if (fits(m)) lo = m;\n else hi = m;\n }\n return lo;\n};\n\n/** The next band a fill enters: selling A walks down the ladder, buying A walks up. */\nexport const nextBand = (\n k: number,\n isAInput: boolean,\n n: number,\n): number | null =>\n isAInput ? (k === 0 ? null : k - 1) : k + 1 >= n ? null : k + 1;\n\n/** One band of a fill: what it paid, and the state it left. */\nexport type TFillStep = {\n band: number;\n input: bigint;\n output: bigint;\n after: TWitness;\n};\n\n/**\n * Price `dx` across as many bands as it takes, as the scooper's\n * `swap_steps` does: fill the active band, cross to the next, repeat.\n * Returns the steps, or null when the ladder cannot absorb `dx` (the\n * direction is exhausted, or the remainder pays nothing).\n */\nexport const swapSteps = (\n ladder: TLadder,\n A: bigint,\n B: bigint,\n isAInput: boolean,\n dx: bigint,\n hint?: TWitness,\n): TFillStep[] | null => {\n const l = indexLadder(ladder);\n const n = l.bands.length;\n let ca = A;\n let cb = B;\n let remaining = dx;\n const steps: TFillStep[] = [];\n let known: TWitness | null = findWitness(l, A, B, hint);\n if (!known) return null;\n let prefer: number | null = null;\n let hintX: bigint | undefined;\n for (let guard = 0; remaining > 0n; guard++) {\n if (guard > 2 * n + 2) return null;\n let before: TWitness | null = known;\n known = null;\n if (!before) {\n if (prefer !== null) before = findWitnessInBand(l, ca, cb, prefer, hintX);\n if (!before) before = findWitness(l, ca, cb);\n if (!before) return null;\n }\n const view = bandView(l, ca, cb, before);\n const capDx = maxDxInBand(view, isAInput);\n const stepDx = capDx < remaining ? capDx : remaining;\n const dy = stepDx > 0n ? bandOutput(view, isAInput, stepDx) : 0n;\n if (dy <= 0n) {\n const kNext = nextBand(before.k, isAInput, n);\n if (kNext === null || prefer === kNext) return null;\n prefer = kNext;\n continue;\n }\n const na = isAInput ? ca + stepDx : ca - dy;\n const nb = isAInput ? cb - dy : cb + stepDx;\n const crossing = stepDx < remaining;\n let after: TWitness | null = null;\n if (crossing) {\n const kNext = nextBand(before.k, isAInput, n);\n if (kNext !== null) after = findWitnessInBand(l, na, nb, kNext, before.x);\n } else {\n after = findWitnessInBand(l, na, nb, before.k, before.x);\n }\n if (!after) after = findWitness(l, na, nb);\n if (!after || after.x < before.x) return null;\n steps.push({ band: before.k, input: stepDx, output: dy, after });\n remaining -= stepDx;\n ca = na;\n cb = nb;\n prefer = after.k;\n hintX = after.x;\n known = after;\n }\n return steps;\n};\n\n/**\n * The swap output of a concentrated-liquidity pool for `input` of one asset, crossing\n * bands as needed. `aReserve`/`bReserve` are the pool's reserves in\n * canonical order; `hint` is the indexed `bandCounter` / `activeBand`,\n * which seeds the witness search and may be stale.\n *\n * The `lpFee` is the fee the bands kept of the input, summed across the\n * steps. `priceImpact` is against the active band's opening marginal\n * price. Throws when the ladder cannot absorb the input.\n */\nexport const getSwapOutput = (\n inputMetadata: IAssetAmountMetadata,\n input: bigint,\n aReserve: bigint,\n bReserve: bigint,\n ladder: TLadder,\n isAInput: boolean,\n hint?: TWitness,\n): TSwapOutcome & { steps: TFillStep[] } => {\n if (input <= 0n || aReserve < 0n || bReserve < 0n)\n throw new Error(\"Input must be positive and reserves non-negative\");\n if (ladder.bands.length === 0 || ladder.weightTotal <= 0n)\n throw new Error(\"The ladder has no bands\");\n const l = indexLadder(ladder);\n const steps = swapSteps(l, aReserve, bReserve, isAInput, input, hint);\n if (!steps || steps.length === 0)\n throw new Error(\"The ladder cannot absorb this input in this direction\");\n let output = 0n;\n let lpFee = 0n;\n for (const s of steps) {\n output += s.output;\n const band = l.bands[s.band]!;\n const fee = isAInput ? band.feeSell : band.feeBuy;\n lpFee += bandFee(s.input, fee);\n }\n const inputReserve = isAInput ? aReserve : bReserve;\n const outputReserve = isAInput ? bReserve : aReserve;\n if (output > outputReserve) output = outputReserve;\n // Price impact against the opening marginal of the first band traded.\n const w0 = findWitness(l, aReserve, bReserve, hint)!;\n const v0 = bandView(l, aReserve, bReserve, w0);\n let priceImpact = Fraction.ZERO;\n if (output > 0n) {\n let ideal: Fraction;\n if (v0.curve === 1) {\n const pn = v0.lo.num * v0.hi.num;\n const pd = v0.lo.den * v0.hi.den;\n ideal = isAInput ? new Fraction(pd, pn) : new Fraction(pn, pd);\n } else {\n const va0 = v0.ra * v0.hi.num + v0.l * v0.hi.den;\n const vb0 = v0.rb * v0.lo.den + v0.l * v0.lo.num;\n ideal = isAInput\n ? new Fraction(va0 * v0.lo.den, vb0 * v0.hi.num)\n : new Fraction(vb0 * v0.hi.num, va0 * v0.lo.den);\n }\n const actual = new Fraction(input - lpFee, output);\n priceImpact = Fraction.ONE.subtract(ideal.divide(actual));\n }\n return {\n input,\n output,\n lpFee: new AssetAmount(lpFee, inputMetadata),\n nextInputReserve: inputReserve + input,\n nextOutputReserve: outputReserve - output,\n priceImpact,\n steps,\n };\n};\n\n/** What each band holds at the pool's reserves. */\nexport type TBandState = {\n /** The band's reserves in canonical order. The bands sum to the pool's reserves. */\n quantities: [bigint, bigint];\n liquidity: bigint;\n active: boolean;\n};\n\n/**\n * Every band's state at the pool's reserves: a band below the price holds\n * only B, a band above it only A, the active band some of both. Null when\n * the reserves sit on no point of the ladder.\n */\nexport const bandStates = (\n ladder: TLadder,\n aReserve: bigint,\n bReserve: bigint,\n hint?: TWitness,\n): TBandState[] | null => {\n const l = indexLadder(ladder);\n const w = findWitness(l, aReserve, bReserve, hint);\n if (!w) return null;\n const out: TBandState[] = [];\n let restA = 0n;\n let restB = 0n;\n for (let i = 0; i < l.bands.length; i++) {\n const liquidity = liquidityOf(l, w.x, i);\n if (i < w.k) {\n const b = bSat(l, w.x, i);\n restB += b;\n out.push({ quantities: [0n, b], liquidity, active: false });\n } else if (i > w.k) {\n const a = aSat(l, w.x, i);\n restA += a;\n out.push({ quantities: [a, 0n], liquidity, active: false });\n } else {\n out.push({ quantities: [0n, 0n], liquidity, active: true });\n }\n }\n const ra = aReserve - restA;\n const rb = bReserve - restB;\n out[w.k]!.quantities = [ra < 0n ? 0n : ra, rb < 0n ? 0n : rb];\n return out;\n};\n\n/** Which band holds a sqrt-price. */\nexport const bandOf = (l: TLadder, s: TFrac): number => {\n for (let i = 0; i < l.bands.length; i++) {\n const hi = upperEdge(l, i);\n if (s.num * hi.den < hi.num * s.den) return i;\n }\n return l.bands.length - 1;\n};\n\n/**\n * The exact reserves a ladder holds at counter `x` with the price at\n * sqrt-price `s`, which must lie in band `k`: what a pool creator deposits\n * for a chosen shape, scale and launch price. The result is floored, so\n * `findWitness` must still be run on it to learn the counter the chain\n * derives — usually `x`, but rounding can move it.\n */\nexport const reservesAt = (\n l: TLadder,\n x: bigint,\n k: number,\n s: TFrac,\n): { A: bigint; B: bigint } => {\n let A = 0n;\n let B = 0n;\n for (let i = 0; i < l.bands.length; i++) {\n if (i > k) {\n A += aSat(l, x, i);\n continue;\n }\n if (i < k) {\n B += bSat(l, x, i);\n continue;\n }\n const lo = l.bands[i]!.start;\n const hi = upperEdge(l, i);\n const L = liquidityOf(l, x, i);\n if (l.bands[i]!.curve === 1) {\n // A constant-sum bin prices at the geometric mean; `s` only says how\n // far through the bin the conversion has gone.\n const K = L * delta(lo, hi);\n const frac = (s.num * lo.den - lo.num * s.den) * hi.den;\n const span = (hi.num * lo.den - lo.num * hi.den) * s.den;\n const rb = (K * frac) / (span * (lo.den * hi.den));\n A += (K - rb * (lo.den * hi.den)) / (lo.num * hi.num);\n B += rb;\n } else {\n // a = L·(1/s − 1/hi), b = L·(s − lo), in exact rationals.\n A += (L * (s.den * hi.num - s.num * hi.den)) / (s.num * hi.num);\n B += (L * (s.num * lo.den - lo.num * s.den)) / (s.den * lo.den);\n }\n }\n return { A, B };\n};\n\n/** A fraction in lowest terms. */\nconst reduceFrac = (f: TFrac): TFrac => {\n const gcd = (a: bigint, b: bigint): bigint => (b === 0n ? a : gcd(b, a % b));\n const g = gcd(f.num < 0n ? -f.num : f.num, f.den);\n return g > 1n ? { num: f.num / g, den: f.den / g } : f;\n};\n\n/**\n * An equal-weight ladder of `n` bands from `lo` to `hi`, every band a CL\n * arc at `fee` unless named in `curves`. The edges are built over a common\n * denominator and reduced: every rational component of a concentrated-liquidity config\n * must stay below 2^64 (spec V9).\n */\nexport const uniformLadder = (\n n: number,\n lo: TFrac,\n hi: TFrac,\n fee: TFrac,\n curves: (0 | 1)[] = [],\n): TLadder => {\n if (n < 1) throw new Error(\"A ladder needs at least one band\");\n if (lo.num * hi.den >= hi.num * lo.den)\n throw new Error(\"The lower edge must be strictly below the upper edge\");\n const span = hi.num * lo.den - lo.num * hi.den;\n const commonDen = lo.den * hi.den * BigInt(n);\n const bands: TBand[] = [];\n for (let i = 0; i < n; i++) {\n bands.push({\n start: reduceFrac({\n num: lo.num * hi.den * BigInt(n) + span * BigInt(i),\n den: commonDen,\n }),\n weight: 1n,\n curve: curves[i] ?? 0,\n feeBuy: fee,\n feeSell: fee,\n });\n }\n return {\n bands,\n closing: reduceFrac({\n num: lo.num * hi.den * BigInt(n) + span * BigInt(n),\n den: commonDen,\n }),\n weightTotal: BigInt(n),\n };\n};\n\n/** Band weight profiles. Every weight is at least 1, as `Create` demands. */\nexport type TWeightShape =\n | \"flat\"\n | \"concentrated\"\n | \"skewed-low\"\n | \"skewed-high\"\n | \"bimodal\";\n\nexport const bandWeights = (\n n: number,\n shape: TWeightShape = \"concentrated\",\n opts: { centre?: number; peak?: bigint; tail?: bigint } = {},\n): bigint[] => {\n if (shape === \"flat\") return Array.from({ length: n }, () => 1n);\n const peak = Number(opts.peak ?? 64n);\n const tail = Number(opts.tail ?? 1n);\n const centre = opts.centre ?? (n - 1) / 2;\n const sigma = Math.max(n / 5, 0.75);\n const bell = (i: number, c: number) => Math.exp(-(((i - c) / sigma) ** 2));\n const profile = (i: number): number => {\n switch (shape) {\n case \"concentrated\":\n return bell(i, centre);\n case \"skewed-low\":\n return Math.exp(-i / Math.max(n / 3, 1));\n case \"skewed-high\":\n return Math.exp(-(n - 1 - i) / Math.max(n / 3, 1));\n case \"bimodal\":\n return Math.max(bell(i, (n - 1) / 4), bell(i, (3 * (n - 1)) / 4));\n default:\n return 1;\n }\n };\n return Array.from({ length: n }, (_, i) => {\n const w = Math.round(tail + (peak - tail) * profile(i));\n return BigInt(Math.max(1, w));\n });\n};\n\n/**\n * A ladder of `n` bands from `lo` to `hi` with a weight shape, optional\n * constant-sum bins and an optional per-band fee. The edges are\n * `uniformLadder`'s exactly; only the weights, curves and fees differ.\n */\nexport const shapedLadder = (\n n: number,\n lo: TFrac,\n hi: TFrac,\n fee: TFrac,\n opts: {\n shape?: TWeightShape;\n centre?: number;\n peak?: bigint;\n tail?: bigint;\n /** Zero-based band indices to price as constant-sum bins. */\n csBands?: number[];\n /** Overrides `fee` per band. */\n feeAt?: (i: number) => TFrac;\n } = {},\n): TLadder => {\n const base = uniformLadder(n, lo, hi, fee);\n const weights = bandWeights(n, opts.shape ?? \"concentrated\", opts);\n const cs = new Set(opts.csBands ?? []);\n const bands: TBand[] = base.bands.map((b, i) => {\n const f = opts.feeAt ? opts.feeAt(i) : fee;\n return {\n ...b,\n weight: weights[i]!,\n curve: cs.has(i) ? 1 : 0,\n feeBuy: f,\n feeSell: f,\n };\n });\n return {\n bands,\n closing: base.closing,\n weightTotal: weights.reduce((s, w) => s + w, 0n),\n };\n};\n"],"mappings":"AAAA,SAASA,WAAW,QAA8B,mBAAmB;AACrE,SAASC,QAAQ,QAAQ,sBAAsB;;AAE/C;AACA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAGA;;AAcA;;AAQA;;AAGA;AACA,OAAO,MAAMC,SAAS,GAAG,EAAE,IAAI,GAAG;;AAElC;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,GAAG,KAAK;;AAE3C;AACA,OAAO,MAAMC,gBAAgB,GAAIC,MAAe,IAC9CF,sBAAsB,GAAGE,MAAM,CAACC,WAAW;AAE7C,MAAMC,OAAO,GAAGA,CAACC,CAAS,EAAEC,CAAS,KAAa,CAACD,CAAC,GAAGC,CAAC,GAAG,EAAE,IAAIA,CAAC;;AAElE;AACA,OAAO,MAAMC,SAAS,GAAGA,CAACC,CAAU,EAAEC,CAAS,KAC7CA,CAAC,GAAG,CAAC,GAAGD,CAAC,CAACE,KAAK,CAACC,MAAM,GAAGH,CAAC,CAACE,KAAK,CAACD,CAAC,GAAG,CAAC,CAAC,CAAEG,KAAK,GAAGJ,CAAC,CAACK,OAAO;;AAE5D;AACA,OAAO,MAAMC,KAAK,GAAGA,CAACC,EAAS,EAAEC,EAAS,KACxCA,EAAE,CAACC,GAAG,GAAGF,EAAE,CAACG,GAAG,GAAGH,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG;;AAEnC;AACA,OAAO,MAAMC,IAAI,GAAGA,CAACX,CAAU,EAAEY,CAAS,EAAEX,CAAS,KAAa;EAChE,MAAMM,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEG,KAAK;EAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;EAC1B,OAAOL,OAAO,CACZI,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEY,MAAM,GAAGD,CAAC,GAAGN,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC,EACtCR,CAAC,CAACL,WAAW,GAAGY,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACC,GAC9B,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMK,IAAI,GAAGA,CAACd,CAAU,EAAEY,CAAS,EAAEX,CAAS,KAAa;EAChE,MAAMM,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEG,KAAK;EAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;EAC1B,OAAOL,OAAO,CACZI,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEY,MAAM,GAAGD,CAAC,GAAGN,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC,EACtCR,CAAC,CAACL,WAAW,GAAGY,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAC9B,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMK,WAAW,GAAGA,CAACf,CAAU,EAAEY,CAAS,EAAEI,CAAS,KACzDhB,CAAC,CAACE,KAAK,CAACc,CAAC,CAAC,CAAEH,MAAM,GAAGD,CAAC,GAAIZ,CAAC,CAACL,WAAW;;AAE1C;AACA,OAAO,MAAMsB,MAAM,GAAGA,CAACjB,CAAU,EAAEC,CAAS,KAAa;EACvD,MAAMM,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEG,KAAK;EAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;EAC1B,OAAOL,OAAO,CACZI,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEY,MAAM,GAAGP,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC,GAAGjB,SAAS,EAC9CS,CAAC,CAACL,WAAW,GAAGY,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACC,GAC9B,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMS,MAAM,GAAGA,CAAClB,CAAU,EAAEC,CAAS,KAAa;EACvD,MAAMM,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEG,KAAK;EAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;EAC1B,OAAOL,OAAO,CACZI,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEY,MAAM,GAAGP,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC,GAAGjB,SAAS,EAC9CS,CAAC,CAACL,WAAW,GAAGY,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAC9B,CAAC;AACH,CAAC;;AAED;;AAGA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMS,UAAU,GAAInB,CAAU,IAAoB;EACvD,MAAMH,CAAC,GAAGG,CAAC,CAACE,KAAK,CAACC,MAAM;EACxB,MAAMiB,CAAC,GAAGC,KAAK,CAACC,IAAI,CAAC;IAAEnB,MAAM,EAAEN;EAAE,CAAC,EAAE,CAAC0B,CAAC,EAAEtB,CAAC,KAAKgB,MAAM,CAACjB,CAAC,EAAEC,CAAC,CAAC,CAAC;EAC3D,MAAMuB,CAAC,GAAGH,KAAK,CAACC,IAAI,CAAC;IAAEnB,MAAM,EAAEN;EAAE,CAAC,EAAE,CAAC0B,CAAC,EAAEtB,CAAC,KAAKiB,MAAM,CAAClB,CAAC,EAAEC,CAAC,CAAC,CAAC;EAC3D,MAAMwB,GAAkB,GAAG,EAAE;EAC7B,KAAK,IAAIT,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGnB,CAAC,EAAEmB,CAAC,EAAE,EAAE;IAC1B,IAAIU,EAAE,GAAG,EAAE;IACX,IAAIC,EAAE,GAAG,EAAE;IACX,KAAK,IAAI1B,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,CAAC,EAAEI,CAAC,EAAE,EAAE;MAC1B,IAAIA,CAAC,GAAGe,CAAC,EAAEU,EAAE,IAAIN,CAAC,CAACnB,CAAC,CAAE;MACtB,IAAIA,CAAC,GAAGe,CAAC,EAAEW,EAAE,IAAIH,CAAC,CAACvB,CAAC,CAAE;IACxB;IACAwB,GAAG,CAACG,IAAI,CAAC;MAAEF,EAAE;MAAEC;IAAG,CAAC,CAAC;EACtB;EACA,OAAOF,GAAG;AACZ,CAAC;;AAED;AACA;AACA;AACA;AACA;;AAGA,OAAO,MAAMI,WAAW,GAAI7B,CAAU,IACpC,OAAO,IAAIA,CAAC,IAAIqB,KAAK,CAACS,OAAO,CAAE9B,CAAC,CAAoB+B,KAAK,CAAC,GACrD/B,CAAC,GACF;EAAE,GAAGA,CAAC;EAAE+B,KAAK,EAAEZ,UAAU,CAACnB,CAAC;AAAE,CAAC;;AAEpC;AACA,OAAO,MAAMgC,QAAQ,GAAGA,CACtBhC,CAAiB,EACjBY,CAAS,EACTI,CAAS,KACsB;EAC/B,MAAMiB,CAAC,GAAGjC,CAAC,CAAC+B,KAAK,CAACf,CAAC,CAAE;EACrB,OAAO;IAAEU,EAAE,EAAE9B,OAAO,CAACqC,CAAC,CAACP,EAAE,GAAGd,CAAC,EAAErB,SAAS,CAAC;IAAEoC,EAAE,EAAE/B,OAAO,CAACqC,CAAC,CAACN,EAAE,GAAGf,CAAC,EAAErB,SAAS;EAAE,CAAC;AAC/E,CAAC;;AAED;AACA,MAAM2C,GAAG,GAAGA,CAACd,CAAS,EAAEI,CAAS,EAAEW,CAAS,EAAE5B,EAAS,EAAEC,EAAS,KAChE,CAACY,CAAC,GAAGZ,EAAE,CAACC,GAAG,GAAG0B,CAAC,GAAG3B,EAAE,CAACE,GAAG,KAAKc,CAAC,GAAGjB,EAAE,CAACG,GAAG,GAAGyB,CAAC,GAAG5B,EAAE,CAACE,GAAG,CAAC,GACrD0B,CAAC,GAAGA,CAAC,GAAG3B,EAAE,CAACC,GAAG,GAAGF,EAAE,CAACG,GAAG;;AAEzB;AACA,MAAM0B,GAAG,GAAGA,CACVpC,CAAiB,EACjBqC,CAAS,EACTC,CAAS,EACT1B,CAAS,EACTI,CAAS,KACE;EACX,MAAM;IAAEU,EAAE;IAAEC;EAAG,CAAC,GAAGK,QAAQ,CAAChC,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC;EACpC,MAAMT,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACc,CAAC,CAAC,CAAEZ,KAAK;EAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEgB,CAAC,CAAC;EAC1B,MAAMuB,EAAE,GAAGF,CAAC,GAAGX,EAAE;EACjB,MAAMc,EAAE,GAAGF,CAAC,GAAGX,EAAE;EACjB,MAAMQ,CAAC,GAAGpB,WAAW,CAACf,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC;EAC9B,OAAOhB,CAAC,CAACE,KAAK,CAACc,CAAC,CAAC,CAAEyB,KAAK,KAAK,CAAC,GAC1BP,GAAG,CAACK,EAAE,EAAEC,EAAE,EAAEL,CAAC,EAAE5B,EAAE,EAAEC,EAAE,CAAC,GACtB+B,EAAE,IAAIhC,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACC,GAAG,CAAC,GAAG+B,EAAE,IAAIjC,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAAG,CAAC,GAAGyB,CAAC,GAAG7B,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC;AACzE,CAAC;;AAED;AACA,OAAO,MAAMkC,SAAS,GAAGA,CACvB1C,CAAiB,EACjBqC,CAAS,EACTC,CAAS,EACT1B,CAAS,EACTI,CAAS,KACG;EACZ,IAAIJ,CAAC,GAAGZ,CAAC,CAACL,WAAW,EAAE,OAAO,KAAK,CAAC,CAAC;EACrC,MAAM;IAAE+B,EAAE;IAAEC;EAAG,CAAC,GAAGK,QAAQ,CAAChC,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC;EACpC,MAAMuB,EAAE,GAAGF,CAAC,GAAGX,EAAE;EACjB,MAAMc,EAAE,GAAGF,CAAC,GAAGX,EAAE;EACjB,IAAIY,EAAE,GAAG,EAAE,IAAIC,EAAE,GAAG,EAAE,EAAE,OAAO,KAAK,CAAC,CAAC;EACtC,IAAID,EAAE,GAAG5B,IAAI,CAACX,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC,IAAIwB,EAAE,GAAG1B,IAAI,CAACd,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,CAAC;EAC5D,IAAIoB,GAAG,CAACpC,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAE1B,CAAC,EAAEI,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,KAAK,CAAC,CAAC;EAC3C,OAAOoB,GAAG,CAACpC,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAE1B,CAAC,GAAG,EAAE,EAAEI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM2B,IAAI,GAAG,IAAI;AACjB,MAAMC,GAAG,GAAG,EAAE,IAAI,GAAG;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,GAAGA,CAC/B7C,CAAiB,EACjBqC,CAAS,EACTC,CAAS,EACTtB,CAAS,EACT8B,IAAa,KACO;EACpB,MAAMC,EAAE,GAAInC,CAAS,IAAc;IACjC,MAAM;MAAEc,EAAE;MAAEC;IAAG,CAAC,GAAGK,QAAQ,CAAChC,CAAC,EAAEY,CAAC,EAAEI,CAAC,CAAC;IACpC,OAAOqB,CAAC,GAAGX,EAAE,IAAI,EAAE,IAAIY,CAAC,GAAGX,EAAE,IAAI,EAAE,IAAIS,GAAG,CAACpC,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAE1B,CAAC,EAAEI,CAAC,CAAC,IAAI,EAAE;EACjE,CAAC;EACD,MAAMgC,MAAM,GAAI5C,KAAa,IAAsB;IACjD,IAAIG,EAAE,GAAGH,KAAK;IACd,IAAI6C,IAAI,GAAG,EAAE;IACb,IAAIzC,EAAE,GAAGD,EAAE,GAAG0C,IAAI;IAClB,OAAOF,EAAE,CAACvC,EAAE,CAAC,IAAIA,EAAE,GAAGoC,GAAG,EAAE;MACzBrC,EAAE,GAAGC,EAAE;MACPyC,IAAI,IAAI,EAAE;MACVzC,EAAE,GAAGD,EAAE,GAAG0C,IAAI;IAChB;IACA,OAAO1C,EAAE,GAAG,EAAE,GAAGC,EAAE,EAAE;MACnB,MAAM0C,CAAC,GAAG,CAAC3C,EAAE,GAAGC,EAAE,IAAI,EAAE;MACxB,IAAIuC,EAAE,CAACG,CAAC,CAAC,EAAE3C,EAAE,GAAG2C,CAAC,CAAC,KACb1C,EAAE,GAAG0C,CAAC;IACb;IACA,MAAM5B,IAAI,GAAGf,EAAE,GAAGoC,IAAI,GAAGpC,EAAE,GAAGoC,IAAI,GAAG,EAAE;IACvC,KAAK,IAAI/B,CAAC,GAAGL,EAAE,EAAEK,CAAC,IAAIU,IAAI,EAAEV,CAAC,EAAE,EAAE;MAC/B,IAAI8B,SAAS,CAAC1C,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAE1B,CAAC,EAAEI,CAAC,CAAC,EAAE,OAAO;QAAEJ,CAAC;QAAEI;MAAE,CAAC;IAC/C;IACA,KAAK,IAAIJ,CAAC,GAAGL,EAAE,GAAG,EAAE,EAAEK,CAAC,IAAIL,EAAE,GAAGoC,IAAI,EAAE/B,CAAC,EAAE,EAAE;MACzC,IAAI8B,SAAS,CAAC1C,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAE1B,CAAC,EAAEI,CAAC,CAAC,EAAE,OAAO;QAAEJ,CAAC;QAAEI;MAAE,CAAC;IAC/C;IACA,OAAO,IAAI;EACb,CAAC;EACD,IAAI8B,IAAI,KAAKK,SAAS,IAAIL,IAAI,GAAG,EAAE,IAAIC,EAAE,CAACD,IAAI,CAAC,EAAE;IAC/C,MAAMM,CAAC,GAAGJ,MAAM,CAACF,IAAI,CAAC;IACtB,IAAIM,CAAC,EAAE,OAAOA,CAAC;EACjB;EACA,IAAI,CAACL,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,IAAI;EACxB,OAAOC,MAAM,CAAC,EAAE,CAAC;AACnB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMK,WAAW,GAAGA,CACzB3D,MAAe,EACf2C,CAAS,EACTC,CAAS,EACTQ,IAAe,KACK;EACpB,MAAM9C,CAAC,GAAG6B,WAAW,CAACnC,MAAM,CAAC;EAC7B,IAAIoD,IAAI,IAAIA,IAAI,CAAC9B,CAAC,IAAI,CAAC,IAAI8B,IAAI,CAAC9B,CAAC,GAAGhB,CAAC,CAACE,KAAK,CAACC,MAAM,EAAE;IAClD,IAAIuC,SAAS,CAAC1C,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAEQ,IAAI,CAAClC,CAAC,EAAEkC,IAAI,CAAC9B,CAAC,CAAC,EAAE,OAAO8B,IAAI;IACnD,MAAMM,CAAC,GAAGP,iBAAiB,CAAC7C,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAEQ,IAAI,CAAC9B,CAAC,EAAE8B,IAAI,CAAClC,CAAC,CAAC;IACpD,IAAIwC,CAAC,EAAE,OAAOA,CAAC;EACjB;EACA,KAAK,IAAIpC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGhB,CAAC,CAACE,KAAK,CAACC,MAAM,EAAEa,CAAC,EAAE,EAAE;IACvC,MAAMoC,CAAC,GAAGP,iBAAiB,CAAC7C,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAEtB,CAAC,CAAC;IACvC,IAAIoC,CAAC,EAAE,OAAOA,CAAC;EACjB;EACA,OAAO,IAAI;AACb,CAAC;;AAED;;AAYA,OAAO,MAAME,QAAQ,GAAGA,CACtBtD,CAAiB,EACjBqC,CAAS,EACTC,CAAS,EACTc,CAAW,KACG;EACd,MAAM;IAAE1B,EAAE;IAAEC;EAAG,CAAC,GAAGK,QAAQ,CAAChC,CAAC,EAAEoD,CAAC,CAACxC,CAAC,EAAEwC,CAAC,CAACpC,CAAC,CAAC;EACxC,MAAMuC,IAAI,GAAGvD,CAAC,CAACE,KAAK,CAACkD,CAAC,CAACpC,CAAC,CAAE;EAC1B,OAAO;IACLuB,EAAE,EAAEF,CAAC,GAAGX,EAAE;IACVc,EAAE,EAAEF,CAAC,GAAGX,EAAE;IACV3B,CAAC,EAAEe,WAAW,CAACf,CAAC,EAAEoD,CAAC,CAACxC,CAAC,EAAEwC,CAAC,CAACpC,CAAC,CAAC;IAC3BT,EAAE,EAAEgD,IAAI,CAACnD,KAAK;IACdI,EAAE,EAAET,SAAS,CAACC,CAAC,EAAEoD,CAAC,CAACpC,CAAC,CAAC;IACrByB,KAAK,EAAEc,IAAI,CAACd,KAAK;IACjBe,MAAM,EAAED,IAAI,CAACC,MAAM;IACnBC,OAAO,EAAEF,IAAI,CAACE;EAChB,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMC,MAAM,GAAGA,CAACC,CAAY,EAAEC,QAAiB,KACpDA,QAAQ,GAAGD,CAAC,CAACF,OAAO,GAAGE,CAAC,CAACH,MAAM;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMK,OAAO,GAAGA,CAACC,EAAU,EAAEC,GAAU,KAC5C,CAACD,EAAE,GAAGC,GAAG,CAACtD,GAAG,GAAGsD,GAAG,CAACrD,GAAG,GAAG,EAAE,IAAIqD,GAAG,CAACrD,GAAG;;AAEzC;AACA,OAAO,MAAMsD,UAAU,GAAGA,CACxBL,CAAY,EACZC,QAAiB,EACjBE,EAAU,KACC;EACX,MAAMC,GAAG,GAAGL,MAAM,CAACC,CAAC,EAAEC,QAAQ,CAAC;EAC/B,IAAIG,GAAG,CAACrD,GAAG,IAAI,EAAE,EAAE,OAAO,EAAE;EAC5B,MAAMuD,KAAK,GAAGH,EAAE,GAAGD,OAAO,CAACC,EAAE,EAAEC,GAAG,CAAC;EACnC,IAAIE,KAAK,IAAI,EAAE,EAAE,OAAO,EAAE;EAC1B,IAAIN,CAAC,CAAClB,KAAK,KAAK,CAAC,EAAE;IACjB,MAAMyB,GAAG,GAAGP,CAAC,CAACpB,EAAE,GAAGoB,CAAC,CAACnD,EAAE,CAACC,GAAG,GAAGkD,CAAC,CAAC3D,CAAC,GAAG2D,CAAC,CAACnD,EAAE,CAACE,GAAG;IAC5C,MAAMyD,GAAG,GAAGR,CAAC,CAACnB,EAAE,GAAGmB,CAAC,CAACpD,EAAE,CAACG,GAAG,GAAGiD,CAAC,CAAC3D,CAAC,GAAG2D,CAAC,CAACpD,EAAE,CAACE,GAAG;IAC5C,IAAImD,QAAQ,EAAE;MACZ,MAAMQ,GAAG,GAAGH,KAAK,GAAGN,CAAC,CAACnD,EAAE,CAACC,GAAG;MAC5B,MAAMC,GAAG,GAAG,CAACwD,GAAG,GAAGE,GAAG,IAAIT,CAAC,CAACpD,EAAE,CAACG,GAAG;MAClC,OAAOA,GAAG,KAAK,EAAE,GAAG,EAAE,GAAIyD,GAAG,GAAGC,GAAG,GAAI1D,GAAG;IAC5C;IACA,MAAM2D,GAAG,GAAGJ,KAAK,GAAGN,CAAC,CAACpD,EAAE,CAACG,GAAG;IAC5B,MAAMA,GAAG,GAAG,CAACyD,GAAG,GAAGE,GAAG,IAAIV,CAAC,CAACnD,EAAE,CAACC,GAAG;IAClC,OAAOC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAIwD,GAAG,GAAGG,GAAG,GAAI3D,GAAG;EAC5C;EACA,MAAM4D,EAAE,GAAGX,CAAC,CAACpD,EAAE,CAACE,GAAG,GAAGkD,CAAC,CAACnD,EAAE,CAACC,GAAG;EAC9B,MAAM8D,EAAE,GAAGZ,CAAC,CAACpD,EAAE,CAACG,GAAG,GAAGiD,CAAC,CAACnD,EAAE,CAACE,GAAG;EAC9B,OAAOkD,QAAQ,GAAIK,KAAK,GAAGK,EAAE,GAAIC,EAAE,GAAIN,KAAK,GAAGM,EAAE,GAAID,EAAE;AACzD,CAAC;;AAED;AACA,OAAO,MAAME,YAAY,GAAGA,CAACb,CAAY,EAAEC,QAAiB,KAC1DA,QAAQ,GAAGD,CAAC,CAACnB,EAAE,GAAGmB,CAAC,CAACpB,EAAE;;AAExB;AACA,OAAO,MAAMkC,WAAW,GAAGA,CAACd,CAAY,EAAEC,QAAiB,KAAa;EACtE,MAAMc,GAAG,GAAGF,YAAY,CAACb,CAAC,EAAEC,QAAQ,CAAC;EACrC,IAAIc,GAAG,IAAI,EAAE,EAAE,OAAO,EAAE;EACxB,MAAMC,IAAI,GAAIb,EAAU,IAAKE,UAAU,CAACL,CAAC,EAAEC,QAAQ,EAAEE,EAAE,CAAC,IAAIY,GAAG;EAC/D,IAAIlE,EAAE,GAAG,EAAE;EACX,KAAK,IAAIoE,KAAK,GAAG,CAAC,EAAED,IAAI,CAACnE,EAAE,CAAC,EAAEoE,KAAK,EAAE,EAAE;IACrCpE,EAAE,IAAI,EAAE;IACR,IAAIoE,KAAK,GAAG,GAAG,EAAE,OAAOpE,EAAE;EAC5B;EACA,IAAID,EAAE,GAAG,EAAE;EACX,OAAOA,EAAE,GAAG,EAAE,GAAGC,EAAE,EAAE;IACnB,MAAM0C,CAAC,GAAG,CAAC3C,EAAE,GAAGC,EAAE,IAAI,EAAE;IACxB,IAAImE,IAAI,CAACzB,CAAC,CAAC,EAAE3C,EAAE,GAAG2C,CAAC,CAAC,KACf1C,EAAE,GAAG0C,CAAC;EACb;EACA,OAAO3C,EAAE;AACX,CAAC;;AAED;AACA,OAAO,MAAMsE,QAAQ,GAAGA,CACtB7D,CAAS,EACT4C,QAAiB,EACjB/D,CAAS,KAET+D,QAAQ,GAAI5C,CAAC,KAAK,CAAC,GAAG,IAAI,GAAGA,CAAC,GAAG,CAAC,GAAIA,CAAC,GAAG,CAAC,IAAInB,CAAC,GAAG,IAAI,GAAGmB,CAAC,GAAG,CAAC;;AAEjE;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM8D,SAAS,GAAGA,CACvBpF,MAAe,EACf2C,CAAS,EACTC,CAAS,EACTsB,QAAiB,EACjBE,EAAU,EACVhB,IAAe,KACQ;EACvB,MAAM9C,CAAC,GAAG6B,WAAW,CAACnC,MAAM,CAAC;EAC7B,MAAMG,CAAC,GAAGG,CAAC,CAACE,KAAK,CAACC,MAAM;EACxB,IAAIuB,EAAE,GAAGW,CAAC;EACV,IAAIV,EAAE,GAAGW,CAAC;EACV,IAAIyC,SAAS,GAAGjB,EAAE;EAClB,MAAMkB,KAAkB,GAAG,EAAE;EAC7B,IAAIC,KAAsB,GAAG5B,WAAW,CAACrD,CAAC,EAAEqC,CAAC,EAAEC,CAAC,EAAEQ,IAAI,CAAC;EACvD,IAAI,CAACmC,KAAK,EAAE,OAAO,IAAI;EACvB,IAAIC,MAAqB,GAAG,IAAI;EAChC,IAAIC,KAAyB;EAC7B,KAAK,IAAIP,KAAK,GAAG,CAAC,EAAEG,SAAS,GAAG,EAAE,EAAEH,KAAK,EAAE,EAAE;IAC3C,IAAIA,KAAK,GAAG,CAAC,GAAG/E,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI;IAClC,IAAIuF,MAAuB,GAAGH,KAAK;IACnCA,KAAK,GAAG,IAAI;IACZ,IAAI,CAACG,MAAM,EAAE;MACX,IAAIF,MAAM,KAAK,IAAI,EAAEE,MAAM,GAAGvC,iBAAiB,CAAC7C,CAAC,EAAE0B,EAAE,EAAEC,EAAE,EAAEuD,MAAM,EAAEC,KAAK,CAAC;MACzE,IAAI,CAACC,MAAM,EAAEA,MAAM,GAAG/B,WAAW,CAACrD,CAAC,EAAE0B,EAAE,EAAEC,EAAE,CAAC;MAC5C,IAAI,CAACyD,MAAM,EAAE,OAAO,IAAI;IAC1B;IACA,MAAMC,IAAI,GAAG/B,QAAQ,CAACtD,CAAC,EAAE0B,EAAE,EAAEC,EAAE,EAAEyD,MAAM,CAAC;IACxC,MAAME,KAAK,GAAGb,WAAW,CAACY,IAAI,EAAEzB,QAAQ,CAAC;IACzC,MAAM2B,MAAM,GAAGD,KAAK,GAAGP,SAAS,GAAGO,KAAK,GAAGP,SAAS;IACpD,MAAMS,EAAE,GAAGD,MAAM,GAAG,EAAE,GAAGvB,UAAU,CAACqB,IAAI,EAAEzB,QAAQ,EAAE2B,MAAM,CAAC,GAAG,EAAE;IAChE,IAAIC,EAAE,IAAI,EAAE,EAAE;MACZ,MAAMC,KAAK,GAAGZ,QAAQ,CAACO,MAAM,CAACpE,CAAC,EAAE4C,QAAQ,EAAE/D,CAAC,CAAC;MAC7C,IAAI4F,KAAK,KAAK,IAAI,IAAIP,MAAM,KAAKO,KAAK,EAAE,OAAO,IAAI;MACnDP,MAAM,GAAGO,KAAK;MACd;IACF;IACA,MAAMC,EAAE,GAAG9B,QAAQ,GAAGlC,EAAE,GAAG6D,MAAM,GAAG7D,EAAE,GAAG8D,EAAE;IAC3C,MAAMG,EAAE,GAAG/B,QAAQ,GAAGjC,EAAE,GAAG6D,EAAE,GAAG7D,EAAE,GAAG4D,MAAM;IAC3C,MAAMK,QAAQ,GAAGL,MAAM,GAAGR,SAAS;IACnC,IAAIc,KAAsB,GAAG,IAAI;IACjC,IAAID,QAAQ,EAAE;MACZ,MAAMH,KAAK,GAAGZ,QAAQ,CAACO,MAAM,CAACpE,CAAC,EAAE4C,QAAQ,EAAE/D,CAAC,CAAC;MAC7C,IAAI4F,KAAK,KAAK,IAAI,EAAEI,KAAK,GAAGhD,iBAAiB,CAAC7C,CAAC,EAAE0F,EAAE,EAAEC,EAAE,EAAEF,KAAK,EAAEL,MAAM,CAACxE,CAAC,CAAC;IAC3E,CAAC,MAAM;MACLiF,KAAK,GAAGhD,iBAAiB,CAAC7C,CAAC,EAAE0F,EAAE,EAAEC,EAAE,EAAEP,MAAM,CAACpE,CAAC,EAAEoE,MAAM,CAACxE,CAAC,CAAC;IAC1D;IACA,IAAI,CAACiF,KAAK,EAAEA,KAAK,GAAGxC,WAAW,CAACrD,CAAC,EAAE0F,EAAE,EAAEC,EAAE,CAAC;IAC1C,IAAI,CAACE,KAAK,IAAIA,KAAK,CAACjF,CAAC,GAAGwE,MAAM,CAACxE,CAAC,EAAE,OAAO,IAAI;IAC7CoE,KAAK,CAACpD,IAAI,CAAC;MAAE2B,IAAI,EAAE6B,MAAM,CAACpE,CAAC;MAAE8E,KAAK,EAAEP,MAAM;MAAEQ,MAAM,EAAEP,EAAE;MAAEK;IAAM,CAAC,CAAC;IAChEd,SAAS,IAAIQ,MAAM;IACnB7D,EAAE,GAAGgE,EAAE;IACP/D,EAAE,GAAGgE,EAAE;IACPT,MAAM,GAAGW,KAAK,CAAC7E,CAAC;IAChBmE,KAAK,GAAGU,KAAK,CAACjF,CAAC;IACfqE,KAAK,GAAGY,KAAK;EACf;EACA,OAAOb,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMgB,aAAa,GAAGA,CAC3BC,aAAmC,EACnCH,KAAa,EACbI,QAAgB,EAChBC,QAAgB,EAChBzG,MAAe,EACfkE,QAAiB,EACjBd,IAAe,KAC2B;EAC1C,IAAIgD,KAAK,IAAI,EAAE,IAAII,QAAQ,GAAG,EAAE,IAAIC,QAAQ,GAAG,EAAE,EAC/C,MAAM,IAAIC,KAAK,CAAC,kDAAkD,CAAC;EACrE,IAAI1G,MAAM,CAACQ,KAAK,CAACC,MAAM,KAAK,CAAC,IAAIT,MAAM,CAACC,WAAW,IAAI,EAAE,EACvD,MAAM,IAAIyG,KAAK,CAAC,yBAAyB,CAAC;EAC5C,MAAMpG,CAAC,GAAG6B,WAAW,CAACnC,MAAM,CAAC;EAC7B,MAAMsF,KAAK,GAAGF,SAAS,CAAC9E,CAAC,EAAEkG,QAAQ,EAAEC,QAAQ,EAAEvC,QAAQ,EAAEkC,KAAK,EAAEhD,IAAI,CAAC;EACrE,IAAI,CAACkC,KAAK,IAAIA,KAAK,CAAC7E,MAAM,KAAK,CAAC,EAC9B,MAAM,IAAIiG,KAAK,CAAC,uDAAuD,CAAC;EAC1E,IAAIL,MAAM,GAAG,EAAE;EACf,IAAIM,KAAK,GAAG,EAAE;EACd,KAAK,MAAMC,CAAC,IAAItB,KAAK,EAAE;IACrBe,MAAM,IAAIO,CAAC,CAACP,MAAM;IAClB,MAAMxC,IAAI,GAAGvD,CAAC,CAACE,KAAK,CAACoG,CAAC,CAAC/C,IAAI,CAAE;IAC7B,MAAMQ,GAAG,GAAGH,QAAQ,GAAGL,IAAI,CAACE,OAAO,GAAGF,IAAI,CAACC,MAAM;IACjD6C,KAAK,IAAIxC,OAAO,CAACyC,CAAC,CAACR,KAAK,EAAE/B,GAAG,CAAC;EAChC;EACA,MAAMwC,YAAY,GAAG3C,QAAQ,GAAGsC,QAAQ,GAAGC,QAAQ;EACnD,MAAMK,aAAa,GAAG5C,QAAQ,GAAGuC,QAAQ,GAAGD,QAAQ;EACpD,IAAIH,MAAM,GAAGS,aAAa,EAAET,MAAM,GAAGS,aAAa;EAClD;EACA,MAAMC,EAAE,GAAGpD,WAAW,CAACrD,CAAC,EAAEkG,QAAQ,EAAEC,QAAQ,EAAErD,IAAI,CAAE;EACpD,MAAM4D,EAAE,GAAGpD,QAAQ,CAACtD,CAAC,EAAEkG,QAAQ,EAAEC,QAAQ,EAAEM,EAAE,CAAC;EAC9C,IAAIE,WAAW,GAAGrH,QAAQ,CAACsH,IAAI;EAC/B,IAAIb,MAAM,GAAG,EAAE,EAAE;IACf,IAAIc,KAAe;IACnB,IAAIH,EAAE,CAACjE,KAAK,KAAK,CAAC,EAAE;MAClB,MAAM6B,EAAE,GAAGoC,EAAE,CAACnG,EAAE,CAACE,GAAG,GAAGiG,EAAE,CAAClG,EAAE,CAACC,GAAG;MAChC,MAAM8D,EAAE,GAAGmC,EAAE,CAACnG,EAAE,CAACG,GAAG,GAAGgG,EAAE,CAAClG,EAAE,CAACE,GAAG;MAChCmG,KAAK,GAAGjD,QAAQ,GAAG,IAAItE,QAAQ,CAACiF,EAAE,EAAED,EAAE,CAAC,GAAG,IAAIhF,QAAQ,CAACgF,EAAE,EAAEC,EAAE,CAAC;IAChE,CAAC,MAAM;MACL,MAAML,GAAG,GAAGwC,EAAE,CAACnE,EAAE,GAAGmE,EAAE,CAAClG,EAAE,CAACC,GAAG,GAAGiG,EAAE,CAAC1G,CAAC,GAAG0G,EAAE,CAAClG,EAAE,CAACE,GAAG;MAChD,MAAMyD,GAAG,GAAGuC,EAAE,CAAClE,EAAE,GAAGkE,EAAE,CAACnG,EAAE,CAACG,GAAG,GAAGgG,EAAE,CAAC1G,CAAC,GAAG0G,EAAE,CAACnG,EAAE,CAACE,GAAG;MAChDoG,KAAK,GAAGjD,QAAQ,GACZ,IAAItE,QAAQ,CAAC4E,GAAG,GAAGwC,EAAE,CAACnG,EAAE,CAACG,GAAG,EAAEyD,GAAG,GAAGuC,EAAE,CAAClG,EAAE,CAACC,GAAG,CAAC,GAC9C,IAAInB,QAAQ,CAAC6E,GAAG,GAAGuC,EAAE,CAAClG,EAAE,CAACC,GAAG,EAAEyD,GAAG,GAAGwC,EAAE,CAACnG,EAAE,CAACG,GAAG,CAAC;IACpD;IACA,MAAMoG,MAAM,GAAG,IAAIxH,QAAQ,CAACwG,KAAK,GAAGO,KAAK,EAAEN,MAAM,CAAC;IAClDY,WAAW,GAAGrH,QAAQ,CAACyH,GAAG,CAACC,QAAQ,CAACH,KAAK,CAACI,MAAM,CAACH,MAAM,CAAC,CAAC;EAC3D;EACA,OAAO;IACLhB,KAAK;IACLC,MAAM;IACNM,KAAK,EAAE,IAAIhH,WAAW,CAACgH,KAAK,EAAEJ,aAAa,CAAC;IAC5CiB,gBAAgB,EAAEX,YAAY,GAAGT,KAAK;IACtCqB,iBAAiB,EAAEX,aAAa,GAAGT,MAAM;IACzCY,WAAW;IACX3B;EACF,CAAC;AACH,CAAC;;AAED;;AAQA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMoC,UAAU,GAAGA,CACxB1H,MAAe,EACfwG,QAAgB,EAChBC,QAAgB,EAChBrD,IAAe,KACS;EACxB,MAAM9C,CAAC,GAAG6B,WAAW,CAACnC,MAAM,CAAC;EAC7B,MAAM0D,CAAC,GAAGC,WAAW,CAACrD,CAAC,EAAEkG,QAAQ,EAAEC,QAAQ,EAAErD,IAAI,CAAC;EAClD,IAAI,CAACM,CAAC,EAAE,OAAO,IAAI;EACnB,MAAM3B,GAAiB,GAAG,EAAE;EAC5B,IAAI4F,KAAK,GAAG,EAAE;EACd,IAAIC,KAAK,GAAG,EAAE;EACd,KAAK,IAAIrH,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,CAAC,CAACE,KAAK,CAACC,MAAM,EAAEF,CAAC,EAAE,EAAE;IACvC,MAAMsH,SAAS,GAAGxG,WAAW,CAACf,CAAC,EAAEoD,CAAC,CAACxC,CAAC,EAAEX,CAAC,CAAC;IACxC,IAAIA,CAAC,GAAGmD,CAAC,CAACpC,CAAC,EAAE;MACX,MAAMQ,CAAC,GAAGV,IAAI,CAACd,CAAC,EAAEoD,CAAC,CAACxC,CAAC,EAAEX,CAAC,CAAC;MACzBqH,KAAK,IAAI9F,CAAC;MACVC,GAAG,CAACG,IAAI,CAAC;QAAE4F,UAAU,EAAE,CAAC,EAAE,EAAEhG,CAAC,CAAC;QAAE+F,SAAS;QAAEE,MAAM,EAAE;MAAM,CAAC,CAAC;IAC7D,CAAC,MAAM,IAAIxH,CAAC,GAAGmD,CAAC,CAACpC,CAAC,EAAE;MAClB,MAAMI,CAAC,GAAGT,IAAI,CAACX,CAAC,EAAEoD,CAAC,CAACxC,CAAC,EAAEX,CAAC,CAAC;MACzBoH,KAAK,IAAIjG,CAAC;MACVK,GAAG,CAACG,IAAI,CAAC;QAAE4F,UAAU,EAAE,CAACpG,CAAC,EAAE,EAAE,CAAC;QAAEmG,SAAS;QAAEE,MAAM,EAAE;MAAM,CAAC,CAAC;IAC7D,CAAC,MAAM;MACLhG,GAAG,CAACG,IAAI,CAAC;QAAE4F,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;QAAED,SAAS;QAAEE,MAAM,EAAE;MAAK,CAAC,CAAC;IAC7D;EACF;EACA,MAAMlF,EAAE,GAAG2D,QAAQ,GAAGmB,KAAK;EAC3B,MAAM7E,EAAE,GAAG2D,QAAQ,GAAGmB,KAAK;EAC3B7F,GAAG,CAAC2B,CAAC,CAACpC,CAAC,CAAC,CAAEwG,UAAU,GAAG,CAACjF,EAAE,GAAG,EAAE,GAAG,EAAE,GAAGA,EAAE,EAAEC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAGA,EAAE,CAAC;EAC7D,OAAOf,GAAG;AACZ,CAAC;;AAED;AACA,OAAO,MAAMiG,MAAM,GAAGA,CAAC1H,CAAU,EAAEsG,CAAQ,KAAa;EACtD,KAAK,IAAIrG,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,CAAC,CAACE,KAAK,CAACC,MAAM,EAAEF,CAAC,EAAE,EAAE;IACvC,MAAMO,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;IAC1B,IAAIqG,CAAC,CAAC7F,GAAG,GAAGD,EAAE,CAACE,GAAG,GAAGF,EAAE,CAACC,GAAG,GAAG6F,CAAC,CAAC5F,GAAG,EAAE,OAAOT,CAAC;EAC/C;EACA,OAAOD,CAAC,CAACE,KAAK,CAACC,MAAM,GAAG,CAAC;AAC3B,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMwH,UAAU,GAAGA,CACxB3H,CAAU,EACVY,CAAS,EACTI,CAAS,EACTsF,CAAQ,KACqB;EAC7B,IAAIjE,CAAC,GAAG,EAAE;EACV,IAAIC,CAAC,GAAG,EAAE;EACV,KAAK,IAAIrC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,CAAC,CAACE,KAAK,CAACC,MAAM,EAAEF,CAAC,EAAE,EAAE;IACvC,IAAIA,CAAC,GAAGe,CAAC,EAAE;MACTqB,CAAC,IAAI1B,IAAI,CAACX,CAAC,EAAEY,CAAC,EAAEX,CAAC,CAAC;MAClB;IACF;IACA,IAAIA,CAAC,GAAGe,CAAC,EAAE;MACTsB,CAAC,IAAIxB,IAAI,CAACd,CAAC,EAAEY,CAAC,EAAEX,CAAC,CAAC;MAClB;IACF;IACA,MAAMM,EAAE,GAAGP,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEG,KAAK;IAC5B,MAAMI,EAAE,GAAGT,SAAS,CAACC,CAAC,EAAEC,CAAC,CAAC;IAC1B,MAAMkC,CAAC,GAAGpB,WAAW,CAACf,CAAC,EAAEY,CAAC,EAAEX,CAAC,CAAC;IAC9B,IAAID,CAAC,CAACE,KAAK,CAACD,CAAC,CAAC,CAAEwC,KAAK,KAAK,CAAC,EAAE;MAC3B;MACA;MACA,MAAMmF,CAAC,GAAGzF,CAAC,GAAG7B,KAAK,CAACC,EAAE,EAAEC,EAAE,CAAC;MAC3B,MAAMqH,IAAI,GAAG,CAACvB,CAAC,CAAC7F,GAAG,GAAGF,EAAE,CAACG,GAAG,GAAGH,EAAE,CAACE,GAAG,GAAG6F,CAAC,CAAC5F,GAAG,IAAIF,EAAE,CAACE,GAAG;MACvD,MAAMuC,IAAI,GAAG,CAACzC,EAAE,CAACC,GAAG,GAAGF,EAAE,CAACG,GAAG,GAAGH,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG,IAAI4F,CAAC,CAAC5F,GAAG;MACxD,MAAM8B,EAAE,GAAIoF,CAAC,GAAGC,IAAI,IAAK5E,IAAI,IAAI1C,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAAG,CAAC,CAAC;MAClD2B,CAAC,IAAI,CAACuF,CAAC,GAAGpF,EAAE,IAAIjC,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAAG,CAAC,KAAKH,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACC,GAAG,CAAC;MACrD6B,CAAC,IAAIE,EAAE;IACT,CAAC,MAAM;MACL;MACAH,CAAC,IAAKF,CAAC,IAAImE,CAAC,CAAC5F,GAAG,GAAGF,EAAE,CAACC,GAAG,GAAG6F,CAAC,CAAC7F,GAAG,GAAGD,EAAE,CAACE,GAAG,CAAC,IAAK4F,CAAC,CAAC7F,GAAG,GAAGD,EAAE,CAACC,GAAG,CAAC;MAC/D6B,CAAC,IAAKH,CAAC,IAAImE,CAAC,CAAC7F,GAAG,GAAGF,EAAE,CAACG,GAAG,GAAGH,EAAE,CAACE,GAAG,GAAG6F,CAAC,CAAC5F,GAAG,CAAC,IAAK4F,CAAC,CAAC5F,GAAG,GAAGH,EAAE,CAACG,GAAG,CAAC;IACjE;EACF;EACA,OAAO;IAAE2B,CAAC;IAAEC;EAAE,CAAC;AACjB,CAAC;;AAED;AACA,MAAMwF,UAAU,GAAIC,CAAQ,IAAY;EACtC,MAAMC,GAAG,GAAGA,CAAC5G,CAAS,EAAEI,CAAS,KAAcA,CAAC,KAAK,EAAE,GAAGJ,CAAC,GAAG4G,GAAG,CAACxG,CAAC,EAAEJ,CAAC,GAAGI,CAAC,CAAE;EAC5E,MAAMyG,CAAC,GAAGD,GAAG,CAACD,CAAC,CAACtH,GAAG,GAAG,EAAE,GAAG,CAACsH,CAAC,CAACtH,GAAG,GAAGsH,CAAC,CAACtH,GAAG,EAAEsH,CAAC,CAACrH,GAAG,CAAC;EACjD,OAAOuH,CAAC,GAAG,EAAE,GAAG;IAAExH,GAAG,EAAEsH,CAAC,CAACtH,GAAG,GAAGwH,CAAC;IAAEvH,GAAG,EAAEqH,CAAC,CAACrH,GAAG,GAAGuH;EAAE,CAAC,GAAGF,CAAC;AACxD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,aAAa,GAAGA,CAC3BrI,CAAS,EACTU,EAAS,EACTC,EAAS,EACTuD,GAAU,EACVoE,MAAiB,GAAG,EAAE,KACV;EACZ,IAAItI,CAAC,GAAG,CAAC,EAAE,MAAM,IAAIuG,KAAK,CAAC,kCAAkC,CAAC;EAC9D,IAAI7F,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG,IAAIF,EAAE,CAACC,GAAG,GAAGF,EAAE,CAACG,GAAG,EACpC,MAAM,IAAI0F,KAAK,CAAC,sDAAsD,CAAC;EACzE,MAAMnD,IAAI,GAAGzC,EAAE,CAACC,GAAG,GAAGF,EAAE,CAACG,GAAG,GAAGH,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG;EAC9C,MAAM0H,SAAS,GAAG7H,EAAE,CAACG,GAAG,GAAGF,EAAE,CAACE,GAAG,GAAG2H,MAAM,CAACxI,CAAC,CAAC;EAC7C,MAAMK,KAAc,GAAG,EAAE;EACzB,KAAK,IAAID,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,CAAC,EAAEI,CAAC,EAAE,EAAE;IAC1BC,KAAK,CAAC0B,IAAI,CAAC;MACTxB,KAAK,EAAE0H,UAAU,CAAC;QAChBrH,GAAG,EAAEF,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG,GAAG2H,MAAM,CAACxI,CAAC,CAAC,GAAGoD,IAAI,GAAGoF,MAAM,CAACpI,CAAC,CAAC;QACnDS,GAAG,EAAE0H;MACP,CAAC,CAAC;MACFvH,MAAM,EAAE,EAAE;MACV4B,KAAK,EAAE0F,MAAM,CAAClI,CAAC,CAAC,IAAI,CAAC;MACrBuD,MAAM,EAAEO,GAAG;MACXN,OAAO,EAAEM;IACX,CAAC,CAAC;EACJ;EACA,OAAO;IACL7D,KAAK;IACLG,OAAO,EAAEyH,UAAU,CAAC;MAClBrH,GAAG,EAAEF,EAAE,CAACE,GAAG,GAAGD,EAAE,CAACE,GAAG,GAAG2H,MAAM,CAACxI,CAAC,CAAC,GAAGoD,IAAI,GAAGoF,MAAM,CAACxI,CAAC,CAAC;MACnDa,GAAG,EAAE0H;IACP,CAAC,CAAC;IACFzI,WAAW,EAAE0I,MAAM,CAACxI,CAAC;EACvB,CAAC;AACH,CAAC;;AAED;;AAQA,OAAO,MAAMyI,WAAW,GAAGA,CACzBzI,CAAS,EACT0I,KAAmB,GAAG,cAAc,EACpCC,IAAuD,GAAG,CAAC,CAAC,KAC/C;EACb,IAAID,KAAK,KAAK,MAAM,EAAE,OAAOlH,KAAK,CAACC,IAAI,CAAC;IAAEnB,MAAM,EAAEN;EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;EAChE,MAAM4I,IAAI,GAAGC,MAAM,CAACF,IAAI,CAACC,IAAI,IAAI,GAAG,CAAC;EACrC,MAAME,IAAI,GAAGD,MAAM,CAACF,IAAI,CAACG,IAAI,IAAI,EAAE,CAAC;EACpC,MAAMC,MAAM,GAAGJ,IAAI,CAACI,MAAM,IAAI,CAAC/I,CAAC,GAAG,CAAC,IAAI,CAAC;EACzC,MAAMgJ,KAAK,GAAGC,IAAI,CAACC,GAAG,CAAClJ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;EACnC,MAAMmJ,IAAI,GAAGA,CAAC/I,CAAS,EAAEgJ,CAAS,KAAKH,IAAI,CAACI,GAAG,CAAC,EAAE,CAAC,CAACjJ,CAAC,GAAGgJ,CAAC,IAAIJ,KAAK,KAAK,CAAC,CAAC,CAAC;EAC1E,MAAMM,OAAO,GAAIlJ,CAAS,IAAa;IACrC,QAAQsI,KAAK;MACX,KAAK,cAAc;QACjB,OAAOS,IAAI,CAAC/I,CAAC,EAAE2I,MAAM,CAAC;MACxB,KAAK,YAAY;QACf,OAAOE,IAAI,CAACI,GAAG,CAAC,CAACjJ,CAAC,GAAG6I,IAAI,CAACC,GAAG,CAAClJ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;MAC1C,KAAK,aAAa;QAChB,OAAOiJ,IAAI,CAACI,GAAG,CAAC,EAAErJ,CAAC,GAAG,CAAC,GAAGI,CAAC,CAAC,GAAG6I,IAAI,CAACC,GAAG,CAAClJ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;MACpD,KAAK,SAAS;QACZ,OAAOiJ,IAAI,CAACC,GAAG,CAACC,IAAI,CAAC/I,CAAC,EAAE,CAACJ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAEmJ,IAAI,CAAC/I,CAAC,EAAG,CAAC,IAAIJ,CAAC,GAAG,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC;MACnE;QACE,OAAO,CAAC;IACZ;EACF,CAAC;EACD,OAAOwB,KAAK,CAACC,IAAI,CAAC;IAAEnB,MAAM,EAAEN;EAAE,CAAC,EAAE,CAAC0B,CAAC,EAAEtB,CAAC,KAAK;IACzC,MAAMmD,CAAC,GAAG0F,IAAI,CAACM,KAAK,CAACT,IAAI,GAAG,CAACF,IAAI,GAAGE,IAAI,IAAIQ,OAAO,CAAClJ,CAAC,CAAC,CAAC;IACvD,OAAOoI,MAAM,CAACS,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE3F,CAAC,CAAC,CAAC;EAC/B,CAAC,CAAC;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMiG,YAAY,GAAGA,CAC1BxJ,CAAS,EACTU,EAAS,EACTC,EAAS,EACTuD,GAAU,EACVyE,IASC,GAAG,CAAC,CAAC,KACM;EACZ,MAAMc,IAAI,GAAGpB,aAAa,CAACrI,CAAC,EAAEU,EAAE,EAAEC,EAAE,EAAEuD,GAAG,CAAC;EAC1C,MAAMwF,OAAO,GAAGjB,WAAW,CAACzI,CAAC,EAAE2I,IAAI,CAACD,KAAK,IAAI,cAAc,EAAEC,IAAI,CAAC;EAClE,MAAMgB,EAAE,GAAG,IAAIC,GAAG,CAACjB,IAAI,CAACkB,OAAO,IAAI,EAAE,CAAC;EACtC,MAAMxJ,KAAc,GAAGoJ,IAAI,CAACpJ,KAAK,CAACyJ,GAAG,CAAC,CAACnI,CAAC,EAAEvB,CAAC,KAAK;IAC9C,MAAM8H,CAAC,GAAGS,IAAI,CAACoB,KAAK,GAAGpB,IAAI,CAACoB,KAAK,CAAC3J,CAAC,CAAC,GAAG8D,GAAG;IAC1C,OAAO;MACL,GAAGvC,CAAC;MACJX,MAAM,EAAE0I,OAAO,CAACtJ,CAAC,CAAE;MACnBwC,KAAK,EAAE+G,EAAE,CAACK,GAAG,CAAC5J,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;MACxBuD,MAAM,EAAEuE,CAAC;MACTtE,OAAO,EAAEsE;IACX,CAAC;EACH,CAAC,CAAC;EACF,OAAO;IACL7H,KAAK;IACLG,OAAO,EAAEiJ,IAAI,CAACjJ,OAAO;IACrBV,WAAW,EAAE4J,OAAO,CAACO,MAAM,CAAC,CAACxD,CAAC,EAAElD,CAAC,KAAKkD,CAAC,GAAGlD,CAAC,EAAE,EAAE;EACjD,CAAC;AACH,CAAC","ignoreList":[]}
@@ -309,27 +309,27 @@ export const getSwapOutput = (outputMetadata, input, inputReserve, outputReserve
309
309
  };
310
310
 
311
311
  /**
312
- * Calculates the current price (exchange rate) of asset A in terms of asset B for a Stableswaps pool.
313
- * The price is derived from the Stableswaps curve equation and takes into account the amplification factor.
312
+ * The pool's marginal price as raw units of asset A per raw unit of asset B,
313
+ * |dx/dy| at the current reserves. This is the "ideal" price that swap price
314
+ * impact is measured against.
314
315
  *
315
- * The calculation uses the formula:
316
+ * Derived from the Stableswaps invariant 4A(x + y) + D = 4AD + D^3 / (4xy):
316
317
  * price = (xpA + (dR * aReserve) / bReserve) / (xpA + dR)
317
- * where xpA = (Ann * aReserve) / A_PRECISION and dR is derived from the sum invariant
318
+ * where xpA = 4 * laf * aReserve and dR = D^3 / (4 * aReserve * bReserve)
318
319
  *
319
320
  * @param {bigint} aReserve - The current reserve amount of asset A in the pool.
320
321
  * @param {bigint} bReserve - The current reserve amount of asset B in the pool.
321
322
  * @param {bigint} laf - The linear amplification factor of the pool.
322
- * @returns {Fraction} The price of asset A in terms of asset B as a Fraction.
323
+ * @returns {Fraction} Raw A per raw B at the current reserves.
323
324
  */
324
325
  export function getPrice(aReserve, bReserve, laf) {
325
- // dx_0 / dx_1 only, however can have any number of coins in pool
326
- const ann = laf * 2n * A_PRECISION;
327
326
  const sumInvariant = getSumInvariant(laf, aReserve, bReserve) / RESERVE_PRECISION;
328
327
  // D / n^n with n = 2
329
328
  let dR = sumInvariant / 4n;
330
329
  dR = dR * sumInvariant / aReserve;
331
330
  dR = dR * sumInvariant / bReserve;
332
- const xpA = ann * aReserve / A_PRECISION;
331
+ // 4A is the amplification term of the on-chain invariant, A = laf.
332
+ const xpA = 4n * laf * aReserve;
333
333
  const p = new Fraction(xpA + dR * aReserve / bReserve, xpA + dR);
334
334
  return p;
335
335
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StableSwapsPool.js","names":["AssetAmount","SharedPoolMath","Fraction","liquidityInvariant","assetA","assetB","linearAmplification","newSumInvariant","four_a","four_x_y","d_plus_one","d_cubed","d_plus_one_cubed","x_plus_y","sixteen_a_x_y","sixteen_a_x_y_x_plus_y","f1","f2","A_PRECISION","RESERVE_PRECISION","FEE_PRECISION","getSumInvariant","a","x","y","Error","sum","d","ann","i","d_p","d_prev","getNewY","newX","aRaw","sumInvariant","yPrev","c","b","getFirstLp","laf","calculateLiquidity","aReserve","bReserve","totalLp","oldSumInvariant","newLpTokens","newTotalLpTokens","nextTotalLp","generatedLp","shareAfterDeposit","getShare","aChange","bChange","actualDepositedA","actualDepositedB","getTokensForLp","lp","quotient","getSwapOutput","outputMetadata","input","inputReserve","outputReserve","fee","protocolFee","roundOutputUp","asFraction","lt","ZERO","gte","ONE","combinedFee","add","nextInputReserve","newY","deltaYPrec","deltaY","totalFee","multiply","divide","totalProtocolFee","totalLpFee","output","subtract","safeOutput","numerator","denominator","nextOutputReserve","idealPrice","getPrice","actualPrice","priceImpact","lpFee","nextSumInvariant","dR","xpA","p","getSwapInput","rawOutputF","sub","rawOutput"],"sources":["../../../src/PoolMath/StableSwapsPool.ts"],"sourcesContent":["import { AssetAmount, IAssetAmountMetadata } from \"@sundaeswap/asset\";\nimport { SharedPoolMath } from \"./index.js\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\n\n/**\n * Validates that a given sum invariant (D) satisfies the liquidity invariant equation\n * for the Stableswaps curve. This function checks if D is within the valid range by\n * evaluating the invariant function at D and D+1.\n *\n * The liquidity invariant ensures that the curve equation is satisfied:\n * 4A * 4xy * D + D^3 - (4xy * 4A * (x + y) + 4xy * D) should be <= 0 at D and > 0 at D+1\n *\n * @param {bigint} assetA - The reserve amount of asset A (already scaled by RESERVE_PRECISION).\n * @param {bigint} assetB - The reserve amount of asset B (already scaled by RESERVE_PRECISION).\n * @param {bigint} linearAmplification - The amplification coefficient for the pool.\n * @param {bigint} newSumInvariant - The proposed sum invariant (D) to validate.\n * @returns {boolean} True if the sum invariant satisfies the liquidity invariant equation, false otherwise.\n */\nexport function liquidityInvariant(\n assetA: bigint,\n assetB: bigint,\n linearAmplification: bigint,\n newSumInvariant: bigint,\n) {\n // 4 * A * 4 * (x*y) * D + D^3 - (4(x*y) * (4A(x + y) + D))\n // 4A * 4xy * D + D^3 - (4xy * 4a * (x + y) + 4xy * D)\n // 16Axy * D + D^3 - (16Axy * (x + y) + 4xy * D)\n const four_a = 4n * linearAmplification;\n const four_x_y = 4n * assetA * assetB;\n const d_plus_one = newSumInvariant + 1n;\n const d_cubed = newSumInvariant * newSumInvariant * newSumInvariant;\n const d_plus_one_cubed = d_plus_one * d_plus_one * d_plus_one;\n const x_plus_y = assetA + assetB;\n const sixteen_a_x_y = four_a * four_x_y;\n const sixteen_a_x_y_x_plus_y = sixteen_a_x_y * x_plus_y;\n const f1 =\n sixteen_a_x_y * newSumInvariant +\n d_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * newSumInvariant);\n const f2 =\n sixteen_a_x_y * d_plus_one +\n d_plus_one_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * d_plus_one);\n return f1 <= 0n && f2 > 0n;\n}\n\n/**\n * Precision factor for the amplification coefficient calculations.\n * Used to scale the amplification factor for more precise arithmetic operations.\n */\nexport const A_PRECISION: bigint = 200n;\n\n/**\n * Precision factor for reserve calculations in the Stableswaps curve.\n * Reserves are multiplied by this value to maintain precision during calculations.\n * This allows for accurate fractional calculations with integer arithmetic.\n */\nexport const RESERVE_PRECISION: bigint = 1_000_000_000_000n;\n\n/**\n * Precision factor for fee calculations, representing basis points.\n * A value of 10,000 means fees are calculated with 0.01% precision (1 basis point).\n */\nexport const FEE_PRECISION: bigint = 10_000n;\n\n/**\n * Calculates the sum invariant (D) for a Stableswaps pool using Newton's method.\n * The sum invariant represents the total value in the pool and is used to determine\n * the fair exchange rate between assets.\n *\n * This function iteratively solves for D in the Stableswaps invariant equation:\n * Ann * sum + D_p * 2 = Ann * D + D_p * 3\n * where D_p = D^3 / (4 * x * y) and Ann = A * n^n (with n=2)\n *\n * The iteration continues until convergence (difference <= 1) or fails after 255 iterations.\n *\n * @param {bigint} a - The amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} x - The reserve amount of the first asset (will be scaled by RESERVE_PRECISION).\n * @param {bigint} y - The reserve amount of the second asset (will be scaled by RESERVE_PRECISION).\n * @returns {bigint} The calculated sum invariant (D) scaled by RESERVE_PRECISION.\n * @throws {Error} If the amplification coefficient is not positive.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getSumInvariant(a: bigint, x: bigint, y: bigint): bigint {\n if (a <= 0n) {\n throw new Error(\"Amplification coefficient must be positive.\");\n }\n x = x * RESERVE_PRECISION;\n y = y * RESERVE_PRECISION;\n a = a * A_PRECISION;\n const sum: bigint = x + y;\n if (sum === 0n) {\n return 0n;\n }\n\n let d = sum;\n const ann = a * 2n;\n for (let i = 0; i < 255; i++) {\n const d_p = (d * d * d) / (4n * x * y);\n const d_prev = d;\n\n d =\n (((ann * sum) / 100n + d_p * 2n) * d) /\n (((ann - 100n) * d) / 100n + 3n * d_p);\n\n if (d > d_prev) {\n if (d - d_prev <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n } else {\n if (d_prev - d <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on D value after 255 iterations.\");\n}\n\n/**\n * Calculates the new Y reserve value given a new X reserve value and the sum invariant.\n * This function uses Newton's method to iteratively solve for Y in the Stableswaps equation\n * while maintaining the pool's invariant (D).\n *\n * The function solves: Y^2 + (sum + (D * A_PRECISION) / (2 * Ann) - D) * Y - c = 0\n * where c is derived from D and the pool parameters.\n *\n * This is used during swaps to determine the output reserve after an input is added.\n *\n * @param {bigint} newX - The new reserve amount for asset X (will be scaled by RESERVE_PRECISION internally).\n * @param {bigint} aRaw - The raw amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} sumInvariant - The pool's sum invariant (D), already scaled.\n * @returns {bigint} The calculated Y reserve value scaled by RESERVE_PRECISION.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getNewY(\n newX: bigint,\n aRaw: bigint,\n sumInvariant: bigint,\n): bigint {\n newX = newX * RESERVE_PRECISION;\n const sum = newX;\n let yPrev: bigint;\n let c = sumInvariant;\n const ann = aRaw * A_PRECISION * 2n;\n\n c = (c * sumInvariant) / (newX * 2n);\n c = (c * sumInvariant * A_PRECISION) / 2n;\n c = c / (ann * 2n);\n const b = sum + (sumInvariant * A_PRECISION) / 2n / ann;\n let y = sumInvariant;\n for (let i = 0; i < 255; i++) {\n yPrev = y;\n y = (y * y + c) / (y * 2n + b - sumInvariant);\n if (y > yPrev) {\n if (y - yPrev <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n } else {\n if (yPrev - y <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on y value after 255 iterations.\");\n}\n\n/**\n * Calculates the initial LP token amount for the first liquidity provision to a pool.\n * This is used when bootstrapping a new pool with initial reserves of assets A and B.\n *\n * The LP tokens minted are derived from the sum invariant (D) divided by the reserve precision,\n * effectively representing the pool's total value at inception.\n *\n * @param {bigint} a - The initial amount of token A being deposited.\n * @param {bigint} b - The initial amount of token B being deposited.\n * @param {bigint} laf - The linear amplification factor for the pool.\n * @returns {bigint} The amount of LP tokens to mint for the first liquidity provision.\n */\nexport const getFirstLp = (a: bigint, b: bigint, laf: bigint) =>\n getSumInvariant(laf, a, b) / RESERVE_PRECISION;\n\n/**\n * Calculates the liquidity parameters for adding liquidity to a Stableswaps pool.\n * This function supports mixed deposits where both assets can be deposited in any proportion.\n *\n * The calculation is based on the change in the sum invariant (D) before and after the deposit.\n * LP tokens are minted proportionally to the increase in D relative to the old D value.\n *\n * TODO: Investigate way to optimize actual deposited amounts\n *\n * @param {bigint} a - The amount of token A to deposit.\n * @param {bigint} b - The amount of token B to deposit.\n * @param {bigint} aReserve - The current reserve of token A in the pool.\n * @param {bigint} bReserve - The current reserve of token B in the pool.\n * @param {bigint} totalLp - The total LP tokens for the pool before the deposit.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @throws {Error} If the pool doesn't have enough liquidity (both reserves are zero).\n * @throws {Error} If both deposit amounts are zero.\n * @returns {Object} An object containing:\n * - nextTotalLp: The total LP tokens for the pool after the deposit.\n * - generatedLp: The amount of LP tokens generated by the deposit.\n * - shareAfterDeposit: The depositor's share of the pool after the deposit (as a Fraction).\n * - aChange: Always 0n for Stableswaps (no refund needed).\n * - bChange: Always 0n for Stableswaps (no refund needed).\n * - actualDepositedA: The actual amount of A deposited (always equal to input a).\n * - actualDepositedB: The actual amount of B deposited (always equal to input b).\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n laf: bigint,\n) => {\n if (aReserve === 0n && bReserve === 0n) {\n throw new Error(\"Not enough pool liquidity\");\n }\n\n if (a === 0n && b === 0n) {\n throw new Error(\"Cannot use a deposit asset amount of 0\");\n }\n\n const oldSumInvariant = getSumInvariant(laf, aReserve, bReserve);\n\n const newSumInvariant = getSumInvariant(laf, aReserve + a, bReserve + b);\n\n const newLpTokens =\n ((newSumInvariant - oldSumInvariant) * totalLp) / oldSumInvariant;\n\n const newTotalLpTokens = totalLp + newLpTokens;\n\n return {\n nextTotalLp: newTotalLpTokens,\n generatedLp: newLpTokens,\n shareAfterDeposit: SharedPoolMath.getShare(newLpTokens, newTotalLpTokens),\n aChange: 0n,\n bChange: 0n,\n actualDepositedA: a,\n actualDepositedB: b,\n };\n};\n\n/**\n * Calculates the token amounts that a given LP token amount represents when withdrawing\n * from a Stableswaps pool. The withdrawal is proportional to the LP tokens being redeemed\n * relative to the total LP supply.\n *\n * This uses a simple linear proportion: amount = (lp * reserve) / totalLp for each asset.\n *\n * @param {bigint} lp - The amount of LP tokens being redeemed.\n * @param {bigint} aReserve - The pool's current reserve amount of token A.\n * @param {bigint} bReserve - The pool's current reserve amount of token B.\n * @param {bigint} totalLp - The pool's total minted LP tokens currently in circulation.\n * @returns {SharedPoolMath.TPair} A tuple [a, b] containing the amounts of tokens A and B to withdraw.\n */\nexport const getTokensForLp = (\n lp: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n): SharedPoolMath.TPair => [\n new Fraction(lp * aReserve, totalLp).quotient,\n new Fraction(lp * bReserve, totalLp).quotient,\n];\n\n/**\n * Represents the complete outcome of a swap operation in a Stableswaps pool.\n * Contains all relevant information about the swap including amounts, fees, updated reserves,\n * and price impact.\n */\nexport type TSwapOutcome = {\n /** The amount of input tokens being swapped */\n input: bigint;\n /** The amount of output tokens received (after all fees) */\n output: bigint;\n /** The portion of fees that goes to liquidity providers */\n lpFee: AssetAmount<IAssetAmountMetadata>;\n /** The portion of fees that goes to the protocol */\n protocolFee: AssetAmount<IAssetAmountMetadata>;\n /** The input asset reserve amount after the swap */\n nextInputReserve: bigint;\n /** The output asset reserve amount after the swap (excluding protocol fees) */\n nextOutputReserve: bigint;\n /** The pool's sum invariant (D) after the swap */\n nextSumInvariant: bigint;\n /** The price impact of the swap as a fraction (difference between ideal and actual price) */\n priceImpact: Fraction;\n};\n\n/**\n * Calculates the output amount and all swap parameters for a given input amount in a Stableswaps pool.\n * This function determines how many output tokens will be received for a given input, accounting for\n * the Stableswaps curve, LP fees, and protocol fees.\n *\n * The calculation process:\n * 1. Validates inputs and fees\n * 2. Calculates the current sum invariant (D)\n * 3. Determines the new Y value after adding input to X\n * 4. Calculates raw output and applies fees (LP + protocol)\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} input - The amount of input tokens to swap.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @param {boolean} [roundOutputUp] - Optional flag to round output up instead of down (default: false).\n * @returns {TSwapOutcome} The complete swap outcome including output, fees, reserves, and price impact.\n * @throws {Error} If input or reserves are not positive.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapOutput = (\n outputMetadata: IAssetAmountMetadata,\n input: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n roundOutputUp?: boolean,\n): TSwapOutcome => {\n if (input <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Input and reserves must be positive\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be between 0 and 1\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const nextInputReserve = inputReserve + input;\n const newY = getNewY(nextInputReserve, laf, sumInvariant);\n\n const deltaYPrec = outputReserve * RESERVE_PRECISION - newY;\n const deltaY = new Fraction(deltaYPrec, RESERVE_PRECISION);\n const totalFee = combinedFee\n .multiply(FEE_PRECISION)\n .multiply(deltaY.quotient)\n .add(Fraction.asFraction(FEE_PRECISION - 1n))\n .divide(FEE_PRECISION).quotient;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n const totalLpFee = totalFee - totalProtocolFee;\n const output = deltaY.subtract(totalFee);\n const safeOutput = roundOutputUp\n ? (output.numerator + output.denominator - 1n) / output.denominator\n : output.quotient;\n const nextOutputReserve = outputReserve - safeOutput - totalProtocolFee;\n\n // PRICEIMPACT: \"priceImpact\" is slightly misleadingly named in the industry as a whole\n // just by it's name, it would imply that it's the percentage difference between\n // the current price and the price after the swap, but it's actually the percentage\n // difference between the real price of your swap, and the price implied by the current\n // reserves; We got this wrong in v1, but this aligns it with the industry standard\n // Source: https://dailydefi.org/articles/price-impact-and-how-to-calculate/\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, safeOutput);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n return {\n input,\n output: safeOutput,\n lpFee: new AssetAmount(totalLpFee, outputMetadata),\n protocolFee: new AssetAmount(totalProtocolFee, outputMetadata),\n nextInputReserve,\n nextOutputReserve,\n nextSumInvariant: getSumInvariant(laf, nextInputReserve, nextOutputReserve),\n priceImpact,\n };\n};\n\n/**\n * Calculates the current price (exchange rate) of asset A in terms of asset B for a Stableswaps pool.\n * The price is derived from the Stableswaps curve equation and takes into account the amplification factor.\n *\n * The calculation uses the formula:\n * price = (xpA + (dR * aReserve) / bReserve) / (xpA + dR)\n * where xpA = (Ann * aReserve) / A_PRECISION and dR is derived from the sum invariant\n *\n * @param {bigint} aReserve - The current reserve amount of asset A in the pool.\n * @param {bigint} bReserve - The current reserve amount of asset B in the pool.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {Fraction} The price of asset A in terms of asset B as a Fraction.\n */\nexport function getPrice(\n aReserve: bigint,\n bReserve: bigint,\n laf: bigint,\n): Fraction {\n // dx_0 / dx_1 only, however can have any number of coins in pool\n const ann = laf * 2n * A_PRECISION;\n const sumInvariant =\n getSumInvariant(laf, aReserve, bReserve) / RESERVE_PRECISION;\n // D / n^n with n = 2\n let dR = sumInvariant / 4n;\n dR = (dR * sumInvariant) / aReserve;\n dR = (dR * sumInvariant) / bReserve;\n const xpA = (ann * aReserve) / A_PRECISION;\n const p = new Fraction(xpA + (dR * aReserve) / bReserve, xpA + dR);\n return p;\n}\n\n/**\n * Calculates the required input amount and all swap parameters for a desired output amount in a Stableswaps pool.\n * This is the reverse operation of getSwapOutput - given how much you want to receive, it determines\n * how much you need to provide as input, accounting for fees and the Stableswaps curve.\n *\n * The calculation process:\n * 1. Validates inputs, fees, and output constraints\n * 2. Calculates raw output needed before fees\n * 3. Determines the new X value to achieve the desired Y reduction\n * 4. Calculates required input and separates LP and protocol fees\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} output - The desired amount of output tokens to receive.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {TSwapOutcome} The complete swap outcome including required input, fees, reserves, and price impact.\n * @throws {Error} If output or reserves are not positive.\n * @throws {Error} If output is greater than or equal to the output reserve.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapInput = (\n outputMetadata: IAssetAmountMetadata,\n output: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n): TSwapOutcome => {\n if (output <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Output and reserves must be positive\");\n\n if (output >= outputReserve)\n throw new Error(\"Output must be less than output reserve\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be [0,1)\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n\n // output = rawOutput * (1-fee)\n // rawOutput = output / (1-fee)\n const rawOutputF = Fraction.asFraction(output).divide(\n Fraction.ONE.sub(combinedFee),\n );\n const rawOutput =\n (rawOutputF.numerator + rawOutputF.denominator - 1n) /\n rawOutputF.denominator;\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const newX = getNewY(outputReserve - rawOutput, laf, sumInvariant);\n const input =\n (newX - inputReserve * RESERVE_PRECISION + RESERVE_PRECISION - 1n) /\n RESERVE_PRECISION;\n\n const totalFee =\n (combinedFee.multiply(FEE_PRECISION).quotient * rawOutput +\n FEE_PRECISION -\n 1n) /\n FEE_PRECISION;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n\n const totalLpFee = totalFee - totalProtocolFee;\n\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output - totalProtocolFee;\n\n // See PRICEIMPACT\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, output);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n\n const nextSumInvariant = getSumInvariant(\n laf,\n nextInputReserve,\n nextOutputReserve,\n );\n\n return {\n input,\n output,\n lpFee: new AssetAmount(totalLpFee, outputMetadata),\n protocolFee: new AssetAmount(totalProtocolFee, outputMetadata),\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n nextSumInvariant,\n };\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"StableSwapsPool.js","names":["AssetAmount","SharedPoolMath","Fraction","liquidityInvariant","assetA","assetB","linearAmplification","newSumInvariant","four_a","four_x_y","d_plus_one","d_cubed","d_plus_one_cubed","x_plus_y","sixteen_a_x_y","sixteen_a_x_y_x_plus_y","f1","f2","A_PRECISION","RESERVE_PRECISION","FEE_PRECISION","getSumInvariant","a","x","y","Error","sum","d","ann","i","d_p","d_prev","getNewY","newX","aRaw","sumInvariant","yPrev","c","b","getFirstLp","laf","calculateLiquidity","aReserve","bReserve","totalLp","oldSumInvariant","newLpTokens","newTotalLpTokens","nextTotalLp","generatedLp","shareAfterDeposit","getShare","aChange","bChange","actualDepositedA","actualDepositedB","getTokensForLp","lp","quotient","getSwapOutput","outputMetadata","input","inputReserve","outputReserve","fee","protocolFee","roundOutputUp","asFraction","lt","ZERO","gte","ONE","combinedFee","add","nextInputReserve","newY","deltaYPrec","deltaY","totalFee","multiply","divide","totalProtocolFee","totalLpFee","output","subtract","safeOutput","numerator","denominator","nextOutputReserve","idealPrice","getPrice","actualPrice","priceImpact","lpFee","nextSumInvariant","dR","xpA","p","getSwapInput","rawOutputF","sub","rawOutput"],"sources":["../../../src/PoolMath/StableSwapsPool.ts"],"sourcesContent":["import { AssetAmount, IAssetAmountMetadata } from \"@sundaeswap/asset\";\nimport { SharedPoolMath } from \"./index.js\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\n\n/**\n * Validates that a given sum invariant (D) satisfies the liquidity invariant equation\n * for the Stableswaps curve. This function checks if D is within the valid range by\n * evaluating the invariant function at D and D+1.\n *\n * The liquidity invariant ensures that the curve equation is satisfied:\n * 4A * 4xy * D + D^3 - (4xy * 4A * (x + y) + 4xy * D) should be <= 0 at D and > 0 at D+1\n *\n * @param {bigint} assetA - The reserve amount of asset A (already scaled by RESERVE_PRECISION).\n * @param {bigint} assetB - The reserve amount of asset B (already scaled by RESERVE_PRECISION).\n * @param {bigint} linearAmplification - The amplification coefficient for the pool.\n * @param {bigint} newSumInvariant - The proposed sum invariant (D) to validate.\n * @returns {boolean} True if the sum invariant satisfies the liquidity invariant equation, false otherwise.\n */\nexport function liquidityInvariant(\n assetA: bigint,\n assetB: bigint,\n linearAmplification: bigint,\n newSumInvariant: bigint,\n) {\n // 4 * A * 4 * (x*y) * D + D^3 - (4(x*y) * (4A(x + y) + D))\n // 4A * 4xy * D + D^3 - (4xy * 4a * (x + y) + 4xy * D)\n // 16Axy * D + D^3 - (16Axy * (x + y) + 4xy * D)\n const four_a = 4n * linearAmplification;\n const four_x_y = 4n * assetA * assetB;\n const d_plus_one = newSumInvariant + 1n;\n const d_cubed = newSumInvariant * newSumInvariant * newSumInvariant;\n const d_plus_one_cubed = d_plus_one * d_plus_one * d_plus_one;\n const x_plus_y = assetA + assetB;\n const sixteen_a_x_y = four_a * four_x_y;\n const sixteen_a_x_y_x_plus_y = sixteen_a_x_y * x_plus_y;\n const f1 =\n sixteen_a_x_y * newSumInvariant +\n d_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * newSumInvariant);\n const f2 =\n sixteen_a_x_y * d_plus_one +\n d_plus_one_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * d_plus_one);\n return f1 <= 0n && f2 > 0n;\n}\n\n/**\n * Precision factor for the amplification coefficient calculations.\n * Used to scale the amplification factor for more precise arithmetic operations.\n */\nexport const A_PRECISION: bigint = 200n;\n\n/**\n * Precision factor for reserve calculations in the Stableswaps curve.\n * Reserves are multiplied by this value to maintain precision during calculations.\n * This allows for accurate fractional calculations with integer arithmetic.\n */\nexport const RESERVE_PRECISION: bigint = 1_000_000_000_000n;\n\n/**\n * Precision factor for fee calculations, representing basis points.\n * A value of 10,000 means fees are calculated with 0.01% precision (1 basis point).\n */\nexport const FEE_PRECISION: bigint = 10_000n;\n\n/**\n * Calculates the sum invariant (D) for a Stableswaps pool using Newton's method.\n * The sum invariant represents the total value in the pool and is used to determine\n * the fair exchange rate between assets.\n *\n * This function iteratively solves for D in the Stableswaps invariant equation:\n * Ann * sum + D_p * 2 = Ann * D + D_p * 3\n * where D_p = D^3 / (4 * x * y) and Ann = A * n^n (with n=2)\n *\n * The iteration continues until convergence (difference <= 1) or fails after 255 iterations.\n *\n * @param {bigint} a - The amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} x - The reserve amount of the first asset (will be scaled by RESERVE_PRECISION).\n * @param {bigint} y - The reserve amount of the second asset (will be scaled by RESERVE_PRECISION).\n * @returns {bigint} The calculated sum invariant (D) scaled by RESERVE_PRECISION.\n * @throws {Error} If the amplification coefficient is not positive.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getSumInvariant(a: bigint, x: bigint, y: bigint): bigint {\n if (a <= 0n) {\n throw new Error(\"Amplification coefficient must be positive.\");\n }\n x = x * RESERVE_PRECISION;\n y = y * RESERVE_PRECISION;\n a = a * A_PRECISION;\n const sum: bigint = x + y;\n if (sum === 0n) {\n return 0n;\n }\n\n let d = sum;\n const ann = a * 2n;\n for (let i = 0; i < 255; i++) {\n const d_p = (d * d * d) / (4n * x * y);\n const d_prev = d;\n\n d =\n (((ann * sum) / 100n + d_p * 2n) * d) /\n (((ann - 100n) * d) / 100n + 3n * d_p);\n\n if (d > d_prev) {\n if (d - d_prev <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n } else {\n if (d_prev - d <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on D value after 255 iterations.\");\n}\n\n/**\n * Calculates the new Y reserve value given a new X reserve value and the sum invariant.\n * This function uses Newton's method to iteratively solve for Y in the Stableswaps equation\n * while maintaining the pool's invariant (D).\n *\n * The function solves: Y^2 + (sum + (D * A_PRECISION) / (2 * Ann) - D) * Y - c = 0\n * where c is derived from D and the pool parameters.\n *\n * This is used during swaps to determine the output reserve after an input is added.\n *\n * @param {bigint} newX - The new reserve amount for asset X (will be scaled by RESERVE_PRECISION internally).\n * @param {bigint} aRaw - The raw amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} sumInvariant - The pool's sum invariant (D), already scaled.\n * @returns {bigint} The calculated Y reserve value scaled by RESERVE_PRECISION.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getNewY(\n newX: bigint,\n aRaw: bigint,\n sumInvariant: bigint,\n): bigint {\n newX = newX * RESERVE_PRECISION;\n const sum = newX;\n let yPrev: bigint;\n let c = sumInvariant;\n const ann = aRaw * A_PRECISION * 2n;\n\n c = (c * sumInvariant) / (newX * 2n);\n c = (c * sumInvariant * A_PRECISION) / 2n;\n c = c / (ann * 2n);\n const b = sum + (sumInvariant * A_PRECISION) / 2n / ann;\n let y = sumInvariant;\n for (let i = 0; i < 255; i++) {\n yPrev = y;\n y = (y * y + c) / (y * 2n + b - sumInvariant);\n if (y > yPrev) {\n if (y - yPrev <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n } else {\n if (yPrev - y <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on y value after 255 iterations.\");\n}\n\n/**\n * Calculates the initial LP token amount for the first liquidity provision to a pool.\n * This is used when bootstrapping a new pool with initial reserves of assets A and B.\n *\n * The LP tokens minted are derived from the sum invariant (D) divided by the reserve precision,\n * effectively representing the pool's total value at inception.\n *\n * @param {bigint} a - The initial amount of token A being deposited.\n * @param {bigint} b - The initial amount of token B being deposited.\n * @param {bigint} laf - The linear amplification factor for the pool.\n * @returns {bigint} The amount of LP tokens to mint for the first liquidity provision.\n */\nexport const getFirstLp = (a: bigint, b: bigint, laf: bigint) =>\n getSumInvariant(laf, a, b) / RESERVE_PRECISION;\n\n/**\n * Calculates the liquidity parameters for adding liquidity to a Stableswaps pool.\n * This function supports mixed deposits where both assets can be deposited in any proportion.\n *\n * The calculation is based on the change in the sum invariant (D) before and after the deposit.\n * LP tokens are minted proportionally to the increase in D relative to the old D value.\n *\n * TODO: Investigate way to optimize actual deposited amounts\n *\n * @param {bigint} a - The amount of token A to deposit.\n * @param {bigint} b - The amount of token B to deposit.\n * @param {bigint} aReserve - The current reserve of token A in the pool.\n * @param {bigint} bReserve - The current reserve of token B in the pool.\n * @param {bigint} totalLp - The total LP tokens for the pool before the deposit.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @throws {Error} If the pool doesn't have enough liquidity (both reserves are zero).\n * @throws {Error} If both deposit amounts are zero.\n * @returns {Object} An object containing:\n * - nextTotalLp: The total LP tokens for the pool after the deposit.\n * - generatedLp: The amount of LP tokens generated by the deposit.\n * - shareAfterDeposit: The depositor's share of the pool after the deposit (as a Fraction).\n * - aChange: Always 0n for Stableswaps (no refund needed).\n * - bChange: Always 0n for Stableswaps (no refund needed).\n * - actualDepositedA: The actual amount of A deposited (always equal to input a).\n * - actualDepositedB: The actual amount of B deposited (always equal to input b).\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n laf: bigint,\n) => {\n if (aReserve === 0n && bReserve === 0n) {\n throw new Error(\"Not enough pool liquidity\");\n }\n\n if (a === 0n && b === 0n) {\n throw new Error(\"Cannot use a deposit asset amount of 0\");\n }\n\n const oldSumInvariant = getSumInvariant(laf, aReserve, bReserve);\n\n const newSumInvariant = getSumInvariant(laf, aReserve + a, bReserve + b);\n\n const newLpTokens =\n ((newSumInvariant - oldSumInvariant) * totalLp) / oldSumInvariant;\n\n const newTotalLpTokens = totalLp + newLpTokens;\n\n return {\n nextTotalLp: newTotalLpTokens,\n generatedLp: newLpTokens,\n shareAfterDeposit: SharedPoolMath.getShare(newLpTokens, newTotalLpTokens),\n aChange: 0n,\n bChange: 0n,\n actualDepositedA: a,\n actualDepositedB: b,\n };\n};\n\n/**\n * Calculates the token amounts that a given LP token amount represents when withdrawing\n * from a Stableswaps pool. The withdrawal is proportional to the LP tokens being redeemed\n * relative to the total LP supply.\n *\n * This uses a simple linear proportion: amount = (lp * reserve) / totalLp for each asset.\n *\n * @param {bigint} lp - The amount of LP tokens being redeemed.\n * @param {bigint} aReserve - The pool's current reserve amount of token A.\n * @param {bigint} bReserve - The pool's current reserve amount of token B.\n * @param {bigint} totalLp - The pool's total minted LP tokens currently in circulation.\n * @returns {SharedPoolMath.TPair} A tuple [a, b] containing the amounts of tokens A and B to withdraw.\n */\nexport const getTokensForLp = (\n lp: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n): SharedPoolMath.TPair => [\n new Fraction(lp * aReserve, totalLp).quotient,\n new Fraction(lp * bReserve, totalLp).quotient,\n];\n\n/**\n * Represents the complete outcome of a swap operation in a Stableswaps pool.\n * Contains all relevant information about the swap including amounts, fees, updated reserves,\n * and price impact.\n */\nexport type TSwapOutcome = {\n /** The amount of input tokens being swapped */\n input: bigint;\n /** The amount of output tokens received (after all fees) */\n output: bigint;\n /** The portion of fees that goes to liquidity providers */\n lpFee: AssetAmount<IAssetAmountMetadata>;\n /** The portion of fees that goes to the protocol */\n protocolFee: AssetAmount<IAssetAmountMetadata>;\n /** The input asset reserve amount after the swap */\n nextInputReserve: bigint;\n /** The output asset reserve amount after the swap (excluding protocol fees) */\n nextOutputReserve: bigint;\n /** The pool's sum invariant (D) after the swap */\n nextSumInvariant: bigint;\n /** The price impact of the swap as a fraction (difference between ideal and actual price) */\n priceImpact: Fraction;\n};\n\n/**\n * Calculates the output amount and all swap parameters for a given input amount in a Stableswaps pool.\n * This function determines how many output tokens will be received for a given input, accounting for\n * the Stableswaps curve, LP fees, and protocol fees.\n *\n * The calculation process:\n * 1. Validates inputs and fees\n * 2. Calculates the current sum invariant (D)\n * 3. Determines the new Y value after adding input to X\n * 4. Calculates raw output and applies fees (LP + protocol)\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} input - The amount of input tokens to swap.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @param {boolean} [roundOutputUp] - Optional flag to round output up instead of down (default: false).\n * @returns {TSwapOutcome} The complete swap outcome including output, fees, reserves, and price impact.\n * @throws {Error} If input or reserves are not positive.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapOutput = (\n outputMetadata: IAssetAmountMetadata,\n input: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n roundOutputUp?: boolean,\n): TSwapOutcome => {\n if (input <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Input and reserves must be positive\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be between 0 and 1\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const nextInputReserve = inputReserve + input;\n const newY = getNewY(nextInputReserve, laf, sumInvariant);\n\n const deltaYPrec = outputReserve * RESERVE_PRECISION - newY;\n const deltaY = new Fraction(deltaYPrec, RESERVE_PRECISION);\n const totalFee = combinedFee\n .multiply(FEE_PRECISION)\n .multiply(deltaY.quotient)\n .add(Fraction.asFraction(FEE_PRECISION - 1n))\n .divide(FEE_PRECISION).quotient;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n const totalLpFee = totalFee - totalProtocolFee;\n const output = deltaY.subtract(totalFee);\n const safeOutput = roundOutputUp\n ? (output.numerator + output.denominator - 1n) / output.denominator\n : output.quotient;\n const nextOutputReserve = outputReserve - safeOutput - totalProtocolFee;\n\n // PRICEIMPACT: \"priceImpact\" is slightly misleadingly named in the industry as a whole\n // just by it's name, it would imply that it's the percentage difference between\n // the current price and the price after the swap, but it's actually the percentage\n // difference between the real price of your swap, and the price implied by the current\n // reserves; We got this wrong in v1, but this aligns it with the industry standard\n // Source: https://dailydefi.org/articles/price-impact-and-how-to-calculate/\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, safeOutput);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n return {\n input,\n output: safeOutput,\n lpFee: new AssetAmount(totalLpFee, outputMetadata),\n protocolFee: new AssetAmount(totalProtocolFee, outputMetadata),\n nextInputReserve,\n nextOutputReserve,\n nextSumInvariant: getSumInvariant(laf, nextInputReserve, nextOutputReserve),\n priceImpact,\n };\n};\n\n/**\n * The pool's marginal price as raw units of asset A per raw unit of asset B,\n * |dx/dy| at the current reserves. This is the \"ideal\" price that swap price\n * impact is measured against.\n *\n * Derived from the Stableswaps invariant 4A(x + y) + D = 4AD + D^3 / (4xy):\n * price = (xpA + (dR * aReserve) / bReserve) / (xpA + dR)\n * where xpA = 4 * laf * aReserve and dR = D^3 / (4 * aReserve * bReserve)\n *\n * @param {bigint} aReserve - The current reserve amount of asset A in the pool.\n * @param {bigint} bReserve - The current reserve amount of asset B in the pool.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {Fraction} Raw A per raw B at the current reserves.\n */\nexport function getPrice(\n aReserve: bigint,\n bReserve: bigint,\n laf: bigint,\n): Fraction {\n const sumInvariant =\n getSumInvariant(laf, aReserve, bReserve) / RESERVE_PRECISION;\n // D / n^n with n = 2\n let dR = sumInvariant / 4n;\n dR = (dR * sumInvariant) / aReserve;\n dR = (dR * sumInvariant) / bReserve;\n // 4A is the amplification term of the on-chain invariant, A = laf.\n const xpA = 4n * laf * aReserve;\n const p = new Fraction(xpA + (dR * aReserve) / bReserve, xpA + dR);\n return p;\n}\n\n/**\n * Calculates the required input amount and all swap parameters for a desired output amount in a Stableswaps pool.\n * This is the reverse operation of getSwapOutput - given how much you want to receive, it determines\n * how much you need to provide as input, accounting for fees and the Stableswaps curve.\n *\n * The calculation process:\n * 1. Validates inputs, fees, and output constraints\n * 2. Calculates raw output needed before fees\n * 3. Determines the new X value to achieve the desired Y reduction\n * 4. Calculates required input and separates LP and protocol fees\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} output - The desired amount of output tokens to receive.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {TSwapOutcome} The complete swap outcome including required input, fees, reserves, and price impact.\n * @throws {Error} If output or reserves are not positive.\n * @throws {Error} If output is greater than or equal to the output reserve.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapInput = (\n outputMetadata: IAssetAmountMetadata,\n output: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n): TSwapOutcome => {\n if (output <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Output and reserves must be positive\");\n\n if (output >= outputReserve)\n throw new Error(\"Output must be less than output reserve\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be [0,1)\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n\n // output = rawOutput * (1-fee)\n // rawOutput = output / (1-fee)\n const rawOutputF = Fraction.asFraction(output).divide(\n Fraction.ONE.sub(combinedFee),\n );\n const rawOutput =\n (rawOutputF.numerator + rawOutputF.denominator - 1n) /\n rawOutputF.denominator;\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const newX = getNewY(outputReserve - rawOutput, laf, sumInvariant);\n const input =\n (newX - inputReserve * RESERVE_PRECISION + RESERVE_PRECISION - 1n) /\n RESERVE_PRECISION;\n\n const totalFee =\n (combinedFee.multiply(FEE_PRECISION).quotient * rawOutput +\n FEE_PRECISION -\n 1n) /\n FEE_PRECISION;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n\n const totalLpFee = totalFee - totalProtocolFee;\n\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output - totalProtocolFee;\n\n // See PRICEIMPACT\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, output);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n\n const nextSumInvariant = getSumInvariant(\n laf,\n nextInputReserve,\n nextOutputReserve,\n );\n\n return {\n input,\n output,\n lpFee: new AssetAmount(totalLpFee, outputMetadata),\n protocolFee: new AssetAmount(totalProtocolFee, outputMetadata),\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n nextSumInvariant,\n };\n};\n"],"mappings":"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","ignoreList":[]}