From 01f359e60ccdf9a83fab188d687b8a4b9f7c8b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Ludue=C3=B1a?= Date: Sun, 22 Mar 2026 18:14:50 -0300 Subject: [PATCH 1/5] feat: initial submission hydra boys --- lazer/cardano/hermes/README.md | 13 + lazer/cardano/hermes/doc/report.typ | 229 + lazer/cardano/hermes/doc/transactions.pdf | Bin 0 -> 173788 bytes lazer/cardano/hermes/doc/transactions.typ | 575 ++ lazer/cardano/hermes/infra/.gitignore | 1 + lazer/cardano/hermes/infra/README.md | 16 + .../hermes/infra/credentials/hydra-funds.addr | 1 + .../hermes/infra/credentials/hydra-funds.sk | 5 + .../hermes/infra/credentials/hydra-funds.vk | 5 + .../hermes/infra/credentials/hydra-peer.sk | 5 + .../hermes/infra/credentials/hydra-peer.vk | 5 + .../cardano/hermes/infra/credentials/hydra.sk | 5 + .../cardano/hermes/infra/credentials/hydra.vk | 5 + .../cardano/hermes/infra/docker-compose.yaml | 87 + .../hydra-bootstrap/reference-script.plutus | 5 + .../hydra-bootstrap/seed-output-datum.cbor | Bin 0 -> 106 bytes .../infra/hydra-bootstrap/seed-spend.raw | 5 + .../hermes/infra/initial-utxo-set.json | 12 + .../hermes/infra/protocol-parameters.json | 707 ++ .../hermes/infra/seed-spend.signed.json | 5 + lazer/cardano/hermes/infra/submit-seed-tx.sh | 101 + lazer/cardano/hermes/server/.gitignore | 3 + lazer/cardano/hermes/server/package.json | 28 + lazer/cardano/hermes/server/pnpm-lock.yaml | 2025 +++++ lazer/cardano/hermes/server/src/index.ts | 203 + lazer/cardano/hermes/server/src/market.ts | 43 + lazer/cardano/hermes/server/src/matcher.ts | 45 + .../hermes/server/src/offchain/claims.ts | 15 + .../server/src/offchain/hydra/handler.ts | 344 + .../server/src/offchain/hydra/provider.ts | 123 + .../hermes/server/src/offchain/index.ts | 3 + .../hermes/server/src/offchain/market.ts | 70 + .../hermes/server/src/offchain/orders.ts | 53 + lazer/cardano/hermes/server/src/rest.ts | 116 + .../hermes/server/src/streams/btcPrice.ts | 72 + .../hermes/server/src/streams/orderbook.ts | 72 + .../hermes/server/src/streams/positions.ts | 57 + lazer/cardano/hermes/server/src/types.ts | 91 + lazer/cardano/hermes/server/tsconfig.json | 13 + lazer/cardano/hermes/src/onchain/.gitignore | 6 + lazer/cardano/hermes/src/onchain/README.md | 65 + lazer/cardano/hermes/src/onchain/aiken.lock | 15 + lazer/cardano/hermes/src/onchain/aiken.toml | 18 + lazer/cardano/hermes/src/onchain/lib/types.ak | 57 + lazer/cardano/hermes/src/onchain/plutus.json | 387 + .../hermes/src/onchain/validators/market.ak | 22 + .../hermes/src/onchain/validators/order.ak | 23 + lazer/cardano/hermes/ui/.gitignore | 24 + lazer/cardano/hermes/ui/.prettierignore | 7 + lazer/cardano/hermes/ui/.prettierrc | 11 + lazer/cardano/hermes/ui/README.md | 21 + lazer/cardano/hermes/ui/components.json | 25 + lazer/cardano/hermes/ui/eslint.config.js | 23 + lazer/cardano/hermes/ui/index.html | 13 + lazer/cardano/hermes/ui/package.json | 47 + lazer/cardano/hermes/ui/pnpm-lock.yaml | 6723 +++++++++++++++++ lazer/cardano/hermes/ui/public/vite.svg | 1 + lazer/cardano/hermes/ui/src/App.tsx | 16 + lazer/cardano/hermes/ui/src/assets/react.svg | 1 + .../hermes/ui/src/components/FillRow.tsx | 28 + .../ui/src/components/MarketDashboard.tsx | 122 + .../hermes/ui/src/components/OrderBook.tsx | 30 + .../hermes/ui/src/components/OrderRow.tsx | 34 + .../hermes/ui/src/components/Positions.tsx | 44 + .../hermes/ui/src/components/PriceChart.tsx | 103 + .../hermes/ui/src/components/TradeForm.tsx | 241 + .../hermes/ui/src/components/TuiPanel.tsx | 23 + .../ui/src/components/theme-provider.tsx | 230 + .../hermes/ui/src/components/ui/badge.tsx | 49 + .../hermes/ui/src/components/ui/button.tsx | 67 + .../hermes/ui/src/components/ui/input.tsx | 19 + .../hermes/ui/src/components/ui/tabs.tsx | 88 + .../hermes/ui/src/hooks/useMarketStream.ts | 160 + lazer/cardano/hermes/ui/src/index.css | 133 + lazer/cardano/hermes/ui/src/lib/utils.ts | 6 + lazer/cardano/hermes/ui/src/main.tsx | 14 + .../hermes/ui/src/pages/HistoryPage.tsx | 152 + lazer/cardano/hermes/ui/src/types/market.ts | 93 + lazer/cardano/hermes/ui/tsconfig.app.json | 32 + lazer/cardano/hermes/ui/tsconfig.json | 13 + lazer/cardano/hermes/ui/tsconfig.node.json | 26 + lazer/cardano/hermes/ui/vite.config.ts | 27 + 82 files changed, 14402 insertions(+) create mode 100644 lazer/cardano/hermes/README.md create mode 100644 lazer/cardano/hermes/doc/report.typ create mode 100644 lazer/cardano/hermes/doc/transactions.pdf create mode 100644 lazer/cardano/hermes/doc/transactions.typ create mode 100644 lazer/cardano/hermes/infra/.gitignore create mode 100644 lazer/cardano/hermes/infra/README.md create mode 100644 lazer/cardano/hermes/infra/credentials/hydra-funds.addr create mode 100644 lazer/cardano/hermes/infra/credentials/hydra-funds.sk create mode 100644 lazer/cardano/hermes/infra/credentials/hydra-funds.vk create mode 100644 lazer/cardano/hermes/infra/credentials/hydra-peer.sk create mode 100644 lazer/cardano/hermes/infra/credentials/hydra-peer.vk create mode 100644 lazer/cardano/hermes/infra/credentials/hydra.sk create mode 100644 lazer/cardano/hermes/infra/credentials/hydra.vk create mode 100644 lazer/cardano/hermes/infra/docker-compose.yaml create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/reference-script.plutus create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.cbor create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw create mode 100644 lazer/cardano/hermes/infra/initial-utxo-set.json create mode 100644 lazer/cardano/hermes/infra/protocol-parameters.json create mode 100644 lazer/cardano/hermes/infra/seed-spend.signed.json create mode 100755 lazer/cardano/hermes/infra/submit-seed-tx.sh create mode 100644 lazer/cardano/hermes/server/.gitignore create mode 100644 lazer/cardano/hermes/server/package.json create mode 100644 lazer/cardano/hermes/server/pnpm-lock.yaml create mode 100644 lazer/cardano/hermes/server/src/index.ts create mode 100644 lazer/cardano/hermes/server/src/market.ts create mode 100644 lazer/cardano/hermes/server/src/matcher.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/claims.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/hydra/handler.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/hydra/provider.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/index.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/market.ts create mode 100644 lazer/cardano/hermes/server/src/offchain/orders.ts create mode 100644 lazer/cardano/hermes/server/src/rest.ts create mode 100644 lazer/cardano/hermes/server/src/streams/btcPrice.ts create mode 100644 lazer/cardano/hermes/server/src/streams/orderbook.ts create mode 100644 lazer/cardano/hermes/server/src/streams/positions.ts create mode 100644 lazer/cardano/hermes/server/src/types.ts create mode 100644 lazer/cardano/hermes/server/tsconfig.json create mode 100644 lazer/cardano/hermes/src/onchain/.gitignore create mode 100644 lazer/cardano/hermes/src/onchain/README.md create mode 100644 lazer/cardano/hermes/src/onchain/aiken.lock create mode 100644 lazer/cardano/hermes/src/onchain/aiken.toml create mode 100644 lazer/cardano/hermes/src/onchain/lib/types.ak create mode 100644 lazer/cardano/hermes/src/onchain/plutus.json create mode 100644 lazer/cardano/hermes/src/onchain/validators/market.ak create mode 100644 lazer/cardano/hermes/src/onchain/validators/order.ak create mode 100644 lazer/cardano/hermes/ui/.gitignore create mode 100644 lazer/cardano/hermes/ui/.prettierignore create mode 100644 lazer/cardano/hermes/ui/.prettierrc create mode 100644 lazer/cardano/hermes/ui/README.md create mode 100644 lazer/cardano/hermes/ui/components.json create mode 100644 lazer/cardano/hermes/ui/eslint.config.js create mode 100644 lazer/cardano/hermes/ui/index.html create mode 100644 lazer/cardano/hermes/ui/package.json create mode 100644 lazer/cardano/hermes/ui/pnpm-lock.yaml create mode 100644 lazer/cardano/hermes/ui/public/vite.svg create mode 100644 lazer/cardano/hermes/ui/src/App.tsx create mode 100644 lazer/cardano/hermes/ui/src/assets/react.svg create mode 100644 lazer/cardano/hermes/ui/src/components/FillRow.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/MarketDashboard.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/OrderBook.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/OrderRow.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/Positions.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/PriceChart.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/TradeForm.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/TuiPanel.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/theme-provider.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/ui/badge.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/ui/button.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/ui/input.tsx create mode 100644 lazer/cardano/hermes/ui/src/components/ui/tabs.tsx create mode 100644 lazer/cardano/hermes/ui/src/hooks/useMarketStream.ts create mode 100644 lazer/cardano/hermes/ui/src/index.css create mode 100644 lazer/cardano/hermes/ui/src/lib/utils.ts create mode 100644 lazer/cardano/hermes/ui/src/main.tsx create mode 100644 lazer/cardano/hermes/ui/src/pages/HistoryPage.tsx create mode 100644 lazer/cardano/hermes/ui/src/types/market.ts create mode 100644 lazer/cardano/hermes/ui/tsconfig.app.json create mode 100644 lazer/cardano/hermes/ui/tsconfig.json create mode 100644 lazer/cardano/hermes/ui/tsconfig.node.json create mode 100644 lazer/cardano/hermes/ui/vite.config.ts diff --git a/lazer/cardano/hermes/README.md b/lazer/cardano/hermes/README.md new file mode 100644 index 00000000..1c2599a4 --- /dev/null +++ b/lazer/cardano/hermes/README.md @@ -0,0 +1,13 @@ +# Team "Los Hydra Boys" Pythathon Submission + +## Details + +Team Name: Los Hydra Boys +Submission Name: Hermes Market +Team Members: Ignacio Dopazo (@ignaciodopazo), Nicolás Ludueña (@nicolasLuduena), Valentino Cerutti (@Micrograx) +Contact: luduena.nicolas.victorio@gmail.com + +## Project Description + +Hermes market is a proof of concept integration of Pyth oracle information with Cardano's bleeding edge L2 [Hydra](https://hydra.family/head-protocol) that allows for real time bets on BTC price. Therefore truly giving an edge over a simple 5 minute market with up to 2 minute block finality in the L1 on the worst cases. Even on mainnet with high congestion scenarios, block confirmation is not guaranteed after several days. + diff --git a/lazer/cardano/hermes/doc/report.typ b/lazer/cardano/hermes/doc/report.typ new file mode 100644 index 00000000..cf667230 --- /dev/null +++ b/lazer/cardano/hermes/doc/report.typ @@ -0,0 +1,229 @@ +// Transaction diagrams + +#let tx_out_height_estimate(input) = { + let address = if "address" in input { 1 } else { 0 } + let value = if "value" in input { input.value.len() } else { 0 } + let datum = if "datum" in input { input.datum.len() } else { 0 } + return (address + value + datum) * 8pt +} + +#let datum_field(indent, k, val) = [ + #if val == "" [ + #h(indent)\+ #raw(k) + ] else [ + #h(indent)\+ #raw(k): + #if type(val) == content { val } + #if type(val) == str and val != "" { repr(val) } + #if type(val) == int { repr(val) } + #if type(val) == array [ + #stack(dir: ttb, spacing: 0.4em, for item in val [ + #datum_field(indent + 1.2em, "", item) \ + ]) + ] + #if type(val) == dictionary [ + #v(-0.7em) + #stack(dir: ttb, spacing: 0em, for (k, v) in val.pairs() [ + #datum_field(indent + 1.2em, k, v) \ + ]) + ] + ] +] + +#let tx_out(input, position, inputHeight) = { + let address = if "address" in input [ + *Address: #h(0.5em) #input.address* + ] else [] + let value = if "value" in input [ + *Value:* #if ("ada" in input.value) [ *#input.value.ada* ADA ] \ + #v(-1.0em) + #stack(dir: ttb, spacing: 0.4em, ..input + .value + .pairs() + .map(((k, v)) => [ + #if k != "ada" [ + #h(2.3em) \+ + #if type(v) == content { math.bold(v) } + #if type(v) == str and v != "" [*#v*] + #k + ] + ])) + ] else [] + let datum = if "datum" in input [ + *Datum:* \ + #v(-0.8em) + #stack(dir: ttb, spacing: 0.4em, ..input.datum.pairs().map(((k, val)) => datum_field(1.2em, k, val))) + ] else [] + let addressHeight = measure(address).height + if "address" in input { 6pt } else { 0pt } + let valueHeight = measure(value).height + if "value" in input { 6pt } else { 0pt } + let datumHeight = measure(datum).height + if "datum" in input { 6pt } else { 0pt } + let thisHeight = 32pt + addressHeight + valueHeight + datumHeight + + if "dots" in input { + return ( + content: place(dx: position.x, dy: position.y, [ + #place(dx: 4em, dy: -1em)[*.*] + #place(dx: 4em, dy: 0em)[*.*] + #place(dx: 4em, dy: 1em)[*.*] + ]), + height: thisHeight, + ) + } else { + return ( + content: place(dx: position.x, dy: position.y, [ + *#input.name* + #line(start: (-4em, -1em), end: (10em, -1em), stroke: red) + #place(dx: 10em, dy: -1.5em)[#circle(radius: 0.5em, fill: white, stroke: red)] + #if "address" in input { place(dx: 0em, dy: -3pt)[#address] } + #place(dx: 0em, dy: addressHeight)[#value] + #if "datum" in input { place(dx: 0em, dy: addressHeight + valueHeight)[#datum] } + ]), + height: thisHeight, + ) + } +} + +#let vanilla_transaction( + name, + inputs: (), + outputs: (), + signatures: (), + certificates: (), + withdrawals: (), + mint: (:), + validRange: none, + notes: none, +) = context { + let inputHeightEstimate = inputs.fold(0pt, (sum, input) => sum + tx_out_height_estimate(input)) + let inputHeight = 0em + let inputs = [ + #let start = (x: -18em, y: 1em) + #for input in inputs { + let tx_out = tx_out(input, start, inputHeight) + + tx_out.content + + // Now connect this output to the transaction + if not "dots" in input { + place(dx: start.x + 10.5em, dy: start.y + 0.84em)[ + #let lineStroke = if input.at("reference", default: false) { + (paint: blue, thickness: 1pt, dash: "dashed") + } else { blue } + #line(start: (0em, 0em), end: (7.44em, 0em), stroke: lineStroke) + ] + place(dx: start.x + 10.26em, dy: start.y + 0.59em)[#circle(radius: 0.25em, fill: blue)] + } + if input.at("redeemer", default: none) != none { + place(dx: start.x + 12.26em, dy: start.y - 0.2em)[#input.at("redeemer")] + } + + start = (x: start.x, y: start.y + tx_out.height) + inputHeight += tx_out.height + } + ] + + let outputHeightEstimate = outputs.fold(0pt, (sum, output) => sum + tx_out_height_estimate(output)) + let outputHeight = 0em + let outputs = [ + #let start = (x: 4em, y: 1em) + #for output in outputs { + let tx_out = tx_out(output, start, outputHeight) + tx_out.content + start = (x: start.x, y: start.y + tx_out.height) + outputHeight += tx_out.height + } + ] + + // Collapse down the `mint` array + let display_mint = (:) + for (k, v) in mint { + let display = [] + if type(v) == int { + // the provided value is an integer + if v == 0 { + continue + } else if v > 0 { + display += [ \+ ] + } else if v < 0 { + display += [ \- ] + } + display += [#calc.abs(v)] + } else { + // the provided value can be a letter or variable name + if type(v) == str and v.starts-with("-") { + display += [\- #v.slice(1)] + } else { + display += [\+ #v] + } + } + display += [ #raw(k)] + display_mint.insert(k, display) + } + + let mints = if display_mint.len() > 0 [ + *Mint:* \ + #for (k, v) in display_mint [ + #v \ + ] + ] else [] + let sigs = if signatures.len() > 0 [ + *Signatures:* \ + #for signature in signatures [ + - #signature + ] + ] else [] + let certs = if certificates.len() > 0 [ + *Certificates:* + #for certificate in certificates [ + - #certificate + ] + ] else [] + let withs = if withdrawals.len() > 0 [ + *Withdrawals:* + #for withdrawal in withdrawals [ + - #withdrawal + ] + ] else [] + let valid_range = if validRange != none [ + *Valid Range:* \ + #if "lower" in validRange [#validRange.lower $<=$ ] + `slot` + #if "upper" in validRange [$<=$ #validRange.upper] + ] else [] + + let boxHeight = { + 100pt + 32pt * (mint.len() + certificates.len() + signatures.len()) + 40pt * withdrawals.len() + } + + let transaction = [ + #set align(center) + #rect( + radius: 4pt, + height: calc.max(boxHeight, inputHeight + 16pt, outputHeight + 16pt), + [ + #pad(top: 1em, name) + #v(1em) + #set align(left) + #stack(dir: ttb, spacing: 1em, mints, sigs, certs, withs, valid_range) + ], + ) + ] + + let diagram = stack(dir: ltr, inputs, transaction, outputs) + let size = measure(diagram) + block(width: 100%)[ + #set align(center) + #diagram + #set align(left) + #if notes != none [ + #box( + width: 100%, + fill: rgb("f0f0f0"), + stroke: 0.5pt + black, + inset: 8pt, + )[ + #set text(size: 9pt) + *Notes*: #notes + ] + ] + ] +} diff --git a/lazer/cardano/hermes/doc/transactions.pdf b/lazer/cardano/hermes/doc/transactions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..76a5845fcf6d1520c2a7f21677e5dfaf84ed049c GIT binary patch literal 173788 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 R>zuR3xAg1Rf3;oY{{hU+8KeLJ literal 0 HcmV?d00001 diff --git a/lazer/cardano/hermes/doc/transactions.typ b/lazer/cardano/hermes/doc/transactions.typ new file mode 100644 index 00000000..65684e9a --- /dev/null +++ b/lazer/cardano/hermes/doc/transactions.typ @@ -0,0 +1,575 @@ +#import "report.typ": * + +#let tx_create_market = vanilla_transaction( + "Create Market", + mint: ( + "Control Token": 1, + ), + inputs: ( + ( + reference: true, + name: "Pyth State", + value: ( + "Pyth NFT": 1, + ), + datum: ( + "Pyth Datum": ("...":"", "withdraw_script":"") + ), + ), + ( name: "Seed UTxO" ) + ), + outputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `None`, + remainingShares: 0 + ), + ), + ), + withdrawals: ("withdraw_script",), + // TODO: Think about this + validRange: (lower: "time", upper: "time + 4.5 minutes"), + notes: [ + startValue should be provided by the oracle + ] +) + +#tx_create_market + +#pagebreak() + +#let tx_record_close_price = vanilla_transaction( + "Record Close Price", + inputs: ( + ( + reference: true, + name: "Pyth State", + value: ( + "Pyth NFT": 1, + ), + datum: ( + "Pyth Datum": ("...":"", "withdraw_script":"") + ), + ), + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `None`, + remainingShares: "X" + ), + redeemer: [#h(-1.5em)"RecordClosePrice"] + ), + ), + outputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "X" + ), + ), + ), + withdrawals: ("withdraw_script",), + // TODO: Think about this + validRange: (lower: "endTimestamp"), + notes: [ + endValue should be provided by the oracle + ] +) + +#tx_record_close_price + +#pagebreak() + +#let tx_claim_winnings = vanilla_transaction( + "Claim Winnings", + inputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": `M` + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "X" + ), + redeemer: [#h(-1.5em)"ClaimWinnings"] + ), + ( + name: "User UTxO", + value: ( + "PositionToken": "C", + ), + ) + ), + outputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": `M - C` + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "X - C" + ), + ), + ( + name: "User UTxO", + value: ( + "ADA": "C", + ), + ) + ), + mint: ( + "PositionToken": "-C" + ), + notes: [ + if P' >= P { PositionToken = "UP" } \ + else { PositionToken = "DOWN"} + ] +) + +#tx_claim_winnings + +#pagebreak() + +#let tx_claim_losings = vanilla_transaction( + "Claim Losing", + inputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": `M` + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "X" + ), + redeemer: [#h(-1.5em)"ClaimLosings"] + ), + ( + name: "User UTxO", + value: ( + "PositionToken": "C", + ), + ) + ), + outputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": `M` + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "X - C" + ), + ), + ), + mint: ( + "PositionToken": "-C" + ), + notes: [ + if P' < P { PositionToken = "UP" } \ + else { PositionToken = "DOWN"} + ] +) + +#tx_claim_losings + +#pagebreak() + +#let tx_close_market = vanilla_transaction( + "Close Market", + inputs: ( + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": `M` + ), + datum: ( + startTimestamp: `time`, + startValue: "P", + endTimestamp: `time + 5 minutes`, + endValue: `Some(P')`, + remainingShares: "0" + ), + redeemer: [Close] + ), + ), + outputs: ( + ( + name: "User UTxO", + value: ( + "ADA": "M", + ), + ), + ), + +) + +#tx_close_market + +#pagebreak() + +#let tx_place_buy_order = vanilla_transaction( + "Place Buy Order", + mint: ( + "Order Control Token": 1, + ), + inputs: ( + ), + outputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "ADAs": `M`, + ), + datum: ( + owner: `pkh`, + direction: "Up|Down", + operation: `Buy`, + price: `N`, + ), + ), + ), +) + +#tx_place_buy_order + +#let tx_place_sell_order = vanilla_transaction( + "Place Sell Order", + mint: ( + "Order Control Token": 1, + ), + inputs: ( + ), + outputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "BUY/SELL": `M`, + ), + datum: ( + owner: `pkh`, + direction: "Up|Down", + operation: `Sell`, + price: `N`, + ), + ), + ), +) + +#tx_place_sell_order + + +#pagebreak() + +#let tx_complete_fill_order = vanilla_transaction( + "Complete Fill Order", + mint: ( + "Order Control Token": -1, + ), + inputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "offered_token": `N`, + ), + datum: ( + owner: `pkh`, + direction: "Up|Down", + operation: `Sell|Down`, + price: `P`, + ), + redeemer: ("CompleteFill"), + ), + ( + name: "User UTxO", + value: ( + "asked_token": `M`, + ), + ), + ), + outputs: ( + ( + name: "Order Fill UTxO", + address: "owner", + value: ( + "asked_token": `M`, + ), + ), + ( + name: "User UTxO", + value: ( + "offered_token": `N`, + ), + ), + ), + notes: [If operation == Sell { M = P \* N } else { N = P \* M }], +) + +#tx_complete_fill_order + +#pagebreak() + +#let tx_partial_fill_order = vanilla_transaction( + "Partial Fill Order", + mint: ( + "Order Control Token": -1, + ), + inputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "offered_token": `N`, + ), + datum: ( + owner: `pkh`, + direction: "Up|Down", + operation: `Sell|Down`, + price: `P`, + ), + redeemer: ("PartialFill"), + ), + ( + name: "User UTxO", + value: ( + "asked_token": `M`, + ), + ), + ), + outputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "offered_token": `N - N'`, + ), + datum: ( + owner: `pkh`, + direction: "Up|Down", + operation: `Sell|Down`, + price: `P`, + ), + redeemer: ("FillOrder"), + ), + ( + name: "Order Fill UTxO", + address: "owner", + value: ( + "asked_token": `M`, + ), + ), + ( + name: "User UTxO", + value: ( + "offered_token": `N'`, + ), + ), + ), + notes: [If operation == Sell { M = P \* N' } else { N' = P \* M }], +) + +#tx_partial_fill_order + +#pagebreak() + +#let tx_match_orders = vanilla_transaction( + "Match Orders", + mint: ( + "Order Control Token": "O", + "UP": "N", + "DOWN": "N" + ), + inputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "ADAs": [$N_1$], + ), + datum: ( + owner: [$"pkh"_1$], + direction: "Up", + operation: `Buy`, + price: [$P_1$], + ), + redeemer: ([$R_1$]), + ), + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "ADAs": [$N_2$], + ), + datum: ( + owner: [$"pkh"_2$], + direction: "Down", + operation: `Buy`, + price: [$P_2$], + ), + redeemer: ([$R_2$]), + ), + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": "C" + ), + datum: ( + endTimestamp: `T`, + remainingShares: `X`, + "...": "" + ), + redeemer: "Match" + ), + ), + outputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "ADAs": [N'], + ), + datum: ( + owner: [$"pkh"_n$], + direction: [$D_n$], + operation: `Buy`, + price: [$P_n$], + ), + redeemer: ("PartialMatch"), + ), + ( + name: "Up UTxO", + address: [$"pkh"_1$], + value: ( + "UP": `N`, + ), + ), + ( + name: "Down UTxO", + address: [$"pkh"_2$], + value: ( + "DOWN": `N`, + ), + ), + ( + name: "Market", + address: "market script address", + value: ( + "Control token": "1", + "ADA": "C + N" + ), + datum: ( + endTimestamp: `T`, + remainingShares: `X + 2 * N`, + "...": "" + ), + ), + ), + notes: [ + $ + N = min(N_1, N_2) \ + $ + + If N_1 > N_2 { R1 = PartialMatch; R2 = Match; $"pkh"_n$ = $"pkh"_1$; $D_n$ = Up; $P_n$ = $P_1$; O = -1 } \ + else if N_2 > N_1 { R1 = Match; R2 = PartialMatch; $"pkh"_n$ = $"pkh"_2$; $D_n$ = Down; $P_n$ = $P_2$; O = 1} \ + else { R1 = R2 = Match; O = 2 } + ], +) + +#tx_match_orders + +#pagebreak() + +#let tx_cancel_order = vanilla_transaction( + "Cancel Order", + mint: ( + "Order Control Token": -1, + ), + inputs: ( + ( + name: "Order", + address: "order book address", + value: ( + "Order Control token": "1", + "V": ``, + ), + datum: ( + owner: "pkh", + "...":"" + ), + redeemer: ("Cancel"), + ), + ), + outputs: ( + ( + name: "Owner UTxO", + address: "pkh", + value: ( + "V": ``, + ), + ), + ), + signatures: ("pkh",) +) + +#tx_cancel_order \ No newline at end of file diff --git a/lazer/cardano/hermes/infra/.gitignore b/lazer/cardano/hermes/infra/.gitignore new file mode 100644 index 00000000..f7fceb78 --- /dev/null +++ b/lazer/cardano/hermes/infra/.gitignore @@ -0,0 +1 @@ +persistence \ No newline at end of file diff --git a/lazer/cardano/hermes/infra/README.md b/lazer/cardano/hermes/infra/README.md new file mode 100644 index 00000000..55e106f2 --- /dev/null +++ b/lazer/cardano/hermes/infra/README.md @@ -0,0 +1,16 @@ +# Infrastructure + +Docker Compose stack (Hydra peers + automatic seed tx). + +```bash +cd infra + +# for running the infra +docker compose up -d + +# for reseting infra state +docker compose down -v && rm -rf persistence/ + +# for reset + restart +docker compose down -v && rm -rf persistence/ && docker compose up -d +``` diff --git a/lazer/cardano/hermes/infra/credentials/hydra-funds.addr b/lazer/cardano/hermes/infra/credentials/hydra-funds.addr new file mode 100644 index 00000000..3be26909 --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra-funds.addr @@ -0,0 +1 @@ +addr_test1vzqdn97wxxuem2ukec6fswslmknuj2zlcwhuz2wfqvkdcgq9235ym \ No newline at end of file diff --git a/lazer/cardano/hermes/infra/credentials/hydra-funds.sk b/lazer/cardano/hermes/infra/credentials/hydra-funds.sk new file mode 100644 index 00000000..04598af4 --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra-funds.sk @@ -0,0 +1,5 @@ +{ + "type": "PaymentSigningKeyShelley_ed25519", + "description": "Payment Signing Key", + "cborHex": "5820245120cdf333f8ea69114a2b3f05bcbc0d5c8e8486ca94c020623d5cca822e04" +} diff --git a/lazer/cardano/hermes/infra/credentials/hydra-funds.vk b/lazer/cardano/hermes/infra/credentials/hydra-funds.vk new file mode 100644 index 00000000..bb5e7905 --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra-funds.vk @@ -0,0 +1,5 @@ +{ + "type": "PaymentVerificationKeyShelley_ed25519", + "description": "Payment Verification Key", + "cborHex": "5820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e0" +} diff --git a/lazer/cardano/hermes/infra/credentials/hydra-peer.sk b/lazer/cardano/hermes/infra/credentials/hydra-peer.sk new file mode 100644 index 00000000..c29acf0c --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra-peer.sk @@ -0,0 +1,5 @@ +{ + "type": "HydraSigningKey_ed25519", + "description": "", + "cborHex": "58200f443860b542a1df129d3ea775f6b04b40a0534ee0bd0a4b69b31966c9743380" +} diff --git a/lazer/cardano/hermes/infra/credentials/hydra-peer.vk b/lazer/cardano/hermes/infra/credentials/hydra-peer.vk new file mode 100644 index 00000000..f4a31386 --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra-peer.vk @@ -0,0 +1,5 @@ +{ + "type": "HydraVerificationKey_ed25519", + "description": "", + "cborHex": "58208d279429c491414c1da80373d38d88141c46c86584a8cca81c2481139b1021b3" +} diff --git a/lazer/cardano/hermes/infra/credentials/hydra.sk b/lazer/cardano/hermes/infra/credentials/hydra.sk new file mode 100644 index 00000000..656fe1f0 --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra.sk @@ -0,0 +1,5 @@ +{ + "type": "HydraSigningKey_ed25519", + "description": "", + "cborHex": "582083139d5660a51960770abd900669899e42c07994925d09ad7e881341ef852392" +} diff --git a/lazer/cardano/hermes/infra/credentials/hydra.vk b/lazer/cardano/hermes/infra/credentials/hydra.vk new file mode 100644 index 00000000..6f64eb0f --- /dev/null +++ b/lazer/cardano/hermes/infra/credentials/hydra.vk @@ -0,0 +1,5 @@ +{ + "type": "HydraVerificationKey_ed25519", + "description": "", + "cborHex": "58204a3fd9c3c461c04bf5b8f83ade43ec89a8dbee1ee261015d564a32fc8595024d" +} diff --git a/lazer/cardano/hermes/infra/docker-compose.yaml b/lazer/cardano/hermes/infra/docker-compose.yaml new file mode 100644 index 00000000..d9be7cf2 --- /dev/null +++ b/lazer/cardano/hermes/infra/docker-compose.yaml @@ -0,0 +1,87 @@ +services: + # Two distinct Hydra parties are required for offline head so the + # initial UTxO snapshot is agreed before L2 txs validate. + hydra-node: + user: "1000:1000" + image: ghcr.io/cardano-scaling/hydra-node:1.3.0 + restart: always + volumes: + - .:/devnet + ports: + - "4011:4011" + - "5011:5011" + - "6011:6011" + command: + [ + "--node-id", "1", + "--api-host", "0.0.0.0", + "--listen", "172.29.88.11:5011", + "--monitoring-port", "6011", + "--api-port", "4011", + "--peer", "172.29.88.12:5012", + "--hydra-signing-key", "/devnet/credentials/hydra.sk", + "--hydra-verification-key", "/devnet/credentials/hydra-peer.vk", + "--persistence-dir", "/devnet/persistence/hydra-node", + "--offline-head-seed", "fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa", + "--ledger-protocol-parameters", "/devnet/protocol-parameters.json", + "--initial-utxo", "/devnet/initial-utxo-set.json" + ] + networks: + pythathon_hydra: + ipv4_address: 172.29.88.11 + + hydra-node-peer: + user: "1000:1000" + image: ghcr.io/cardano-scaling/hydra-node:1.3.0 + restart: always + volumes: + - .:/devnet + ports: + - "4012:4012" + - "5012:5012" + - "6012:6012" + command: + [ + "--node-id", "2", + "--api-host", "0.0.0.0", + "--listen", "172.29.88.12:5012", + "--monitoring-port", "6012", + "--api-port", "4012", + "--peer", "172.29.88.11:5011", + "--hydra-signing-key", "/devnet/credentials/hydra-peer.sk", + "--hydra-verification-key", "/devnet/credentials/hydra.vk", + "--persistence-dir", "/devnet/persistence/hydra-node-peer", + "--offline-head-seed", "fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa", + "--ledger-protocol-parameters", "/devnet/protocol-parameters.json", + "--initial-utxo", "/devnet/initial-utxo-set.json" + ] + networks: + pythathon_hydra: + ipv4_address: 172.29.88.12 + + # Writes /devnet/persistence/.hydra-seed-tx.done on success (wiped with persistence/). + hydra-seed-tx: + image: alpine:3.20 + restart: "no" + depends_on: + hydra-node: + condition: service_started + hydra-node-peer: + condition: service_started + volumes: + - .:/devnet + environment: + HYDRA_HTTP_HOST: hydra-node + HYDRA_HTTP_PORT: "4011" + HYDRA_WS_URL: ws://hydra-node:4011 + command: ["/bin/sh", "/devnet/submit-seed-tx.sh"] + networks: + - pythathon_hydra + +networks: + pythathon_hydra: + driver: bridge + ipam: + config: + - subnet: 172.29.88.0/24 + gateway: 172.29.88.1 diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/reference-script.plutus b/lazer/cardano/hermes/infra/hydra-bootstrap/reference-script.plutus new file mode 100644 index 00000000..ad24817f --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/reference-script.plutus @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV3", + "description": "", + "cborHex": "590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e60001" +} diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.cbor b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.cbor new file mode 100644 index 0000000000000000000000000000000000000000..26f8b0833d9e33ce7ee0b478055a89de18665874 GIT binary patch literal 106 zcmV-w0G0pPd7s#MpI96=J%OJnDs1wm!pm#CXdyK?HC(1nOJrgW6qK3)SRkWfH19V_ zqRBxvwlrJL|3wFp?;gCF=@{{EfOVunyCeYrprBYBXsDMX1XOP&Ouu4TmcyyytcDMF Msr=OLpL39V{|N;$iU0rr literal 0 HcmV?d00001 diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw new file mode 100644 index 00000000..21dbe60a --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw @@ -0,0 +1,5 @@ +{ + "type": "Tx ConwayEra", + "description": "Ledger Cddl Format", + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d818586ad8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb2400ffa0a0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abe8203590ab9590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a0f5f6" +} diff --git a/lazer/cardano/hermes/infra/initial-utxo-set.json b/lazer/cardano/hermes/infra/initial-utxo-set.json new file mode 100644 index 00000000..be4b9cf5 --- /dev/null +++ b/lazer/cardano/hermes/infra/initial-utxo-set.json @@ -0,0 +1,12 @@ +{ + "0000000000000000000000000000000000000000000000000000000000000000#0": { + "address": "addr_test1vzqdn97wxxuem2ukec6fswslmknuj2zlcwhuz2wfqvkdcgq9235ym", + "value": { + "lovelace": 100000000041175, + "d799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6": {"50797468205374617465": 1} + }, + "referenceScript": { + "script": {"type": "PlutusScriptV3","cborHex": "590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e60001", "description": ""} + } + } +} diff --git a/lazer/cardano/hermes/infra/protocol-parameters.json b/lazer/cardano/hermes/infra/protocol-parameters.json new file mode 100644 index 00000000..d13b71e1 --- /dev/null +++ b/lazer/cardano/hermes/infra/protocol-parameters.json @@ -0,0 +1,707 @@ +{ + "collateralPercentage": 150, + "committeeMaxTermLength": 146, + "committeeMinSize": 7, + "costModels": { + "PlutusV1": [ + 100788, + 420, + 1, + 1, + 1000, + 173, + 0, + 1, + 1000, + 59957, + 4, + 1, + 11183, + 32, + 201305, + 8356, + 4, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 100, + 100, + 16000, + 100, + 94375, + 32, + 132994, + 32, + 61462, + 4, + 72010, + 178, + 0, + 1, + 22151, + 32, + 91189, + 769, + 4, + 2, + 85848, + 228465, + 122, + 0, + 1, + 1, + 1000, + 42921, + 4, + 2, + 24548, + 29498, + 38, + 1, + 898148, + 27279, + 1, + 51775, + 558, + 1, + 39184, + 1000, + 60594, + 1, + 141895, + 32, + 83150, + 32, + 15299, + 32, + 76049, + 1, + 13169, + 4, + 22100, + 10, + 28999, + 74, + 1, + 28999, + 74, + 1, + 43285, + 552, + 1, + 44749, + 541, + 1, + 33852, + 32, + 68246, + 32, + 72362, + 32, + 7243, + 32, + 7391, + 32, + 11546, + 32, + 85848, + 228465, + 122, + 0, + 1, + 1, + 90434, + 519, + 0, + 1, + 74433, + 32, + 85848, + 228465, + 122, + 0, + 1, + 1, + 85848, + 228465, + 122, + 0, + 1, + 1, + 270652, + 22588, + 4, + 1457325, + 64566, + 4, + 20467, + 1, + 4, + 0, + 141992, + 32, + 100788, + 420, + 1, + 1, + 81663, + 32, + 59498, + 32, + 20142, + 32, + 24588, + 32, + 20744, + 32, + 25933, + 32, + 24623, + 32, + 53384111, + 14333, + 10 + ], + "PlutusV2": [ + 100788, + 420, + 1, + 1, + 1000, + 173, + 0, + 1, + 1000, + 59957, + 4, + 1, + 11183, + 32, + 201305, + 8356, + 4, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 100, + 100, + 16000, + 100, + 94375, + 32, + 132994, + 32, + 61462, + 4, + 72010, + 178, + 0, + 1, + 22151, + 32, + 91189, + 769, + 4, + 2, + 85848, + 228465, + 122, + 0, + 1, + 1, + 1000, + 42921, + 4, + 2, + 24548, + 29498, + 38, + 1, + 898148, + 27279, + 1, + 51775, + 558, + 1, + 39184, + 1000, + 60594, + 1, + 141895, + 32, + 83150, + 32, + 15299, + 32, + 76049, + 1, + 13169, + 4, + 22100, + 10, + 28999, + 74, + 1, + 28999, + 74, + 1, + 43285, + 552, + 1, + 44749, + 541, + 1, + 33852, + 32, + 68246, + 32, + 72362, + 32, + 7243, + 32, + 7391, + 32, + 11546, + 32, + 85848, + 228465, + 122, + 0, + 1, + 1, + 90434, + 519, + 0, + 1, + 74433, + 32, + 85848, + 228465, + 122, + 0, + 1, + 1, + 85848, + 228465, + 122, + 0, + 1, + 1, + 955506, + 213312, + 0, + 2, + 270652, + 22588, + 4, + 1457325, + 64566, + 4, + 20467, + 1, + 4, + 0, + 141992, + 32, + 100788, + 420, + 1, + 1, + 81663, + 32, + 59498, + 32, + 20142, + 32, + 24588, + 32, + 20744, + 32, + 25933, + 32, + 24623, + 32, + 43053543, + 10, + 53384111, + 14333, + 10, + 43574283, + 26308, + 10 + ], + "PlutusV3": [ + 100788, + 420, + 1, + 1, + 1000, + 173, + 0, + 1, + 1000, + 59957, + 4, + 1, + 11183, + 32, + 201305, + 8356, + 4, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 16000, + 100, + 100, + 100, + 16000, + 100, + 94375, + 32, + 132994, + 32, + 61462, + 4, + 72010, + 178, + 0, + 1, + 22151, + 32, + 91189, + 769, + 4, + 2, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 1, + 1000, + 42921, + 4, + 2, + 24548, + 29498, + 38, + 1, + 898148, + 27279, + 1, + 51775, + 558, + 1, + 39184, + 1000, + 60594, + 1, + 141895, + 32, + 83150, + 32, + 15299, + 32, + 76049, + 1, + 13169, + 4, + 22100, + 10, + 28999, + 74, + 1, + 28999, + 74, + 1, + 43285, + 552, + 1, + 44749, + 541, + 1, + 33852, + 32, + 68246, + 32, + 72362, + 32, + 7243, + 32, + 7391, + 32, + 11546, + 32, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 90434, + 519, + 0, + 1, + 74433, + 32, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 1, + 85848, + 123203, + 7305, + -900, + 1716, + 549, + 57, + 85848, + 0, + 1, + 955506, + 213312, + 0, + 2, + 270652, + 22588, + 4, + 1457325, + 64566, + 4, + 20467, + 1, + 4, + 0, + 141992, + 32, + 100788, + 420, + 1, + 1, + 81663, + 32, + 59498, + 32, + 20142, + 32, + 24588, + 32, + 20744, + 32, + 25933, + 32, + 24623, + 32, + 43053543, + 10, + 53384111, + 14333, + 10, + 43574283, + 26308, + 10, + 16000, + 100, + 16000, + 100, + 962335, + 18, + 2780678, + 6, + 442008, + 1, + 52538055, + 3756, + 18, + 267929, + 18, + 76433006, + 8868, + 18, + 52948122, + 18, + 1995836, + 36, + 3227919, + 12, + 901022, + 1, + 166917843, + 4307, + 36, + 284546, + 36, + 158221314, + 26549, + 36, + 74698472, + 36, + 333849714, + 1, + 254006273, + 72, + 2174038, + 72, + 2261318, + 64571, + 4, + 207616, + 8310, + 4, + 1293828, + 28716, + 63, + 0, + 1, + 1006041, + 43623, + 251, + 0, + 1, + 100181, + 726, + 719, + 0, + 1, + 100181, + 726, + 719, + 0, + 1, + 100181, + 726, + 719, + 0, + 1, + 107878, + 680, + 0, + 1, + 95336, + 1, + 281145, + 18848, + 0, + 1, + 180194, + 159, + 1, + 1, + 158519, + 8942, + 0, + 1, + 159378, + 8813, + 0, + 1, + 107490, + 3298, + 1, + 106057, + 655, + 1, + 1964219, + 24520, + 3 + ] + }, + "dRepActivity": 20, + "dRepDeposit": 500000000, + "dRepVotingThresholds": { + "committeeNoConfidence": 0.6, + "committeeNormal": 0.67, + "hardForkInitiation": 0.6, + "motionNoConfidence": 0.67, + "ppEconomicGroup": 0.67, + "ppGovGroup": 0.75, + "ppNetworkGroup": 0.67, + "ppTechnicalGroup": 0.67, + "treasuryWithdrawal": 0.67, + "updateToConstitution": 0.75 + }, + "executionUnitPrices": { + "priceMemory": 0, + "priceSteps": 0 + }, + "govActionDeposit": 100000000000, + "govActionLifetime": 6, + "maxBlockBodySize": 90112, + "maxBlockExecutionUnits": { + "memory": 62000000000000, + "steps": 20000000000000000 + }, + "maxBlockHeaderSize": 1100, + "maxCollateralInputs": 3, + "maxTxExecutionUnits": { + "memory": 14000000000000, + "steps": 10000000000000000 + }, + "maxTxSize": 25000, + "maxValueSize": 5000, + "minFeeRefScriptCostPerByte": 15, + "minPoolCost": 170000000, + "monetaryExpansion": 3.0e-3, + "poolPledgeInfluence": 0.3, + "poolRetireMaxEpoch": 18, + "poolVotingThresholds": { + "committeeNoConfidence": 0.51, + "committeeNormal": 0.51, + "hardForkInitiation": 0.51, + "motionNoConfidence": 0.51, + "ppSecurityGroup": 0.51 + }, + "protocolVersion": { + "major": 9, + "minor": 0 + }, + "stakeAddressDeposit": 2000000, + "stakePoolDeposit": 500000000, + "stakePoolTargetNum": 500, + "treasuryCut": 0.2, + "txFeeFixed": 0, + "txFeePerByte": 0, + "utxoCostPerByte": 4310 +} diff --git a/lazer/cardano/hermes/infra/seed-spend.signed.json b/lazer/cardano/hermes/infra/seed-spend.signed.json new file mode 100644 index 00000000..ee2a3381 --- /dev/null +++ b/lazer/cardano/hermes/infra/seed-spend.signed.json @@ -0,0 +1,5 @@ +{ + "type": "Tx ConwayEra", + "description": "Ledger Cddl Format", + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d818586ad8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb2400ffa0a0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abe8203590ab9590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a100d9010281825820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e0584031f301f65559513835fb48e290bd6f0f4bfd1cf9daa2bb2765a9bf0e92383b7e110661d7e5ba33aa8c3db2d0f429285df6840b1204469128f84f3d3d6b196c08f5f6" +} diff --git a/lazer/cardano/hermes/infra/submit-seed-tx.sh b/lazer/cardano/hermes/infra/submit-seed-tx.sh new file mode 100755 index 00000000..2e483204 --- /dev/null +++ b/lazer/cardano/hermes/infra/submit-seed-tx.sh @@ -0,0 +1,101 @@ +#!/bin/sh +set -eu + +# Keep sentinel under persistence/ so `rm -rf persistence/` or a fresh volume wipes it. +# (A file at /devnet/.hydra-seed-tx.done survives `docker compose down -v` because ./ is a bind mount.) +SENTINEL=/devnet/persistence/.hydra-seed-tx.done +PYTH_SETUP_TX_ADDR=/devnet/seed-spend.signed.json +INITIAL_UTXO_REF='0000000000000000000000000000000000000000000000000000000000000000#0' +PYTH_OUTPUT_ADDR='addr_test1wrm3tr5zpw9k2nefjtsz66wfzn6flnphr5kd6ak9ufrl3wcqqfyn8' + +HYDRA_HTTP_HOST="${HYDRA_HTTP_HOST:-hydra-node}" +HYDRA_HTTP_PORT="${HYDRA_HTTP_PORT:-4011}" +WS_URL="${HYDRA_WS_URL:-ws://${HYDRA_HTTP_HOST}:${HYDRA_HTTP_PORT}}" +MAX_WAIT="${SEED_TX_MAX_WAIT:-180}" + +if [ ! -f "$PYTH_SETUP_TX_ADDR" ]; then + echo "Missing $PYTH_SETUP_TX_ADDR" >&2 + exit 1 +fi + +mkdir -p /devnet/persistence + +if [ -f "$SENTINEL" ]; then + echo "Seed tx already submitted ($(basename "$SENTINEL") exists)." + exit 0 +fi + +apk add --no-cache curl jq ca-certificates websocat >/dev/null + +api_root() { + curl -sf "http://${HYDRA_HTTP_HOST}:${HYDRA_HTTP_PORT}$1" || true +} + +echo "Waiting for Hydra HTTP API (protocol-parameters)..." +n=0 +until api_root /protocol-parameters | jq -e . >/dev/null 2>&1; do + n=$((n + 1)) + if [ "$n" -ge "$MAX_WAIT" ]; then + echo "Timeout waiting for Hydra API." >&2 + exit 1 + fi + sleep 1 +done + +echo "Waiting for initial UTxO with ref ${INITIAL_UTXO_REF} in /snapshot/utxo..." +n=0 +while true; do + body=$(api_root /snapshot/utxo) + if echo "$body" | jq -e --arg k "$INITIAL_UTXO_REF" --arg a "$PYTH_OUTPUT_ADDR" ' + type == "object" + and (has($k) | not) + and (to_entries | map(.value.address == $a and .value.inlineDatumRaw != null) | any) + ' >/dev/null 2>&1; then + touch "$SENTINEL" + echo "Head already seeded (no fiction UTxO; found output at ${PYTH_OUTPUT_ADDR})." + exit 0 + fi + if echo "$body" | jq -e --arg k "$INITIAL_UTXO_REF" 'type == "object" and has($k)' >/dev/null 2>&1; then + break + fi + n=$((n + 1)) + if [ "$n" -ge "$MAX_WAIT" ]; then + echo "Timeout: initial UTxO not in snapshot. Ensure all Hydra peers are up and connected." >&2 + exit 1 + fi + sleep 1 +done + +MSG=$(jq -c '{tag: "NewTx", transaction: .}' "$PYTH_SETUP_TX_ADDR") +WS_FULL="${WS_URL}?history=no" + +echo "Submitting NewTx via ${WS_FULL} ..." +OUT=$( (sleep 0.3; echo "$MSG"; sleep 4) | websocat "$WS_FULL" 2>&1) || true + +if echo "$OUT" | grep -q '"tag":"TxValid"'; then + mkdir -p "$(dirname "$SENTINEL")" + touch "$SENTINEL" + echo "Seed tx accepted (TxValid)." + exit 0 +fi + +if echo "$OUT" | grep -q '"tag":"TxInvalid"'; then + body=$(api_root /snapshot/utxo) + if echo "$body" | jq -e --arg k "$INITIAL_UTXO_REF" --arg a "$PYTH_OUTPUT_ADDR" ' + type == "object" + and (has($k) | not) + and (to_entries | map(.value.address == $a and .value.inlineDatumRaw != null) | any) + ' >/dev/null 2>&1; then + mkdir -p "$(dirname "$SENTINEL")" + touch "$SENTINEL" + echo "Seed already applied (TxInvalid on replay; snapshot shows seeded output)." + exit 0 + fi + echo "$OUT" | tail -n 3 >&2 + echo "Hydra rejected the seed transaction (TxInvalid)." >&2 + exit 1 +fi + +echo "$OUT" >&2 +echo "Unexpected WebSocket response; not marking done." >&2 +exit 1 diff --git a/lazer/cardano/hermes/server/.gitignore b/lazer/cardano/hermes/server/.gitignore new file mode 100644 index 00000000..9c97bbd4 --- /dev/null +++ b/lazer/cardano/hermes/server/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +.env diff --git a/lazer/cardano/hermes/server/package.json b/lazer/cardano/hermes/server/package.json new file mode 100644 index 00000000..40323f68 --- /dev/null +++ b/lazer/cardano/hermes/server/package.json @@ -0,0 +1,28 @@ +{ + "name": "hermes-server", + "version": "0.0.1", + "type": "module", + "scripts": { + "api": "tsx watch src/index.ts", + "matcher": "tsx watch src/matcher.ts", + "build": "tsc", + "start": "node dist/index.js", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@lucid-evolution/lucid": "^0.4.29", + "@pythnetwork/pyth-lazer-sdk": "^6.2.1", + "axios": "^1.13.6", + "bignumber.js": "^10.0.2", + "blake2b": "^2.1.4", + "dotenv": "^17.3.1", + "ws": "^8.18.2" + }, + "devDependencies": { + "@types/blake2b": "^2.1.3", + "@types/ws": "^8.5.14", + "prettier": "^3.8.1", + "tsx": "^4.19.4", + "typescript": "~5.9.3" + } +} diff --git a/lazer/cardano/hermes/server/pnpm-lock.yaml b/lazer/cardano/hermes/server/pnpm-lock.yaml new file mode 100644 index 00000000..b038359c --- /dev/null +++ b/lazer/cardano/hermes/server/pnpm-lock.yaml @@ -0,0 +1,2025 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@lucid-evolution/lucid': + specifier: ^0.4.29 + version: 0.4.29(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)(fast-check@3.23.2) + '@pythnetwork/pyth-lazer-sdk': + specifier: ^6.2.1 + version: 6.2.1 + axios: + specifier: ^1.13.6 + version: 1.13.6 + bignumber.js: + specifier: ^10.0.2 + version: 10.0.2 + blake2b: + specifier: ^2.1.4 + version: 2.1.4 + dotenv: + specifier: ^17.3.1 + version: 17.3.1 + ws: + specifier: ^8.18.2 + version: 8.20.0 + devDependencies: + '@types/blake2b': + specifier: ^2.1.3 + version: 2.1.3 + '@types/ws': + specifier: ^8.5.14 + version: 8.18.1 + prettier: + specifier: ^3.8.1 + version: 3.8.1 + tsx: + specifier: ^4.19.4 + version: 4.21.0 + typescript: + specifier: ~5.9.3 + version: 5.9.3 + +packages: + + '@anastasia-labs/cardano-multiplatform-lib-browser@6.0.2-2': + resolution: {integrity: sha512-sSPPjO1Zye82YVqrUGIKrli/Zt2pPkZkQd/jv9k6AzjIZdNPD3hvuB2yH6RHeZUO8+K57bu9r7Rlyf7VGbhhTQ==} + + '@anastasia-labs/cardano-multiplatform-lib-browser@6.0.2-3': + resolution: {integrity: sha512-EP5Kr21xPtfEuCM3lR5tCIUQpMQ4Moisig8zD9BqUmBhQr/2ddxuE+MWhBF6tqH1AepzeXqRuTD1ozvdRn49Bw==} + + '@anastasia-labs/cardano-multiplatform-lib-nodejs@6.0.2-2': + resolution: {integrity: sha512-KLYHyJWtFsTUUbIVz9dn5GiCbI4Mrx5mRpDWXa3lVLWFKok6AkvYlyHk4OH4NNa4JBerrHTB6ZJrk75UgKAaMA==} + + '@anastasia-labs/cardano-multiplatform-lib-nodejs@6.0.2-3': + resolution: {integrity: sha512-Jy7QKahRQJgX6OFeuQvPXO0ejKfT9cQ8m3PFLBhbM04jjzFnaxlJJJ5+7qNHe3xdy40fMbMMe2SgAYPJ4gZ2Xw==} + + '@biglup/is-cid@1.0.3': + resolution: {integrity: sha512-R0XPZ/IQhU2TtetSFI9vI+7kJOJYNiCncn5ixEBW+/LNaZCo2HK37Mq3pRNzrM4FryuAkyeqY7Ujmj3I3e3t9g==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + + '@cardano-ogmios/client@6.9.0': + resolution: {integrity: sha512-IsoUVsaMXiYyhWrdVKYOA5PDlX0EZ2gaq4lfk4JelRw6mcWVxemUrMaU2ndvugO9LQ3SCM1nESPgMIU0xe5FWw==} + engines: {node: '>=14'} + + '@cardano-ogmios/schema@6.9.0': + resolution: {integrity: sha512-e7QVLF+dQMIv9p+p5CWQjMfBmkERYRa2wK2AjyehQZCJnecZ0gvTbRqewdX5VW4mVXf6KUfFyphsxWK46Pg6LA==} + engines: {node: '>=14'} + + '@cardano-sdk/core@0.45.10': + resolution: {integrity: sha512-PU/onQuPgsy0CtFKDlHcozGHMTHrigWztTmKq54tL0TdWRcClXbMh5Q63ALcP388ZouPC1nKomOAooVgyrrEfw==} + engines: {node: '>=16.20.2'} + peerDependencies: + rxjs: ^7.4.0 + peerDependenciesMeta: + rxjs: + optional: true + + '@cardano-sdk/crypto@0.2.3': + resolution: {integrity: sha512-jTl8rbocV1XO5DBR6+lGY6Owc/bP+wBg5eO3PttTeKhx/J7o99pyuTa5H36a/XTJwqDwKIXV922QxZR+rfjVbA==} + engines: {node: '>=16.20.2'} + peerDependencies: + '@dcspark/cardano-multiplatform-lib-asmjs': ^3.1.1 + '@dcspark/cardano-multiplatform-lib-browser': ^3.1.1 + '@dcspark/cardano-multiplatform-lib-nodejs': ^3.1.1 + peerDependenciesMeta: + '@dcspark/cardano-multiplatform-lib-asmjs': + optional: true + '@dcspark/cardano-multiplatform-lib-browser': + optional: true + '@dcspark/cardano-multiplatform-lib-nodejs': + optional: true + + '@cardano-sdk/util@0.16.0': + resolution: {integrity: sha512-f0tfX8oiauqAFCyyc/o2Ouezyk83QD4zqLl4DUjZNyCtITL8gBHh25Bkw7RUCGEZ+hf6Qms1n0ui0j3wVY7zRg==} + engines: {node: '>=16.20.2'} + + '@cardanosolutions/json-bigint@1.1.0': + resolution: {integrity: sha512-Pdgz18cSwLKKgheOqW/dqbzNI+CliNT4AdaKaKY/P++J9qLxIB8MITCurlzbaFWV3W4nmK0CRQwI1yvuArmjFg==} + + '@cbor-extract/cbor-extract-darwin-arm64@2.2.2': + resolution: {integrity: sha512-ZKZ/F8US7JR92J4DMct6cLW/Y66o2K576+zjlEN/MevH70bFIsB10wkZEQPLzl2oNh2SMGy55xpJ9JoBRl5DOA==} + cpu: [arm64] + os: [darwin] + + '@cbor-extract/cbor-extract-darwin-x64@2.2.2': + resolution: {integrity: sha512-32b1mgc+P61Js+KW9VZv/c+xRw5EfmOcPx990JbCBSkYJFY0l25VinvyyWfl+3KjibQmAcYwmyzKF9J4DyKP/Q==} + cpu: [x64] + os: [darwin] + + '@cbor-extract/cbor-extract-linux-arm64@2.2.2': + resolution: {integrity: sha512-wfqgzqCAy/Vn8i6WVIh7qZd0DdBFaWBjPdB6ma+Wihcjv0gHqD/mw3ouVv7kbbUNrab6dKEx/w3xQZEdeXIlzg==} + cpu: [arm64] + os: [linux] + + '@cbor-extract/cbor-extract-linux-arm@2.2.2': + resolution: {integrity: sha512-tNg0za41TpQfkhWjptD+0gSD2fggMiDCSacuIeELyb2xZhr7PrhPe5h66Jc67B/5dmpIhI2QOUtv4SBsricyYQ==} + cpu: [arm] + os: [linux] + + '@cbor-extract/cbor-extract-linux-x64@2.2.2': + resolution: {integrity: sha512-rpiLnVEsqtPJ+mXTdx1rfz4RtUGYIUg2rUAZgd1KjiC1SehYUSkJN7Yh+aVfSjvCGtVP0/bfkQkXpPXKbmSUaA==} + cpu: [x64] + os: [linux] + + '@cbor-extract/cbor-extract-win32-x64@2.2.2': + resolution: {integrity: sha512-dI+9P7cfWxkTQ+oE+7Aa6onEn92PHgfWXZivjNheCRmTBDBf2fx6RyTi0cmgpYLnD1KLZK9ZYrMxaPZ4oiXhGA==} + cpu: [x64] + os: [win32] + + '@chainsafe/is-ip@2.1.0': + resolution: {integrity: sha512-KIjt+6IfysQ4GCv66xihEitBjvhU/bixbbbFxdJ1sqCp4uJ0wuZiYBPhksZoy4lfaF0k9cwNzY5upEW/VWdw3w==} + + '@chainsafe/netmask@2.0.0': + resolution: {integrity: sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg==} + + '@dnsquery/dns-packet@6.1.1': + resolution: {integrity: sha512-WXTuFvL3G+74SchFAtz3FgIYVOe196ycvGsMgvSH/8Goptb1qpIQtIuM4SOK9G9lhMWYpHxnXyy544ZhluFOew==} + engines: {node: '>=6'} + + '@effect/platform@0.71.7': + resolution: {integrity: sha512-Ttw8OhbcP1x5cPgcX4VdnDSWrskVdUrf9bO3eDd++TTcQzEiYVu9GZJaSMvz6Yqzfzt+1tIKoKi2jp6dLdJ9dg==} + peerDependencies: + effect: ^3.11.10 + + '@effect/schema@0.66.16': + resolution: {integrity: sha512-sT/k5NOgKslGPzs3DUaCFuM6g2JQoIIT8jpwEorAZooplPIMK2xIspr7ECz6pp6Dc7Wz/ppXGk7HVyGZQsIYEQ==} + deprecated: this package has been merged into the main effect package + peerDependencies: + effect: ^3.1.3 + fast-check: ^3.13.2 + + '@effect/schema@0.68.27': + resolution: {integrity: sha512-/rmIb+4QaQTecdTfeYSZtNikIV+BeIbYDl/hpgBTaS96en7pKNW5hcygFQhdocjKguIL7Y/be+oUrVafWV60ew==} + deprecated: this package has been merged into the main effect package + peerDependencies: + effect: ^3.5.7 + + '@emurgo/cardano-message-signing-browser@1.1.0': + resolution: {integrity: sha512-LyeiGIqCyZu9DZnKsi4wlBjZA1MN+uy3Cqpb5J6RZWvFXDJnCoxrYB/EixUiGRD/la4WsldBgtPsrIHyGsVkpg==} + + '@emurgo/cardano-message-signing-nodejs@1.1.0': + resolution: {integrity: sha512-PQRc8K8wZshEdmQenNUzVtiI8oJNF/1uAnBhidee5C4o1l2mDLOW+ur46HWHIFKQ6x8mSJTllcjMscHgzju0gQ==} + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@foxglove/crc@0.0.3': + resolution: {integrity: sha512-DjIZsnL3CyP/yQ/vUYA9cjrD0a/8YXejI5ZmsaOiT16cLfZcTwaCxIN01/ys4jsy+dZCQ/9DnWFn7AEFbiMDaA==} + + '@harmoniclabs/bigint-utils@1.0.0': + resolution: {integrity: sha512-OhZMHcdtH2hHKMlxWFHf71PmKHdoi9ARpjS9mUu0/cd8VWDDjT7VQoQwC5NN/68iyO4O5Dojrvrp9tjG5BDABA==} + + '@harmoniclabs/biguint@1.0.0': + resolution: {integrity: sha512-5DyCIBDL4W+7ffR1IJSbGrCG4xEYxAlFH5gCNF42qtyL5ltwZ92Ae1MyXpHM2TUPy7ocSTqlLUsOdy+SvqVVPw==} + + '@harmoniclabs/bitstream@1.0.0': + resolution: {integrity: sha512-Ed/I46IuCiytE5QiMmmUo9kPJcypM7OuUqoRaAXUALL5C6LKLpT6kYE1qeuhLkx2/WvkHT18jcOX6jhM/nmqoA==} + + '@harmoniclabs/bytestring@1.0.0': + resolution: {integrity: sha512-d5m10O0okKc6QNX0pSRriFTkk/kNMnMBGbo5X3kEZwKaXTI4tDVoTZBL7bwbYHwOEdSxWJjVtlO9xtB7ZrYZNg==} + + '@harmoniclabs/cbor@1.6.6': + resolution: {integrity: sha512-nOcts7PhkKCbqPKwP3/IsIQACwJvqchpT88cwvKspB+oR09YfB1LC1NrUTsFg1DusLRydVsOwR07KgYTF5uNOA==} + + '@harmoniclabs/crypto@0.2.5': + resolution: {integrity: sha512-t2saWMFWBx8tOHotiYTTfQKhPGpWT4AMLXxq3u0apShVXNV0vgL0gEgSMudBjES/wrKByCqa2xmU70gadz26hA==} + + '@harmoniclabs/obj-utils@1.0.0': + resolution: {integrity: sha512-EO1bQBZAORrutcP+leP5YNDwNd/9TOE23VEvs3ktniXg6w0knUrLjUIl2Pkcbs/D1VQxqmsNpXho+vaMj00qxA==} + + '@harmoniclabs/pair@1.0.0': + resolution: {integrity: sha512-D9OBowsUsy1LctHxWzd9AngTzoo5x3rBiJ0gu579t41Q23pb+VNx1euEfluUEiaYbgljcl1lb/4D1fFTZd1tRQ==} + + '@harmoniclabs/plutus-data@1.2.6': + resolution: {integrity: sha512-rF046GZ07XDpjZBNybALKYSycjxCLzXKbhLylu9pRuZiii5fVXReEfgtLB29TsPBvGY6ZBeiyHgJnLgm+huZBw==} + peerDependencies: + '@harmoniclabs/bytestring': ^1.0.0 + '@harmoniclabs/cbor': ^1.3.0 + + '@harmoniclabs/uint8array-utils@1.0.4': + resolution: {integrity: sha512-Z454prSbX4geXGHyjjcn9vm6u9NsD3VJykv8f8yE1VjIXSPitaLPEnm8u2+B+GMp1chYlLilOq+kW4OvJ6y28A==} + + '@harmoniclabs/uplc@1.4.1': + resolution: {integrity: sha512-sELKStjxPBPBxBMylU4oBSUe0/8eJe2HqRblNSwrMu8Fso4YpSPDqHZ33iDZ8QAadVUsT5r2EQKX0TLrj7qXvQ==} + peerDependencies: + '@harmoniclabs/bytestring': ^1.0.0 + '@harmoniclabs/cbor': ^1.3.0 + '@harmoniclabs/crypto': ^0.3.0-dev0 + '@harmoniclabs/pair': ^1.0.0 + '@harmoniclabs/plutus-data': ^1.2.4 + + '@isaacs/ttlcache@1.4.1': + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@libp2p/interface@3.1.0': + resolution: {integrity: sha512-RE7/XyvC47fQBe1cHxhMvepYKa5bFCUyFrrpj8PuM0E7JtzxU7F+Du5j4VXbg2yLDcToe0+j8mB7jvwE2AThYw==} + + '@lucid-evolution/core-types@0.1.22': + resolution: {integrity: sha512-2ffw82PAjB9wdnW62zWh5J8Wkqrr+sMrdXtndejdu4UYmTdmf7rIClr+AfKO8IStCciVcNT/wQj59PyYu/Jg1Q==} + + '@lucid-evolution/core-utils@0.1.16': + resolution: {integrity: sha512-fNKZiGl1h6tf48bji067uxHZpDlhkrIDrwhZLt5DQC/c6GVdZb4TSvqgs7MOmMqp1dj9dy6NDYWnCHeTqZAhJw==} + + '@lucid-evolution/crc8@0.1.8': + resolution: {integrity: sha512-88+/S6n+sPgxYtG05rvbJDVb8MoFGzckkR3p26uGrzngYzlJGfxBWIzNhVwfI2mgINPo2C5lkZW3GYnfY0MjuA==} + + '@lucid-evolution/lucid@0.4.29': + resolution: {integrity: sha512-+9pXlHivIGE4xJC6EZ62vtOBfgHgPpbJHgd7d6Ztk3lmbBwsM1PZVQ1WSE2upXSvqGE8KT/99IxmZ3kKfbtDUg==} + + '@lucid-evolution/plutus@0.1.29': + resolution: {integrity: sha512-GHmq9Pso+xeFszwKAd9jvRFnmnV4fRKdm+OHYLrS58yh3uazKr9VR+amtT9SmKufoLy/gNo5sL7i6gcNSW+yIg==} + + '@lucid-evolution/provider@0.1.90': + resolution: {integrity: sha512-8vzVDlWJiDfuvuE2Un18N5uTK8qDkVB5GiglwoDV/qgBNRljQjiih53LbhcGa4KMXgufjZNyNDH854jFkJ95cg==} + + '@lucid-evolution/sign_data@0.1.25': + resolution: {integrity: sha512-ZDDl3SyO3Lf+/ji9u0Fg6I9oNs+tW//aHkgz4NlS+9xbx2bT9YU+mV9ZLLjWSZVGTb0TbzT4NGvVqdgRNspdYQ==} + + '@lucid-evolution/uplc@0.2.20': + resolution: {integrity: sha512-+40qeHmjMnM4Sjdq9JAf190a1t3TMbV1vegVLQGqt2AouOkIunZfziBZwuaqcgUVVbynW+j2Qx2ijK83Pap4XQ==} + + '@lucid-evolution/utils@0.1.66': + resolution: {integrity: sha512-sp6vsxrc0u9rYgb4ExRP4LRQM0oK6mVxqt70axK0T4DSS06KYtCqUWX6kjcOHY8jxDGfjK5RLh9hBY+Gul4OSQ==} + + '@lucid-evolution/wallet@0.1.72': + resolution: {integrity: sha512-keGeDV4jUX2MAld79zAGja4mFNQ9FP4HJM8OB8DEnakewTVG4fk38SMSfvuQAh6yH8ZxTNoGUphrMSeVFU4OjQ==} + + '@multiformats/dns@1.0.13': + resolution: {integrity: sha512-yr4bxtA3MbvJ+2461kYIYMsiiZj/FIqKI64hE4SdvWJUdWF9EtZLar38juf20Sf5tguXKFUruluswAO6JsjS2w==} + + '@multiformats/mafmt@12.1.6': + resolution: {integrity: sha512-tlJRfL21X+AKn9b5i5VnaTD6bNttpSpcqwKVmDmSHLwxoz97fAHaepqFOk/l1fIu94nImIXneNbhsJx/RQNIww==} + + '@multiformats/multiaddr@12.5.1': + resolution: {integrity: sha512-+DDlr9LIRUS8KncI1TX/FfUn8F2dl6BIxJgshS/yFQCNB5IAF0OGzcwB39g5NLE22s4qqDePv0Qof6HdpJ/4aQ==} + + '@multiformats/multiaddr@13.0.1': + resolution: {integrity: sha512-XToN915cnfr6Lr9EdGWakGJbPT0ghpg/850HvdC+zFX8XvpLZElwa8synCiwa8TuvKNnny6m8j8NVBNCxhIO3g==} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@pythnetwork/pyth-lazer-sdk@6.2.1': + resolution: {integrity: sha512-+d+ATApOBF5z3YvqwP/5R42xr9vWpLOvbAFWDWldYiltlH8eU9PaGgeczgCs3it3STpnL+8jTXsUBhqv9T94Aw==} + engines: {node: ^24.0.0} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@sinclair/typebox@0.32.35': + resolution: {integrity: sha512-Ul3YyOTU++to8cgNkttakC0dWvpERr6RYoHO2W47DLbFvrwBDJUY31B1sImH6JZSYc4Kt4PyHtoPNu+vL2r2dA==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@types/blake2b@2.1.3': + resolution: {integrity: sha512-MFCdX0MNxFBP/xEILO5Td0kv6nI7+Q2iRWZbTL/yzH2/eDVZS5Wd1LHdsmXClvsCyzqaZfHFzZaN6BUeUCfSDA==} + + '@types/json-bigint@1.0.4': + resolution: {integrity: sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==} + + '@types/node@25.5.0': + resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@zxing/text-encoding@0.9.0': + resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} + + abort-error@1.0.1: + resolution: {integrity: sha512-fxqCblJiIPdSXIUrxI0PL+eJG49QdP9SQ70qtB65MVAoMr2rASlOyAbJFOylfB467F/f+5BCLJJq58RYi7mGfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} + + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bech32@2.0.0: + resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} + + bignumber.js@10.0.2: + resolution: {integrity: sha512-E8Wp9O06QA6lneJ4aRUXKYf/1GIomqUEmUMwtIOMtDxf1U52ffJY+y7JBk/8wRafA8qOIqLnXQGqonYXZdBnFQ==} + + bip39@3.1.0: + resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} + + blake2b-wasm@2.4.0: + resolution: {integrity: sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==} + + blake2b@2.1.4: + resolution: {integrity: sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + cbor-extract@2.2.2: + resolution: {integrity: sha512-hlSxxI9XO2yQfe9g6msd3g4xCfDqK5T5P0fRMLuaLHhxn4ViPrm+a+MUfhrvH2W962RGxcBwEGzLQyjbDG1gng==} + hasBin: true + + cbor-x@1.6.4: + resolution: {integrity: sha512-UGKHjp6RHC6QuZ2yy5LCKm7MojM4716DwoSaqwQpaH4DvZvbBTGcoDNTiG9Y2lByXZYFEs9WRkS5tLl96IrF1Q==} + + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + effect@3.21.0: + resolution: {integrity: sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + find-my-way-ts@0.1.6: + resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + fraction.js@4.0.1: + resolution: {integrity: sha512-NQYzZw8MUsxSZFQo6E8tKOlmSd/BlDTNOR4puXFSHSwFwNaIlmbortQy5PDN/KnVQ4xWG2NtN0J0hjPw7eE06A==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + + hashlru@2.3.0: + resolution: {integrity: sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + i@0.3.7: + resolution: {integrity: sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==} + engines: {node: '>=0.4'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + iso-url@1.2.1: + resolution: {integrity: sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng==} + engines: {node: '>=12'} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + libsodium-sumo@0.7.16: + resolution: {integrity: sha512-x6atrz2AdXCJg6G709x9W9TTJRI6/0NcL5dD0l5GGVqNE48UJmDsjO4RUWYTeyXXUpg+NXZ2SHECaZnFRYzwGA==} + + libsodium-wrappers-sumo@0.7.16: + resolution: {integrity: sha512-gR0JEFPeN3831lB9+ogooQk0KH4K5LSMIO5Prd5Q5XYR2wHFtZfPg0eP7t1oJIWq+UIzlU4WVeBxZ97mt28tXw==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + main-event@1.0.1: + resolution: {integrity: sha512-NWtdGrAca/69fm6DIVd8T9rtfDII4Q8NQbIbsKQq2VzS9eqOGYs8uaNQjcuaCq/d9H/o625aOTJX2Qoxzqw0Pw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + multiformats@13.4.2: + resolution: {integrity: sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==} + + multipasta@0.2.7: + resolution: {integrity: sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==} + + nanoassert@2.0.0: + resolution: {integrity: sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build-optional-packages@5.1.1: + resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} + hasBin: true + + npm@9.9.4: + resolution: {integrity: sha512-NzcQiLpqDuLhavdyJ2J3tGJ/ni/ebcqHVFZkv1C4/6lblraUPbPgCJ4Vhb4oa3FFhRa2Yj9gA58jGH/ztKueNQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/run-script' + - abbrev + - archy + - cacache + - chalk + - ci-info + - cli-columns + - cli-table3 + - columnify + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - normalize-package-data + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - npmlog + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - sigstore + - spdx-expression-parse + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic + + p-queue@9.1.0: + resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==} + engines: {node: '>=20'} + + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress-events@1.0.1: + resolution: {integrity: sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + serialize-error@8.1.0: + resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==} + engines: {node: '>=10'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-custom-error@3.3.1: + resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==} + engines: {node: '>=14.0.0'} + + ts-log@2.2.7: + resolution: {integrity: sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uint8-varint@2.0.4: + resolution: {integrity: sha512-FwpTa7ZGA/f/EssWAb5/YV6pHgVF1fViKdW8cWaEarjB8t7NyofSWBdOTyFPaGuUG4gx3v1O3PQ8etsiOs3lcw==} + + uint8arraylist@2.4.8: + resolution: {integrity: sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==} + + uint8arrays@5.1.0: + resolution: {integrity: sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==} + + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + utf8-codec@1.0.0: + resolution: {integrity: sha512-S/QSLezp3qvG4ld5PUfXiH7mCFxLKjSVZRFkB3DOjgwHuJPFDkInAXc/anf7BAbHt/D38ozDzL+QMZ6/7gsI6w==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + web-encoding@1.1.5: + resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@anastasia-labs/cardano-multiplatform-lib-browser@6.0.2-2': {} + + '@anastasia-labs/cardano-multiplatform-lib-browser@6.0.2-3': {} + + '@anastasia-labs/cardano-multiplatform-lib-nodejs@6.0.2-2': {} + + '@anastasia-labs/cardano-multiplatform-lib-nodejs@6.0.2-3': {} + + '@biglup/is-cid@1.0.3': + dependencies: + '@multiformats/mafmt': 12.1.6 + '@multiformats/multiaddr': 12.5.1 + iso-url: 1.2.1 + multiformats: 13.4.2 + uint8arrays: 5.1.0 + + '@cardano-ogmios/client@6.9.0': + dependencies: + '@cardano-ogmios/schema': 6.9.0 + '@cardanosolutions/json-bigint': 1.1.0 + '@types/json-bigint': 1.0.4 + bech32: 2.0.0 + cross-fetch: 3.2.0 + fastq: 1.20.1 + isomorphic-ws: 4.0.1(ws@7.5.10) + nanoid: 3.3.11 + ts-custom-error: 3.3.1 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@cardano-ogmios/schema@6.9.0': {} + + '@cardano-sdk/core@0.45.10': + dependencies: + '@biglup/is-cid': 1.0.3 + '@cardano-ogmios/client': 6.9.0 + '@cardano-ogmios/schema': 6.9.0 + '@cardano-sdk/crypto': 0.2.3 + '@cardano-sdk/util': 0.16.0 + '@foxglove/crc': 0.0.3 + '@scure/base': 1.2.6 + fraction.js: 4.0.1 + ip-address: 9.0.5 + lodash: 4.17.23 + ts-custom-error: 3.3.1 + ts-log: 2.2.7 + web-encoding: 1.1.5 + transitivePeerDependencies: + - '@dcspark/cardano-multiplatform-lib-asmjs' + - '@dcspark/cardano-multiplatform-lib-browser' + - '@dcspark/cardano-multiplatform-lib-nodejs' + - bufferutil + - encoding + - react-native-b4a + - utf-8-validate + + '@cardano-sdk/crypto@0.2.3': + dependencies: + '@cardano-sdk/util': 0.16.0 + blake2b: 2.1.4 + i: 0.3.7 + libsodium-wrappers-sumo: 0.7.16 + lodash: 4.17.23 + npm: 9.9.4 + pbkdf2: 3.1.5 + ts-custom-error: 3.3.1 + ts-log: 2.2.7 + transitivePeerDependencies: + - react-native-b4a + + '@cardano-sdk/util@0.16.0': + dependencies: + bech32: 2.0.0 + lodash: 4.17.23 + serialize-error: 8.1.0 + ts-custom-error: 3.3.1 + ts-log: 2.2.7 + type-fest: 2.19.0 + + '@cardanosolutions/json-bigint@1.1.0': {} + + '@cbor-extract/cbor-extract-darwin-arm64@2.2.2': + optional: true + + '@cbor-extract/cbor-extract-darwin-x64@2.2.2': + optional: true + + '@cbor-extract/cbor-extract-linux-arm64@2.2.2': + optional: true + + '@cbor-extract/cbor-extract-linux-arm@2.2.2': + optional: true + + '@cbor-extract/cbor-extract-linux-x64@2.2.2': + optional: true + + '@cbor-extract/cbor-extract-win32-x64@2.2.2': + optional: true + + '@chainsafe/is-ip@2.1.0': {} + + '@chainsafe/netmask@2.0.0': + dependencies: + '@chainsafe/is-ip': 2.1.0 + + '@dnsquery/dns-packet@6.1.1': + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + utf8-codec: 1.0.0 + + '@effect/platform@0.71.7(effect@3.21.0)': + dependencies: + effect: 3.21.0 + find-my-way-ts: 0.1.6 + multipasta: 0.2.7 + + '@effect/schema@0.66.16(effect@3.21.0)(fast-check@3.23.2)': + dependencies: + effect: 3.21.0 + fast-check: 3.23.2 + + '@effect/schema@0.68.27(effect@3.21.0)': + dependencies: + effect: 3.21.0 + fast-check: 3.23.2 + + '@emurgo/cardano-message-signing-browser@1.1.0': {} + + '@emurgo/cardano-message-signing-nodejs@1.1.0': {} + + '@esbuild/aix-ppc64@0.27.4': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + + '@foxglove/crc@0.0.3': {} + + '@harmoniclabs/bigint-utils@1.0.0': + dependencies: + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/biguint@1.0.0': {} + + '@harmoniclabs/bitstream@1.0.0': + dependencies: + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/bytestring@1.0.0': + dependencies: + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/cbor@1.6.6': + dependencies: + '@harmoniclabs/bytestring': 1.0.0 + '@harmoniclabs/obj-utils': 1.0.0 + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/crypto@0.2.5': + dependencies: + '@harmoniclabs/bitstream': 1.0.0 + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/obj-utils@1.0.0': {} + + '@harmoniclabs/pair@1.0.0': {} + + '@harmoniclabs/plutus-data@1.2.6(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)': + dependencies: + '@harmoniclabs/biguint': 1.0.0 + '@harmoniclabs/bytestring': 1.0.0 + '@harmoniclabs/cbor': 1.6.6 + '@harmoniclabs/crypto': 0.2.5 + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@harmoniclabs/uint8array-utils@1.0.4': {} + + '@harmoniclabs/uplc@1.4.1(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)(@harmoniclabs/plutus-data@1.2.6(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6))': + dependencies: + '@harmoniclabs/bigint-utils': 1.0.0 + '@harmoniclabs/bytestring': 1.0.0 + '@harmoniclabs/cbor': 1.6.6 + '@harmoniclabs/crypto': 0.2.5 + '@harmoniclabs/pair': 1.0.0 + '@harmoniclabs/plutus-data': 1.2.6(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6) + '@harmoniclabs/uint8array-utils': 1.0.4 + + '@isaacs/ttlcache@1.4.1': {} + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@libp2p/interface@3.1.0': + dependencies: + '@multiformats/dns': 1.0.13 + '@multiformats/multiaddr': 13.0.1 + main-event: 1.0.1 + multiformats: 13.4.2 + progress-events: 1.0.1 + uint8arraylist: 2.4.8 + + '@lucid-evolution/core-types@0.1.22': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + + '@lucid-evolution/core-utils@0.1.16': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-2 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-2 + + '@lucid-evolution/crc8@0.1.8': {} + + '@lucid-evolution/lucid@0.4.29(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)(fast-check@3.23.2)': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@effect/schema': 0.66.16(effect@3.21.0)(fast-check@3.23.2) + '@emurgo/cardano-message-signing-nodejs': 1.1.0 + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + '@lucid-evolution/plutus': 0.1.29 + '@lucid-evolution/provider': 0.1.90(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + '@lucid-evolution/sign_data': 0.1.25 + '@lucid-evolution/uplc': 0.2.20 + '@lucid-evolution/utils': 0.1.66(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + '@lucid-evolution/wallet': 0.1.72(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + effect: 3.21.0 + transitivePeerDependencies: + - '@dcspark/cardano-multiplatform-lib-asmjs' + - '@dcspark/cardano-multiplatform-lib-browser' + - '@dcspark/cardano-multiplatform-lib-nodejs' + - '@harmoniclabs/bytestring' + - '@harmoniclabs/cbor' + - '@harmoniclabs/crypto' + - '@harmoniclabs/pair' + - bufferutil + - encoding + - fast-check + - react-native-b4a + - rxjs + - utf-8-validate + + '@lucid-evolution/plutus@0.1.29': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + '@sinclair/typebox': 0.32.35 + + '@lucid-evolution/provider@0.1.90(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@effect/platform': 0.71.7(effect@3.21.0) + '@effect/schema': 0.68.27(effect@3.21.0) + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + '@lucid-evolution/utils': 0.1.66(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + '@lucid-evolution/wallet': 0.1.72(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + effect: 3.21.0 + transitivePeerDependencies: + - '@dcspark/cardano-multiplatform-lib-asmjs' + - '@dcspark/cardano-multiplatform-lib-browser' + - '@dcspark/cardano-multiplatform-lib-nodejs' + - '@harmoniclabs/bytestring' + - '@harmoniclabs/cbor' + - '@harmoniclabs/crypto' + - '@harmoniclabs/pair' + - bufferutil + - encoding + - react-native-b4a + - rxjs + - utf-8-validate + + '@lucid-evolution/sign_data@0.1.25': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@emurgo/cardano-message-signing-browser': 1.1.0 + '@emurgo/cardano-message-signing-nodejs': 1.1.0 + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + + '@lucid-evolution/uplc@0.2.20': {} + + '@lucid-evolution/utils@0.1.66(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@cardano-sdk/core': 0.45.10 + '@effect/schema': 0.68.27(effect@3.21.0) + '@harmoniclabs/plutus-data': 1.2.6(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6) + '@harmoniclabs/uplc': 1.4.1(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)(@harmoniclabs/plutus-data@1.2.6(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)) + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + '@lucid-evolution/crc8': 0.1.8 + '@lucid-evolution/plutus': 0.1.29 + '@lucid-evolution/uplc': 0.2.20 + bip39: 3.1.0 + cbor-x: 1.6.4 + effect: 3.21.0 + transitivePeerDependencies: + - '@dcspark/cardano-multiplatform-lib-asmjs' + - '@dcspark/cardano-multiplatform-lib-browser' + - '@dcspark/cardano-multiplatform-lib-nodejs' + - '@harmoniclabs/bytestring' + - '@harmoniclabs/cbor' + - '@harmoniclabs/crypto' + - '@harmoniclabs/pair' + - bufferutil + - encoding + - react-native-b4a + - rxjs + - utf-8-validate + + '@lucid-evolution/wallet@0.1.72(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0)': + dependencies: + '@anastasia-labs/cardano-multiplatform-lib-browser': 6.0.2-3 + '@anastasia-labs/cardano-multiplatform-lib-nodejs': 6.0.2-3 + '@lucid-evolution/core-types': 0.1.22 + '@lucid-evolution/core-utils': 0.1.16 + '@lucid-evolution/sign_data': 0.1.25 + '@lucid-evolution/utils': 0.1.66(@harmoniclabs/bytestring@1.0.0)(@harmoniclabs/cbor@1.6.6)(@harmoniclabs/crypto@0.2.5)(@harmoniclabs/pair@1.0.0) + bip39: 3.1.0 + transitivePeerDependencies: + - '@dcspark/cardano-multiplatform-lib-asmjs' + - '@dcspark/cardano-multiplatform-lib-browser' + - '@dcspark/cardano-multiplatform-lib-nodejs' + - '@harmoniclabs/bytestring' + - '@harmoniclabs/cbor' + - '@harmoniclabs/crypto' + - '@harmoniclabs/pair' + - bufferutil + - encoding + - react-native-b4a + - rxjs + - utf-8-validate + + '@multiformats/dns@1.0.13': + dependencies: + '@dnsquery/dns-packet': 6.1.1 + '@libp2p/interface': 3.1.0 + hashlru: 2.3.0 + p-queue: 9.1.0 + progress-events: 1.0.1 + uint8arrays: 5.1.0 + + '@multiformats/mafmt@12.1.6': + dependencies: + '@multiformats/multiaddr': 12.5.1 + + '@multiformats/multiaddr@12.5.1': + dependencies: + '@chainsafe/is-ip': 2.1.0 + '@chainsafe/netmask': 2.0.0 + '@multiformats/dns': 1.0.13 + abort-error: 1.0.1 + multiformats: 13.4.2 + uint8-varint: 2.0.4 + uint8arrays: 5.1.0 + + '@multiformats/multiaddr@13.0.1': + dependencies: + '@chainsafe/is-ip': 2.1.0 + multiformats: 13.4.2 + uint8-varint: 2.0.4 + uint8arrays: 5.1.0 + + '@noble/hashes@1.8.0': {} + + '@pythnetwork/pyth-lazer-sdk@6.2.1': + dependencies: + '@isaacs/ttlcache': 1.4.1 + buffer: 6.0.3 + isomorphic-ws: 5.0.0(ws@8.20.0) + ts-log: 2.2.7 + ws: 8.20.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@scure/base@1.2.6': {} + + '@sinclair/typebox@0.32.35': {} + + '@standard-schema/spec@1.1.0': {} + + '@types/blake2b@2.1.3': {} + + '@types/json-bigint@1.0.4': {} + + '@types/node@25.5.0': + dependencies: + undici-types: 7.18.2 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.5.0 + + '@zxing/text-encoding@0.9.0': + optional: true + + abort-error@1.0.1: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios@1.13.6: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + b4a@1.8.0: {} + + base64-js@1.5.1: {} + + bech32@2.0.0: {} + + bignumber.js@10.0.2: {} + + bip39@3.1.0: + dependencies: + '@noble/hashes': 1.8.0 + + blake2b-wasm@2.4.0: + dependencies: + b4a: 1.8.0 + nanoassert: 2.0.0 + transitivePeerDependencies: + - react-native-b4a + + blake2b@2.1.4: + dependencies: + blake2b-wasm: 2.4.0 + nanoassert: 2.0.0 + transitivePeerDependencies: + - react-native-b4a + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + cbor-extract@2.2.2: + dependencies: + node-gyp-build-optional-packages: 5.1.1 + optionalDependencies: + '@cbor-extract/cbor-extract-darwin-arm64': 2.2.2 + '@cbor-extract/cbor-extract-darwin-x64': 2.2.2 + '@cbor-extract/cbor-extract-linux-arm': 2.2.2 + '@cbor-extract/cbor-extract-linux-arm64': 2.2.2 + '@cbor-extract/cbor-extract-linux-x64': 2.2.2 + '@cbor-extract/cbor-extract-win32-x64': 2.2.2 + optional: true + + cbor-x@1.6.4: + optionalDependencies: + cbor-extract: 2.2.2 + + cipher-base@1.0.7: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + core-util-is@1.0.3: {} + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.7 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.3 + sha.js: 2.4.12 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.7 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: + optional: true + + dotenv@17.3.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + effect@3.21.0: + dependencies: + '@standard-schema/spec': 1.1.0 + fast-check: 3.23.2 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + + eventemitter3@5.0.4: {} + + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + find-my-way-ts@0.1.6: {} + + follow-redirects@1.15.11: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fraction.js@4.0.1: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + generator-function@2.0.1: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + gopd@1.2.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hash-base@3.1.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + hashlru@2.3.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + i@0.3.7: {} + + ieee754@1.2.1: {} + + inherits@2.0.4: {} + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + iso-url@1.2.1: {} + + isomorphic-ws@4.0.1(ws@7.5.10): + dependencies: + ws: 7.5.10 + + isomorphic-ws@5.0.0(ws@8.20.0): + dependencies: + ws: 8.20.0 + + jsbn@1.1.0: {} + + libsodium-sumo@0.7.16: {} + + libsodium-wrappers-sumo@0.7.16: + dependencies: + libsodium-sumo: 0.7.16 + + lodash@4.17.23: {} + + main-event@1.0.1: {} + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + multiformats@13.4.2: {} + + multipasta@0.2.7: {} + + nanoassert@2.0.0: {} + + nanoid@3.3.11: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build-optional-packages@5.1.1: + dependencies: + detect-libc: 2.1.2 + optional: true + + npm@9.9.4: {} + + p-queue@9.1.0: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-timeout@7.0.1: {} + + pbkdf2@3.1.5: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + to-buffer: 1.2.2 + + possible-typed-array-names@1.1.0: {} + + prettier@3.8.1: {} + + process-nextick-args@2.0.1: {} + + progress-events@1.0.1: {} + + proxy-from-env@1.1.0: {} + + pure-rand@6.1.0: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + resolve-pkg-maps@1.0.0: {} + + reusify@1.1.0: {} + + ripemd160@2.0.3: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + serialize-error@8.1.0: + dependencies: + type-fest: 0.20.2 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + sprintf-js@1.1.3: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + tr46@0.0.3: {} + + ts-custom-error@3.3.1: {} + + ts-log@2.2.7: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.4 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + + type-fest@0.20.2: {} + + type-fest@2.19.0: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript@5.9.3: {} + + uint8-varint@2.0.4: + dependencies: + uint8arraylist: 2.4.8 + uint8arrays: 5.1.0 + + uint8arraylist@2.4.8: + dependencies: + uint8arrays: 5.1.0 + + uint8arrays@5.1.0: + dependencies: + multiformats: 13.4.2 + + undici-types@7.18.2: {} + + utf8-codec@1.0.0: {} + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.20 + + web-encoding@1.1.5: + dependencies: + util: 0.12.5 + optionalDependencies: + '@zxing/text-encoding': 0.9.0 + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + ws@7.5.10: {} + + ws@8.20.0: {} diff --git a/lazer/cardano/hermes/server/src/index.ts b/lazer/cardano/hermes/server/src/index.ts new file mode 100644 index 00000000..8ddea60e --- /dev/null +++ b/lazer/cardano/hermes/server/src/index.ts @@ -0,0 +1,203 @@ +import "dotenv/config"; +import { createServer } from "node:http"; +import { WebSocketServer } from "ws"; +import type WebSocket from "ws"; +import type { + Action, + ClientMessage, + Fill, + Order, + PositionSummary, + RollingAverages, + ServerMessage, + Side, +} from "./types.js"; +import { createBtcPriceStream } from "./streams/btcPrice.js"; +import { createOrderbookStream } from "./streams/orderbook.js"; +import { createPositionsStream } from "./streams/positions.js"; +import { createMarket } from "./offchain/index.js"; +import { handleRestRequest } from "./rest.js"; + +const PORT = 8080; +const AVG_WINDOW = 20; +const MAX_ORDERS_SERVER = 50; // kept in memory for rolling average computation + +// ── State ───────────────────────────────────────────────────────────────────── + +// eslint-disable-next-line prefer-const +let currentMarket!: import("./types.js").Market; // set in async IIFE before first WS connection +let orderWindow: Order[] = []; +let positionSummary: PositionSummary = { + upContracts: 0, + upAvgPrice: 0, + downContracts: 0, + downAvgPrice: 0, +}; + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +function computeRollingAverages(orders: Order[]): RollingAverages { + const window = orders.slice(0, AVG_WINDOW); + const avg = (side: Side, action: Action): number => { + const bucket = window.filter((o) => o.side === side && o.action === action); + if (bucket.length === 0) return 0.5; + return bucket.reduce((sum, o) => sum + o.price, 0) / bucket.length; + }; + return { + upBuyAvg: avg("UP", "BUY"), + upSellAvg: avg("UP", "SELL"), + downBuyAvg: avg("DOWN", "BUY"), + downSellAvg: avg("DOWN", "SELL"), + }; +} + +function updatePositionSummary( + prev: PositionSummary, + fill: Fill, +): PositionSummary { + if (fill.side === "UP") { + const total = prev.upContracts + fill.quantity; + const avgPrice = + total === 0 + ? 0 + : (prev.upAvgPrice * prev.upContracts + fill.price * fill.quantity) / + total; + return { ...prev, upContracts: total, upAvgPrice: avgPrice }; + } else { + const total = prev.downContracts + fill.quantity; + const avgPrice = + total === 0 + ? 0 + : (prev.downAvgPrice * prev.downContracts + + fill.price * fill.quantity) / + total; + return { ...prev, downContracts: total, downAvgPrice: avgPrice }; + } +} + +function send(ws: WebSocket, msg: ServerMessage): void { + if (ws.readyState === ws.OPEN) { + ws.send(JSON.stringify(msg)); + } +} + +function broadcast(wss: WebSocketServer, msg: ServerMessage): void { + wss.clients.forEach((client) => send(client, msg)); +} + +// ── Server ──────────────────────────────────────────────────────────────────── + +const httpServer = createServer(handleRestRequest); +const wss = new WebSocketServer({ server: httpServer }); +httpServer.listen(PORT, () => { + console.log(`[server] listening on http://localhost:${PORT}`); +}); + +// ── Market lifecycle ────────────────────────────────────────────────────────── + +function resetMarketState(): void { + orderWindow = []; + positionSummary = { + upContracts: 0, + upAvgPrice: 0, + downContracts: 0, + downAvgPrice: 0, + }; +} + +async function startNextMarket(): Promise { + currentMarket = await createMarket(); + resetMarketState(); + console.log( + `[server] market ${currentMarket.id} started, strikePrice=${currentMarket.strikePrice}, ends ${new Date(currentMarket.endTime).toISOString()}`, + ); + broadcast(wss, { type: "market_started", data: { market: currentMarket } }); + scheduleNextMarket(); +} + +function scheduleNextMarket(): void { + const remaining = Math.max(0, currentMarket.endTime - Date.now()); + setTimeout(startNextMarket, remaining); +} + +// ── Streams + initial market ────────────────────────────────────────────────── + +void (async () => { + currentMarket = await createMarket(); + console.log( + `[server] market ${currentMarket.id} started, strikePrice=${currentMarket.strikePrice}, ends ${new Date(currentMarket.endTime).toISOString()}`, + ); + scheduleNextMarket(); + + const { emitter: priceEmitter, getPrice } = await createBtcPriceStream(); + const { emitter: orderbookEmitter, getLatestOrder } = + createOrderbookStream(getPrice); + const positionsEmitter = createPositionsStream(getLatestOrder); + + priceEmitter.on("tick", (tick) => { + broadcast(wss, { type: "price_tick", data: tick }); + }); + + orderbookEmitter.on("order", (order: Order) => { + orderWindow = [order, ...orderWindow].slice(0, MAX_ORDERS_SERVER); + broadcast(wss, { type: "order", data: order }); + broadcast(wss, { + type: "rolling_averages", + data: computeRollingAverages(orderWindow), + }); + }); + + positionsEmitter.on("fill", (fill: Fill) => { + positionSummary = updatePositionSummary(positionSummary, fill); + broadcast(wss, { type: "fill", data: fill }); + broadcast(wss, { type: "position_summary", data: positionSummary }); + }); +})(); + +// ── Connection handling ─────────────────────────────────────────────────────── + +wss.on("connection", (ws) => { + console.log("[server] client connected"); + + // Send initial handshake with the current active market + send(ws, { type: "connected", data: { market: currentMarket } }); + + ws.on("message", (raw) => { + let msg: ClientMessage; + try { + msg = JSON.parse(raw.toString()) as ClientMessage; + } catch { + console.warn("[server] received non-JSON message, ignoring"); + return; + } + + if (msg.type === "place_order") { + const { side, action, price, quantity } = msg.data; + console.log( + `[server] place_order received: ${action} ${quantity} ${side} @ ${price.toFixed(4)}`, + ); + + // TODO: Submit the order to the Orderbook smart contract instead of logging. + // + // import { ethers } from "ethers" + // + // const ORDERBOOK_ADDRESS = "0x..." // TODO: deployed contract address + // const ABI = [...] // TODO: contract ABI + // const provider = new ethers.JsonRpcProvider("https://your-rpc-url") + // const signer = new ethers.Wallet(process.env.SIGNER_PRIVATE_KEY!, provider) + // const contract = new ethers.Contract(ORDERBOOK_ADDRESS, ABI, signer) + // + // const tx = await contract.placeOrder( + // side === "UP" ? 0 : 1, + // action === "BUY" ? 0 : 1, + // ethers.parseEther(price.toString()), + // quantity + // ) + // await tx.wait() + // console.log(`[server] order submitted: ${tx.hash}`) + } + }); + + ws.on("close", () => console.log("[server] client disconnected")); + ws.on("error", (err) => console.error("[server] client error:", err.message)); +}); diff --git a/lazer/cardano/hermes/server/src/market.ts b/lazer/cardano/hermes/server/src/market.ts new file mode 100644 index 00000000..66fa2ca3 --- /dev/null +++ b/lazer/cardano/hermes/server/src/market.ts @@ -0,0 +1,43 @@ +import type { Market } from "./types.js"; + +export const MARKET_DURATION_MS = 5 * 60 * 1000; // 5 minutes + +// TODO: When reading the current market from the blockchain, replace +// createMarket() calls in index.ts with a fetch from the contract: +// +// import { ethers } from "ethers" +// +// const CONTRACT_ADDRESS = "0x..." // TODO: deployed market factory address +// const ABI = [...] // TODO: contract ABI +// const provider = new ethers.WebSocketProvider("wss://your-rpc-url") +// const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider) +// +// async function fetchCurrentMarket(): Promise { +// const marketId = await contract.currentMarketId() +// const marketData = await contract.markets(marketId) +// return { +// id: marketId.toString(), +// startTime: Number(marketData.startTime) * 1000, // contract: unix seconds +// endTime: Number(marketData.endTime) * 1000, +// strikePrice: Number(marketData.strikePrice) / 1e18, +// } +// } +// +// TODO: When creating a new market on-chain, replace createMarket() with: +// +// async function createOnChainMarket(strikePrice: number): Promise { +// const strikePriceWei = ethers.parseEther(strikePrice.toString()) +// const tx = await contract.createMarket(strikePriceWei) +// await tx.wait() +// return fetchCurrentMarket() +// } + +export function createMarket(strikePrice: number): Market { + const now = Date.now(); + return { + id: crypto.randomUUID(), + startTime: now, + endTime: now + MARKET_DURATION_MS, + strikePrice, + }; +} diff --git a/lazer/cardano/hermes/server/src/matcher.ts b/lazer/cardano/hermes/server/src/matcher.ts new file mode 100644 index 00000000..c17e8d23 --- /dev/null +++ b/lazer/cardano/hermes/server/src/matcher.ts @@ -0,0 +1,45 @@ +import "dotenv/config"; +import { getOpenOrders, removeOrder } from "./offchain/index.js"; + +const POLL_INTERVAL_MS = 500; + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +async function runMatcher(): Promise { + console.log("[matcher] starting, polling every", POLL_INTERVAL_MS, "ms"); + + while (true) { + const orders = getOpenOrders(); + // Only BUY orders on both sides participate in matching + const upBuys = orders.filter((o) => o.side === "UP" && o.action === "BUY"); + const downBuys = orders.filter( + (o) => o.side === "DOWN" && o.action === "BUY", + ); + + for (const up of upBuys) { + for (const down of downBuys) { + if (up.price + down.price !== 1) continue; + + const qty = Math.min(up.quantity, down.quantity); + console.log( + `[matcher] matched UP@${up.price.toFixed(4)} + DOWN@${down.price.toFixed(4)}` + + ` qty=${qty} buyer=${up.ownerAddress} vs ${down.ownerAddress}`, + ); + + // TODO: Replace with on-chain match call: + // await contract.matchOrders(up.id, down.id, qty) + removeOrder(up.id); + removeOrder(down.id); + } + } + + await sleep(POLL_INTERVAL_MS); + } +} + +runMatcher().catch((err: unknown) => { + console.error("[matcher] fatal:", err); + process.exit(1); +}); diff --git a/lazer/cardano/hermes/server/src/offchain/claims.ts b/lazer/cardano/hermes/server/src/offchain/claims.ts new file mode 100644 index 00000000..044463a7 --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/claims.ts @@ -0,0 +1,15 @@ +// TODO: Replace with on-chain claim: +// +// export async function claimWonShares(marketId: string, ownerAddress: string): Promise { +// const tx = await contract.claimShares(marketId, ownerAddress) +// await tx.wait() +// } + +// ── MOCK ────────────────────────────────────────────────────────────────────── +export function claimWonShares(marketId: string, ownerAddress: string): void { + // MOCK: no-op — in production this calls the settlement contract + console.log( + `[offchain] claimWonShares: market=${marketId} owner=${ownerAddress} (mock)`, + ); +} +// ── END MOCK ────────────────────────────────────────────────────────────────── diff --git a/lazer/cardano/hermes/server/src/offchain/hydra/handler.ts b/lazer/cardano/hermes/server/src/offchain/hydra/handler.ts new file mode 100644 index 00000000..27a10fb1 --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/hydra/handler.ts @@ -0,0 +1,344 @@ +import Websocket from 'ws'; +import axios from 'axios'; +import { + Assets, + CBORHex, + CML, + fromUnit, + UTxO, +} from '@lucid-evolution/lucid'; +import blake2b from 'blake2b'; + +const ERROR_TAGS = [ + 'PeerHandshakeFailure', + 'TxInvalid', + 'InvalidInput', + 'PostTxOnChainFailed', + 'CommandFailed', + 'DecommitInvalid', +]; + +/** + * Listen and send messages to a Hydra node. + */ +class HydraHandler { + private connection: Websocket; + private url: URL; + private isReady: boolean = false; + + /** + * @constructor + * @param url - The URL of the Hydra node WebSocket server. + * Initializes the HydraHandler class and sets up the WebSocket connection. + */ + constructor(url: string) { + const wsURL = new URL(url); + wsURL.protocol = wsURL.protocol.replace('http', 'ws'); + + this.url = wsURL; + this.connection = new Websocket(wsURL + '?history=no'); + this.setupEventHandlers(); + } + + private async ensureConnectionReady(): Promise { + if (!this.isReady) { + await new Promise((resolve) => (this.connection.onopen = resolve)); + } + } + + private setupEventHandlers() { + this.connection.onopen = () => { + console.debug('WebSocket connection opened.'); + this.isReady = true; + }; + + this.connection.onerror = () => { + console.error('Error on Hydra websocket'); + }; + + this.connection.onclose = () => { + console.debug('WebSocket connection closed.'); + this.isReady = false; + }; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private waitForMessage(tag: string, timeout = 10000): Promise { + return new Promise((resolve) => { + const timeoutId = setTimeout(() => { + resolve(`Timeout waiting for tag: ${tag}`); + }, timeout); + + this.connection.onmessage = (msg: Websocket.MessageEvent) => { + const data = JSON.parse(msg.data.toString()); + if (data.tag === tag) { + console.debug(`Received ${tag}`); + clearTimeout(timeoutId); + resolve(data); + } else if (ERROR_TAGS.includes(data.tag)) { + console.error(`Received ${data.tag}`); + } else { + console.debug(`Received ${data.tag} while waiting for ${tag}`); + } + }; + }); + } + + /** + * Listens for a specific tag from the Hydra node's WebSocket. + * + * @param tag - The tag to listen for in incoming messages. + * @returns the tag when it is received from the Hydra node. + */ + public async listen(tag: string): Promise { + return new Promise((resolve) => { + this.connection.onopen = () => { + console.debug(`Awaiting for ${tag} events...`); + }; + this.connection.onmessage = async (msg: Websocket.MessageEvent) => { + const data = JSON.parse(msg.data.toString()); + if (ERROR_TAGS.includes(data.tag)) { + console.error(`Received: ${data.tag}`); + resolve(data.tag); + } + console.debug(`Received: ${data.tag}`); + resolve(data.tag); + }; + }); + } + + /** + * Closes the WebSocket connection to the Hydra node. + * @returns A promise that resolves when the connection is closed. + */ + public async stop(): Promise { + return new Promise((resolve) => { + this.connection.close(); + resolve(); + }); + } + + /** + * Sends an "Init" message to the Hydra node to start a new head. + * @returns the tag "HeadIsInitializing" once the head is initialized. + */ + async init(): Promise { + await this.ensureConnectionReady(); + console.debug('Sending init command...'); + this.connection.send(JSON.stringify({ tag: 'Init' })); + return this.listen('HeadIsInitializing'); + } + + /** + * Sends an "Abort" message to the Hydra node to abort the initialization of a Hydra head. + * @returns the tag "HeadIsAborted" if the head was aborted successfully. + */ + async abort(): Promise { + await this.ensureConnectionReady(); + console.debug('Aborting head opening...'); + this.connection.send(JSON.stringify({ tag: 'Abort' })); + return new Promise(async (resolve) => { + const tag = await this.listen('HeadIsAborted'); + resolve(tag); + }).then(() => this.stop()); + } + + /** + * Sends a commit transaction to the Hydra node. + * @param apiUrl - The URL of the Hydra API endpoint. + * @param blueprint - The CBOR-encoded transaction blueprint. + * @param utxos - An array of the UTxOs to commit. + * @returns the transaction hash once the commit is successful. + */ + async sendCommit( + _apiUrl: string, + _utxos: UTxO[], + _blueprint?: CBORHex + ): Promise { + throw new Error('Not implemented'); + } + + /** + * Sends a raw transaction to the Hydra node. + * @param tx - The CBOR-encoded transaction to send. + * @returns the tag "TxValid" when the transaction is valid and "SnapshotConfirmed" when the snapshot is confirmed. + */ + async sendTx(tx: CBORHex): Promise { + await this.ensureConnectionReady(); + console.debug('Sending transaction...'); + this.connection.send( + JSON.stringify({ + tag: 'NewTx', + transaction: { cborHex: tx, description: '', type: 'Tx BabbageEra' }, + }) + ); + return this.listen('TxValid'); + } + + /** + * Retrieves the UTxO snapshot from the Hydra node. + * @returns an array of UTxOs from the snapshot. + */ + async getSnapshot(): Promise { + const apiURL = `${this.url.origin.replace('ws', 'http')}/snapshot/utxo`; + try { + const response = await axios.get(apiURL); + const hydraUtxos = Object.entries(response.data); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const lucidUtxos = hydraUtxos.map((utxo: any) => { + const [hash, idx] = utxo[0].split('#'); + const output = utxo[1]; + return hydraUtxoToLucidUtxo(hash, idx, output); + }); + return lucidUtxos; + } catch (error) { + console.debug(error as unknown as string); + throw error; + } + } + + /** + * Sends a decommit transaction to the Hydra node. + * @param apiUrl - The URL of the Hydra API endpoint. + * @param tx - The CBOR-encoded transaction to send for decommitment. + * @returns the response data from the Hydra node. + */ + async decommit(apiUrl: string, tx: CBORHex): Promise { + try { + const payload = { + cborHex: tx, + description: '', + type: 'Tx BabbageEra', + }; + const response = await axios.post(apiUrl, payload); + return response.data; + } catch (error) { + console.error(error as unknown as string); + throw error; + } + } + + /** + * Sends a "Close" message to the Hydra node to close the current head. + * @returns the tag "HeadIsClosed" once the head is closed successfully. + */ + async close(): Promise { + await this.ensureConnectionReady(); + console.debug('Closing head...'); + this.connection.send(JSON.stringify({ tag: 'Close' })); + const data = await this.waitForMessage('HeadIsClosed', 30_000); + return data.tag; + } + + /** + * Sends a "Fanout" message to the Hydra node to finalize the current head. + * @returns the tag "HeadIsFinalized" once the head is finalized. + */ + async fanout(): Promise { + await this.ensureConnectionReady(); + console.debug('Sending fanout command...'); + this.connection.send(JSON.stringify({ tag: 'Fanout' })); + return this.listen('HeadIsFinalized'); + } +} + +type HydraUtxo = { + address: string; + datum: string | null; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + inlineDatum: any; + inlineDatumhash: string | null; + referenceScript: { + script: { cborHex: string; description: string; type: string }; + scriptLanguage: string; + } | null; + value: Record>; +}; +function lucidUtxoToHydraUtxo(utxo: UTxO): HydraUtxo { + const address = utxo.address; + const value: Record> = {}; + // Probably needs fix for datums which are not inlined + const datum = null; + let inlineDatum = null; + let inlineDatumhash = null; + let referenceScript = null; + + for (const [unit, amount] of Object.entries(utxo.assets)) { + if (unit === 'lovelace') { + value['lovelace'] = Number(amount); + } else { + const fromU = fromUnit(unit); + const currentValue = + (value[fromU.policyId] as Record) || {}; + currentValue[fromU.assetName!] = Number(amount); + value[fromU.policyId] = currentValue; + } + } + if (utxo.datum) { + const plutusData = CML.PlutusData.from_cbor_hex(utxo.datum); + inlineDatum = JSON.parse( + CML.decode_plutus_datum_to_json_str( + plutusData, + CML.CardanoNodePlutusDatumSchema.DetailedSchema + ) + ); + inlineDatumhash = blake2b(32) + .update(Buffer.from(utxo.datum, 'hex')) + .digest('hex'); + } + if (utxo.scriptRef) { + let refinedScriptType; + /** + * Lucid ScriptType = Native | PlutusV1 | PlutusV2 | PlutusV3 + * Hydra ScriptType = PlutusScriptV3 | ... + */ + if (utxo.scriptRef.type.includes('Plutus')) { + refinedScriptType = utxo.scriptRef.type.replace('Plutus', 'PlutusScript'); + } else { + refinedScriptType = utxo.scriptRef.type; + } + referenceScript = { + script: { + cborHex: utxo.scriptRef.script, + description: '', + type: refinedScriptType, + }, + scriptLanguage: `PlutusScriptLanguage ${refinedScriptType}`, + }; + } + return { + address, + value, + datum, + inlineDatum, + inlineDatumhash, + referenceScript, + }; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function hydraUtxoToLucidUtxo(hash: string, idx: number, output: any): UTxO { + const datumBytes = output.inlineDatum ? output.inlineDatumRaw : null; + const assets: Assets = {}; + for (const [policy, value] of Object.entries(output.value)) { + if (policy === 'lovelace') { + assets[policy] = BigInt(value as number); + } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const namesAndAmounts: [string, number][] = Object.entries(value as any); + for (const [assetName, amount] of namesAndAmounts) { + const unit = `${policy}${assetName}`; + assets[unit] = BigInt(amount as number); + } + } + } + return { + txHash: hash, + outputIndex: Number(idx), + assets: assets, + address: output.address, + datum: datumBytes, + }; +} + +export { HydraHandler, lucidUtxoToHydraUtxo }; diff --git a/lazer/cardano/hermes/server/src/offchain/hydra/provider.ts b/lazer/cardano/hermes/server/src/offchain/hydra/provider.ts new file mode 100644 index 00000000..a9e6a486 --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/hydra/provider.ts @@ -0,0 +1,123 @@ +import { Address, CML, OutRef, ProtocolParameters, Provider, Unit, UTxO, Credential, RewardAddress, Delegation, Datum, DatumHash, TxHash, Transaction, EvalRedeemer, credentialToAddress } from "@lucid-evolution/lucid"; +import { join } from 'path'; +import { HydraHandler } from './handler.js'; +import { readFileSync } from "fs"; + +// load and convert protocol parameters +const protocolParametersFromFile = JSON.parse(readFileSync(join(process.cwd(), '../infra/protocol-parameters.json'), 'utf8')); + +class HydraProvider implements Provider { + + constructor(private readonly hydra: HydraHandler) { + this.hydra = hydra; + } + + async getProtocolParameters(): Promise { + const protocolParameters: ProtocolParameters = { + minFeeA: protocolParametersFromFile.txFeeFixed, + minFeeB: protocolParametersFromFile.txFeePerByte, + maxTxSize: protocolParametersFromFile.maxTxSize, + maxValSize: protocolParametersFromFile.maxValueSize, + keyDeposit: BigInt(protocolParametersFromFile.stakeAddressDeposit), + poolDeposit: BigInt(protocolParametersFromFile.stakePoolDeposit), + drepDeposit: BigInt(protocolParametersFromFile.dRepDeposit), + govActionDeposit: BigInt(protocolParametersFromFile.govActionDeposit), + priceMem: protocolParametersFromFile.executionUnitPrices.priceMemory, + priceStep: protocolParametersFromFile.executionUnitPrices.priceSteps, + maxTxExMem: BigInt(protocolParametersFromFile.maxTxExecutionUnits.memory), + maxTxExSteps: BigInt(protocolParametersFromFile.maxTxExecutionUnits.steps), + coinsPerUtxoByte: BigInt(protocolParametersFromFile.utxoCostPerByte), + collateralPercentage: protocolParametersFromFile.collateralPercentage, + maxCollateralInputs: protocolParametersFromFile.maxCollateralInputs, + minFeeRefScriptCostPerByte: protocolParametersFromFile.minFeeRefScriptCostPerByte, + costModels: protocolParametersFromFile.costModels, + } + return protocolParameters; + } + + async getUtxos(addressOrCredential: Address | Credential): Promise { + const result: UTxO[] = []; + + const snapshotUTxOs = await this.hydra.getSnapshot(); + + if (typeof addressOrCredential === 'string') { + // Direct address string + snapshotUTxOs.forEach((utxo) => { + if (utxo.address === addressOrCredential) { + result.push(utxo); + } + }); + } else { + const credential = credentialToAddress("Custom", addressOrCredential); + console.info(`credential: ${credential}`); + console.info(snapshotUTxOs); + snapshotUTxOs.forEach((utxo) => { + if (utxo.address === credential) { + result.push(utxo); + } + }); + } + return result; + } + + async getUtxosWithUnit(addressOrCredential: Address | Credential, unit: Unit): Promise { + const result: UTxO[] = []; + const utxos = await this.getUtxos(addressOrCredential); + utxos.filter((utxo) => utxo.assets[unit] > 0n); + return result; + } + + async getUtxoByUnit(unit: Unit): Promise { + const utxos = await this.hydra.getSnapshot(); + const utxosWithUnit = utxos.filter((utxo) => utxo.assets[unit] > 0n); + if (utxosWithUnit.length !== 1) { + throw new Error(`UTxOs with unit ${unit} found: ${utxosWithUnit}`); + } + return utxosWithUnit[0]; + } + + async getUtxosByOutRef(outRefs: Array): Promise { + const utxos = await this.hydra.getSnapshot(); + return utxos.filter((utxo) => outRefs.some( + (outRef) => + outRef.txHash === utxo.txHash + && outRef.outputIndex === utxo.outputIndex + ), + ); + } + + async getDelegation(_rewardAddress: RewardAddress): Promise { + throw new Error('Not implemented'); + } + + async getDatum(_datumHash: DatumHash): Promise { + throw new Error('Not implemented'); + } + + async awaitTx(txHash: TxHash, checkInterval: number = 5000): Promise { + console.info(`Waiting for ${checkInterval} milliseconds`); + let snapshot = await this.hydra.getSnapshot(); + while (!snapshot.some((utxo) => utxo.txHash === txHash)) { + await new Promise(resolve => setTimeout(resolve, checkInterval)); + snapshot = await this.hydra.getSnapshot(); + } + return true; + } + + async submitTx(tx: Transaction): Promise { + const txValidity = await this.hydra.sendTx(tx); + if (txValidity === 'TxValid') { + // calculate tx hash + const cmlTx = CML.Transaction.from_cbor_hex(tx) + const txHash = CML.hash_transaction(cmlTx.body()); + return txHash.to_hex(); + } + throw new Error('Transaction not valid'); + } + + async evaluateTx(_tx: Transaction, _additionalUTxOs?: UTxO[]): Promise { + throw new Error('Not implemented'); + } +} + +export { HydraProvider }; diff --git a/lazer/cardano/hermes/server/src/offchain/index.ts b/lazer/cardano/hermes/server/src/offchain/index.ts new file mode 100644 index 00000000..1e9653d5 --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/index.ts @@ -0,0 +1,3 @@ +export * from "./orders.js"; +export * from "./market.js"; +export * from "./claims.js"; diff --git a/lazer/cardano/hermes/server/src/offchain/market.ts b/lazer/cardano/hermes/server/src/offchain/market.ts new file mode 100644 index 00000000..c1859d50 --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/market.ts @@ -0,0 +1,70 @@ +import BigNumber from "bignumber.js"; +import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; +import { createMarket as _createMarket } from "../market.js"; +import type { Market } from "../types.js"; + +// TODO: Replace with on-chain reads/writes: +// +// export async function createMarket(): Promise { +// const strikePrice = await pythOracle.getPrice(BTC_FEED_ID) // on-chain oracle read +// const tx = await contract.createMarket(ethers.parseEther(strikePrice.toString())) +// await tx.wait() +// return getCurrentMarket() +// } +// +// export async function getCurrentMarket(): Promise { +// const id = await contract.currentMarketId() +// const m = await contract.markets(id) +// return { +// id: id.toString(), +// startTime: Number(m.startTime) * 1000, +// endTime: Number(m.endTime) * 1000, +// strikePrice: Number(m.strikePrice) / 1e18, +// } +// } + +// TODO: confirm BTC/USD feed ID — same as btcPrice.ts stream +const BTC_FEED_ID = 1; + +async function fetchBtcPrice(): Promise { + const token = process.env["PYTH_ACCESS_TOKEN"]; + if (!token) + throw new Error("[offchain/market] PYTH_ACCESS_TOKEN env var is required"); + + const client = await PythLazerClient.create({ + token, + webSocketPoolConfig: {}, + }); + try { + const update = await client.getLatestPrice({ + priceFeedIds: [BTC_FEED_ID], + properties: ["price", "exponent"], + formats: [], + channel: "fixed_rate@200ms", + }); + const feed = update.parsed?.priceFeeds?.[0]; + if (feed?.price === undefined || feed.exponent === undefined) { + throw new Error("[offchain/market] no price data returned from Pyth"); + } + return new BigNumber(feed.price).shiftedBy(feed.exponent).toNumber(); + } finally { + client.shutdown(); + } +} + +// ── MOCK ────────────────────────────────────────────────────────────────────── +let currentMarket: Market | undefined; + +export async function createMarket(): Promise { + const strikePrice = await fetchBtcPrice(); + currentMarket = _createMarket(strikePrice); + console.log( + `[offchain/market] created market ${currentMarket.id} strikePrice=${strikePrice}`, + ); + return currentMarket; +} + +export function getCurrentMarket(): Market | undefined { + return currentMarket; +} +// ── END MOCK ────────────────────────────────────────────────────────────────── diff --git a/lazer/cardano/hermes/server/src/offchain/orders.ts b/lazer/cardano/hermes/server/src/offchain/orders.ts new file mode 100644 index 00000000..3ce0b9fc --- /dev/null +++ b/lazer/cardano/hermes/server/src/offchain/orders.ts @@ -0,0 +1,53 @@ +import type { Action, Order, Side } from "../types.js"; + +// TODO: Replace every function body with smart contract calls, e.g.: +// +// import { ethers } from "ethers" +// const contract = new ethers.Contract(ORDERBOOK_ADDRESS, ABI, signer) +// +// export async function createOrder(...): Promise { +// const tx = await contract.placeOrder(side, action, price, quantity) +// await tx.wait() +// return fetchOrderFromChain(tx) +// } +// +// export async function getOpenOrders(): Promise { +// return contract.getOpenOrders() +// } +// +// export async function removeOrder(id: string): Promise { +// // handled on-chain when orders are matched; no separate removal needed +// } + +// ── MOCK ────────────────────────────────────────────────────────────────────── +const store = new Map(); + +export function createOrder( + side: Side, + action: Action, + price: number, + quantity: number, + ownerAddress: string, +): Order { + const order: Order = { + id: crypto.randomUUID(), + timestamp: Date.now(), + side, + action, + price, + quantity, + ownerAddress, + }; + store.set(order.id, order); + return order; +} + +export function getOpenOrders(): Order[] { + // MOCK: returns the in-memory store (empty until createOrder is called) + return [...store.values()]; +} + +export function removeOrder(id: string): void { + store.delete(id); +} +// ── END MOCK ────────────────────────────────────────────────────────────────── diff --git a/lazer/cardano/hermes/server/src/rest.ts b/lazer/cardano/hermes/server/src/rest.ts new file mode 100644 index 00000000..58009606 --- /dev/null +++ b/lazer/cardano/hermes/server/src/rest.ts @@ -0,0 +1,116 @@ +import type { IncomingMessage, ServerResponse } from "node:http"; +import type { + MarketHistoryEntry, + MarketOutcome, + Side, + UserPosition, +} from "./types.js"; + +// TODO: Replace getMockHistory() with real blockchain reads: +// +// import { ethers } from "ethers" +// +// const CONTRACT_ADDRESS = "0x..." // TODO: deployed market factory address +// const ABI = [...] // TODO: contract ABI +// const provider = new ethers.JsonRpcProvider("https://your-rpc-url") +// const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider) +// +// async function getHistory(address: string): Promise { +// const marketCount = await contract.marketCount() +// const entries: MarketHistoryEntry[] = [] +// for (let i = Number(marketCount) - 1; i >= 0; i--) { +// const market = await contract.markets(i) +// const pos = address ? await contract.positionOf(i, address) : null +// entries.push({ +// marketId: i.toString(), +// startTime: Number(market.startTime) * 1000, +// endTime: Number(market.endTime) * 1000, +// strikePrice: Number(market.strikePrice) / 1e18, +// finalBtcPrice: Number(market.finalPrice) / 1e18, +// outcome: Number(market.finalPrice) > Number(market.strikePrice) ? "UP" : "DOWN", +// userPosition: pos && Number(pos.quantity) > 0 ? { +// side: Number(pos.side) === 0 ? "UP" : "DOWN", +// quantity: Number(pos.quantity), +// avgPrice: Number(pos.avgPrice) / 1e18, +// result: /* derive from outcome vs side */, +// pnl: /* derive from result */, +// } : null, +// }) +// } +// return entries +// } + +const STRIKE = 67_500; +const MARKET_DURATION_MS = 5 * 60 * 1000; + +// Stable mock final prices — alternating above/below strike +const MOCK_FINALS = [67_820, 67_210, 68_100, 66_950, 67_640]; + +// Markets where the user has a position (by index into the 5-entry list) +const USER_POSITION_INDICES = new Set([0, 2, 3]); + +function buildUserPosition( + index: number, + outcome: MarketOutcome, + address: string, +): UserPosition | null { + if (!address || !USER_POSITION_INDICES.has(index)) return null; + + // Mock: user always bet UP in markets 0 and 2, DOWN in market 3 + const side: Side = index === 3 ? "DOWN" : "UP"; + const quantity = (index + 1) * 50; + const avgPrice = 0.48 + index * 0.02; + const won = side === outcome; + const pnl = won + ? Math.round(quantity * (1 - avgPrice) * 100) / 100 + : Math.round(-quantity * avgPrice * 100) / 100; + + return { + side, + quantity, + avgPrice, + result: won ? "WON" : "LOST", + pnl, + }; +} + +function getMockHistory(address: string): MarketHistoryEntry[] { + const now = Date.now(); + return MOCK_FINALS.map((finalBtcPrice, i) => { + const endTime = now - i * MARKET_DURATION_MS; + const startTime = endTime - MARKET_DURATION_MS; + const outcome: MarketOutcome = finalBtcPrice > STRIKE ? "UP" : "DOWN"; + return { + marketId: `mock-market-${5 - i}`, + startTime, + endTime, + strikePrice: STRIKE, + finalBtcPrice, + outcome, + userPosition: buildUserPosition(i, outcome, address), + }; + }); +} + +function setCors(res: ServerResponse): void { + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Content-Type", "application/json"); +} + +export function handleRestRequest( + req: IncomingMessage, + res: ServerResponse, +): void { + const url = new URL(req.url ?? "/", "http://localhost"); + + if (req.method === "GET" && url.pathname === "/api/markets/history") { + const address = url.searchParams.get("address") ?? ""; + setCors(res); + res.writeHead(200); + res.end(JSON.stringify(getMockHistory(address))); + return; + } + + res.writeHead(404); + res.end(JSON.stringify({ error: "not found" })); +} diff --git a/lazer/cardano/hermes/server/src/streams/btcPrice.ts b/lazer/cardano/hermes/server/src/streams/btcPrice.ts new file mode 100644 index 00000000..5a9789ac --- /dev/null +++ b/lazer/cardano/hermes/server/src/streams/btcPrice.ts @@ -0,0 +1,72 @@ +import { EventEmitter } from "node:events"; +import BigNumber from "bignumber.js"; +import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; +import type { PriceTick } from "../types.js"; + +const BTC_FEED_ID = 1; + +interface CurrentPrice { + raw: string; + exponent: number; + num: number; // pre-computed float, used by the mock orderbook +} + +export async function createBtcPriceStream(): Promise<{ + emitter: EventEmitter; + getPrice: () => number | undefined; +}> { + const token = process.env["PYTH_ACCESS_TOKEN"]; + if (!token) + throw new Error("[btcPrice] PYTH_ACCESS_TOKEN env var is required"); + + const emitter = new EventEmitter(); + let current: CurrentPrice | undefined; + + // TODO: Once the settlement contract is wired, switch to a verified feed: + // formats: ["evm"], deliveryFormat: "binary" + // and pass the signed payload to the contract for on-chain price validation. + const client = await PythLazerClient.create({ + token, + webSocketPoolConfig: {}, + }); + + client.subscribe({ + type: "subscribe", + subscriptionId: 1, + priceFeedIds: [BTC_FEED_ID], + properties: ["price", "exponent", "feedUpdateTimestamp"], + formats: [], + deliveryFormat: "json", + channel: "fixed_rate@200ms", + }); + + client.addMessageListener((event) => { + if (event.type !== "json") return; + if (event.value.type !== "streamUpdated") return; + const feed = event.value.parsed?.priceFeeds?.[0]; + if ( + feed?.price === undefined || + feed.exponent === undefined || + feed.feedUpdateTimestamp === undefined + ) + return; + + const bn = new BigNumber(feed.price).shiftedBy(feed.exponent); + current = { + raw: feed.price, + exponent: feed.exponent, + num: bn.toNumber(), + }; + + const tick: PriceTick = { + timestamp: feed.feedUpdateTimestamp / 1000, // µs → ms + btcPriceStr: bn.toFixed(2), + btcPriceRaw: feed.price, + exponent: feed.exponent, + }; + emitter.emit("tick", tick); + }); + + console.log("[btcPrice] Pyth Lazer connected, subscribed to BTC/USD feed"); + return { emitter, getPrice: () => current?.num }; +} diff --git a/lazer/cardano/hermes/server/src/streams/orderbook.ts b/lazer/cardano/hermes/server/src/streams/orderbook.ts new file mode 100644 index 00000000..3793eae1 --- /dev/null +++ b/lazer/cardano/hermes/server/src/streams/orderbook.ts @@ -0,0 +1,72 @@ +import { EventEmitter } from "node:events"; +import type { Action, Order, Side } from "../types.js"; + +// TODO: Replace the mock below with real smart contract events. +// +// The Orderbook contract emits an "OrderPlaced" event whenever a new limit +// order is submitted on-chain. Subscribe using ethers.js or viem: +// +// import { ethers } from "ethers" +// +// const ORDERBOOK_ADDRESS = "0x..." // TODO: fill in deployed contract address +// const ABI = [...] // TODO: fill in contract ABI (at minimum the OrderPlaced event) +// +// const provider = new ethers.WebSocketProvider("wss://your-rpc-url") +// const contract = new ethers.Contract(ORDERBOOK_ADDRESS, ABI, provider) +// +// contract.on("OrderPlaced", (id, owner, side, action, price, qty, ts) => { +// const order: Order = { +// id: id.toString(), +// timestamp: Number(ts) * 1000, // contract emits unix seconds +// side: side === 0n ? "UP" : "DOWN", +// action: action === 0n ? "BUY" : "SELL", +// price: Number(price) / 1e18, // contract stores as uint256 wei-scaled +// quantity: Number(qty), +// ownerAddress: owner, +// } +// emitter.emit("order", order) +// }) +// +// Remove the MOCK block below once the real subscription is wired in. + +const ADDRESS_POOL = Array.from({ length: 10 }, (_, i) => `addr_${i + 1}`); +const STRIKE = 67_500; +const INTERVAL_MS = 300; + +function clamp(v: number, lo: number, hi: number): number { + return Math.min(hi, Math.max(lo, v)); +} + +export function createOrderbookStream(getBtcPrice: () => number | undefined): { + emitter: EventEmitter; + getLatestOrder: () => Order | null; +} { + const emitter = new EventEmitter(); + let latestOrder: Order | null = null; + + // ── MOCK: remove once real contract events are wired in ─────────────────── + setInterval(() => { + const btcPrice = getBtcPrice(); + if (btcPrice === undefined) return; // wait for first Pyth tick + const side: Side = Math.random() > 0.5 ? "UP" : "DOWN"; + const action: Action = Math.random() > 0.5 ? "BUY" : "SELL"; + const baseUpProb = clamp(0.5 + (btcPrice - STRIKE) / 10_000, 0.05, 0.95); + const ref = side === "UP" ? baseUpProb : 1 - baseUpProb; + const price = clamp(ref + (Math.random() - 0.5) * 0.06, 0.01, 0.99); + const order: Order = { + id: crypto.randomUUID(), + timestamp: Date.now(), + side, + action, + price, + quantity: Math.floor(Math.random() * 500) + 1, + ownerAddress: + ADDRESS_POOL[Math.floor(Math.random() * ADDRESS_POOL.length)], + }; + latestOrder = order; + emitter.emit("order", order); + }, INTERVAL_MS); + // ── END MOCK ────────────────────────────────────────────────────────────── + + return { emitter, getLatestOrder: () => latestOrder }; +} diff --git a/lazer/cardano/hermes/server/src/streams/positions.ts b/lazer/cardano/hermes/server/src/streams/positions.ts new file mode 100644 index 00000000..6314090a --- /dev/null +++ b/lazer/cardano/hermes/server/src/streams/positions.ts @@ -0,0 +1,57 @@ +import { EventEmitter } from "node:events"; +import type { Fill, Order } from "../types.js"; + +// TODO: Replace the mock below with real smart contract events. +// +// The Market (settlement) contract emits an "OrderFilled" event when two +// orders are matched on-chain. Subscribe using ethers.js or viem: +// +// import { ethers } from "ethers" +// +// const MARKET_ADDRESS = "0x..." // TODO: fill in deployed contract address +// const ABI = [...] // TODO: fill in contract ABI (at minimum the OrderFilled event) +// +// const provider = new ethers.WebSocketProvider("wss://your-rpc-url") +// const contract = new ethers.Contract(MARKET_ADDRESS, ABI, provider) +// +// contract.on("OrderFilled", (id, owner, side, qty, price, ts) => { +// const fill: Fill = { +// id: id.toString(), +// timestamp: Number(ts) * 1000, // contract emits unix seconds +// side: side === 0n ? "UP" : "DOWN", +// quantity: Number(qty), +// price: Number(price) / 1e18, // uint256 wei-scaled +// ownerAddress: owner, +// } +// emitter.emit("fill", fill) +// }) +// +// Remove the MOCK block below once the real subscription is wired in. + +const ADDRESS_POOL = Array.from({ length: 10 }, (_, i) => `addr_${i + 1}`); +const INTERVAL_MS = 800; + +export function createPositionsStream( + getLatestOrder: () => Order | null, +): EventEmitter { + const emitter = new EventEmitter(); + + // ── MOCK: remove once real contract events are wired in ─────────────────── + setInterval(() => { + const latest = getLatestOrder(); + if (!latest) return; + const fill: Fill = { + id: crypto.randomUUID(), + timestamp: Date.now(), + side: latest.side, + quantity: Math.floor(latest.quantity * (0.3 + Math.random() * 0.7)), + price: latest.price, + ownerAddress: + ADDRESS_POOL[Math.floor(Math.random() * ADDRESS_POOL.length)], + }; + emitter.emit("fill", fill); + }, INTERVAL_MS); + // ── END MOCK ────────────────────────────────────────────────────────────── + + return emitter; +} diff --git a/lazer/cardano/hermes/server/src/types.ts b/lazer/cardano/hermes/server/src/types.ts new file mode 100644 index 00000000..d9b69596 --- /dev/null +++ b/lazer/cardano/hermes/server/src/types.ts @@ -0,0 +1,91 @@ +export interface Market { + id: string; // crypto.randomUUID() — future: on-chain market ID (uint256) + startTime: number; // ms timestamp — future: from block.timestamp at creation + endTime: number; // ms timestamp — future: startTime + duration from contract + strikePrice: number; // future: read from contract's stored strike at creation +} + +export type Side = "UP" | "DOWN"; +export type Action = "BUY" | "SELL"; +export type MarketOutcome = "UP" | "DOWN"; +export type UserResult = "WON" | "LOST"; + +export interface UserPosition { + side: Side; + quantity: number; + avgPrice: number; // price paid per share (0–1) + result: UserResult; + pnl: number; // quantity*(1-avgPrice) if won, -quantity*avgPrice if lost +} + +export interface MarketHistoryEntry { + marketId: string; + startTime: number; // ms + endTime: number; // ms + strikePrice: number; + finalBtcPrice: number; + outcome: MarketOutcome; // which side won + userPosition: UserPosition | null; // null if address had no shares +} + +export interface PriceTick { + timestamp: number; + btcPriceStr: string; // display-ready decimal string, e.g. "67543.21" (BigNumber-computed) + btcPriceRaw: string; // raw Pyth integer string, e.g. "6754321000000" + exponent: number; // e.g. -8; actual = btcPriceRaw * 10^exponent +} + +export interface Order { + id: string; + timestamp: number; + side: Side; + action: Action; + price: number; // 0–1 probability price of the bet position + quantity: number; + ownerAddress: string; // plain string; format determined by backend/wallet +} + +export interface Fill { + id: string; + timestamp: number; + side: Side; + quantity: number; + price: number; + ownerAddress: string; +} + +export interface PositionSummary { + upContracts: number; + upAvgPrice: number; + downContracts: number; + downAvgPrice: number; +} + +export interface RollingAverages { + upBuyAvg: number; + upSellAvg: number; + downBuyAvg: number; + downSellAvg: number; +} + +// ── Server → Client ─────────────────────────────────────────────────────────── + +export type ServerMessage = + | { type: "connected"; data: { market: Market } } + | { type: "market_started"; data: { market: Market } } + | { type: "price_tick"; data: PriceTick } + | { type: "order"; data: Order } + | { type: "fill"; data: Fill } + | { type: "position_summary"; data: PositionSummary } + | { type: "rolling_averages"; data: RollingAverages }; + +// ── Client → Server ─────────────────────────────────────────────────────────── + +export interface PlaceOrderPayload { + side: Side; + action: Action; + price: number; + quantity: number; +} + +export type ClientMessage = { type: "place_order"; data: PlaceOrderPayload }; diff --git a/lazer/cardano/hermes/server/tsconfig.json b/lazer/cardano/hermes/server/tsconfig.json new file mode 100644 index 00000000..574c1991 --- /dev/null +++ b/lazer/cardano/hermes/server/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "dist", + "rootDir": "src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "include": ["src"] +} diff --git a/lazer/cardano/hermes/src/onchain/.gitignore b/lazer/cardano/hermes/src/onchain/.gitignore new file mode 100644 index 00000000..ff7811b1 --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/.gitignore @@ -0,0 +1,6 @@ +# Aiken compilation artifacts +artifacts/ +# Aiken's project working directory +build/ +# Aiken's default documentation export +docs/ diff --git a/lazer/cardano/hermes/src/onchain/README.md b/lazer/cardano/hermes/src/onchain/README.md new file mode 100644 index 00000000..91bda432 --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/README.md @@ -0,0 +1,65 @@ +# hermes + +Write validators in the `validators` folder, and supporting functions in the `lib` folder using `.ak` as a file extension. + +```aiken +validator my_first_validator { + spend(_datum: Option, _redeemer: Data, _output_reference: Data, _context: Data) { + True + } +} +``` + +## Building + +```sh +aiken build +``` + +## Configuring + +**aiken.toml** +```toml +[config.default] +network_id = 41 +``` + +Or, alternatively, write conditional environment modules under `env`. + +## Testing + +You can write tests in any module using the `test` keyword. For example: + +```aiken +use config + +test foo() { + config.network_id + 1 == 42 +} +``` + +To run all tests, simply do: + +```sh +aiken check +``` + +To run only tests matching the string `foo`, do: + +```sh +aiken check -m foo +``` + +## Documentation + +If you're writing a library, you might want to generate an HTML documentation for it. + +Use: + +```sh +aiken docs +``` + +## Resources + +Find more on the [Aiken's user manual](https://aiken-lang.org). diff --git a/lazer/cardano/hermes/src/onchain/aiken.lock b/lazer/cardano/hermes/src/onchain/aiken.lock new file mode 100644 index 00000000..1a4fdb1c --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/aiken.lock @@ -0,0 +1,15 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v3.0.0" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v3.0.0" +requirements = [] +source = "github" + +[etags] diff --git a/lazer/cardano/hermes/src/onchain/aiken.toml b/lazer/cardano/hermes/src/onchain/aiken.toml new file mode 100644 index 00000000..483c43bd --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/aiken.toml @@ -0,0 +1,18 @@ +name = "los-hydra-boys/hermes" +version = "0.0.0" +compiler = "v1.1.21" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'los-hydra-boys/hermes'" + +[repository] +user = "los-hydra-boys" +project = "hermes" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "v3.0.0" +source = "github" + +[config] diff --git a/lazer/cardano/hermes/src/onchain/lib/types.ak b/lazer/cardano/hermes/src/onchain/lib/types.ak new file mode 100644 index 00000000..4ae4914b --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/lib/types.ak @@ -0,0 +1,57 @@ +use aiken/crypto.{VerificationKeyHash} + +pub type PosixTime = + Int + +pub type Direction { + Up + Down +} + +pub type Operation { + Buy + Sell +} + +pub type Price { + numerator: Int, + denominator: Int, +} + +pub type OrderDatum { + direction: Direction, + operation: Operation, + price: Price, + owner: VerificationKeyHash, +} + +pub type OrderRedeemer { + Cancel + Match + Fill +} + +pub type OrderMintRedeemer { + Mint + Burn +} + +pub type MarketDatum { + start_price: Price, + end_price: Option, + ramaining_shares: Int, +} + +pub type MarketRedeemer { + RecordFinalPrice + ClaimWinnings + ClaimLosings + CloseMarket +} + +pub type MarketMintRedeemer { + MintControlToken + BurnControlToken + MintPositionToken(Direction) + BurnPositionToken(Direction) +} diff --git a/lazer/cardano/hermes/src/onchain/plutus.json b/lazer/cardano/hermes/src/onchain/plutus.json new file mode 100644 index 00000000..d69ac6a4 --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/plutus.json @@ -0,0 +1,387 @@ +{ + "preamble": { + "title": "los-hydra-boys/hermes", + "description": "Aiken contracts for project 'los-hydra-boys/hermes'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.21+42babe5" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "market.market.mint", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/types~1MarketMintRedeemer" + } + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/types~1PosixTime" + } + } + ], + "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", + "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" + }, + { + "title": "market.market.spend", + "datum": { + "title": "_datum", + "schema": { + "$ref": "#/definitions/types~1MarketDatum" + } + }, + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/types~1MarketRedeemer" + } + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/types~1PosixTime" + } + } + ], + "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", + "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" + }, + { + "title": "market.market.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/types~1PosixTime" + } + } + ], + "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", + "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" + }, + { + "title": "order.order.mint", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/types~1OrderMintRedeemer" + } + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + } + ], + "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", + "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" + }, + { + "title": "order.order.spend", + "datum": { + "title": "_datum", + "schema": { + "$ref": "#/definitions/types~1OrderDatum" + } + }, + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/types~1OrderRedeemer" + } + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + } + ], + "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", + "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" + }, + { + "title": "order.order.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + } + ], + "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", + "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" + } + ], + "definitions": { + "Int": { + "dataType": "integer" + }, + "Option": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/types~1Price" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "aiken/crypto/ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "aiken/crypto/VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "types/Direction": { + "title": "Direction", + "anyOf": [ + { + "title": "Up", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Down", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/MarketDatum": { + "title": "MarketDatum", + "anyOf": [ + { + "title": "MarketDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "start_price", + "$ref": "#/definitions/types~1Price" + }, + { + "title": "end_price", + "$ref": "#/definitions/Option" + }, + { + "title": "ramaining_shares", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/MarketMintRedeemer": { + "title": "MarketMintRedeemer", + "anyOf": [ + { + "title": "MintControlToken", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "BurnControlToken", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "MintPositionToken", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "$ref": "#/definitions/types~1Direction" + } + ] + }, + { + "title": "BurnPositionToken", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "$ref": "#/definitions/types~1Direction" + } + ] + } + ] + }, + "types/MarketRedeemer": { + "title": "MarketRedeemer", + "anyOf": [ + { + "title": "RecordFinalPrice", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "ClaimWinnings", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "ClaimLosings", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "CloseMarket", + "dataType": "constructor", + "index": 3, + "fields": [] + } + ] + }, + "types/Operation": { + "title": "Operation", + "anyOf": [ + { + "title": "Buy", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Sell", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/OrderDatum": { + "title": "OrderDatum", + "anyOf": [ + { + "title": "OrderDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "direction", + "$ref": "#/definitions/types~1Direction" + }, + { + "title": "operation", + "$ref": "#/definitions/types~1Operation" + }, + { + "title": "price", + "$ref": "#/definitions/types~1Price" + }, + { + "title": "owner", + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + } + ] + } + ] + }, + "types/OrderMintRedeemer": { + "title": "OrderMintRedeemer", + "anyOf": [ + { + "title": "Mint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Burn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/OrderRedeemer": { + "title": "OrderRedeemer", + "anyOf": [ + { + "title": "Cancel", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Match", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "Fill", + "dataType": "constructor", + "index": 2, + "fields": [] + } + ] + }, + "types/PosixTime": { + "title": "PosixTime", + "dataType": "integer" + }, + "types/Price": { + "title": "Price", + "anyOf": [ + { + "title": "Price", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "numerator", + "$ref": "#/definitions/Int" + }, + { + "title": "denominator", + "$ref": "#/definitions/Int" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/lazer/cardano/hermes/src/onchain/validators/market.ak b/lazer/cardano/hermes/src/onchain/validators/market.ak new file mode 100644 index 00000000..3e2e7b0e --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/validators/market.ak @@ -0,0 +1,22 @@ +use cardano/assets.{PolicyId} +use cardano/transaction.{OutputReference, Transaction} +use types.{MarketDatum, MarketMintRedeemer, MarketRedeemer, PosixTime} + +validator market(start_time: PosixTime) { + mint(_redeemer: MarketMintRedeemer, _policy_id: PolicyId, _self: Transaction) { + True + } + + spend( + _datum: Option, + _redeemer: MarketRedeemer, + _utxo: OutputReference, + _self: Transaction, + ) { + True + } + + else(_) { + fail + } +} diff --git a/lazer/cardano/hermes/src/onchain/validators/order.ak b/lazer/cardano/hermes/src/onchain/validators/order.ak new file mode 100644 index 00000000..ecae45a2 --- /dev/null +++ b/lazer/cardano/hermes/src/onchain/validators/order.ak @@ -0,0 +1,23 @@ +use aiken/crypto.{ScriptHash} +use cardano/assets.{PolicyId} +use cardano/transaction.{OutputReference, Transaction} +use types.{OrderDatum, OrderMintRedeemer, OrderRedeemer} + +validator order(market_script_hash: ScriptHash) { + mint(_redeemer: OrderMintRedeemer, _policy_id: PolicyId, _self: Transaction) { + True + } + + spend( + _datum: Option, + _redeemer: OrderRedeemer, + _utxo: OutputReference, + _self: Transaction, + ) { + True + } + + else(_) { + fail + } +} diff --git a/lazer/cardano/hermes/ui/.gitignore b/lazer/cardano/hermes/ui/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/lazer/cardano/hermes/ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/lazer/cardano/hermes/ui/.prettierignore b/lazer/cardano/hermes/ui/.prettierignore new file mode 100644 index 00000000..0b4a1db4 --- /dev/null +++ b/lazer/cardano/hermes/ui/.prettierignore @@ -0,0 +1,7 @@ +node_modules/ +coverage/ +.pnpm-store/ +pnpm-lock.yaml +package-lock.json +pnpm-lock.yaml +yarn.lock diff --git a/lazer/cardano/hermes/ui/.prettierrc b/lazer/cardano/hermes/ui/.prettierrc new file mode 100644 index 00000000..9000bfaa --- /dev/null +++ b/lazer/cardano/hermes/ui/.prettierrc @@ -0,0 +1,11 @@ +{ + "endOfLine": "lf", + "semi": false, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 80, + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindStylesheet": "src/index.css", + "tailwindFunctions": ["cn", "cva"] +} diff --git a/lazer/cardano/hermes/ui/README.md b/lazer/cardano/hermes/ui/README.md new file mode 100644 index 00000000..811328a4 --- /dev/null +++ b/lazer/cardano/hermes/ui/README.md @@ -0,0 +1,21 @@ +# React + TypeScript + Vite + shadcn/ui + +This is a template for a new Vite project with React, TypeScript, and shadcn/ui. + +## Adding components + +To add components to your app, run the following command: + +```bash +npx shadcn@latest add button +``` + +This will place the ui components in the `src/components` directory. + +## Using components + +To use the components in your app, import them as follows: + +```tsx +import { Button } from "@/components/ui/button" +``` diff --git a/lazer/cardano/hermes/ui/components.json b/lazer/cardano/hermes/ui/components.json new file mode 100644 index 00000000..5c23ec49 --- /dev/null +++ b/lazer/cardano/hermes/ui/components.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "radix-nova", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "rtl": false, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "menuColor": "default", + "menuAccent": "subtle", + "registries": {} +} diff --git a/lazer/cardano/hermes/ui/eslint.config.js b/lazer/cardano/hermes/ui/eslint.config.js new file mode 100644 index 00000000..5e6b472f --- /dev/null +++ b/lazer/cardano/hermes/ui/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/lazer/cardano/hermes/ui/index.html b/lazer/cardano/hermes/ui/index.html new file mode 100644 index 00000000..1f738fe7 --- /dev/null +++ b/lazer/cardano/hermes/ui/index.html @@ -0,0 +1,13 @@ + + + + + + + vite-app + + +
+ + + diff --git a/lazer/cardano/hermes/ui/package.json b/lazer/cardano/hermes/ui/package.json new file mode 100644 index 00000000..75262eab --- /dev/null +++ b/lazer/cardano/hermes/ui/package.json @@ -0,0 +1,47 @@ +{ + "name": "hermes", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "format": "prettier --write \"**/*.{ts,tsx}\"", + "typecheck": "tsc --noEmit", + "preview": "vite preview" + }, + "dependencies": { + "@fontsource-variable/geist": "^5.2.8", + "@tailwindcss/vite": "^4.2.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "dotenv": "^17.3.1", + "lucide-react": "^0.577.0", + "radix-ui": "^1.4.3", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.13.1", + "recharts": "^3.8.0", + "shadcn": "^4.1.0", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.2.1", + "tw-animate-css": "^1.4.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/node": "^24.12.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^5.2.0", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^16.5.0", + "prettier": "^3.8.1", + "prettier-plugin-tailwindcss": "^0.7.2", + "typescript": "~5.9.3", + "typescript-eslint": "^8.57.1", + "vite": "^7.3.1" + } +} diff --git a/lazer/cardano/hermes/ui/pnpm-lock.yaml b/lazer/cardano/hermes/ui/pnpm-lock.yaml new file mode 100644 index 00000000..bb0ef69b --- /dev/null +++ b/lazer/cardano/hermes/ui/pnpm-lock.yaml @@ -0,0 +1,6723 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@fontsource-variable/geist': + specifier: ^5.2.8 + version: 5.2.8 + '@tailwindcss/vite': + specifier: ^4.2.1 + version: 4.2.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + dotenv: + specifier: ^17.3.1 + version: 17.3.1 + lucide-react: + specifier: ^0.577.0 + version: 0.577.0(react@19.2.4) + radix-ui: + specifier: ^1.4.3 + version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: + specifier: ^19.2.4 + version: 19.2.4 + react-dom: + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) + react-router-dom: + specifier: ^7.13.1 + version: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + recharts: + specifier: ^3.8.0 + version: 3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1) + shadcn: + specifier: ^4.1.0 + version: 4.1.0(@types/node@24.12.0)(typescript@5.9.3) + tailwind-merge: + specifier: ^3.5.0 + version: 3.5.0 + tailwindcss: + specifier: ^4.2.1 + version: 4.2.2 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 + devDependencies: + '@eslint/js': + specifier: ^9.39.4 + version: 9.39.4 + '@types/node': + specifier: ^24.12.0 + version: 24.12.0 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^5.2.0 + version: 5.2.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)) + eslint: + specifier: ^9.39.4 + version: 9.39.4(jiti@2.6.1) + eslint-plugin-react-hooks: + specifier: ^7.0.1 + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-react-refresh: + specifier: ^0.5.2 + version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) + globals: + specifier: ^16.5.0 + version: 16.5.0 + prettier: + specifier: ^3.8.1 + version: 3.8.1 + prettier-plugin-tailwindcss: + specifier: ^0.7.2 + version: 0.7.2(prettier@3.8.1) + typescript: + specifier: ~5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.57.1 + version: 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + vite: + specifier: ^7.3.1 + version: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0) + +packages: + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@dotenvx/dotenvx@1.57.1': + resolution: {integrity: sha512-iKXuo8Nes9Ft4zF3AZOT4FHkl6OV8bHqn61a67qHokkBzSEurnKZAlOkT0FYrRNVGvE6nCfZMtYswyjfXCR1MQ==} + hasBin: true + + '@ecies/ciphers@0.2.5': + resolution: {integrity: sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@fontsource-variable/geist@5.2.8': + resolution: {integrity: sha512-cJ6m9e+8MQ5dCYJsLylfZrgBh6KkG4bOLckB35Tr9J/EqdkEM6QllH5PxqP1dhTvFup+HtMRPuz9xOjxXJggxw==} + + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@mswjs/interceptors@0.41.3': + resolution: {integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==} + engines: {node: '>=18'} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-accessible-icon@1.1.7': + resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-alert-dialog@1.1.15': + resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-aspect-ratio@1.1.7': + resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-avatar@1.1.10': + resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-checkbox@1.3.3': + resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context-menu@2.2.16': + resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-form@0.1.8': + resolution: {integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-hover-card@1.1.15': + resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.7': + resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menubar@1.1.16': + resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-navigation-menu@1.2.14': + resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-one-time-password-field@0.1.8': + resolution: {integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-password-toggle-field@0.1.3': + resolution: {integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-progress@1.1.7': + resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-radio-group@1.3.8': + resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.2.6': + resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.1.7': + resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.3.6': + resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toast@1.2.15': + resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle-group@1.1.11': + resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle@1.1.10': + resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toolbar@1.1.11': + resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-is-hydrated@0.1.0': + resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@reduxjs/toolkit@2.11.2': + resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 || ^19 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + + '@rollup/rollup-android-arm-eabi@4.60.0': + resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.0': + resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.0': + resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.0': + resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.0': + resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.0': + resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.60.0': + resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.60.0': + resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.60.0': + resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.60.0': + resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.60.0': + resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.0': + resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.0': + resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.0': + resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@ts-morph/common@0.27.0': + resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + + '@types/validate-npm-package-name@4.0.2': + resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} + + '@typescript-eslint/eslint-plugin@8.57.1': + resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.57.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.57.1': + resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.57.1': + resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.57.1': + resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.57.1': + resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.57.1': + resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.57.1': + resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.57.1': + resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.57.1': + resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.57.1': + resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.10: + resolution: {integrity: sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001780: + resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + code-block-writer@13.0.3: + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + engines: {node: '>=0.3.1'} + + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eciesjs@0.4.18: + resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.321: + resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.45.1: + resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.5.2: + resolution: {integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==} + peerDependencies: + eslint: ^9 || ^10 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + fuzzysort@3.1.0: + resolution: {integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-own-enumerable-keys@1.0.0: + resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} + engines: {node: '>=14.16'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql@16.13.1: + resolution: {integrity: sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + hono@4.12.8: + resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} + engines: {node: '>=16.9.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immer@10.2.0: + resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} + + immer@11.1.4: + resolution: {integrity: sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@3.0.0: + resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} + engines: {node: '>=12'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-regexp@3.1.0: + resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==} + engines: {node: '>=12'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.577.0: + resolution: {integrity: sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.12.14: + resolution: {integrity: sha512-4KXa4nVBIBjbDbd7vfQNuQ25eFxug0aropCQFoI0JdOBuJWamkT1yLVIWReFI8SiTRc+H1hKzaNk+cLk2N9rtQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-tailwindcss@0.7.2: + resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} + engines: {node: '>=20.19'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-hermes': '*' + '@prettier/plugin-oxc': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-hermes': + optional: true + '@prettier/plugin-oxc': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-svelte: + optional: true + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + radix-ui@1.4.3: + resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-is@19.2.4: + resolution: {integrity: sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==} + + react-redux@9.2.0: + resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==} + peerDependencies: + '@types/react': ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + redux: + optional: true + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-router-dom@7.13.1: + resolution: {integrity: sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.13.1: + resolution: {integrity: sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + recharts@3.8.0: + resolution: {integrity: sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + redux-thunk@3.1.0: + resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} + peerDependencies: + redux: ^5.0.0 + + redux@5.0.1: + resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + reselect@5.1.1: + resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + rettime@0.10.1: + resolution: {integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.60.0: + resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shadcn@4.1.0: + resolution: {integrity: sha512-3zETJ+0Ezj69FS6RL0HOkLKKAR5yXisXx1iISJdfLQfrUqj/VIQlanQi1Ukk+9OE+XHZVj4FQNTBSfbr2CyCYg==} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + stringify-object@5.0.0: + resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} + engines: {node: '>=14.16'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tldts-core@7.0.27: + resolution: {integrity: sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==} + + tldts@7.0.27: + resolution: {integrity: sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} + engines: {node: '>=16'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-morph@26.0.0: + resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@5.5.0: + resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} + engines: {node: '>=20'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typescript-eslint@8.57.1: + resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + until-async@3.0.2: + resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + validate-npm-package-name@7.0.2: + resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} + engines: {node: ^20.17.0 || >=22.9.0} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + victory-vendor@37.3.6: + resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==} + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + +snapshots: + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@dotenvx/dotenvx@1.57.1': + dependencies: + commander: 11.1.0 + dotenv: 17.3.1 + eciesjs: 0.4.18 + execa: 5.1.1 + fdir: 6.5.0(picomatch@4.0.3) + ignore: 5.3.2 + object-treeify: 1.1.33 + picomatch: 4.0.3 + which: 4.0.0 + + '@ecies/ciphers@0.2.5(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@esbuild/aix-ppc64@0.27.4': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': + dependencies: + eslint: 9.39.4(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@floating-ui/utils@0.2.11': {} + + '@fontsource-variable/geist@5.2.8': {} + + '@hono/node-server@1.19.11(hono@4.12.8)': + dependencies: + hono: 4.12.8 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@inquirer/ansi@1.0.2': {} + + '@inquirer/confirm@5.1.21(@types/node@24.12.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) + optionalDependencies: + '@types/node': 24.12.0 + + '@inquirer/core@10.3.2(@types/node@24.12.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.12.0) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.12.0 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/type@3.0.10(@types/node@24.12.0)': + optionalDependencies: + '@types/node': 24.12.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@modelcontextprotocol/sdk@1.27.1(zod@3.25.76)': + dependencies: + '@hono/node-server': 1.19.11(hono@4.12.8) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.8 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.1(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@mswjs/interceptors@0.41.3': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + aria-hidden: 1.2.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-form@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-label@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + aria-hidden: 1.2.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + aria-hidden: 1.2.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/rect': 1.1.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-progress@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + aria-hidden: 1.2.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slider@1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toast@1.2.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/rect@1.1.1': {} + + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@standard-schema/utils': 0.3.0 + immer: 11.1.4 + redux: 5.0.1 + redux-thunk: 3.1.0(redux@5.0.1) + reselect: 5.1.1 + optionalDependencies: + react: 19.2.4 + react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1) + + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rollup/rollup-android-arm-eabi@4.60.0': + optional: true + + '@rollup/rollup-android-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-x64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.0': + optional: true + + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@standard-schema/spec@1.1.0': {} + + '@standard-schema/utils@0.3.0': {} + + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/vite@4.2.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0) + + '@ts-morph/common@0.27.0': + dependencies: + fast-glob: 3.3.3 + minimatch: 10.2.4 + path-browserify: 1.0.1 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.12.0': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/statuses@2.0.6': {} + + '@types/use-sync-external-store@0.0.6': {} + + '@types/validate-npm-package-name@4.0.2': {} + + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + eslint: 9.39.4(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.57.1': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 + + '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.57.1': {} + + '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.57.1': + dependencies: + '@typescript-eslint/types': 8.57.1 + eslint-visitor-keys: 5.0.1 + + '@vitejs/plugin-react@5.2.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.10: {} + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.10 + caniuse-lite: 1.0.30001780 + electron-to-chromium: 1.5.321 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001780: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} + + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clsx@2.1.1: {} + + code-block-writer@13.0.3: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@11.1.0: {} + + commander@14.0.3: {} + + concat-map@0.0.1: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cookie@1.1.1: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig@9.0.1(typescript@5.9.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.3 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-ease@3.0.1: {} + + d3-format@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@3.1.0: {} + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + data-uri-to-buffer@4.0.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js-light@2.5.1: {} + + dedent@1.7.2: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + depd@2.0.0: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + diff@8.0.3: {} + + dotenv@17.3.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eciesjs@0.4.18: + dependencies: + '@ecies/ciphers': 0.2.5(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.321: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + env-paths@2.2.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-toolkit@1.45.1: {} + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 9.39.4(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.6.1)): + dependencies: + eslint: 9.39.4(jiti@2.6.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eventemitter3@5.0.4: {} + + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + express-rate-limit@8.3.1(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-uri@3.1.0: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + fuzzysort@3.1.0: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.5.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-own-enumerable-keys@1.0.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.5.0: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphql@16.13.1: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + headers-polyfill@4.0.3: {} + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + hono@4.12.8: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + human-signals@8.0.1: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immer@10.2.0: {} + + immer@11.1.4: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + internmap@2.0.3: {} + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + is-arrayish@0.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-node-process@1.2.0: {} + + is-number@7.0.0: {} + + is-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + + is-promise@4.0.0: {} + + is-regexp@3.1.0: {} + + is-stream@2.0.1: {} + + is-stream@4.0.1: {} + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isexe@2.0.0: {} + + isexe@3.1.5: {} + + jiti@2.6.1: {} + + jose@6.2.2: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lines-and-columns@1.2.4: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.577.0(react@19.2.4): + dependencies: + react: 19.2.4 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimic-fn@2.1.0: {} + + mimic-function@5.0.1: {} + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + ms@2.1.3: {} + + msw@2.12.14(@types/node@24.12.0)(typescript@5.9.3): + dependencies: + '@inquirer/confirm': 5.1.21(@types/node@24.12.0) + '@mswjs/interceptors': 0.41.3 + '@open-draft/deferred-promise': 2.2.0 + '@types/statuses': 2.0.6 + cookie: 1.1.1 + graphql: 16.13.1 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.10.1 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.1 + type-fest: 5.5.0 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + + mute-stream@2.0.0: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + negotiator@1.0.0: {} + + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-releases@2.0.36: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-treeify@1.1.33: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + outvariant@1.4.3: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-ms@4.0.0: {} + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-to-regexp@6.3.0: {} + + path-to-regexp@8.3.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pkce-challenge@5.0.1: {} + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + powershell-utils@0.1.0: {} + + prelude-ls@1.2.1: {} + + prettier-plugin-tailwindcss@0.7.2(prettier@3.8.1): + dependencies: + prettier: 3.8.1 + + prettier@3.8.1: {} + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-form': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-is@19.2.4: {} + + react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1): + dependencies: + '@types/use-sync-external-store': 0.0.6 + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + redux: 5.0.1 + + react-refresh@0.18.0: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.4) + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4) + use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + + react-router-dom@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + + react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + + react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + get-nonce: 1.0.1 + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react@19.2.4: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recharts@3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1): + dependencies: + '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4) + clsx: 2.1.1 + decimal.js-light: 2.5.1 + es-toolkit: 1.45.1 + eventemitter3: 5.0.4 + immer: 10.2.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-is: 19.2.4 + react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1) + reselect: 5.1.1 + tiny-invariant: 1.3.3 + use-sync-external-store: 1.6.0(react@19.2.4) + victory-vendor: 37.3.6 + transitivePeerDependencies: + - '@types/react' + - redux + + redux-thunk@3.1.0(redux@5.0.1): + dependencies: + redux: 5.0.1 + + redux@5.0.1: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + reselect@5.1.1: {} + + resolve-from@4.0.0: {} + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + rettime@0.10.1: {} + + reusify@1.1.0: {} + + rollup@4.60.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.0 + '@rollup/rollup-android-arm64': 4.60.0 + '@rollup/rollup-darwin-arm64': 4.60.0 + '@rollup/rollup-darwin-x64': 4.60.0 + '@rollup/rollup-freebsd-arm64': 4.60.0 + '@rollup/rollup-freebsd-x64': 4.60.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 + '@rollup/rollup-linux-arm-musleabihf': 4.60.0 + '@rollup/rollup-linux-arm64-gnu': 4.60.0 + '@rollup/rollup-linux-arm64-musl': 4.60.0 + '@rollup/rollup-linux-loong64-gnu': 4.60.0 + '@rollup/rollup-linux-loong64-musl': 4.60.0 + '@rollup/rollup-linux-ppc64-gnu': 4.60.0 + '@rollup/rollup-linux-ppc64-musl': 4.60.0 + '@rollup/rollup-linux-riscv64-gnu': 4.60.0 + '@rollup/rollup-linux-riscv64-musl': 4.60.0 + '@rollup/rollup-linux-s390x-gnu': 4.60.0 + '@rollup/rollup-linux-x64-gnu': 4.60.0 + '@rollup/rollup-linux-x64-musl': 4.60.0 + '@rollup/rollup-openbsd-x64': 4.60.0 + '@rollup/rollup-openharmony-arm64': 4.60.0 + '@rollup/rollup-win32-arm64-msvc': 4.60.0 + '@rollup/rollup-win32-ia32-msvc': 4.60.0 + '@rollup/rollup-win32-x64-gnu': 4.60.0 + '@rollup/rollup-win32-x64-msvc': 4.60.0 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-cookie-parser@2.7.2: {} + + setprototypeof@1.2.0: {} + + shadcn@4.1.0(@types/node@24.12.0)(typescript@5.9.3): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@dotenvx/dotenvx': 1.57.1 + '@modelcontextprotocol/sdk': 1.27.1(zod@3.25.76) + '@types/validate-npm-package-name': 4.0.2 + browserslist: 4.28.1 + commander: 14.0.3 + cosmiconfig: 9.0.1(typescript@5.9.3) + dedent: 1.7.2 + deepmerge: 4.3.1 + diff: 8.0.3 + execa: 9.6.1 + fast-glob: 3.3.3 + fs-extra: 11.3.4 + fuzzysort: 3.1.0 + https-proxy-agent: 7.0.6 + kleur: 4.1.5 + msw: 2.12.14(@types/node@24.12.0)(typescript@5.9.3) + node-fetch: 3.3.2 + open: 11.0.0 + ora: 8.2.0 + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + prompts: 2.4.2 + recast: 0.23.11 + stringify-object: 5.0.0 + tailwind-merge: 3.5.0 + ts-morph: 26.0.0 + tsconfig-paths: 4.2.0 + validate-npm-package-name: 7.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.1(zod@3.25.76) + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@types/node' + - babel-plugin-macros + - supports-color + - typescript + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sisteransi@1.0.5: {} + + source-map-js@1.2.1: {} + + source-map@0.6.1: {} + + statuses@2.0.2: {} + + stdin-discarder@0.2.2: {} + + strict-event-emitter@0.5.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + + stringify-object@5.0.0: + dependencies: + get-own-enumerable-keys: 1.0.0 + is-obj: 3.0.0 + is-regexp: 3.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tagged-tag@1.0.0: {} + + tailwind-merge@3.5.0: {} + + tailwindcss@4.2.2: {} + + tapable@2.3.0: {} + + tiny-invariant@1.3.3: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tldts-core@7.0.27: {} + + tldts@7.0.27: + dependencies: + tldts-core: 7.0.27 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tough-cookie@6.0.1: + dependencies: + tldts: 7.0.27 + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-morph@26.0.0: + dependencies: + '@ts-morph/common': 0.27.0 + code-block-writer: 13.0.3 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + tw-animate-css@1.4.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@5.5.0: + dependencies: + tagged-tag: 1.0.0 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + typescript-eslint@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici-types@7.16.0: {} + + unicorn-magic@0.3.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + until-async@3.0.2: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + + util-deprecate@1.0.2: {} + + validate-npm-package-name@7.0.2: {} + + vary@1.1.2: {} + + victory-vendor@37.3.6: + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + + vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0): + dependencies: + esbuild: 0.27.4 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.8 + rollup: 4.60.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.12.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.32.0 + + web-streams-polyfill@3.3.3: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@4.0.0: + dependencies: + isexe: 3.1.5 + + word-wrap@1.2.5: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yoctocolors-cjs@2.1.3: {} + + yoctocolors@2.1.2: {} + + zod-to-json-schema@3.25.1(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@3.25.76: {} + + zod@4.3.6: {} diff --git a/lazer/cardano/hermes/ui/public/vite.svg b/lazer/cardano/hermes/ui/public/vite.svg new file mode 100644 index 00000000..e7b8dfb1 --- /dev/null +++ b/lazer/cardano/hermes/ui/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lazer/cardano/hermes/ui/src/App.tsx b/lazer/cardano/hermes/ui/src/App.tsx new file mode 100644 index 00000000..2e0f41a2 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/App.tsx @@ -0,0 +1,16 @@ +import { BrowserRouter, Route, Routes } from "react-router-dom" +import { MarketDashboard } from "@/components/MarketDashboard" +import { HistoryPage } from "@/pages/HistoryPage" + +export function App() { + return ( + + + } /> + } /> + + + ) +} + +export default App diff --git a/lazer/cardano/hermes/ui/src/assets/react.svg b/lazer/cardano/hermes/ui/src/assets/react.svg new file mode 100644 index 00000000..6c87de9b --- /dev/null +++ b/lazer/cardano/hermes/ui/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lazer/cardano/hermes/ui/src/components/FillRow.tsx b/lazer/cardano/hermes/ui/src/components/FillRow.tsx new file mode 100644 index 00000000..fc51286c --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/FillRow.tsx @@ -0,0 +1,28 @@ +import { memo } from "react" +import type { Fill } from "@/types/market" + +interface FillRowProps { + fill: Fill +} + +function formatTime(ts: number): string { + return new Date(ts).toLocaleTimeString("en-GB") +} + +export const FillRow = memo(function FillRow({ fill }: FillRowProps) { + const isUp = fill.side === "UP" + + return ( +
+ + {formatTime(fill.timestamp)} + + + {fill.side} + + {fill.quantity} + {fill.price.toFixed(4)} + {fill.ownerAddress} +
+ ) +}) diff --git a/lazer/cardano/hermes/ui/src/components/MarketDashboard.tsx b/lazer/cardano/hermes/ui/src/components/MarketDashboard.tsx new file mode 100644 index 00000000..15400270 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/MarketDashboard.tsx @@ -0,0 +1,122 @@ +import { Link } from "react-router-dom" +import { useMarketStream } from "@/hooks/useMarketStream" +import { PriceChart } from "./PriceChart" +import { OrderBook } from "./OrderBook" +import { Positions } from "./Positions" +import { TradeForm } from "./TradeForm" + +const STATUS_LABEL = { + connecting: "○ CONNECTING", + live: "● LIVE", + disconnected: "○ DISCONNECTED", +} as const + +const STATUS_CLASS = { + connecting: "text-yellow-400", + live: "text-green-400", + disconnected: "text-muted-foreground", +} as const + +function formatTime(ts: number): string { + return new Date(ts).toLocaleTimeString("en-GB") +} + +function formatCountdown(secs: number): string { + const m = Math.floor(secs / 60) + .toString() + .padStart(2, "0") + const s = (secs % 60).toString().padStart(2, "0") + return `${m}:${s}` +} + +function countdownClass(secs: number): string { + if (secs > 60) return "text-green-400" + if (secs > 10) return "text-yellow-400" + return "text-red-400" +} + +export function MarketDashboard() { + const { + market, + secondsRemaining, + priceTicks, + currentBtcPriceStr, + orders, + fills, + positionSummary, + rollingAverages, + status, + placeOrder, + } = useMarketStream() + + const strikePrice = market?.strikePrice + + return ( +
+
+ + BTC/USD PREDICTION MARKET + + + + {STATUS_LABEL[status]} + + + + HISTORY → + + + + {market && ( + <> + + + START{" "} + + {formatTime(market.startTime)} + + + + + + END{" "} + + {formatTime(market.endTime)} + + + + + + ENDS IN{" "} + + {formatCountdown(secondsRemaining)} + + + + )} +
+ +
+
+ + + +
+
+ +
+
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/OrderBook.tsx b/lazer/cardano/hermes/ui/src/components/OrderBook.tsx new file mode 100644 index 00000000..995acb2a --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/OrderBook.tsx @@ -0,0 +1,30 @@ +import type { Order } from "@/types/market" +import { TuiPanel } from "./TuiPanel" +import { OrderRow } from "./OrderRow" + +interface OrderBookProps { + orders: Order[] + strikePrice: number | undefined +} + +export function OrderBook({ orders, strikePrice }: OrderBookProps) { + return ( + ${strikePrice !== undefined ? `$${strikePrice.toLocaleString()}` : "—"}`} + > +
+ TIME + SIDE + TYPE + PRICE + QTY + OWNER +
+
+ {orders.map((order) => ( + + ))} +
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/OrderRow.tsx b/lazer/cardano/hermes/ui/src/components/OrderRow.tsx new file mode 100644 index 00000000..ea2ecd39 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/OrderRow.tsx @@ -0,0 +1,34 @@ +import { memo } from "react" +import type { Order } from "@/types/market" + +interface OrderRowProps { + order: Order +} + +function formatTime(ts: number): string { + return new Date(ts).toLocaleTimeString("en-GB") +} + +export const OrderRow = memo(function OrderRow({ order }: OrderRowProps) { + const isBuy = order.action === "BUY" + const isUp = order.side === "UP" + + return ( +
+ + {formatTime(order.timestamp)} + + + {order.side} + + {order.action} + {order.price.toFixed(4)} + {order.quantity} + {order.ownerAddress} +
+ ) +}) diff --git a/lazer/cardano/hermes/ui/src/components/Positions.tsx b/lazer/cardano/hermes/ui/src/components/Positions.tsx new file mode 100644 index 00000000..c9daa999 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/Positions.tsx @@ -0,0 +1,44 @@ +import type { Fill, PositionSummary } from "@/types/market" +import { TuiPanel } from "./TuiPanel" +import { FillRow } from "./FillRow" + +interface PositionsProps { + fills: Fill[] + summary: PositionSummary +} + +export function Positions({ fills, summary }: PositionsProps) { + return ( + +
+ + UP + {": "} + {summary.upContracts} + {" @ "} + {summary.upAvgPrice.toFixed(4)} + + + + DOWN + {": "} + {summary.downContracts} + {" @ "} + {summary.downAvgPrice.toFixed(4)} + +
+
+ TIME + SIDE + QTY + PRICE + OWNER +
+
+ {fills.map((fill) => ( + + ))} +
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/PriceChart.tsx b/lazer/cardano/hermes/ui/src/components/PriceChart.tsx new file mode 100644 index 00000000..7ce63964 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/PriceChart.tsx @@ -0,0 +1,103 @@ +import { + CartesianGrid, + Line, + LineChart, + ReferenceLine, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from "recharts" +import type { PriceTick } from "@/types/market" +import { TuiPanel } from "./TuiPanel" + +interface PriceChartProps { + ticks: PriceTick[] + strikePrice: number | undefined + currentPrice: string +} + +function formatTime(ts: number): string { + return new Date(ts).toLocaleTimeString("en-GB") +} + +function formatUsd(v: number): string { + return `$${Math.round(v).toLocaleString()}` +} + +export function PriceChart({ + ticks, + strikePrice, + currentPrice, +}: PriceChartProps) { + return ( + +
+ + + + + + formatTime(v as number)} + formatter={(v) => [formatUsd(Number(v)), "BTC/USD"]} + /> + {strikePrice !== undefined && ( + + )} + + parseFloat((tick as PriceTick).btcPriceStr) + } + stroke="#facc15" + strokeWidth={1.5} + dot={false} + isAnimationActive={false} + /> + + +
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/TradeForm.tsx b/lazer/cardano/hermes/ui/src/components/TradeForm.tsx new file mode 100644 index 00000000..9e88580d --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/TradeForm.tsx @@ -0,0 +1,241 @@ +import { useEffect, useState } from "react" +import type { PlaceOrderPayload, RollingAverages } from "@/types/market" +import { TuiPanel } from "./TuiPanel" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" + +interface TradeFormProps { + averages: RollingAverages + strikePrice: number | undefined + onPlaceOrder: (payload: PlaceOrderPayload) => void +} + +interface LastAction { + verb: string + qty: number + side: string + price: string +} + +export function TradeForm({ + averages, + strikePrice, + onPlaceOrder, +}: TradeFormProps) { + const [buyQty, setBuyQty] = useState("100") + const [buyUpPrice, setBuyUpPrice] = useState("") + const [buyDownPrice, setBuyDownPrice] = useState("") + + const [sellQty, setSellQty] = useState("100") + const [sellUpPrice, setSellUpPrice] = useState("") + const [sellDownPrice, setSellDownPrice] = useState("") + + const [lastAction, setLastAction] = useState(null) + + // Pre-fill price fields from rolling averages only when the field is empty + // (i.e., the user hasn't typed a custom value yet) + useEffect(() => { + if (!buyUpPrice) setBuyUpPrice(averages.upBuyAvg.toFixed(4)) + }, [averages.upBuyAvg, buyUpPrice]) + + useEffect(() => { + if (!buyDownPrice) setBuyDownPrice(averages.downBuyAvg.toFixed(4)) + }, [averages.downBuyAvg, buyDownPrice]) + + useEffect(() => { + if (!sellUpPrice) setSellUpPrice(averages.upSellAvg.toFixed(4)) + }, [averages.upSellAvg, sellUpPrice]) + + useEffect(() => { + if (!sellDownPrice) setSellDownPrice(averages.downSellAvg.toFixed(4)) + }, [averages.downSellAvg, sellDownPrice]) + + function validate(qty: string, price: string): boolean { + const q = parseInt(qty, 10) + const p = parseFloat(price) + return !isNaN(q) && q > 0 && !isNaN(p) && p > 0 && p <= 1 + } + + function handleBuy(side: "UP" | "DOWN") { + const price = side === "UP" ? buyUpPrice : buyDownPrice + if (!validate(buyQty, price)) return + const qty = parseInt(buyQty, 10) + onPlaceOrder({ + side, + action: "BUY", + price: parseFloat(price), + quantity: qty, + }) + setLastAction({ verb: "BUY", qty, side, price }) + } + + function handleSell(side: "UP" | "DOWN") { + const price = side === "UP" ? sellUpPrice : sellDownPrice + if (!validate(sellQty, price)) return + const qty = parseInt(sellQty, 10) + onPlaceOrder({ + side, + action: "SELL", + price: parseFloat(price), + quantity: qty, + }) + setLastAction({ verb: "SELL", qty, side, price }) + } + + return ( + ${strikePrice !== undefined ? `$${strikePrice.toLocaleString()}` : "—"}`} + className="h-full" + > + + + + BUY + + + SELL + + + + +
+ + setBuyQty(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> +
+ +
+
+ + setBuyUpPrice(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> + +
+ +
+ + setBuyDownPrice(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> + +
+
+
+ + +
+ + setSellQty(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> +
+ +
+
+ + setSellUpPrice(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> + +
+ +
+ + setSellDownPrice(e.target.value)} + className="h-7 rounded-none border-border font-mono text-xs" + /> + +
+
+
+
+ + {lastAction && ( +
+ {">"}{" "} + + {lastAction.verb} + {" "} + {lastAction.qty}{" "} + + {lastAction.side} + {" "} + @ {lastAction.price} +
+ )} +
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/TuiPanel.tsx b/lazer/cardano/hermes/ui/src/components/TuiPanel.tsx new file mode 100644 index 00000000..43d21577 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/TuiPanel.tsx @@ -0,0 +1,23 @@ +import { cn } from "@/lib/utils" + +interface TuiPanelProps { + title: string + children: React.ReactNode + className?: string +} + +export function TuiPanel({ title, children, className }: TuiPanelProps) { + return ( +
+
+ ┌─ + [ {title} ] + + {"─".repeat(200)} + + ─┐ +
+
{children}
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/components/theme-provider.tsx b/lazer/cardano/hermes/ui/src/components/theme-provider.tsx new file mode 100644 index 00000000..1349a0ca --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/theme-provider.tsx @@ -0,0 +1,230 @@ +/* eslint-disable react-refresh/only-export-components */ +import * as React from "react" + +type Theme = "dark" | "light" | "system" +type ResolvedTheme = "dark" | "light" + +type ThemeProviderProps = { + children: React.ReactNode + defaultTheme?: Theme + storageKey?: string + disableTransitionOnChange?: boolean +} + +type ThemeProviderState = { + theme: Theme + setTheme: (theme: Theme) => void +} + +const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)" +const THEME_VALUES: Theme[] = ["dark", "light", "system"] + +const ThemeProviderContext = React.createContext< + ThemeProviderState | undefined +>(undefined) + +function isTheme(value: string | null): value is Theme { + if (value === null) { + return false + } + + return THEME_VALUES.includes(value as Theme) +} + +function getSystemTheme(): ResolvedTheme { + if (window.matchMedia(COLOR_SCHEME_QUERY).matches) { + return "dark" + } + + return "light" +} + +function disableTransitionsTemporarily() { + const style = document.createElement("style") + style.appendChild( + document.createTextNode( + "*,*::before,*::after{-webkit-transition:none!important;transition:none!important}" + ) + ) + document.head.appendChild(style) + + return () => { + window.getComputedStyle(document.body) + requestAnimationFrame(() => { + requestAnimationFrame(() => { + style.remove() + }) + }) + } +} + +function isEditableTarget(target: EventTarget | null) { + if (!(target instanceof HTMLElement)) { + return false + } + + if (target.isContentEditable) { + return true + } + + const editableParent = target.closest( + "input, textarea, select, [contenteditable='true']" + ) + if (editableParent) { + return true + } + + return false +} + +export function ThemeProvider({ + children, + defaultTheme = "system", + storageKey = "theme", + disableTransitionOnChange = true, + ...props +}: ThemeProviderProps) { + const [theme, setThemeState] = React.useState(() => { + const storedTheme = localStorage.getItem(storageKey) + if (isTheme(storedTheme)) { + return storedTheme + } + + return defaultTheme + }) + + const setTheme = React.useCallback( + (nextTheme: Theme) => { + localStorage.setItem(storageKey, nextTheme) + setThemeState(nextTheme) + }, + [storageKey] + ) + + const applyTheme = React.useCallback( + (nextTheme: Theme) => { + const root = document.documentElement + const resolvedTheme = + nextTheme === "system" ? getSystemTheme() : nextTheme + const restoreTransitions = disableTransitionOnChange + ? disableTransitionsTemporarily() + : null + + root.classList.remove("light", "dark") + root.classList.add(resolvedTheme) + + if (restoreTransitions) { + restoreTransitions() + } + }, + [disableTransitionOnChange] + ) + + React.useEffect(() => { + applyTheme(theme) + + if (theme !== "system") { + return undefined + } + + const mediaQuery = window.matchMedia(COLOR_SCHEME_QUERY) + const handleChange = () => { + applyTheme("system") + } + + mediaQuery.addEventListener("change", handleChange) + + return () => { + mediaQuery.removeEventListener("change", handleChange) + } + }, [theme, applyTheme]) + + React.useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.repeat) { + return + } + + if (event.metaKey || event.ctrlKey || event.altKey) { + return + } + + if (isEditableTarget(event.target)) { + return + } + + if (event.key.toLowerCase() !== "d") { + return + } + + setThemeState((currentTheme) => { + const nextTheme = + currentTheme === "dark" + ? "light" + : currentTheme === "light" + ? "dark" + : getSystemTheme() === "dark" + ? "light" + : "dark" + + localStorage.setItem(storageKey, nextTheme) + return nextTheme + }) + } + + window.addEventListener("keydown", handleKeyDown) + + return () => { + window.removeEventListener("keydown", handleKeyDown) + } + }, [storageKey]) + + React.useEffect(() => { + const handleStorageChange = (event: StorageEvent) => { + if (event.storageArea !== localStorage) { + return + } + + if (event.key !== storageKey) { + return + } + + if (isTheme(event.newValue)) { + setThemeState(event.newValue) + return + } + + setThemeState(defaultTheme) + } + + window.addEventListener("storage", handleStorageChange) + + return () => { + window.removeEventListener("storage", handleStorageChange) + } + }, [defaultTheme, storageKey]) + + const value = React.useMemo( + () => ({ + theme, + setTheme, + }), + [theme, setTheme] + ) + + return ( + + {children} + + ) +} + +export const useTheme = () => { + const context = React.useContext(ThemeProviderContext) + + if (context === undefined) { + throw new Error("useTheme must be used within a ThemeProvider") + } + + return context +} diff --git a/lazer/cardano/hermes/ui/src/components/ui/badge.tsx b/lazer/cardano/hermes/ui/src/components/ui/badge.tsx new file mode 100644 index 00000000..cacff11d --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/ui/badge.tsx @@ -0,0 +1,49 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "radix-ui" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", + secondary: + "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80", + destructive: + "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20", + outline: + "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground", + ghost: + "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50", + link: "text-primary underline-offset-4 hover:underline", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant = "default", + asChild = false, + ...props +}: React.ComponentProps<"span"> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot.Root : "span" + + return ( + + ) +} + +export { Badge, badgeVariants } diff --git a/lazer/cardano/hermes/ui/src/components/ui/button.tsx b/lazer/cardano/hermes/ui/src/components/ui/button.tsx new file mode 100644 index 00000000..c88ffd6f --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/ui/button.tsx @@ -0,0 +1,67 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "radix-ui" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", + outline: + "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", + ghost: + "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50", + destructive: + "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: + "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", + xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", + sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", + lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", + icon: "size-8", + "icon-xs": + "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", + "icon-sm": + "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", + "icon-lg": "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +function Button({ + className, + variant = "default", + size = "default", + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean + }) { + const Comp = asChild ? Slot.Root : "button" + + return ( + + ) +} + +export { Button, buttonVariants } diff --git a/lazer/cardano/hermes/ui/src/components/ui/input.tsx b/lazer/cardano/hermes/ui/src/components/ui/input.tsx new file mode 100644 index 00000000..d763cd9a --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/ui/input.tsx @@ -0,0 +1,19 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Input({ className, type, ...props }: React.ComponentProps<"input">) { + return ( + + ) +} + +export { Input } diff --git a/lazer/cardano/hermes/ui/src/components/ui/tabs.tsx b/lazer/cardano/hermes/ui/src/components/ui/tabs.tsx new file mode 100644 index 00000000..2cb6924e --- /dev/null +++ b/lazer/cardano/hermes/ui/src/components/ui/tabs.tsx @@ -0,0 +1,88 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" +import { Tabs as TabsPrimitive } from "radix-ui" + +import { cn } from "@/lib/utils" + +function Tabs({ + className, + orientation = "horizontal", + ...props +}: React.ComponentProps) { + return ( + + ) +} + +const tabsListVariants = cva( + "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none", + { + variants: { + variant: { + default: "bg-muted", + line: "gap-1 bg-transparent", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function TabsList({ + className, + variant = "default", + ...props +}: React.ComponentProps & + VariantProps) { + return ( + + ) +} + +function TabsTrigger({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function TabsContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants } diff --git a/lazer/cardano/hermes/ui/src/hooks/useMarketStream.ts b/lazer/cardano/hermes/ui/src/hooks/useMarketStream.ts new file mode 100644 index 00000000..04dbc4ee --- /dev/null +++ b/lazer/cardano/hermes/ui/src/hooks/useMarketStream.ts @@ -0,0 +1,160 @@ +import { useCallback, useEffect, useRef, useState } from "react" +import type { + ClientMessage, + Fill, + Market, + Order, + PlaceOrderPayload, + PositionSummary, + PriceTick, + RollingAverages, + ServerMessage, +} from "@/types/market" + +// The WS URL can be overridden via environment variable for production deploys. +// In development the Vite proxy forwards /ws → ws://localhost:8080 (see vite.config.ts). +const WS_URL = + (import.meta.env.VITE_WS_URL as string | undefined) ?? + "ws://localhost:8080/ws" + +const MAX_TICKS = 120 +const MAX_ORDERS = 50 +const MAX_FILLS = 30 + +export type ConnectionStatus = "connecting" | "live" | "disconnected" + +const DEFAULT_AVG: RollingAverages = { + upBuyAvg: 0.5, + upSellAvg: 0.5, + downBuyAvg: 0.5, + downSellAvg: 0.5, +} + +const DEFAULT_SUMMARY: PositionSummary = { + upContracts: 0, + upAvgPrice: 0, + downContracts: 0, + downAvgPrice: 0, +} + +export interface MarketStreamData { + market: Market | null + secondsRemaining: number + priceTicks: PriceTick[] + currentBtcPriceStr: string + orders: Order[] + fills: Fill[] + positionSummary: PositionSummary + rollingAverages: RollingAverages + status: ConnectionStatus + placeOrder: (payload: PlaceOrderPayload) => void +} + +export function useMarketStream(): MarketStreamData { + const [market, setMarket] = useState(null) + const [secondsRemaining, setSecondsRemaining] = useState(0) + const [priceTicks, setPriceTicks] = useState([]) + const [orders, setOrders] = useState([]) + const [fills, setFills] = useState([]) + const [positionSummary, setPositionSummary] = + useState(DEFAULT_SUMMARY) + const [rollingAverages, setRollingAverages] = + useState(DEFAULT_AVG) + const [status, setStatus] = useState("connecting") + + const wsRef = useRef(null) + + // ── WebSocket connection ──────────────────────────────────────────────────── + + useEffect(() => { + const ws = new WebSocket(WS_URL) + wsRef.current = ws + + ws.onopen = () => setStatus("live") + ws.onclose = () => setStatus("disconnected") + ws.onerror = () => setStatus("disconnected") + + ws.onmessage = (event: MessageEvent) => { + const msg = JSON.parse(event.data) as ServerMessage + + switch (msg.type) { + case "connected": + setMarket(msg.data.market) + break + + case "market_started": + setMarket(msg.data.market) + // Reset all market-scoped state for the new market + setPriceTicks([]) + setOrders([]) + setFills([]) + setPositionSummary(DEFAULT_SUMMARY) + setRollingAverages(DEFAULT_AVG) + break + + case "price_tick": + setPriceTicks((prev) => [...prev.slice(-(MAX_TICKS - 1)), msg.data]) + break + + case "order": + setOrders((prev) => [msg.data, ...prev].slice(0, MAX_ORDERS)) + break + + case "fill": + setFills((prev) => [msg.data, ...prev].slice(0, MAX_FILLS)) + break + + case "position_summary": + setPositionSummary(msg.data) + break + + case "rolling_averages": + setRollingAverages(msg.data) + break + } + } + + return () => ws.close() + }, []) + + // ── Countdown timer ───────────────────────────────────────────────────────── + + useEffect(() => { + if (!market) return + // Tick immediately, then every second + setSecondsRemaining( + Math.max(0, Math.round((market.endTime - Date.now()) / 1000)) + ) + const id = setInterval(() => { + setSecondsRemaining( + Math.max(0, Math.round((market.endTime - Date.now()) / 1000)) + ) + }, 1_000) + return () => clearInterval(id) + }, [market]) + + // ── placeOrder ────────────────────────────────────────────────────────────── + + const placeOrder = useCallback((payload: PlaceOrderPayload) => { + const ws = wsRef.current + if (!ws || ws.readyState !== WebSocket.OPEN) return + const msg: ClientMessage = { type: "place_order", data: payload } + ws.send(JSON.stringify(msg)) + }, []) + + const currentBtcPriceStr = + priceTicks.length > 0 ? priceTicks[priceTicks.length - 1].btcPriceStr : "" + + return { + market, + secondsRemaining, + priceTicks, + currentBtcPriceStr, + orders, + fills, + positionSummary, + rollingAverages, + status, + placeOrder, + } +} diff --git a/lazer/cardano/hermes/ui/src/index.css b/lazer/cardano/hermes/ui/src/index.css new file mode 100644 index 00000000..024a264b --- /dev/null +++ b/lazer/cardano/hermes/ui/src/index.css @@ -0,0 +1,133 @@ +@import "tailwindcss"; +@import "tw-animate-css"; +@import "shadcn/tailwind.css"; +@import "@fontsource-variable/geist"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --font-heading: var(--font-sans); + --font-sans: 'Geist Variable', sans-serif; + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --color-foreground: var(--foreground); + --color-background: var(--background); + --radius-sm: calc(var(--radius) * 0.6); + --radius-md: calc(var(--radius) * 0.8); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) * 1.4); + --radius-2xl: calc(var(--radius) * 1.8); + --radius-3xl: calc(var(--radius) * 2.2); + --radius-4xl: calc(var(--radius) * 2.6); +} + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.87 0 0); + --chart-2: oklch(0.556 0 0); + --chart-3: oklch(0.439 0 0); + --chart-4: oklch(0.371 0 0); + --chart-5: oklch(0.269 0 0); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.87 0 0); + --chart-2: oklch(0.556 0 0); + --chart-3: oklch(0.439 0 0); + --chart-4: oklch(0.371 0 0); + --chart-5: oklch(0.269 0 0); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } + html { + @apply font-sans; + } +} +.tui-scroll::-webkit-scrollbar { width: 4px; } +.tui-scroll::-webkit-scrollbar-track { background: transparent; } +.tui-scroll::-webkit-scrollbar-thumb { background: oklch(1 0 0 / 15%); border-radius: 0; } diff --git a/lazer/cardano/hermes/ui/src/lib/utils.ts b/lazer/cardano/hermes/ui/src/lib/utils.ts new file mode 100644 index 00000000..bd0c391d --- /dev/null +++ b/lazer/cardano/hermes/ui/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/lazer/cardano/hermes/ui/src/main.tsx b/lazer/cardano/hermes/ui/src/main.tsx new file mode 100644 index 00000000..2c36773b --- /dev/null +++ b/lazer/cardano/hermes/ui/src/main.tsx @@ -0,0 +1,14 @@ +import { StrictMode } from "react" +import { createRoot } from "react-dom/client" + +import "./index.css" +import App from "./App.tsx" +import { ThemeProvider } from "@/components/theme-provider.tsx" + +createRoot(document.getElementById("root")!).render( + + + + + +) diff --git a/lazer/cardano/hermes/ui/src/pages/HistoryPage.tsx b/lazer/cardano/hermes/ui/src/pages/HistoryPage.tsx new file mode 100644 index 00000000..b19240a6 --- /dev/null +++ b/lazer/cardano/hermes/ui/src/pages/HistoryPage.tsx @@ -0,0 +1,152 @@ +import { useState } from "react" +import { Link } from "react-router-dom" +import type { MarketHistoryEntry } from "@/types/market" +import { TuiPanel } from "@/components/TuiPanel" +import { Input } from "@/components/ui/input" +import { Button } from "@/components/ui/button" + +// In development, Vite proxies /api → http://localhost:8080 (see vite.config.ts). +// Override with VITE_API_URL for production. +const API_BASE = (import.meta.env.VITE_API_URL as string | undefined) ?? "" + +function formatTime(ts: number): string { + return new Date(ts).toLocaleTimeString("en-GB") +} + +function formatUsd(v: number): string { + return `$${Math.round(v).toLocaleString()}` +} + +function shortId(id: string): string { + return id.length > 8 ? id.slice(0, 8) + "…" : id +} + +export function HistoryPage() { + const [address, setAddress] = useState("") + const [entries, setEntries] = useState([]) + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const [loaded, setLoaded] = useState(false) + + async function load() { + setLoading(true) + setError(null) + try { + const params = address ? `?address=${encodeURIComponent(address)}` : "" + const res = await fetch(`${API_BASE}/api/markets/history${params}`) + if (!res.ok) throw new Error(`HTTP ${res.status}`) + const data = (await res.json()) as MarketHistoryEntry[] + setEntries(data) + setLoaded(true) + } catch (err) { + setError(err instanceof Error ? err.message : "fetch failed") + } finally { + setLoading(false) + } + } + + function handleKeyDown(e: React.KeyboardEvent) { + if (e.key === "Enter") void load() + } + + return ( +
+
+ + ← LIVE MARKET + + + + PAST MARKETS + +
+ +
+ +
+ address: + setAddress(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="addr_1 … or leave empty" + className="h-7 w-64 rounded-none border-border font-mono text-xs" + /> + +
+ + {error &&
! {error}
} + + {loaded && ( + <> + {/* Header row */} +
+ MARKET + START + END + STRIKE + FINAL + OUTCOME + YOU +
+ + {entries.length === 0 && ( +
+ no markets found +
+ )} + + {entries.map((entry) => { + const pos = entry.userPosition + const isUp = entry.outcome === "UP" + + return ( +
+ + {shortId(entry.marketId)} + + + {formatTime(entry.startTime)} + + + {formatTime(entry.endTime)} + + {formatUsd(entry.strikePrice)} + {formatUsd(entry.finalBtcPrice)} + + {entry.outcome} {isUp ? "▲" : "▼"} + + {pos ? ( + + {pos.result} {pos.pnl >= 0 ? "+" : ""} + {pos.pnl.toFixed(2)} + + ) : ( + + )} +
+ ) + })} + + )} +
+
+
+ ) +} diff --git a/lazer/cardano/hermes/ui/src/types/market.ts b/lazer/cardano/hermes/ui/src/types/market.ts new file mode 100644 index 00000000..f17bf89f --- /dev/null +++ b/lazer/cardano/hermes/ui/src/types/market.ts @@ -0,0 +1,93 @@ +// Keep in sync with server/src/types.ts + +export interface Market { + id: string // future: on-chain market ID (uint256) + startTime: number // ms timestamp — future: from block.timestamp at creation + endTime: number // ms timestamp — future: startTime + duration from contract + strikePrice: number // future: read from contract's stored strike at creation +} + +export type Side = "UP" | "DOWN" +export type Action = "BUY" | "SELL" +export type MarketOutcome = "UP" | "DOWN" +export type UserResult = "WON" | "LOST" + +export interface UserPosition { + side: Side + quantity: number + avgPrice: number // price paid per share (0–1) + result: UserResult + pnl: number +} + +export interface MarketHistoryEntry { + marketId: string + startTime: number // ms + endTime: number // ms + strikePrice: number + finalBtcPrice: number + outcome: MarketOutcome + userPosition: UserPosition | null +} + +export interface PriceTick { + timestamp: number + btcPriceStr: string // display-ready decimal string, e.g. "67543.21" (BigNumber-computed) + btcPriceRaw: string // raw Pyth integer string, e.g. "6754321000000" + exponent: number // e.g. -8; actual = btcPriceRaw * 10^exponent +} + +export interface Order { + id: string + timestamp: number + side: Side + action: Action + price: number // 0–1 probability price of the bet position + quantity: number + ownerAddress: string // plain string; format determined by backend/wallet +} + +export interface Fill { + id: string + timestamp: number + side: Side + quantity: number + price: number + ownerAddress: string +} + +export interface PositionSummary { + upContracts: number + upAvgPrice: number + downContracts: number + downAvgPrice: number +} + +export interface RollingAverages { + upBuyAvg: number + upSellAvg: number + downBuyAvg: number + downSellAvg: number +} + +// ── Server → Client ─────────────────────────────────────────────────────────── + +export type ServerMessage = + | { type: "connected"; data: { market: Market } } + | { type: "market_started"; data: { market: Market } } + | { type: "price_tick"; data: PriceTick } + | { type: "order"; data: Order } + | { type: "fill"; data: Fill } + | { type: "position_summary"; data: PositionSummary } + | { type: "rolling_averages"; data: RollingAverages } + +// ── Client → Server ─────────────────────────────────────────────────────────── + +export interface PlaceOrderPayload { + side: Side + action: Action + price: number + quantity: number +} + +export type ClientMessage = { type: "place_order"; data: PlaceOrderPayload } diff --git a/lazer/cardano/hermes/ui/tsconfig.app.json b/lazer/cardano/hermes/ui/tsconfig.app.json new file mode 100644 index 00000000..a1323130 --- /dev/null +++ b/lazer/cardano/hermes/ui/tsconfig.app.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/lazer/cardano/hermes/ui/tsconfig.json b/lazer/cardano/hermes/ui/tsconfig.json new file mode 100644 index 00000000..fec8c8e5 --- /dev/null +++ b/lazer/cardano/hermes/ui/tsconfig.json @@ -0,0 +1,13 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ], + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/lazer/cardano/hermes/ui/tsconfig.node.json b/lazer/cardano/hermes/ui/tsconfig.node.json new file mode 100644 index 00000000..8a67f62f --- /dev/null +++ b/lazer/cardano/hermes/ui/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/lazer/cardano/hermes/ui/vite.config.ts b/lazer/cardano/hermes/ui/vite.config.ts new file mode 100644 index 00000000..c8c5e7ef --- /dev/null +++ b/lazer/cardano/hermes/ui/vite.config.ts @@ -0,0 +1,27 @@ +import path from "path" +import tailwindcss from "@tailwindcss/vite" +import react from "@vitejs/plugin-react" +import { defineConfig } from "vite" + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react(), tailwindcss()], + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, + }, + server: { + proxy: { + // Forwards /ws → ws://localhost:8080 so the UI avoids CORS issues in dev. + // VITE_WS_URL defaults to "ws://localhost:8080/ws" which uses this proxy. + "/ws": { + target: "ws://localhost:8080", + ws: true, + }, + "/api": { + target: "http://localhost:8080", + }, + }, + }, +}) From ee265c662c3656d93c5664bf4e1b12c428d7268d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Ludue=C3=B1a?= Date: Sun, 22 Mar 2026 20:00:41 -0300 Subject: [PATCH 2/5] feat: onchain update --- .../hermes/{src => }/onchain/.gitignore | 0 .../hermes/{src => }/onchain/README.md | 0 lazer/cardano/hermes/onchain/aiken.lock | 27 ++ .../hermes/{src => }/onchain/aiken.toml | 5 + lazer/cardano/hermes/onchain/lib/contants.ak | 8 + .../types.ak => onchain/lib/hermes_types.ak} | 10 +- .../lib/subvalidators/common_checks.ak | 41 ++ .../lib/subvalidators/market_checks.ak | 247 ++++++++++ .../onchain/lib/subvalidators/order_checks.ak | 169 +++++++ lazer/cardano/hermes/onchain/plutus.json | 449 ++++++++++++++++++ .../hermes/onchain/validators/market.ak | 80 ++++ .../hermes/onchain/validators/order.ak | 57 +++ lazer/cardano/hermes/src/onchain/aiken.lock | 15 - lazer/cardano/hermes/src/onchain/plutus.json | 387 --------------- .../hermes/src/onchain/validators/market.ak | 22 - .../hermes/src/onchain/validators/order.ak | 23 - 16 files changed, 1089 insertions(+), 451 deletions(-) rename lazer/cardano/hermes/{src => }/onchain/.gitignore (100%) rename lazer/cardano/hermes/{src => }/onchain/README.md (100%) create mode 100644 lazer/cardano/hermes/onchain/aiken.lock rename lazer/cardano/hermes/{src => }/onchain/aiken.toml (78%) create mode 100644 lazer/cardano/hermes/onchain/lib/contants.ak rename lazer/cardano/hermes/{src/onchain/lib/types.ak => onchain/lib/hermes_types.ak} (85%) create mode 100644 lazer/cardano/hermes/onchain/lib/subvalidators/common_checks.ak create mode 100644 lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak create mode 100644 lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak create mode 100644 lazer/cardano/hermes/onchain/plutus.json create mode 100644 lazer/cardano/hermes/onchain/validators/market.ak create mode 100644 lazer/cardano/hermes/onchain/validators/order.ak delete mode 100644 lazer/cardano/hermes/src/onchain/aiken.lock delete mode 100644 lazer/cardano/hermes/src/onchain/plutus.json delete mode 100644 lazer/cardano/hermes/src/onchain/validators/market.ak delete mode 100644 lazer/cardano/hermes/src/onchain/validators/order.ak diff --git a/lazer/cardano/hermes/src/onchain/.gitignore b/lazer/cardano/hermes/onchain/.gitignore similarity index 100% rename from lazer/cardano/hermes/src/onchain/.gitignore rename to lazer/cardano/hermes/onchain/.gitignore diff --git a/lazer/cardano/hermes/src/onchain/README.md b/lazer/cardano/hermes/onchain/README.md similarity index 100% rename from lazer/cardano/hermes/src/onchain/README.md rename to lazer/cardano/hermes/onchain/README.md diff --git a/lazer/cardano/hermes/onchain/aiken.lock b/lazer/cardano/hermes/onchain/aiken.lock new file mode 100644 index 00000000..0bfd0179 --- /dev/null +++ b/lazer/cardano/hermes/onchain/aiken.lock @@ -0,0 +1,27 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v3.0.0" +source = "github" + +[[requirements]] +name = "pyth-network/pyth-lazer-cardano" +version = "main" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v3.0.0" +requirements = [] +source = "github" + +[[packages]] +name = "pyth-network/pyth-lazer-cardano" +version = "main" +requirements = [] +source = "github" + +[etags] +"pyth-network/pyth-lazer-cardano@main" = [{ secs_since_epoch = 1774219791, nanos_since_epoch = 77626650 }, "a46dacd97a22eb07feeaf966d48c3116c8249ddc836705656e3135cea285bcfc"] diff --git a/lazer/cardano/hermes/src/onchain/aiken.toml b/lazer/cardano/hermes/onchain/aiken.toml similarity index 78% rename from lazer/cardano/hermes/src/onchain/aiken.toml rename to lazer/cardano/hermes/onchain/aiken.toml index 483c43bd..7839f420 100644 --- a/lazer/cardano/hermes/src/onchain/aiken.toml +++ b/lazer/cardano/hermes/onchain/aiken.toml @@ -15,4 +15,9 @@ name = "aiken-lang/stdlib" version = "v3.0.0" source = "github" +[[dependencies]] +name = "pyth-network/pyth-lazer-cardano" +version = "main" +source = "github" + [config] diff --git a/lazer/cardano/hermes/onchain/lib/contants.ak b/lazer/cardano/hermes/onchain/lib/contants.ak new file mode 100644 index 00000000..d744adff --- /dev/null +++ b/lazer/cardano/hermes/onchain/lib/contants.ak @@ -0,0 +1,8 @@ +pub const up_tn = "UP" + +pub const down_tn = "DOWN" + +pub const control_token_tn = "CONTROL" + +// Milliseconds in 5 minutes +pub const five_minutes = 300_000 diff --git a/lazer/cardano/hermes/src/onchain/lib/types.ak b/lazer/cardano/hermes/onchain/lib/hermes_types.ak similarity index 85% rename from lazer/cardano/hermes/src/onchain/lib/types.ak rename to lazer/cardano/hermes/onchain/lib/hermes_types.ak index 4ae4914b..89d2e051 100644 --- a/lazer/cardano/hermes/src/onchain/lib/types.ak +++ b/lazer/cardano/hermes/onchain/lib/hermes_types.ak @@ -23,12 +23,13 @@ pub type OrderDatum { operation: Operation, price: Price, owner: VerificationKeyHash, + expected_tokens: Int, } pub type OrderRedeemer { Cancel Match - Fill + Fill(Int) } pub type OrderMintRedeemer { @@ -39,14 +40,15 @@ pub type OrderMintRedeemer { pub type MarketDatum { start_price: Price, end_price: Option, - ramaining_shares: Int, + remaining_shares: Int, } pub type MarketRedeemer { RecordFinalPrice - ClaimWinnings - ClaimLosings + ClaimWinnings(Int) + ClaimLosings(Int) CloseMarket + ProcessMatch } pub type MarketMintRedeemer { diff --git a/lazer/cardano/hermes/onchain/lib/subvalidators/common_checks.ak b/lazer/cardano/hermes/onchain/lib/subvalidators/common_checks.ak new file mode 100644 index 00000000..c4395e8c --- /dev/null +++ b/lazer/cardano/hermes/onchain/lib/subvalidators/common_checks.ak @@ -0,0 +1,41 @@ +use aiken/collection/dict as dict +use aiken/collection/list +use aiken/math/rational.{denominator, numerator} +use cardano/assets.{PolicyId, tokens} +use cardano/transaction.{Transaction} +use hermes_types.{PosixTime, Price} +use pyth +use types/u32 +use types/u64 + +pub fn validate_only_burn(policy_id: PolicyId, tx: Transaction) -> Bool { + // For this policy, all qtys are negative + let Transaction { mint, .. } = tx + + dict.foldl( + tokens(mint, policy_id), + True, + fn(_, qty, acc) -> Bool { acc && qty < 0 }, + ) +} + +pub fn read_btc_usd_price( + pyth_id: PolicyId, + start_time: PosixTime, + self: Transaction, +) -> Price { + expect [update] = pyth.get_updates(pyth_id, self) + expect Some(feed) = + list.find(update.feeds, fn(feed) { u32.as_int(feed.feed_id) == 1 }) + expect Some(Some(price)) = feed.price + expect Some(exponent) = feed.exponent + + expect Some(multiplier) = rational.from_int(10) |> rational.pow(exponent) + let rat_price = rational.from_int(price) |> rational.mul(multiplier) + + let update_timestamp = update.timestamp_us + + expect u64.as_int(update_timestamp) == start_time * 1000 + + Price { denominator: denominator(rat_price), numerator: numerator(rat_price) } +} diff --git a/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak b/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak new file mode 100644 index 00000000..e5b14e34 --- /dev/null +++ b/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak @@ -0,0 +1,247 @@ +use aiken/collection/dict.{to_pairs} +use aiken/collection/list +use cardano/address.{Script} +use cardano/assets.{ + PolicyId, Value, from_asset, from_lovelace, match, merge, negate, tokens, +} +use cardano/transaction.{InlineDatum, Output, Transaction} +use contants.{control_token_tn, down_tn, five_minutes, up_tn} +use hermes_types.{MarketDatum, PosixTime, Price} +use subvalidators/common_checks.{read_btc_usd_price} + +pub fn validate_init_market( + pyth_policy: PolicyId, + start_time: PosixTime, + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { outputs, mint, .. } = tx + + // Only one output at the script address + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + // Extract value and datum + expect Output { + value: o_value, + datum: InlineDatum(o_datum), + reference_script: None, + .. + } = own_output + + // Datum has + // End value is None + // Ramaining shares is 0 + expect MarketDatum { + start_price: o_d_price, + end_price: None, + remaining_shares: 0, + }: MarketDatum = o_datum + + let price = read_btc_usd_price(pyth_policy, start_time, tx) + + // Minting only 1 control token in this policy + expect [Pair(minted_tn, 1)] = tokens(mint, own_policy) |> to_pairs() + + and { + // Start value extracted from oracle + o_d_price == price, + // Value has control token + match(o_value, from_asset(own_policy, control_token_tn, 1), >=), + minted_tn == control_token_tn, + } +} + +pub fn validate_record_final_price( + pyth_policy: PolicyId, + start_time: PosixTime, + own_policy: PolicyId, + own_datum: MarketDatum, + own_value: Value, + tx: Transaction, +) -> Bool { + // Datum only adds the end price + let Transaction { outputs, .. } = tx + + // Only one output at the script address + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + expect Output { + value: o_value, + datum: InlineDatum(o_datum), + reference_script: None, + .. + } = own_output + + let new_price = read_btc_usd_price(pyth_policy, start_time + five_minutes, tx) + + let expected_datum = + MarketDatum { + start_price: own_datum.start_price, + remaining_shares: own_datum.remaining_shares, + end_price: Some(new_price), + } + let expected_datum_data: Data = expected_datum + and { + // Output datum matched expected + o_datum == expected_datum_data, + // Value has not decreased + match(o_value, own_value, >=), + } +} + +pub fn validate_claim_winnings( + own_value: Value, + claimed_tokens: Int, + own_datum: MarketDatum, + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { outputs, mint, .. } = tx + + // Only one output at the script address + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + expect Output { + value: o_value, + datum: InlineDatum(o_datum), + reference_script: None, + .. + } = own_output + + let paid_value = from_lovelace(claimed_tokens * 1_000_000) + + let remaining_value = merge(own_value, negate(paid_value)) + + expect MarketDatum { + start_price: i_d_start_price, + end_price: Some(i_d_end_price), + remaining_shares: i_d_remaining_shares, + } = own_datum + + let expected_datum = + MarketDatum { + start_price: i_d_start_price, + remaining_shares: i_d_remaining_shares - claimed_tokens, + end_price: Some(i_d_end_price), + } + let expected_datum_data: Data = expected_datum + + let claiming_token_name = + if compare_prices(i_d_end_price, i_d_start_price) == Less { + down_tn + } else { + up_tn + } + + expect [Pair(minted_tn, qty)] = tokens(mint, own_policy) |> to_pairs() + + and { + minted_tn == claiming_token_name, + qty == -claimed_tokens, + // Output datum matched expected + o_datum == expected_datum_data, + // Value has not decreased + match(o_value, remaining_value, >=), + } +} + +pub fn validate_claim_losings( + own_value: Value, + claimed_tokens: Int, + own_datum: MarketDatum, + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { outputs, mint, .. } = tx + + // Only one output at the script address + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + expect Output { + value: o_value, + datum: InlineDatum(o_datum), + reference_script: None, + .. + } = own_output + + expect MarketDatum { + start_price: i_d_start_price, + end_price: Some(i_d_end_price), + remaining_shares: i_d_remaining_shares, + } = own_datum + + let expected_datum = + MarketDatum { + start_price: i_d_start_price, + remaining_shares: i_d_remaining_shares - claimed_tokens, + end_price: Some(i_d_end_price), + } + let expected_datum_data: Data = expected_datum + + let claiming_token_name = + if compare_prices(i_d_end_price, i_d_start_price) == Less { + up_tn + } else { + down_tn + } + + expect [Pair(minted_tn, qty)] = tokens(mint, own_policy) |> to_pairs() + + and { + minted_tn == claiming_token_name, + qty == -claimed_tokens, + // Output datum matched expected + o_datum == expected_datum_data, + // Value has not decreased + match(o_value, own_value, >=), + } +} + +pub fn validate_close_market( + own_policy: PolicyId, + own_datum: MarketDatum, + tx: Transaction, +) -> Bool { + let Transaction { mint, .. } = tx + // Burning the control token in this policy + expect [Pair(minted_tn, -1)] = tokens(mint, own_policy) |> to_pairs() + + and { + minted_tn == control_token_tn, + own_datum.remaining_shares == 0, + } + // Burned control token +} + +pub fn validate_process_match() -> Bool { + todo +} + +pub fn compare_prices(price1: Price, price2: Price) -> Ordering { + let l = price1.numerator * price2.denominator + let r = price2.numerator * price1.denominator + + if l > r { + Greater + } else if l < r { + Less + } else { + Equal + } +} diff --git a/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak b/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak new file mode 100644 index 00000000..35a28074 --- /dev/null +++ b/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak @@ -0,0 +1,169 @@ +use aiken/collection/dict.{to_pairs} +use aiken/collection/list as list +use cardano/address.{Address, Script, VerificationKey} +use cardano/assets.{ + PolicyId, Value, from_asset, from_lovelace, match, merge, negate, quantity_of, + tokens, +} +use cardano/transaction.{InlineDatum, Output, Transaction} +use contants.{down_tn, up_tn} +use hermes_types.{Buy, Direction, Down, Operation, OrderDatum, Price, Sell, Up} + +pub fn validate_cancel( + own_datum: OrderDatum, + own_policy: PolicyId, + own_value: Value, + tx: Transaction, +) -> Bool { + let Transaction { extra_signatories, mint, .. } = tx + + let neg_control_token = tokens(negate(own_value), own_policy) + + and { + // Owner is signing the transaction + list.has(extra_signatories, own_datum.owner), + // Control token is burnt + match(mint, neg_control_token, ==), + } +} + +pub fn validate_match() -> Bool { + todo +} + +pub fn validate_fill( + own_datum: OrderDatum, + own_value: Value, + own_policy: PolicyId, + filled_amount: Int, + position_token_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { outputs, mint, .. } = tx + + expect [Pair(control_token_tn, 1)] = + tokens(own_value, own_policy) |> to_pairs() + + let OrderDatum { + direction: i_d_direction, + operation: i_d_operation, + price: i_d_price, + owner: i_d_owner, + expected_tokens: i_d_expected_tokens, + } = own_datum + + let expected_owner_value = + calculate_asked_tokens( + i_d_direction, + i_d_operation, + i_d_price, + filled_amount, + position_token_policy, + ) + + // Owner expected output + // addr: owner + // Value: filled tokens + let owner_output_found = + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, .. }) { + o_addr.payment_credential == VerificationKey(i_d_owner) && match( + o_val, + expected_owner_value, + >=, + ) + }, + ) + + let continuing_order_ok = or { + and { + // Is complete fill + i_d_expected_tokens == filled_amount, + // Control token is burnt + quantity_of(mint, own_policy, control_token_tn) == -1, + }, + { + let expected_datum = + OrderDatum { + ..own_datum, + expected_tokens: i_d_expected_tokens - filled_amount, + } + let expected_datum_data: Data = expected_datum + + let offered_tokens = + calculate_offered_tokens( + i_d_direction, + i_d_operation, + i_d_price, + filled_amount, + position_token_policy, + ) + + let expected_order_value = merge(own_value, negate(offered_tokens)) + + // Continuing order + // addr: own_policy + // Value: own_value - filled_amount + // Datum: expected_datum + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, datum: o_datum, .. }) { + if o_addr.payment_credential == Script(own_policy) { + expect InlineDatum(o_dat) = o_datum + + and { + match(o_val, expected_order_value, >=), + o_dat == expected_datum_data, + } + } else { + False + } + }, + ) + }, + } + + and { + owner_output_found, + continuing_order_ok, + } +} + +//------------------------- +// LIBRARY +//------------------------- + +pub fn calculate_asked_tokens( + dir: Direction, + op: Operation, + price: Price, + filled_amount: Int, + position_token_policy: PolicyId, +) { + when op is { + Buy -> + when dir is { + Up -> from_asset(position_token_policy, up_tn, filled_amount) + Down -> from_asset(position_token_policy, down_tn, filled_amount) + } + Sell -> from_lovelace(filled_amount * price.numerator / price.denominator) + } +} + +pub fn calculate_offered_tokens( + dir: Direction, + op: Operation, + price: Price, + filled_amount: Int, + position_token_policy: PolicyId, +) { + when op is { + Buy -> from_lovelace(filled_amount * price.numerator / price.denominator) + Sell -> + when dir is { + Up -> from_asset(position_token_policy, up_tn, filled_amount) + Down -> from_asset(position_token_policy, down_tn, filled_amount) + } + } +} diff --git a/lazer/cardano/hermes/onchain/plutus.json b/lazer/cardano/hermes/onchain/plutus.json new file mode 100644 index 00000000..e761d6b6 --- /dev/null +++ b/lazer/cardano/hermes/onchain/plutus.json @@ -0,0 +1,449 @@ +{ + "preamble": { + "title": "los-hydra-boys/hermes", + "description": "Aiken contracts for project 'los-hydra-boys/hermes'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.21+42babe5" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "market.market.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/hermes_types~1MarketMintRedeemer" + } + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/hermes_types~1PosixTime" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", + "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + }, + { + "title": "market.market.spend", + "datum": { + "title": "op_datum", + "schema": { + "$ref": "#/definitions/hermes_types~1MarketDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/hermes_types~1MarketRedeemer" + } + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/hermes_types~1PosixTime" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", + "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + }, + { + "title": "market.market.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "start_time", + "schema": { + "$ref": "#/definitions/hermes_types~1PosixTime" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", + "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + }, + { + "title": "order.order.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/hermes_types~1OrderMintRedeemer" + } + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", + "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + }, + { + "title": "order.order.spend", + "datum": { + "title": "op_datum", + "schema": { + "$ref": "#/definitions/hermes_types~1OrderDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/hermes_types~1OrderRedeemer" + } + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", + "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + }, + { + "title": "order.order.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "market_script_hash", + "schema": { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + }, + { + "title": "pyth_policy", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", + "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + } + ], + "definitions": { + "Int": { + "dataType": "integer" + }, + "Option": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/hermes_types~1Price" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "aiken/crypto/ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "aiken/crypto/VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "cardano/assets/PolicyId": { + "title": "PolicyId", + "dataType": "bytes" + }, + "hermes_types/Direction": { + "title": "Direction", + "anyOf": [ + { + "title": "Up", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Down", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "hermes_types/MarketDatum": { + "title": "MarketDatum", + "anyOf": [ + { + "title": "MarketDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "start_price", + "$ref": "#/definitions/hermes_types~1Price" + }, + { + "title": "end_price", + "$ref": "#/definitions/Option" + }, + { + "title": "remaining_shares", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "hermes_types/MarketMintRedeemer": { + "title": "MarketMintRedeemer", + "anyOf": [ + { + "title": "MintControlToken", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "BurnControlToken", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "MintPositionToken", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "$ref": "#/definitions/hermes_types~1Direction" + } + ] + }, + { + "title": "BurnPositionToken", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "$ref": "#/definitions/hermes_types~1Direction" + } + ] + } + ] + }, + "hermes_types/MarketRedeemer": { + "title": "MarketRedeemer", + "anyOf": [ + { + "title": "RecordFinalPrice", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "ClaimWinnings", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "ClaimLosings", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "CloseMarket", + "dataType": "constructor", + "index": 3, + "fields": [] + }, + { + "title": "ProcessMatch", + "dataType": "constructor", + "index": 4, + "fields": [] + } + ] + }, + "hermes_types/Operation": { + "title": "Operation", + "anyOf": [ + { + "title": "Buy", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Sell", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "hermes_types/OrderDatum": { + "title": "OrderDatum", + "anyOf": [ + { + "title": "OrderDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "direction", + "$ref": "#/definitions/hermes_types~1Direction" + }, + { + "title": "operation", + "$ref": "#/definitions/hermes_types~1Operation" + }, + { + "title": "price", + "$ref": "#/definitions/hermes_types~1Price" + }, + { + "title": "owner", + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + }, + { + "title": "expected_tokens", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "hermes_types/OrderMintRedeemer": { + "title": "OrderMintRedeemer", + "anyOf": [ + { + "title": "Mint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Burn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "hermes_types/OrderRedeemer": { + "title": "OrderRedeemer", + "anyOf": [ + { + "title": "Cancel", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Match", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "Fill", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "hermes_types/PosixTime": { + "title": "PosixTime", + "dataType": "integer" + }, + "hermes_types/Price": { + "title": "Price", + "anyOf": [ + { + "title": "Price", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "numerator", + "$ref": "#/definitions/Int" + }, + { + "title": "denominator", + "$ref": "#/definitions/Int" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/lazer/cardano/hermes/onchain/validators/market.ak b/lazer/cardano/hermes/onchain/validators/market.ak new file mode 100644 index 00000000..12f86e66 --- /dev/null +++ b/lazer/cardano/hermes/onchain/validators/market.ak @@ -0,0 +1,80 @@ +use aiken/collection/list +use cardano/address.{Address, Script} +use cardano/assets.{PolicyId} +use cardano/transaction.{Input, Output, OutputReference, Transaction} +use hermes_types.{ + BurnControlToken, BurnPositionToken, ClaimLosings, ClaimWinnings, CloseMarket, + MarketDatum, MarketMintRedeemer, MarketRedeemer, MintControlToken, + MintPositionToken, PosixTime, ProcessMatch, RecordFinalPrice, +} +use subvalidators/common_checks.{validate_only_burn} +use subvalidators/market_checks.{ + validate_claim_losings, validate_claim_winnings, validate_close_market, + validate_init_market, validate_process_match, validate_record_final_price, +} + +validator market(start_time: PosixTime, pyth_policy: PolicyId) { + mint(redeemer: MarketMintRedeemer, policy_id: PolicyId, self: Transaction) { + when redeemer is { + MintControlToken -> + validate_init_market(pyth_policy, start_time, policy_id, self) + BurnControlToken -> validate_only_burn(policy_id, self) + MintPositionToken(_dir) -> todo + BurnPositionToken(_dir) -> validate_only_burn(policy_id, self) + } + } + + spend( + op_datum: Option, + redeemer: MarketRedeemer, + utxo: OutputReference, + self: Transaction, + ) { + expect Some(datum) = op_datum + + let Transaction { inputs, .. } = self + + expect Some(Input { + output: Output { + address: Address { payment_credential: Script(own_script_hash), .. }, + value: i_val, + .. + }, + .. + }) = list.find(inputs, fn(input) { input.output_reference == utxo }) + + when redeemer is { + RecordFinalPrice -> + validate_record_final_price( + pyth_policy, + start_time, + own_script_hash, + datum, + i_val, + self, + ) + ClaimWinnings(claimed_tokens) -> + validate_claim_winnings( + i_val, + claimed_tokens, + datum, + own_script_hash, + self, + ) + ClaimLosings(claimed_tokens) -> + validate_claim_losings( + i_val, + claimed_tokens, + datum, + own_script_hash, + self, + ) + CloseMarket -> validate_close_market(own_script_hash, datum, self) + ProcessMatch -> validate_process_match() + } + } + + else(_) { + fail + } +} diff --git a/lazer/cardano/hermes/onchain/validators/order.ak b/lazer/cardano/hermes/onchain/validators/order.ak new file mode 100644 index 00000000..4fdd2e99 --- /dev/null +++ b/lazer/cardano/hermes/onchain/validators/order.ak @@ -0,0 +1,57 @@ +use aiken/collection/list +use aiken/crypto.{ScriptHash} +use cardano/address.{Address, Script} +use cardano/assets.{PolicyId} +use cardano/transaction.{Input, Output, OutputReference, Transaction} +use hermes_types.{ + Cancel, Fill, Match, OrderDatum, OrderMintRedeemer, OrderRedeemer, +} +use subvalidators/common_checks.{validate_only_burn} +use subvalidators/order_checks.{validate_cancel, validate_fill, validate_match} + +validator order(market_script_hash: ScriptHash) { + mint(redeemer: OrderMintRedeemer, policy_id: PolicyId, self: Transaction) { + when redeemer is { + OrderMintRedeemer.Mint -> todo + OrderMintRedeemer.Burn -> validate_only_burn(policy_id, self) + } + } + + spend( + op_datum: Option, + redeemer: OrderRedeemer, + utxo: OutputReference, + self: Transaction, + ) { + expect Some(datum) = op_datum + + let Transaction { inputs, .. } = self + + expect Some(Input { + output: Output { + address: Address { payment_credential: Script(own_script_hash), .. }, + value: i_val, + .. + }, + .. + }) = list.find(inputs, fn(input) { input.output_reference == utxo }) + + when redeemer is { + Cancel -> validate_cancel(datum, own_script_hash, i_val, self) + Match -> validate_match() + Fill(filled_amount) -> + validate_fill( + datum, + i_val, + own_script_hash, + filled_amount, + market_script_hash, + self, + ) + } + } + + else(_) { + fail + } +} diff --git a/lazer/cardano/hermes/src/onchain/aiken.lock b/lazer/cardano/hermes/src/onchain/aiken.lock deleted file mode 100644 index 1a4fdb1c..00000000 --- a/lazer/cardano/hermes/src/onchain/aiken.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file was generated by Aiken -# You typically do not need to edit this file - -[[requirements]] -name = "aiken-lang/stdlib" -version = "v3.0.0" -source = "github" - -[[packages]] -name = "aiken-lang/stdlib" -version = "v3.0.0" -requirements = [] -source = "github" - -[etags] diff --git a/lazer/cardano/hermes/src/onchain/plutus.json b/lazer/cardano/hermes/src/onchain/plutus.json deleted file mode 100644 index d69ac6a4..00000000 --- a/lazer/cardano/hermes/src/onchain/plutus.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "preamble": { - "title": "los-hydra-boys/hermes", - "description": "Aiken contracts for project 'los-hydra-boys/hermes'", - "version": "0.0.0", - "plutusVersion": "v3", - "compiler": { - "name": "Aiken", - "version": "v1.1.21+42babe5" - }, - "license": "Apache-2.0" - }, - "validators": [ - { - "title": "market.market.mint", - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/types~1MarketMintRedeemer" - } - }, - "parameters": [ - { - "title": "start_time", - "schema": { - "$ref": "#/definitions/types~1PosixTime" - } - } - ], - "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", - "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" - }, - { - "title": "market.market.spend", - "datum": { - "title": "_datum", - "schema": { - "$ref": "#/definitions/types~1MarketDatum" - } - }, - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/types~1MarketRedeemer" - } - }, - "parameters": [ - { - "title": "start_time", - "schema": { - "$ref": "#/definitions/types~1PosixTime" - } - } - ], - "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", - "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" - }, - { - "title": "market.market.else", - "redeemer": { - "schema": {} - }, - "parameters": [ - { - "title": "start_time", - "schema": { - "$ref": "#/definitions/types~1PosixTime" - } - } - ], - "compiledCode": "590198010100229800aba2aba1aab9faab9eaab9dab9a9bad0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa00691192cc004c0180062b3001300f37540070028b20208acc004c01c0062b3001300f37540070028b20208b201a4034601a6ea800a294660166ea80052222598009803800c56600260206ea80160051640451598009804000c56600260206ea801600516404515980099b8748010006264b300130140018998021809800801c5901218081baa0058acc004cdc3a400c00313259800980a000c4cc010c04c00400e2c8090c040dd5002c5900e201c403880711598009802002c4ca6002601e003300f301000198061baa0028a514888966002601000515980098089baa006800c590124566002601200515980098089baa006800c59012456600266e1d20040028acc004c044dd500340062c80922b30013370e9003001456600260226ea801a00316404916403c807900f201e18061baa0068b2014402830083009001300800130043754011149a26cac80101", - "hash": "3862f8828bdd94c1dea68a29b27a286bad414cfc40ff5793c874d2dd" - }, - { - "title": "order.order.mint", - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/types~1OrderMintRedeemer" - } - }, - "parameters": [ - { - "title": "market_script_hash", - "schema": { - "$ref": "#/definitions/aiken~1crypto~1ScriptHash" - } - } - ], - "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", - "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" - }, - { - "title": "order.order.spend", - "datum": { - "title": "_datum", - "schema": { - "$ref": "#/definitions/types~1OrderDatum" - } - }, - "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/types~1OrderRedeemer" - } - }, - "parameters": [ - { - "title": "market_script_hash", - "schema": { - "$ref": "#/definitions/aiken~1crypto~1ScriptHash" - } - } - ], - "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", - "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" - }, - { - "title": "order.order.else", - "redeemer": { - "schema": {} - }, - "parameters": [ - { - "title": "market_script_hash", - "schema": { - "$ref": "#/definitions/aiken~1crypto~1ScriptHash" - } - } - ], - "compiledCode": "590104010100229800aba2aba1aab9faab9eaab9dab9a9bae0024888888966002646465300130063754003370e90014dc3a400130090039804801244444b300130030058cc004dd7180718061baa0068a5198059baa001488966002600c00315980098079baa0048014590104566002600e00315980098079baa00480145901045900d201a4566002600800b13298009807800cc03cc04000660186ea800a29452222598009804001456600260226ea801a0031640491598009804801456600260226ea801a00316404915980099b874801000a2b30013011375400d0018b20248b201e403c807860186ea801a2c805100a0c020c024004c020004c010dd5004452689b2b20041", - "hash": "d2a6f0f4c336bb26a3f5fb0dfaa26d1af8ec98211a91920d43204bfe" - } - ], - "definitions": { - "Int": { - "dataType": "integer" - }, - "Option": { - "title": "Option", - "anyOf": [ - { - "title": "Some", - "description": "An optional value.", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/types~1Price" - } - ] - }, - { - "title": "None", - "description": "Nothing.", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "aiken/crypto/ScriptHash": { - "title": "ScriptHash", - "dataType": "bytes" - }, - "aiken/crypto/VerificationKeyHash": { - "title": "VerificationKeyHash", - "dataType": "bytes" - }, - "types/Direction": { - "title": "Direction", - "anyOf": [ - { - "title": "Up", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "Down", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "types/MarketDatum": { - "title": "MarketDatum", - "anyOf": [ - { - "title": "MarketDatum", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "start_price", - "$ref": "#/definitions/types~1Price" - }, - { - "title": "end_price", - "$ref": "#/definitions/Option" - }, - { - "title": "ramaining_shares", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "types/MarketMintRedeemer": { - "title": "MarketMintRedeemer", - "anyOf": [ - { - "title": "MintControlToken", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "BurnControlToken", - "dataType": "constructor", - "index": 1, - "fields": [] - }, - { - "title": "MintPositionToken", - "dataType": "constructor", - "index": 2, - "fields": [ - { - "$ref": "#/definitions/types~1Direction" - } - ] - }, - { - "title": "BurnPositionToken", - "dataType": "constructor", - "index": 3, - "fields": [ - { - "$ref": "#/definitions/types~1Direction" - } - ] - } - ] - }, - "types/MarketRedeemer": { - "title": "MarketRedeemer", - "anyOf": [ - { - "title": "RecordFinalPrice", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "ClaimWinnings", - "dataType": "constructor", - "index": 1, - "fields": [] - }, - { - "title": "ClaimLosings", - "dataType": "constructor", - "index": 2, - "fields": [] - }, - { - "title": "CloseMarket", - "dataType": "constructor", - "index": 3, - "fields": [] - } - ] - }, - "types/Operation": { - "title": "Operation", - "anyOf": [ - { - "title": "Buy", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "Sell", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "types/OrderDatum": { - "title": "OrderDatum", - "anyOf": [ - { - "title": "OrderDatum", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "direction", - "$ref": "#/definitions/types~1Direction" - }, - { - "title": "operation", - "$ref": "#/definitions/types~1Operation" - }, - { - "title": "price", - "$ref": "#/definitions/types~1Price" - }, - { - "title": "owner", - "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" - } - ] - } - ] - }, - "types/OrderMintRedeemer": { - "title": "OrderMintRedeemer", - "anyOf": [ - { - "title": "Mint", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "Burn", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "types/OrderRedeemer": { - "title": "OrderRedeemer", - "anyOf": [ - { - "title": "Cancel", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "Match", - "dataType": "constructor", - "index": 1, - "fields": [] - }, - { - "title": "Fill", - "dataType": "constructor", - "index": 2, - "fields": [] - } - ] - }, - "types/PosixTime": { - "title": "PosixTime", - "dataType": "integer" - }, - "types/Price": { - "title": "Price", - "anyOf": [ - { - "title": "Price", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "numerator", - "$ref": "#/definitions/Int" - }, - { - "title": "denominator", - "$ref": "#/definitions/Int" - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/lazer/cardano/hermes/src/onchain/validators/market.ak b/lazer/cardano/hermes/src/onchain/validators/market.ak deleted file mode 100644 index 3e2e7b0e..00000000 --- a/lazer/cardano/hermes/src/onchain/validators/market.ak +++ /dev/null @@ -1,22 +0,0 @@ -use cardano/assets.{PolicyId} -use cardano/transaction.{OutputReference, Transaction} -use types.{MarketDatum, MarketMintRedeemer, MarketRedeemer, PosixTime} - -validator market(start_time: PosixTime) { - mint(_redeemer: MarketMintRedeemer, _policy_id: PolicyId, _self: Transaction) { - True - } - - spend( - _datum: Option, - _redeemer: MarketRedeemer, - _utxo: OutputReference, - _self: Transaction, - ) { - True - } - - else(_) { - fail - } -} diff --git a/lazer/cardano/hermes/src/onchain/validators/order.ak b/lazer/cardano/hermes/src/onchain/validators/order.ak deleted file mode 100644 index ecae45a2..00000000 --- a/lazer/cardano/hermes/src/onchain/validators/order.ak +++ /dev/null @@ -1,23 +0,0 @@ -use aiken/crypto.{ScriptHash} -use cardano/assets.{PolicyId} -use cardano/transaction.{OutputReference, Transaction} -use types.{OrderDatum, OrderMintRedeemer, OrderRedeemer} - -validator order(market_script_hash: ScriptHash) { - mint(_redeemer: OrderMintRedeemer, _policy_id: PolicyId, _self: Transaction) { - True - } - - spend( - _datum: Option, - _redeemer: OrderRedeemer, - _utxo: OutputReference, - _self: Transaction, - ) { - True - } - - else(_) { - fail - } -} From a90c200436e5be329041d65823386bdaaaa9ac04 Mon Sep 17 00:00:00 2001 From: Valentino Cerutti Date: Sun, 22 Mar 2026 20:43:31 -0300 Subject: [PATCH 3/5] Adds final validation --- .../hermes/onchain/lib/hermes_types.ak | 3 +- .../lib/subvalidators/market_checks.ak | 103 ++++++- .../onchain/lib/subvalidators/order_checks.ak | 254 +++++++++++++++++- lazer/cardano/hermes/onchain/plutus.json | 73 ++--- .../hermes/onchain/validators/market.ak | 8 +- .../hermes/onchain/validators/order.ak | 9 +- 6 files changed, 401 insertions(+), 49 deletions(-) diff --git a/lazer/cardano/hermes/onchain/lib/hermes_types.ak b/lazer/cardano/hermes/onchain/lib/hermes_types.ak index 89d2e051..47f2b861 100644 --- a/lazer/cardano/hermes/onchain/lib/hermes_types.ak +++ b/lazer/cardano/hermes/onchain/lib/hermes_types.ak @@ -1,4 +1,5 @@ use aiken/crypto.{VerificationKeyHash} +use cardano/transaction.{OutputReference} pub type PosixTime = Int @@ -33,7 +34,7 @@ pub type OrderRedeemer { } pub type OrderMintRedeemer { - Mint + Mint(OutputReference) Burn } diff --git a/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak b/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak index e5b14e34..f04fd75b 100644 --- a/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak +++ b/lazer/cardano/hermes/onchain/lib/subvalidators/market_checks.ak @@ -2,11 +2,14 @@ use aiken/collection/dict.{to_pairs} use aiken/collection/list use cardano/address.{Script} use cardano/assets.{ - PolicyId, Value, from_asset, from_lovelace, match, merge, negate, tokens, + PolicyId, Value, from_asset, from_lovelace, match, merge, negate, quantity_of, + tokens, } -use cardano/transaction.{InlineDatum, Output, Transaction} +use cardano/transaction.{InlineDatum, Input, Output, Spend, Transaction} use contants.{control_token_tn, down_tn, five_minutes, up_tn} -use hermes_types.{MarketDatum, PosixTime, Price} +use hermes_types.{ + MarketDatum, MarketRedeemer, PosixTime, Price, ProcessMatch, +} use subvalidators/common_checks.{read_btc_usd_price} pub fn validate_init_market( @@ -221,7 +224,6 @@ pub fn validate_close_market( let Transaction { mint, .. } = tx // Burning the control token in this policy expect [Pair(minted_tn, -1)] = tokens(mint, own_policy) |> to_pairs() - and { minted_tn == control_token_tn, own_datum.remaining_shares == 0, @@ -229,8 +231,97 @@ pub fn validate_close_market( // Burned control token } -pub fn validate_process_match() -> Bool { - todo +pub fn validate_process_match( + own_datum: MarketDatum, + own_value: Value, + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { outputs, mint, .. } = tx + + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + expect Output { value: o_value, datum: InlineDatum(o_raw_datum), .. } = + own_output + + expect o_datum: MarketDatum = o_raw_datum + + let up_minted = quantity_of(mint, own_policy, up_tn) + let down_minted = quantity_of(mint, own_policy, down_tn) + + // Datum is updated by the amount of up and down tokens minted + let matched_amount = up_minted + + // Value is increased by the matched lovelace (1-to-1 with token scale in matching context) + let matched_lovelace = matched_amount + let expected_value = merge(own_value, from_lovelace(matched_lovelace)) + + and { + up_minted > 0, + up_minted == down_minted, + // Value is increased by matched lovelace AND control token is not stolen + // (`expected_value` includes `own_value` which holds the control token) + match(o_value, expected_value, >=), + // Datum keeps prices and updates shares + o_datum.start_price == own_datum.start_price, + o_datum.end_price == own_datum.end_price, + // Datum is updated by the amount of up and down tokens minted + o_datum.remaining_shares == own_datum.remaining_shares + matched_amount, + } +} + +pub fn validate_mint_position_tokens( + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { inputs, mint, redeemers, .. } = tx + + // Validate that the same amount of up and down tokens got minted + let own_minted = tokens(mint, own_policy) |> to_pairs() + let up_minted = quantity_of(mint, own_policy, up_tn) + let down_minted = quantity_of(mint, own_policy, down_tn) + + let valid_mints = and { + up_minted > 0, + up_minted == down_minted, + } + + // Valiates that no other token with other name is minted + let no_extra_mints = list.length(own_minted) == 2 + + expect Some(market_input) = + list.find( + inputs, + fn(i) { i.output.address.payment_credential == Script(own_policy) }, + ) + + // Validates that the market utxo has the control token + let has_control_token = + quantity_of(market_input.output.value, own_policy, control_token_tn) >= 1 + + // Validate that a market utxo is consumed with match redeemer + expect Some(Pair(_, raw_redeemer)) = + list.find( + redeemers, + fn(pair) { + let Pair(purpose, _) = pair + purpose == Spend(market_input.output_reference) + }, + ) + + expect market_redeemer: MarketRedeemer = raw_redeemer + let is_match_redeemer = market_redeemer == ProcessMatch + + and { + valid_mints, + no_extra_mints, + has_control_token, + is_match_redeemer, + } } pub fn compare_prices(price1: Price, price2: Price) -> Ordering { diff --git a/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak b/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak index 35a28074..482ff079 100644 --- a/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak +++ b/lazer/cardano/hermes/onchain/lib/subvalidators/order_checks.ak @@ -1,14 +1,73 @@ +use aiken/cbor use aiken/collection/dict.{to_pairs} use aiken/collection/list as list +use aiken/crypto.{ScriptHash, blake2b_256} use cardano/address.{Address, Script, VerificationKey} use cardano/assets.{ - PolicyId, Value, from_asset, from_lovelace, match, merge, negate, quantity_of, - tokens, + PolicyId, Value, add, from_asset, from_lovelace, match, merge, negate, + quantity_of, tokens, +} +use cardano/transaction.{ + InlineDatum, Input, Output, OutputReference, Transaction, } -use cardano/transaction.{InlineDatum, Output, Transaction} use contants.{down_tn, up_tn} use hermes_types.{Buy, Direction, Down, Operation, OrderDatum, Price, Sell, Up} +pub fn validate_create_order( + seed: OutputReference, + position_token_policy: PolicyId, + own_policy: PolicyId, + tx: Transaction, +) -> Bool { + let Transaction { extra_signatories, inputs, outputs, mint, .. } = tx + + // Only one output at the script address + expect [own_output] = + list.filter( + outputs, + fn(o) { o.address.payment_credential == Script(own_policy) }, + ) + + expect Some(_) = list.find(inputs, fn(i) { i.output_reference == seed }) + + // Extract value and datum + expect Output { + value: o_value, + datum: InlineDatum(o_datum), + reference_script: None, + .. + } = own_output + + expect OrderDatum { + owner: o_d_owner, + operation: o_d_operation, + direction: o_d_direction, + price: o_d_price, + expected_tokens: o_d_expected_tokens, + }: OrderDatum = o_datum + + // Minting only 1 control token in this policy + expect [Pair(minted_tn, 1)] = tokens(mint, own_policy) |> to_pairs() + + let expected_value = + calculate_offered_tokens( + o_d_direction, + o_d_operation, + o_d_price, + o_d_expected_tokens, + position_token_policy, + ) + + and { + // Signed by owner + list.has(extra_signatories, o_d_owner), + // Value has offered tokens and control token + match(o_value, add(expected_value, own_policy, minted_tn, 1), >=), + // Control token has correct name + minted_tn == blake2b_256(cbor.serialise(seed)), + } +} + pub fn validate_cancel( own_datum: OrderDatum, own_policy: PolicyId, @@ -27,8 +86,193 @@ pub fn validate_cancel( } } -pub fn validate_match() -> Bool { - todo +pub fn validate_match( + own_policy: PolicyId, + market_script_hash: ScriptHash, + tx: Transaction, +) -> Bool { + let Transaction { inputs, outputs, mint, .. } = tx + + // Expect two inputs from the own script + expect [input_a, + input_b] = + list.filter( + inputs, + fn(i) { i.output.address.payment_credential == Script(own_policy) }, + ) + + // Determine which input is "self" and which is "other" + expect Input { + output: Output { value: a_value, datum: InlineDatum(a_raw_datum), .. }, + .. + } = input_a + + expect Input { + output: Output { value: b_value, datum: InlineDatum(b_raw_datum), .. }, + .. + } = input_b + + expect a_datum: OrderDatum = a_raw_datum + expect b_datum: OrderDatum = b_raw_datum + + // Expect different directions + expect a_datum.direction != b_datum.direction + + // Expect both operations to be Buy + expect a_datum.operation == Buy + expect b_datum.operation == Buy + + // Expect the sum of the prices to be 1 + // price_a.num / price_a.den + price_b.num / price_b.den == 1 + // => price_a.num * price_b.den + price_b.num * price_a.den == price_a.den * price_b.den + let price_sum_numerator = + a_datum.price.numerator * b_datum.price.denominator + b_datum.price.numerator * a_datum.price.denominator + let price_sum_denominator = + a_datum.price.denominator * b_datum.price.denominator + expect price_sum_numerator == price_sum_denominator + + // Figure out which order has the greater amount (the one that continues) + // and which has the smaller amount (the one that gets fully consumed) + let (bigger_datum, bigger_value, smaller_datum, _smaller_value) = + if a_datum.expected_tokens >= b_datum.expected_tokens { + (a_datum, a_value, b_datum, b_value) + } else { + (b_datum, b_value, a_datum, a_value) + } + + let matched_amount = smaller_datum.expected_tokens + + // The order with the greater amount should be replicated with updated expected_tokens and value + let is_complete_fill = bigger_datum.expected_tokens == matched_amount + + let continuing_order_ok = or { + // Complete fill: both control tokens burned + is_complete_fill, + // Partial fill: bigger order continues + { + let expected_continuing_datum = + OrderDatum { + ..bigger_datum, + expected_tokens: bigger_datum.expected_tokens - matched_amount, + } + let expected_continuing_datum_data: Data = expected_continuing_datum + + let filled_lovelace = + matched_amount * bigger_datum.price.numerator / bigger_datum.price.denominator + + let expected_continuing_value = + merge(bigger_value, negate(from_lovelace(filled_lovelace))) + + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, datum: o_datum, .. }) { + if o_addr.payment_credential == Script(own_policy) { + expect InlineDatum(o_dat) = o_datum + and { + match(o_val, expected_continuing_value, >=), + o_dat == expected_continuing_datum_data, + } + } else { + False + } + }, + ) + }, + } + + // The other order control token should be burned + // If complete fill, both control tokens should be burned (2 tokens burned from own_policy) + // If partial fill, only the smaller order's control token should be burned (1 token burned) + let expected_burn_count = + if is_complete_fill { + -2 + } else { + -1 + } + + let control_tokens_burned = + dict.foldl(tokens(mint, own_policy), 0, fn(_, qty, acc) { acc + qty }) + + // Both owners should be paid the corresponding position tokens (Up/Down) + let a_position_tn = + when a_datum.direction is { + Up -> up_tn + Down -> down_tn + } + + let b_position_tn = + when b_datum.direction is { + Up -> up_tn + Down -> down_tn + } + + let a_owner_paid = + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, .. }) { + o_addr.payment_credential == VerificationKey(a_datum.owner) && match( + o_val, + from_asset(market_script_hash, a_position_tn, matched_amount), + >=, + ) + }, + ) + + let b_owner_paid = + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, .. }) { + o_addr.payment_credential == VerificationKey(b_datum.owner) && match( + o_val, + from_asset(market_script_hash, b_position_tn, matched_amount), + >=, + ) + }, + ) + + // Up and Down tokens should be minted and sent to the owners + let up_minted = quantity_of(mint, market_script_hash, up_tn) == matched_amount + let down_minted = + quantity_of(mint, market_script_hash, down_tn) == matched_amount + + // Adas should be paid to the market utxo + // The market output should have the market input's existing value plus the matched lovelace + let total_lovelace = + matched_amount * a_datum.price.numerator / a_datum.price.denominator + matched_amount * b_datum.price.numerator / b_datum.price.denominator + + expect Some(market_input) = + list.find( + inputs, + fn(i) { + i.output.address.payment_credential == Script(market_script_hash) + }, + ) + + let expected_market_value = + merge(market_input.output.value, from_lovelace(total_lovelace)) + + let market_paid = + list.any( + outputs, + fn(Output { address: o_addr, value: o_val, .. }) { + o_addr.payment_credential == Script(market_script_hash) && match( + o_val, + expected_market_value, + >=, + ) + }, + ) + + // The market utxo is already guaranteed to be consumed by the expect Some(market_input) above + and { + continuing_order_ok, + control_tokens_burned == expected_burn_count, + a_owner_paid, + b_owner_paid, + up_minted, + down_minted, + market_paid, + } } pub fn validate_fill( diff --git a/lazer/cardano/hermes/onchain/plutus.json b/lazer/cardano/hermes/onchain/plutus.json index e761d6b6..0c1eda7f 100644 --- a/lazer/cardano/hermes/onchain/plutus.json +++ b/lazer/cardano/hermes/onchain/plutus.json @@ -33,8 +33,8 @@ } } ], - "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", - "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + "compiledCode": "5925e90101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae00248888888889660033001300537540172232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003371090004dc0a4001370e90034dc3a4011374a9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a2003006402d1330050053011004402c6eb8c028004dd598058009806800a01614bd6f7b63024444444444444444453001301b012980d00948966002602460306ea800a2646464b30013020002899192cc004c05c0062b3001301e37540050068b203e8acc004c05000626464b300130240028044590211bad3022001301e3754005159800980b000c566002603c6ea800a00d16407d16407080e101c180e1baa001301f0038b203a3259800980e000c566002602660360031689809180d800a0348b203a3754603c002603c00260326ea800a2c80ba444b30010028a508994c004c966002602a60366ea800626eb4c070c07cdd5980f980e1baa0018a400080d0c0780066ebcc078c07c0066eac00d22259800800c566002600400d13300500348002294101c44c96600266ebcc0780053010140008acc004cc018010dd6980f98111bab301f001898019ba630230028a5040751598009980300224001130030078a50407480e8c08400501f0ca6002003004911980f8011980f9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0740066eacc07800660440069112cc004cdc8a441000038acc004cdc7a44100003899802980a998119ba60024bd70000c4cc015300103d87a8000006407d19800803c006446600e0046604a66ec0dd48029ba6004001401c80f8604000480f229422942294101f48896600266e2000520008a40011598009809800c520028992cc004c050cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0300092004401080c8dc1001203040612232330010010032259800800c530103d87a80008992cc004c010006260206603c00297ae089980180198100012034301e00140712300c3301a3750002660349810101004bd704888c8cc88cc008008004896600200300389919912cc004cdc8803801456600266e3c01c00a20030064079133005005302400440786eb8c074004dd6980f0009810000a03c330050040031480024464b300130130018acc004c068dd5001c00a2c80da2b30013010001899192cc004c08000a0091640746eb4c078004c068dd5001c56600260240031323259800981000140122c80e8dd6980f000980d1baa0038acc004c01c0062b3001301a37540070028b20368acc004c0180062b3001301a37540070028b20368b2030406080c1018203030183754005222598009809800c52f5bded8c113232330010014bd6f7b630112cc00400626603e66ec0dd48031ba60034bd6f7b63044ca60026eb8c0740066eacc07800660440049112cc004cdc8005001c4cc08ccdd81ba900a374c00e00b15980099b8f00a00389981199bb037520146e9801c00626604666ec0dd48019ba600233006006001407c80f8604000280f0c8cc0040052f5bded8c044b300100189980f19bb037520086ea000d2f5bded8c113298009bae301c0019bad301d00198108012444b300133720010007133022337606ea4020dd4003802c56600266e3c02000e26604466ec0dd48041ba800700189981119bb037520066ea0008cc01801800501e203c180f800a03a406122598009809180c1baa0028991919912cc004c08400e00b1640786eb4c078004dd6980f001180f000980c9baa0028b202e48888888888a6002604a0173025302600b912cc004c074c08cdd500144c8c8c966002605600513300e302a00313300e0010048b20503029001302900130243754005164089300700748888cc896600260420051329800899912cc004c0900062646644b300130320018991919912cc004c0a8c0c4dd50014566002605060626ea8c0d4c0d800e264b3001302c303237540031323232332259800981e001c4c8cc060004566002605e60706ea800a2b3001303937540051598009819001c4c966002607c0031325980098189bad303b0018acc004cdd7801cc0040de0710234051159800cc00402a6e9a600202748907434f4e54524f4c00a400480da4466e2400400902144cdc79bae303a001488107434f4e54524f4c008a5040e514a081ca2c81c8c0f40062c81d8cc08c0340462c81ba2c81d22c81b8c0ec0162c81c8dd6981c800981c801181c800981c00098199baa0018b20623035303237540051640c11640c060660026eacc0cc008c0cc004c0c8c0b8dd51818800c5902f1bab302f30303030001330263758605e002466ebcc0c0c0b4dd5181818169baa00130183302f375200a97ae0302f302f302b37540271598009810800c4cc00800c04e2b30013023001899191991194c00566002603e00313370e0033001003804522104444f574e00404914a08172660286eb0c0cc0148cdd7981a18189baa303430313754604260626ea8004c070cc0ccdd4804a5eb82605066004004660340060109112cc004c0b0c0c8dd500144c8cc8966002605e606a6ea8006264660300022b30010078acc0040162b3001003899baf0014c103d87d80008a5040d514a081aa2941035181b1919bb0303a001303a303b00137586072606c6ea80062c81a0cdc4a400530013756604860686ea8c090c0d0dd5000c032910107434f4e54524f4c00405864660020026eacc0e0c0e4c0e4c0e4c0e4c0e4024896600200314c0103d87a80008992cc004cdd7981b00098111981c981d181b9baa0044bd7044c0accc0e4dd39981c981b0009981c981b800a5eb812f5c1133003003303b00240d4607200281b8c0d8c0ccdd500145903126002005007a4410255500040446eacc0c00048966002003148002266e01200233002002303300140c0606060606060606000260566ea804e2660040060268149029205222329800800ccc058dd59817981818181818181818161baa002003a514004444b30010028800c4ca60020093033003992cc00400e266e20dd698180012400114a08170dd71817000a008303100240bc60506ea801e60506ea801e4464b300130250018acc004c0b0dd5001c00a2c816a2b300130220018acc004c0b0dd5001c00a2c816a2c815102a18151baa002488966002604a00515980098161baa00a801c5902d4566002604400515980098161baa00a801c5902d45660026048005132598009818800c4cc008c0c00040122c8170c0b0dd500545660026032005132598009818800c4cc008c0c00040122c8170c0b0dd500545902a205440a881506eb8c0acc0a0dd5002c566002603c00513233223300c009159800981218151baa001899912cc004c098c0b0dd5000c4c8c966002604a605c6ea800633001375c6064605e6ea80066eacc0c8c0cc00a53001488100a44100800a02091194c0040060070024004444b30010028800c4c8cc8a600200d303b0059919800800802912cc00400626607666ec0dd48021ba60034bd6f7b63044ca60026eb8c0e40066eacc0e8006607c0049112cc004cdc8004001c4cc0fccdd81ba9008374c00e00b15980099b8f0080038992cc0056600200314a314a081fa2005133040337606ea4024dd30008012078329800800c022006800888966002005100189919914c00401a608e00b32330010010052259800800c4cc11ccdd81ba9004375000697adef6c608994c004dd71822800cdd69823000cc1280092225980099b9000800389982599bb037520106ea001c0162b30013371e010007132598009821800c400a26609866ec0dd48049ba8001002412066e0001c00a26609666ec0dd48019ba800233006006001411c8238609000282310061bae3040001375a60820026086004820a26607e66ec0dd48019ba60023300600600140ec81d8607800281d10061bae30340013756606a002606e00481aa605c6ea803522222598009816800c4c96600260720031323232598009818181b9baa0018acc004c0b8c0dcdd5181d981e001456600266ebcc0ecc0e0dd500098161981d181d981c1baa00d3303a302c3303a980081a4cdc001aa41819e49020404497ae03303a302a3038375401a97ae08cc004dd5981d801cdd3004488cdc4800801203c8a5040d91640d91640d8607400260740026072606a6ea8c0e00062c81b0cc0b8dd6181b981c181c181a1baa01c23375e6070606a6ea8c0e0c0d4dd500098101981b9ba90064bd7044c9660026056005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a4504444f574e008a4502555000410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c660200246466002002602466e080312080897a2259800800c52f5bded8c1132330473376060880026e98c8cc004004dd59823001112cc004006297adef6c608991982519bb030470013750606c6eb4c120004cc00c00cc130008c1280050481980180198248011823800a08a9119b8900100240a114a0820229410404528208030440018b20843042303f3754004660526eacc108c10cc10c0280422c81e8c100004c100008c100004c0ecdd5008459039459039181e800981e800981e181c1baa303b0028b20723303037586072002466ebcc0e8c0dcdd5181d181b9baa001302233039375201097ae0375a6072606c6ea8050c0e4c0e4c0d4dd500ec566002605a005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a45025550008a4504444f574e00410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c025223371200200481422941040452820808a50410060880031641086084607e6ea8008cc0a4dd598211821982180500845903d182000098200011820000981d9baa0108b20728b2072303d001303d001303c3038375460760051640e4660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c06eb4c0e4c0d8dd500a181c981c981a9baa01d8acc004c08800a264b3001303a0018992cc004cdc3a40026eb4c0dc0062b30013371e6eb8c0d8005220107434f4e54524f4c00898181bad30293037375401914a081aa2c81a8c0e40062c81b8cc07cdd5981c181c981c981c981c981a9baa01d00689919912cc004c0f00062646644b30013033303a37540031323259800981b181e1baa002899191919912cc004c11800e266042608a00a264b3001303c0018992cc004c120006266046608e00201116411460866ea800a2b300130390018acc004c10cdd5001401e2c82222c820904118209baa0018b2086375a6086002608600460860026084002607a6ea800a2c81d84c966002605800315980099b870019800803c03a91104444f574e00407d159800cc0040126e98cc02c034c0300064466e24004009023456600266ebcc100c0f4dd50011820181e9baa0128acc004cdd79816981e9baa002302d303d375402513370e6eb4c0bcc0f4dd500119b80375a605e607a6ea8048006294103b452820768a5040ed14a081da294103b4c00401a01b489025550004078607c60766ea80062c81c8dd5981e000981e181e800981e181c1baa303b0018b20723756607260746074002660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c060726072606a6ea8075033206640cc446644b30013371000200514c0103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040d881b0cdc11bad3039303637540046eb4c098c0d8dd500099b82375a6072606c6ea8004dd69813181b1baa00240c88b205a3031302e37546062002605a6ea8c0c0c0c4c0b4dd5181818169baa0018b2056302e302b37540026601e6eb0c0b8c0acdd5009919baf302f302c37540020071640a460580026058605a00260506ea80162c813102618129baa00322232598009817000c4c8c966002604a60566ea800626464b30013027302d375400313259800981418171baa0018992cc004c0a4c0bcdd5000c4c966002605460606ea8006264b30013370e6eb4c0d4c0c8dd500419b8200b483403e2604c66068606a60646ea8004cc0d0c088c0c8dd5000a5eb822c8180cc88c09ccc0d4dd419b82375a606c0046eb4c0d8004cc0d4dd419b82375a606c606e0046eb4c0d8c0dc0052f5c060626ea8c050dd6981a18189baa00330313754606860626ea80062c8178c8ca60026eb4c0d40066eb4c0d4c0d80066eb4c0d4c0c8dd5001a444b3001598009817001c4cdc4800a400114a0819a298103d87a80008acc004c090006260526606e60526606e6ea0cc04000c004cc0dcdd419808001000a5eb812f5c115980099b8800148002260526606e60526606e6ea0cc040008c08c004cc0dcdd4198080019811800a5eb812f5c114c010ad8799fd8799f0101ffff0040cc81990330c0c4dd50009809a40291640b8606460666066606660666066605e6ea800e2c8168c0c4c0b8dd5000c5902c180e98169baa001302f302c37540031640a86601e6eb0c074c0acdd5000918111bad302f302c3754002605a0031640ac64b300130233029375400313259800981218151baa0018991980f800912cc00400a2646600200200844b30010018a5eb822660653001371290004dc62400937009001cdc4a4011371890004dc62401137009003a444444466446605c4646b30013371e6eb8c0f80052210475d3c793008cc004888c8cc00cdd698210009bae3042304300130030019b89480426e3120109b804803e600e90082444446600a464660886ea0cde5250375c608a00266088608a608c00297ae05980098029b8d0018998219ba930020013304337526600860066e340040052f5c11640fc4646600e46608a6ea0cdc7000a40006608a6ea4cc008c0d0dc6800800a5eb808cc0208cc118dd419b8e00148000cc118dd499801981a9b8d0010014bd7011191919824981d998249ba800733049375000a66092609400297ae033049304a304b0014bd7018008012cc004c05400a2653001001a5eb82006800888966002608200312323304c374e002660986ea40092f5c065300100180252f5c080088896600200510018cc00400e60a00053304e304f002001400c826a246530010059982618268008024c0ec00e6eb8c134c138005005191919911919801194c0040066eb0c14800a6086660a260a400c660a2980103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a80004bd702002222598008014400633001003982a8014c8c966002609800313230483305630570013305630483305630573054375400697ae030583058001305337540071598009824800c4c8c8c124cc15cc160008cc15cc160004cc15cc124cc15cc160c154dd500225eb80c164c164004c160004c14cdd5001c56600260960031323232304a33058305900333058305900233058305900133058304a3305830593056375400a97ae0305a305a00130590013058001305337540071598009820000c4c8c8c8c8c12ccc164c168010cc164c16800ccc164c168008cc164c168004cc164c12ccc164c168c15cdd500325eb80c16cc16c004c168004c164004c160004c14cdd5001c566002607e00313232323232304c3305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304c3305a305b3058375400e97ae0305c305c001305b001305a001305900130580013053375400715980099b87480280062646464646464609a660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b6609a660b660b860b26ea80212f5c060ba60ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c138cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c138cc170c174c168dd5004a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d200e0018991919191919191918279982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98279982e982f182d9baa00a4bd70182f982f800982f000982e800982e000982d800982d000982c800982c00098299baa0038acc004cdc3a4020003132323232323232323230503305e305f0093305e305f0083305e305f0073305e305f0063305e305f0053305e305f0043305e305f0033305e305f0023305e305f0013305e30503305e305f305c375401697ae030603060001305f001305e001305d001305c001305b001305a001305900130580013053375400715980099b874804800626464646464646464646460a2660be60c0014660be60c0012660be60c0010660be60c000e660be60c000c660be60c000a660be60c0008660be60c0006660be60c0004660be60c0002660be60a2660be60c060ba6ea80312f5c060c260c200260c000260be00260bc00260ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c148cc180c18402ccc180c184028cc180c184024cc180c184020cc180c18401ccc180c184018cc180c184014cc180c184010cc180c18400ccc180c184008cc180c184004cc180c148cc180c184c178dd5006a5eb80c188c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d201600189919191919191919191919191829998309831006198309831005998309831005198309831004998309831004198309831003998309831003198309831002998309831002198309831001998309831001198309831000998309829998309831182f9baa00e4bd7018319831800983100098308009830000982f800982f000982e800982e000982d800982d000982c800982c00098299baa003899191919191919191919191918299983098310061983098310059983098310051983098310049983098310041983098310039983098310031983098310029983098310021983098310019983098310011983098310009983098311831800998309829998309831182f9baa00e4bd7025eb80c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001a0a24144828905120a24144828905120a24144828905118289baa0013054002400c8290dd718289829000991acc004c07800e2653001001a5eb820088008889660026094003123233055374e002660aa6ea40092f5c065300100180252f5c080088896600200510018cc00400e60b2005330573058002001400c82b2246530010059982a982b0008024c11000e6eb8c158c15c0050051802800a09e8b2098375c60a260a4008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002413d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f413c8278dc4000c888c8cc150c00cdd6982a8009982a182a982b000a5eb80c00c006660a06ea0cdc7000a4000660a06ea4cc034c0fcdc6800800a5eb81222323298009198029191982c1ba833794940dd7182c8009982c182c982d000a5eb816600260326e340062660ae6ea4c058004cc15cdd49980c180b9b8d0010014bd704590531191801acc004c13c006298103d87a8000898251982c1ba80014bd7020a830030019bad3056003911191acc006600260a06eb4c16800694294505544cc02000c8c014c130cc168dd4000a5eb8226016600898103d87a800041546eb8c168c16c004cc160dd419b8e00148000cc160dd49980a98239b8d0010014bd7024446b3001304f00289801918259982c800a5eb822b3001304c00289801918211982c800a5eb822b3001304e00289801919ba548010cc1640052f5c1159800982180144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a400c660b26ea00052f5c1159800982100144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a4010660b26ea16600266e20005208080048800c4cdc080098032404082a92f5c115980099b874802800a26006466e95200a330590014bd70456600266e1d200c002899800919ba548030cc1640052f5c0464660b46ea0c018dd6982d8009982d182d982e000a5eb80c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e900700144cc0048cdd2a401c660b200297ae02323305a375066f29281bae305b0013305a305b305c0014bd702cc004c06cdc6800c4cc164dd4980c0009982c9ba93301a3019371a00200297ae08b20aa8acc004cdc3a402000513300123374a90081982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e9009001448c8c8cc16ccdd2a4024660b660b800297ae03305b305c305d0014bd701800801198041191982d9ba833794940dd7182e0009982d982e182e800a5eb8166002609e6e340062660b46ea4c084004cc168dd49981398131b8d0010014bd7045905612cc004c1440062980103d87980008acc004c138006298103d87a80008acc004c140006298103d87b80008acc004c114006298103d87c80008acc004c110006298103d87d80008b20ac415882b105620ac8acc004cdc3a40280051300323374a900a1982c800a5eb822b30013370e900b00144c00c8cdd2a402c660b200297ae08acc004cdc3a403000513300123374a900c1982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2c82a105420a8415082a105420a8415082a105420a8415082a0dd7182c982d003096600266e2000520808080808080808080028800c4cdc0800980124100028288c00c00c6eb4c13800488cc13c008cc13cdd4800a5eb80c8cc134dd419b8e00148000cc134dd499805181e1b8d0010014bd701bae304d304e001323304c375066f29281bae304d0013304c304d304e0014bd702cc004c058dc6800c4cc12cdd49808800998259ba9330143013371a00200297ae08b208e411916410c6e3120024590391bae303e303f0015980098039b8d00189981e1ba930020013303c37526600a60086e340040052f5c11640e06eb8c0acc0e4dd5198171191acc004cdc79bae303e00148904b9011a820089191919191919199119823181c198231823803998231ba90013304630470024bd70198231823982400125eb80d660026024003125980099b89002371a00313304537526601e0040026608a6ea66002005337026e3400400a002b8c25eb822c820a2c8200dd7182298230011bae3045004375a608800264660866ea0cde5250375c6088002660866088608a00297ae059800981b9b8d0018998211ba930090013304237526601e601c6e340040052f5c11640f86eb8c108c10c004d6600294624b30013371290201b8d0018998209ba93300b48100004cc104dd4cc005204099b80371a002901fc0057184bd7045903d45903c1bae30413042001300100259800a51892cc004cdc4a4100026e3400626607e6ea4cc0252080010013303f37533001482000666e00dc6800a40ff0015c612f5c11640ed1640e91640e46eb8c0f8c0fc00566002600e6e340062660786ea4c008004cc0f0dd49980298021b8d0010014bd704590381bae303c00a300348010c00d200819801001181a000a062899180118198019bae303100240bc6eb0c0b8c0acdd5000c5902919199119801001000912cc004006298103d87a80008992cc004cdd78021816800c4c088cc0c0c0b80052f5c1133003003303200240b060600028170dd5981718179817981798179817981798179817981798159baa0033374a900219816180a99816181698171817181718151baa302d302a375400297ae04bd7045902819198008009bac301a302a375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a5140a91001899801801981800120543259800cc004dd5980e18161baa301c302c3754003374c6605c66ec0dd48031ba63302e3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb182449450124566002604460566ea8c0bcc0b0dd5181798161baa301c302c375400313259800981298161baa0018992cc004c09cc0b4dd5000c4c8c8c8c8cc89660026070007132598009817181a1baa0018991919194c004dd6981e000cdd7181e0024dd6981e001cdd7181e00124444b300130410058998181bab304000e225980080144cc0c8030896600200513035330430144bd7044c8c8cc07cc1080084c00cc11c010dd7182100098220012084899191980e98208010980198228021bae303f001304200241011640f8303c001303b001303a001303537540031640cc606e00d1640d46eb8c0d4004dd5981a801181a800981a000981980098171baa0018b20583030302d37540031640ac603c60586ea8c070c0b0dd5000c5902a4530103d87a800040a8605c0028160452689b2b200601", + "hash": "cdd7308205adaf89370d6f5fe5225b10876165977f2ce4836b67e645" }, { "title": "market.market.spend", @@ -64,8 +64,8 @@ } } ], - "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", - "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + "compiledCode": "5925e90101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae00248888888889660033001300537540172232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003371090004dc0a4001370e90034dc3a4011374a9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a2003006402d1330050053011004402c6eb8c028004dd598058009806800a01614bd6f7b63024444444444444444453001301b012980d00948966002602460306ea800a2646464b30013020002899192cc004c05c0062b3001301e37540050068b203e8acc004c05000626464b300130240028044590211bad3022001301e3754005159800980b000c566002603c6ea800a00d16407d16407080e101c180e1baa001301f0038b203a3259800980e000c566002602660360031689809180d800a0348b203a3754603c002603c00260326ea800a2c80ba444b30010028a508994c004c966002602a60366ea800626eb4c070c07cdd5980f980e1baa0018a400080d0c0780066ebcc078c07c0066eac00d22259800800c566002600400d13300500348002294101c44c96600266ebcc0780053010140008acc004cc018010dd6980f98111bab301f001898019ba630230028a5040751598009980300224001130030078a50407480e8c08400501f0ca6002003004911980f8011980f9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0740066eacc07800660440069112cc004cdc8a441000038acc004cdc7a44100003899802980a998119ba60024bd70000c4cc015300103d87a8000006407d19800803c006446600e0046604a66ec0dd48029ba6004001401c80f8604000480f229422942294101f48896600266e2000520008a40011598009809800c520028992cc004c050cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0300092004401080c8dc1001203040612232330010010032259800800c530103d87a80008992cc004c010006260206603c00297ae089980180198100012034301e00140712300c3301a3750002660349810101004bd704888c8cc88cc008008004896600200300389919912cc004cdc8803801456600266e3c01c00a20030064079133005005302400440786eb8c074004dd6980f0009810000a03c330050040031480024464b300130130018acc004c068dd5001c00a2c80da2b30013010001899192cc004c08000a0091640746eb4c078004c068dd5001c56600260240031323259800981000140122c80e8dd6980f000980d1baa0038acc004c01c0062b3001301a37540070028b20368acc004c0180062b3001301a37540070028b20368b2030406080c1018203030183754005222598009809800c52f5bded8c113232330010014bd6f7b630112cc00400626603e66ec0dd48031ba60034bd6f7b63044ca60026eb8c0740066eacc07800660440049112cc004cdc8005001c4cc08ccdd81ba900a374c00e00b15980099b8f00a00389981199bb037520146e9801c00626604666ec0dd48019ba600233006006001407c80f8604000280f0c8cc0040052f5bded8c044b300100189980f19bb037520086ea000d2f5bded8c113298009bae301c0019bad301d00198108012444b300133720010007133022337606ea4020dd4003802c56600266e3c02000e26604466ec0dd48041ba800700189981119bb037520066ea0008cc01801800501e203c180f800a03a406122598009809180c1baa0028991919912cc004c08400e00b1640786eb4c078004dd6980f001180f000980c9baa0028b202e48888888888a6002604a0173025302600b912cc004c074c08cdd500144c8c8c966002605600513300e302a00313300e0010048b20503029001302900130243754005164089300700748888cc896600260420051329800899912cc004c0900062646644b300130320018991919912cc004c0a8c0c4dd50014566002605060626ea8c0d4c0d800e264b3001302c303237540031323232332259800981e001c4c8cc060004566002605e60706ea800a2b3001303937540051598009819001c4c966002607c0031325980098189bad303b0018acc004cdd7801cc0040de0710234051159800cc00402a6e9a600202748907434f4e54524f4c00a400480da4466e2400400902144cdc79bae303a001488107434f4e54524f4c008a5040e514a081ca2c81c8c0f40062c81d8cc08c0340462c81ba2c81d22c81b8c0ec0162c81c8dd6981c800981c801181c800981c00098199baa0018b20623035303237540051640c11640c060660026eacc0cc008c0cc004c0c8c0b8dd51818800c5902f1bab302f30303030001330263758605e002466ebcc0c0c0b4dd5181818169baa00130183302f375200a97ae0302f302f302b37540271598009810800c4cc00800c04e2b30013023001899191991194c00566002603e00313370e0033001003804522104444f574e00404914a08172660286eb0c0cc0148cdd7981a18189baa303430313754604260626ea8004c070cc0ccdd4804a5eb82605066004004660340060109112cc004c0b0c0c8dd500144c8cc8966002605e606a6ea8006264660300022b30010078acc0040162b3001003899baf0014c103d87d80008a5040d514a081aa2941035181b1919bb0303a001303a303b00137586072606c6ea80062c81a0cdc4a400530013756604860686ea8c090c0d0dd5000c032910107434f4e54524f4c00405864660020026eacc0e0c0e4c0e4c0e4c0e4c0e4024896600200314c0103d87a80008992cc004cdd7981b00098111981c981d181b9baa0044bd7044c0accc0e4dd39981c981b0009981c981b800a5eb812f5c1133003003303b00240d4607200281b8c0d8c0ccdd500145903126002005007a4410255500040446eacc0c00048966002003148002266e01200233002002303300140c0606060606060606000260566ea804e2660040060268149029205222329800800ccc058dd59817981818181818181818161baa002003a514004444b30010028800c4ca60020093033003992cc00400e266e20dd698180012400114a08170dd71817000a008303100240bc60506ea801e60506ea801e4464b300130250018acc004c0b0dd5001c00a2c816a2b300130220018acc004c0b0dd5001c00a2c816a2c815102a18151baa002488966002604a00515980098161baa00a801c5902d4566002604400515980098161baa00a801c5902d45660026048005132598009818800c4cc008c0c00040122c8170c0b0dd500545660026032005132598009818800c4cc008c0c00040122c8170c0b0dd500545902a205440a881506eb8c0acc0a0dd5002c566002603c00513233223300c009159800981218151baa001899912cc004c098c0b0dd5000c4c8c966002604a605c6ea800633001375c6064605e6ea80066eacc0c8c0cc00a53001488100a44100800a02091194c0040060070024004444b30010028800c4c8cc8a600200d303b0059919800800802912cc00400626607666ec0dd48021ba60034bd6f7b63044ca60026eb8c0e40066eacc0e8006607c0049112cc004cdc8004001c4cc0fccdd81ba9008374c00e00b15980099b8f0080038992cc0056600200314a314a081fa2005133040337606ea4024dd30008012078329800800c022006800888966002005100189919914c00401a608e00b32330010010052259800800c4cc11ccdd81ba9004375000697adef6c608994c004dd71822800cdd69823000cc1280092225980099b9000800389982599bb037520106ea001c0162b30013371e010007132598009821800c400a26609866ec0dd48049ba8001002412066e0001c00a26609666ec0dd48019ba800233006006001411c8238609000282310061bae3040001375a60820026086004820a26607e66ec0dd48019ba60023300600600140ec81d8607800281d10061bae30340013756606a002606e00481aa605c6ea803522222598009816800c4c96600260720031323232598009818181b9baa0018acc004c0b8c0dcdd5181d981e001456600266ebcc0ecc0e0dd500098161981d181d981c1baa00d3303a302c3303a980081a4cdc001aa41819e49020404497ae03303a302a3038375401a97ae08cc004dd5981d801cdd3004488cdc4800801203c8a5040d91640d91640d8607400260740026072606a6ea8c0e00062c81b0cc0b8dd6181b981c181c181a1baa01c23375e6070606a6ea8c0e0c0d4dd500098101981b9ba90064bd7044c9660026056005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a4504444f574e008a4502555000410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c660200246466002002602466e080312080897a2259800800c52f5bded8c1132330473376060880026e98c8cc004004dd59823001112cc004006297adef6c608991982519bb030470013750606c6eb4c120004cc00c00cc130008c1280050481980180198248011823800a08a9119b8900100240a114a0820229410404528208030440018b20843042303f3754004660526eacc108c10cc10c0280422c81e8c100004c100008c100004c0ecdd5008459039459039181e800981e800981e181c1baa303b0028b20723303037586072002466ebcc0e8c0dcdd5181d181b9baa001302233039375201097ae0375a6072606c6ea8050c0e4c0e4c0d4dd500ec566002605a005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a45025550008a4504444f574e00410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c025223371200200481422941040452820808a50410060880031641086084607e6ea8008cc0a4dd598211821982180500845903d182000098200011820000981d9baa0108b20728b2072303d001303d001303c3038375460760051640e4660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c06eb4c0e4c0d8dd500a181c981c981a9baa01d8acc004c08800a264b3001303a0018992cc004cdc3a40026eb4c0dc0062b30013371e6eb8c0d8005220107434f4e54524f4c00898181bad30293037375401914a081aa2c81a8c0e40062c81b8cc07cdd5981c181c981c981c981c981a9baa01d00689919912cc004c0f00062646644b30013033303a37540031323259800981b181e1baa002899191919912cc004c11800e266042608a00a264b3001303c0018992cc004c120006266046608e00201116411460866ea800a2b300130390018acc004c10cdd5001401e2c82222c820904118209baa0018b2086375a6086002608600460860026084002607a6ea800a2c81d84c966002605800315980099b870019800803c03a91104444f574e00407d159800cc0040126e98cc02c034c0300064466e24004009023456600266ebcc100c0f4dd50011820181e9baa0128acc004cdd79816981e9baa002302d303d375402513370e6eb4c0bcc0f4dd500119b80375a605e607a6ea8048006294103b452820768a5040ed14a081da294103b4c00401a01b489025550004078607c60766ea80062c81c8dd5981e000981e181e800981e181c1baa303b0018b20723756607260746074002660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c060726072606a6ea8075033206640cc446644b30013371000200514c0103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040d881b0cdc11bad3039303637540046eb4c098c0d8dd500099b82375a6072606c6ea8004dd69813181b1baa00240c88b205a3031302e37546062002605a6ea8c0c0c0c4c0b4dd5181818169baa0018b2056302e302b37540026601e6eb0c0b8c0acdd5009919baf302f302c37540020071640a460580026058605a00260506ea80162c813102618129baa00322232598009817000c4c8c966002604a60566ea800626464b30013027302d375400313259800981418171baa0018992cc004c0a4c0bcdd5000c4c966002605460606ea8006264b30013370e6eb4c0d4c0c8dd500419b8200b483403e2604c66068606a60646ea8004cc0d0c088c0c8dd5000a5eb822c8180cc88c09ccc0d4dd419b82375a606c0046eb4c0d8004cc0d4dd419b82375a606c606e0046eb4c0d8c0dc0052f5c060626ea8c050dd6981a18189baa00330313754606860626ea80062c8178c8ca60026eb4c0d40066eb4c0d4c0d80066eb4c0d4c0c8dd5001a444b3001598009817001c4cdc4800a400114a0819a298103d87a80008acc004c090006260526606e60526606e6ea0cc04000c004cc0dcdd419808001000a5eb812f5c115980099b8800148002260526606e60526606e6ea0cc040008c08c004cc0dcdd4198080019811800a5eb812f5c114c010ad8799fd8799f0101ffff0040cc81990330c0c4dd50009809a40291640b8606460666066606660666066605e6ea800e2c8168c0c4c0b8dd5000c5902c180e98169baa001302f302c37540031640a86601e6eb0c074c0acdd5000918111bad302f302c3754002605a0031640ac64b300130233029375400313259800981218151baa0018991980f800912cc00400a2646600200200844b30010018a5eb822660653001371290004dc62400937009001cdc4a4011371890004dc62401137009003a444444466446605c4646b30013371e6eb8c0f80052210475d3c793008cc004888c8cc00cdd698210009bae3042304300130030019b89480426e3120109b804803e600e90082444446600a464660886ea0cde5250375c608a00266088608a608c00297ae05980098029b8d0018998219ba930020013304337526600860066e340040052f5c11640fc4646600e46608a6ea0cdc7000a40006608a6ea4cc008c0d0dc6800800a5eb808cc0208cc118dd419b8e00148000cc118dd499801981a9b8d0010014bd7011191919824981d998249ba800733049375000a66092609400297ae033049304a304b0014bd7018008012cc004c05400a2653001001a5eb82006800888966002608200312323304c374e002660986ea40092f5c065300100180252f5c080088896600200510018cc00400e60a00053304e304f002001400c826a246530010059982618268008024c0ec00e6eb8c134c138005005191919911919801194c0040066eb0c14800a6086660a260a400c660a2980103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a80004bd702002222598008014400633001003982a8014c8c966002609800313230483305630570013305630483305630573054375400697ae030583058001305337540071598009824800c4c8c8c124cc15cc160008cc15cc160004cc15cc124cc15cc160c154dd500225eb80c164c164004c160004c14cdd5001c56600260960031323232304a33058305900333058305900233058305900133058304a3305830593056375400a97ae0305a305a00130590013058001305337540071598009820000c4c8c8c8c8c12ccc164c168010cc164c16800ccc164c168008cc164c168004cc164c12ccc164c168c15cdd500325eb80c16cc16c004c168004c164004c160004c14cdd5001c566002607e00313232323232304c3305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304c3305a305b3058375400e97ae0305c305c001305b001305a001305900130580013053375400715980099b87480280062646464646464609a660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b6609a660b660b860b26ea80212f5c060ba60ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c138cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c138cc170c174c168dd5004a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d200e0018991919191919191918279982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98279982e982f182d9baa00a4bd70182f982f800982f000982e800982e000982d800982d000982c800982c00098299baa0038acc004cdc3a4020003132323232323232323230503305e305f0093305e305f0083305e305f0073305e305f0063305e305f0053305e305f0043305e305f0033305e305f0023305e305f0013305e30503305e305f305c375401697ae030603060001305f001305e001305d001305c001305b001305a001305900130580013053375400715980099b874804800626464646464646464646460a2660be60c0014660be60c0012660be60c0010660be60c000e660be60c000c660be60c000a660be60c0008660be60c0006660be60c0004660be60c0002660be60a2660be60c060ba6ea80312f5c060c260c200260c000260be00260bc00260ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c148cc180c18402ccc180c184028cc180c184024cc180c184020cc180c18401ccc180c184018cc180c184014cc180c184010cc180c18400ccc180c184008cc180c184004cc180c148cc180c184c178dd5006a5eb80c188c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d201600189919191919191919191919191829998309831006198309831005998309831005198309831004998309831004198309831003998309831003198309831002998309831002198309831001998309831001198309831000998309829998309831182f9baa00e4bd7018319831800983100098308009830000982f800982f000982e800982e000982d800982d000982c800982c00098299baa003899191919191919191919191918299983098310061983098310059983098310051983098310049983098310041983098310039983098310031983098310029983098310021983098310019983098310011983098310009983098311831800998309829998309831182f9baa00e4bd7025eb80c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001a0a24144828905120a24144828905120a24144828905118289baa0013054002400c8290dd718289829000991acc004c07800e2653001001a5eb820088008889660026094003123233055374e002660aa6ea40092f5c065300100180252f5c080088896600200510018cc00400e60b2005330573058002001400c82b2246530010059982a982b0008024c11000e6eb8c158c15c0050051802800a09e8b2098375c60a260a4008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002413d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f413c8278dc4000c888c8cc150c00cdd6982a8009982a182a982b000a5eb80c00c006660a06ea0cdc7000a4000660a06ea4cc034c0fcdc6800800a5eb81222323298009198029191982c1ba833794940dd7182c8009982c182c982d000a5eb816600260326e340062660ae6ea4c058004cc15cdd49980c180b9b8d0010014bd704590531191801acc004c13c006298103d87a8000898251982c1ba80014bd7020a830030019bad3056003911191acc006600260a06eb4c16800694294505544cc02000c8c014c130cc168dd4000a5eb8226016600898103d87a800041546eb8c168c16c004cc160dd419b8e00148000cc160dd49980a98239b8d0010014bd7024446b3001304f00289801918259982c800a5eb822b3001304c00289801918211982c800a5eb822b3001304e00289801919ba548010cc1640052f5c1159800982180144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a400c660b26ea00052f5c1159800982100144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a4010660b26ea16600266e20005208080048800c4cdc080098032404082a92f5c115980099b874802800a26006466e95200a330590014bd70456600266e1d200c002899800919ba548030cc1640052f5c0464660b46ea0c018dd6982d8009982d182d982e000a5eb80c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e900700144cc0048cdd2a401c660b200297ae02323305a375066f29281bae305b0013305a305b305c0014bd702cc004c06cdc6800c4cc164dd4980c0009982c9ba93301a3019371a00200297ae08b20aa8acc004cdc3a402000513300123374a90081982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e9009001448c8c8cc16ccdd2a4024660b660b800297ae03305b305c305d0014bd701800801198041191982d9ba833794940dd7182e0009982d982e182e800a5eb8166002609e6e340062660b46ea4c084004cc168dd49981398131b8d0010014bd7045905612cc004c1440062980103d87980008acc004c138006298103d87a80008acc004c140006298103d87b80008acc004c114006298103d87c80008acc004c110006298103d87d80008b20ac415882b105620ac8acc004cdc3a40280051300323374a900a1982c800a5eb822b30013370e900b00144c00c8cdd2a402c660b200297ae08acc004cdc3a403000513300123374a900c1982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2c82a105420a8415082a105420a8415082a105420a8415082a0dd7182c982d003096600266e2000520808080808080808080028800c4cdc0800980124100028288c00c00c6eb4c13800488cc13c008cc13cdd4800a5eb80c8cc134dd419b8e00148000cc134dd499805181e1b8d0010014bd701bae304d304e001323304c375066f29281bae304d0013304c304d304e0014bd702cc004c058dc6800c4cc12cdd49808800998259ba9330143013371a00200297ae08b208e411916410c6e3120024590391bae303e303f0015980098039b8d00189981e1ba930020013303c37526600a60086e340040052f5c11640e06eb8c0acc0e4dd5198171191acc004cdc79bae303e00148904b9011a820089191919191919199119823181c198231823803998231ba90013304630470024bd70198231823982400125eb80d660026024003125980099b89002371a00313304537526601e0040026608a6ea66002005337026e3400400a002b8c25eb822c820a2c8200dd7182298230011bae3045004375a608800264660866ea0cde5250375c6088002660866088608a00297ae059800981b9b8d0018998211ba930090013304237526601e601c6e340040052f5c11640f86eb8c108c10c004d6600294624b30013371290201b8d0018998209ba93300b48100004cc104dd4cc005204099b80371a002901fc0057184bd7045903d45903c1bae30413042001300100259800a51892cc004cdc4a4100026e3400626607e6ea4cc0252080010013303f37533001482000666e00dc6800a40ff0015c612f5c11640ed1640e91640e46eb8c0f8c0fc00566002600e6e340062660786ea4c008004cc0f0dd49980298021b8d0010014bd704590381bae303c00a300348010c00d200819801001181a000a062899180118198019bae303100240bc6eb0c0b8c0acdd5000c5902919199119801001000912cc004006298103d87a80008992cc004cdd78021816800c4c088cc0c0c0b80052f5c1133003003303200240b060600028170dd5981718179817981798179817981798179817981798159baa0033374a900219816180a99816181698171817181718151baa302d302a375400297ae04bd7045902819198008009bac301a302a375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a5140a91001899801801981800120543259800cc004dd5980e18161baa301c302c3754003374c6605c66ec0dd48031ba63302e3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb182449450124566002604460566ea8c0bcc0b0dd5181798161baa301c302c375400313259800981298161baa0018992cc004c09cc0b4dd5000c4c8c8c8c8cc89660026070007132598009817181a1baa0018991919194c004dd6981e000cdd7181e0024dd6981e001cdd7181e00124444b300130410058998181bab304000e225980080144cc0c8030896600200513035330430144bd7044c8c8cc07cc1080084c00cc11c010dd7182100098220012084899191980e98208010980198228021bae303f001304200241011640f8303c001303b001303a001303537540031640cc606e00d1640d46eb8c0d4004dd5981a801181a800981a000981980098171baa0018b20583030302d37540031640ac603c60586ea8c070c0b0dd5000c5902a4530103d87a800040a8605c0028160452689b2b200601", + "hash": "cdd7308205adaf89370d6f5fe5225b10876165977f2ce4836b67e645" }, { "title": "market.market.else", @@ -86,8 +86,8 @@ } } ], - "compiledCode": "5922700101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c12232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003370290004dc3a400d370e90044dd2a4004911111111111111114c004c068046603202322598009808180b9baa00289919192cc004c07c00a26464b300130150018acc004c074dd5001401a2c80f22b30013012001899192cc004c08c00a0111640806eb4c084004c074dd500145660026028003159800980e9baa00280345901e45901b2036406c60366ea8004c07800e2c80e0c96600260360031598009808980d000c5a26020603400280ca2c80e0dd5180e800980e800980c1baa0028b202c9112cc00400a2942265300132598009809980d1baa00189bad301b301e3756603c60366ea8006290002032301d0019baf301d301e0019bab003488966002003159800980100344cc01400d20008a50406d1325980099baf301d0014c10140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029809998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e48896600266e2000520008a40011598009808800c520028992cc004c048cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0280092004401080c0dc1001202e405d2232330010010032259800800c530103d87a80008992cc004c0100062601c6603a00297ae0899801801980f8012032301d001406d2300a330193750002660329810101004bd70488966002602200314bd6f7b63044c8c8cc0040052f5bded8c044b300100189980f19bb0375200c6e9800d2f5bded8c113298009bae301c0019bab301d00198108012444b300133720014007133022337606ea4028dd3003802c56600266e3c02800e26604466ec0dd48051ba600700189981119bb037520066e98008cc01801800501e203c180f800a03a32330010014bd6f7b630112cc00400626603a66ec0dd48021ba80034bd6f7b63044ca60026eb8c06c0066eb4c07000660400049112cc004cdc8004001c4cc084cdd81ba9008375000e00b15980099b8f00800389981099bb037520106ea001c00626604266ec0dd48019ba800233006006001407480e8603c00280e10172444444453001302100898109811004489660026030603e6ea800a2646464b3001302700289980598130018998058008024590241812800981280098101baa0028b203c9802002244446644b3001301c0028994c0044c966002603c00313232598009816000c4c8c8c966002604460546ea80062b30013020302a3754605c605e00513259800981218159baa0018991919912cc004c0d0006264b300130293030375400313232332259800981c801c566002605460686ea801e2b30013035375400f15980098169bad30380068992cc004c0e8006264b3001302c375a606e00315980099baf0079800819c0d204080a22b300198009bab303a00f9ba69800809d22107434f4e54524f4c00a400480d24466e2400400901e44cdc79bae3036001488107434f4e54524f4c008a5040d514a081aa2c81a8c0e40062c81b8cc0bcdd5981c181c981c807808c590334590364590334590361bad3036001375a606c004606c00260626ea80062c8178c0cc0122c8188c0c4004c0c8004c0c4004c0b0dd5000c5902a181718159baa0018b20528b2052302d001302d001302c3028375460560031640a4660406eb0c0a80048cdd7981598141baa302b302837540026026660546ea40112f5c060546054604c6ea803e2b3001301b0018994c004006660426eacc0a8c0acc0acc0acc0acc09cdd5008001d28a002222598008014400626530010049817001cc9660020071337106eb4c0ac00920008a5040a46eb8c0a4005004181600120548acc004c0740062d164090812102418121baa00798121baa00791192cc004c0800062b3001302837540070028b20528acc004c0740062b3001302837540070028b20528b204c4098604c6ea8009222598009810001456600260506ea802a0071640a5159800980e801456600260506ea802a0071640a5159800980f80144c966002605a003133002302c0010048b205430283754015159800980a80144c966002605a003133002302c0010048b2054302837540151640988131026204c1bae30273024375400b159800980c80144c8cc88cc8966002604200315980098149baa00b80145902a4566002603c0031323259800981780140122c8160dd6981680098149baa00b8acc004c08000626464b3001302f00280245902c1bad302d00130293754017159800980b000c56600260526ea802e0051640a9159800980a800c56600260526ea802e0051640a916409c8139027204e409c2b3001301f302637540031332259800981098141baa001899192cc004c080c0a8dd5000c660026eb8c0b8c0acdd5000cdd5981718178014c0a8dd5006a444b300130260018992cc004c0cc0062646464b3001302930313754003159800981398189baa303530360028acc004cdd7981a98191baa00130253303430353032375401666068604a66069300102e99b8002f483033c9203680792f5c066068604660646ea802d2f5c1198009bab30350039ba60069119b89001002406514a081822c81822c8180c0d0004c0d0004c0ccc0bcdd51819000c59030198139bac303130323032302e375402e466ebcc0c8c0bcdd5181918179baa001301a33031375200897ae08992cc004c09000a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd79980700180226103d87980008a4504444f574e008a450255500040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c653001001808cc8cc004006600291100a4410099b8200d4820225e9021112cc004006297adef6c608991982119bb0303f001374c64660020026eacc104008896600200314bd6f7b63044c8cc114cdd818210009ba83031375a608600266006006608e004608a0028218cc00c00cc110008c10800504020022225980080144006264664530010069823002cc8cc0040040148966002003133046337606ea4010dd3001a5eb7bdb1822653001375c60880033756608a003304900248896600266e4002000e26609466ec0dd48041ba60070058acc004cdc7804001c4c966002b30010018a518a504129100289982599bb037520126e98004009047194c0040060110034004444b30010028800c4c8cc8a600200d30520059919800800802912cc0040062660a466ec0dd48021ba80034bd6f7b63044ca60026eb8c1400066eb4c14400660aa0049112cc004cdc8004001c4cc158cdd81ba9008375000e00b15980099b8f0080038992cc004c1340062005133057337606ea4024dd400080120a63370000e005133056337606ea400cdd400119803003000a0a44148305300141448030dd718258009bad304c001304e002413113304a337606ea400cdd300119803003000a08c4118304700141148030dd7181f8009bab3040001304200241012233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c09800a2646644b3001303600289919192cc004c0b0c0d0dd5000c566002605460686ea8c0e0c0e400a264646644b30013031303837540051332259800981f800c4c96600266e3cdd7181d800acc004cdd799807001802260103d87980008a45025550008a4504444f574e0040e915980099b87375a6078002605401715980099baf303f303c3754010605e6607c0086607c605e6607c00697ae03303e375066e04dd6981f9820003005a5eb82330013756607e015374c0212233712002004811a294103a452820748a5040e8607c0031640f0607860726ea8008cc0ccdd5981e181e981e805007459037181d000981d001181d000981a9baa00e8b20668b206630370013037001303630323754606a0051640cc660526eb0c0cc0048cdd7981a18189baa3034303137540026038660666ea40192f5c06eb4c0ccc0c0dd50091819981998179baa0188acc004c07000a264b300130340018992cc004cdc3a40026eb4c0c40062b30013371e6eb8c0c0005220107434f4e54524f4c00898149bad30223031375401514a0817a2c8178c0cc0062c8188cc0a4dd59819181998199819981998179baa0180048b205a40b4816888cc896600266e2000400a2980103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040c08180cdc11bad3033303037540046eb4c07cc0c0dd500099b82375a606660606ea8004dd6980f98181baa00240b08b2052302d302a3754605a00260526ea8c0b0c0b4c0a4dd5181618149baa0018b204e302a30273754002660186eb0c0a8c09cdd5008119baf302b30283754002007164094604c6ea8024c0a0004c0a0c0a4004c090dd5002c5902220443021375400644464b3001302a001899192cc004c080c09cdd5000c4c8c966002604460526ea8006264b30013023302a375400313259800981218159baa0018992cc004c094c0b0dd5000c4c96600266e1cdd6981898171baa00833704016906807c4c084cc0c0c0c4c0b8dd500099818180e98171baa0014bd7045902c19911811198189ba8337046eb4c0c8008dd69819000998189ba8337046eb4c0c8c0cc008dd698191819800a5eb80c0b4dd518089bad3030302d3754006605a6ea8c0c0c0b4dd5000c5902b19194c004dd69818800cdd698189819000cdd6981898171baa003488966002b30013029003899b8900148002294102f45300103d87a80008acc004cdc4240000031302433033302433033375066020006002660666ea0cc0400080052f5c097ae08acc004cdc4000a40011302433033302433033375066020004603e002660666ea0cc04000cc07c0052f5c097ae08a610ad8799fd8799f0101ffff0040bc817902f0c0b4dd50009808240291640a8605c605e605e605e605e605e60566ea800e2c8148c0b4c0a8dd5000c59028180c18149baa001302b30283754003164098660186eb0c060c09cdd50009180e9bad302b30283754002605200316409c64b3001301e3025375400313259800980f98131baa0018991980d000912cc00400a2646600200200844b30010018a5eb8226605d3001371290004dc62400937009001cdc4a4011371890004dc62401137009003a44444446644660524646b30013371e6eb8c0e80052210475d3c793008cc004888c8cc00cdd6981f0009bae303e303f00130030019b89480426e3120109b804803e600e90082444446600a464660806ea0cde5250375c6082002660806082608400297ae05980098029b8d00189981f9ba930020013303f37526600860066e340040052f5c11640ec4646600e4660826ea0cdc7000a4000660826ea4cc008c0bcdc6800800a5eb808cc0208cc108dd419b8e00148000cc108dd49980198181b8d0010014bd7011191919822981b198229ba800733045375000a6608a608c00297ae033045304630470014bd7018008012cc004c05400a2653001001a5eb820068008889660026078003123233048374e002660906ea40092f5c065300100180252f5c080088896600200510018cc00400e60980053304a304b002001400c824a246530010059982418248008024c0d800e6eb8c124c128005005191919911919801194c0040066eb0c13800a607c6609a609c00c6609a980103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80003304d4c103d87a80004bd70200222259800801440063300100398288014c8c966002608e00313230433305230530013305230433305230533050375400697ae030543054001304f37540071598009822000c4c8c8c110cc14cc150008cc14cc150004cc14cc110cc14cc150c144dd500225eb80c154c154004c150004c13cdd5001c566002608c003132323230453305430550033305430550023305430550013305430453305430553052375400a97ae03056305600130550013054001304f3754007159800981e000c4c8c8c8c8c118cc154c158010cc154c15800ccc154c158008cc154c158004cc154c118cc154c158c14cdd500325eb80c15cc15c004c158004c154004c150004c13cdd5001c56600260760031323232323230473305630570053305630570043305630570033305630570023305630570013305630473305630573054375400e97ae0305830580013057001305600130550013054001304f375400715980099b874802800626464646464646090660ae60b000c660ae60b000a660ae60b0008660ae60b0006660ae60b0004660ae60b0002660ae6090660ae60b060aa6ea80212f5c060b260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c124cc160c16401ccc160c164018cc160c164014cc160c164010cc160c16400ccc160c164008cc160c164004cc160c124cc160c164c158dd5004a5eb80c168c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d200e0018991919191919191918251982c982d0041982c982d0039982c982d0031982c982d0029982c982d0021982c982d0019982c982d0011982c982d0009982c98251982c982d182b9baa00a4bd70182d982d800982d000982c800982c000982b800982b000982a800982a00098279baa0038acc004cdc3a40200031323232323232323232304b3305a305b0093305a305b0083305a305b0073305a305b0063305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304b3305a305b3058375401697ae0305c305c001305b001305a001305900130580013057001305600130550013054001304f375400715980099b87480480062646464646464646464646098660b660b8014660b660b8012660b660b8010660b660b800e660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b66098660b660b860b26ea80312f5c060ba60ba00260b800260b600260b400260b200260b000260ae00260ac00260aa00260a8002609e6ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c134cc170c17402ccc170c174028cc170c174024cc170c174020cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c134cc170c174c168dd5006a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001c56600266e1d2016001899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98271982e982f182d9baa00e4bd70182f982f800982f000982e800982e000982d800982d000982c800982c000982b800982b000982a800982a00098279baa003899191919191919191919191918271982e982f0061982e982f0059982e982f0051982e982f0049982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e982f182f8009982e98271982e982f182d9baa00e4bd7025eb80c178004c174004c170004c16c004c168004c164004c160004c15c004c158004c154004c150004c13cdd5001a09a4134826904d209a4134826904d209a4134826904d18269baa0013050002400c8270dd718269827000991acc004c07800e2653001001a5eb82008800888966002608a003123233051374e002660a26ea40092f5c065300100180252f5c080088896600200510018cc00400e60aa005330533054002001400c8292246530010059982898290008024c0fc00e6eb8c148c14c0050051802800a0968b2090375c609a609c008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002412d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f412c8258dc4000c888c8cc140c00cdd698288009982818289829000a5eb80c00c006660986ea0cdc7000a4000660986ea4cc034c0e8dc6800800a5eb81222323298009198029191982a1ba833794940dd7182a8009982a182a982b000a5eb816600260326e340062660a66ea4c058004cc14cdd49980c180b9b8d0010014bd7045904f1191801acc004c128006298103d87a8000898229982a1ba80014bd7020a030030019bad3052003911191acc006600260966eb4c15800694294505144cc02000c8c014c11ccc158dd4000a5eb8226016600898103d87a800041446eb8c158c15c004cc150dd419b8e00148000cc150dd49980a98211b8d0010014bd7024446b3001304a00289801918231982a800a5eb822b30013047002898019181f1982a800a5eb822b3001304900289801919ba548010cc1540052f5c1159800981f80144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a400c660aa6ea00052f5c1159800981f00144cc01c8c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b30013049371a00313305537526040002660aa6ea4cc098c094dc6800800a5eb822c82888cdd2a4010660aa6ea16600266e20005208080048800c4cdc080098032404082892f5c115980099b874802800a26006466e95200a330550014bd70456600266e1d200c002899800919ba548030cc1540052f5c0464660ac6ea0c018dd6982b8009982b182b982c000a5eb80c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e900700144cc0048cdd2a401c660aa00297ae023233056375066f29281bae305700133056305730580014bd702cc004c06cdc6800c4cc154dd4980c0009982a9ba93301a3019371a00200297ae08b20a28acc004cdc3a402000513300123374a90081982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2b30013370e9009001448c8c8cc15ccdd2a4024660ae60b000297ae033057305830590014bd701800801198041191982b9ba833794940dd7182c0009982b982c182c800a5eb816600260946e340062660ac6ea4c084004cc158dd49981398131b8d0010014bd7045905212cc004c1300062980103d87980008acc004c124006298103d87a80008acc004c12c006298103d87b80008acc004c104006298103d87c80008acc004c100006298103d87d80008b20a44148829105220a48acc004cdc3a40280051300323374a900a1982a800a5eb822b30013370e900b00144c00c8cdd2a402c660aa00297ae08acc004cdc3a403000513300123374a900c1982a800a5eb808c8cc158dd419bca4a06eb8c15c004cc158c15cc1600052f5c0b3001301b371a00313305537526030002660aa6ea4cc068c064dc6800800a5eb822c828a2c828105020a04140828105020a04140828105020a041408280dd7182a982b003096600266e2000520808080808080808080028800c4cdc0800980124100028268c00c00c6eb4c12800488cc12c008cc12cdd4800a5eb80c8cc124dd419b8e00148000cc124dd499805181b9b8d0010014bd701bae3049304a0013233048375066f29281bae3049001330483049304a0014bd702cc004c058dc6800c4cc11cdd49808800998239ba9330143013371a00200297ae08b208641091640fc6e3120024590351bae303a303b0015980098039b8d00189981c1ba930020013303837526600a60086e340040052f5c11640d06eb8c098c0d4dd5198149191acc004cdc79bae303a00148904b9011a8200891919191919191991198211819998211821803998211ba90013304230430024bd70198211821982200125eb80d660026024003125980099b89002371a00313304137526601e004002660826ea66002005337026e3400400a002b8c25eb822c81ea2c81e0dd7182098210011bae3041004375a6080002646607e6ea0cde5250375c60800026607e6080608200297ae05980098191b8d00189981f1ba930090013303e37526601e601c6e340040052f5c11640e86eb8c0f8c0fc004d6600294624b30013371290201b8d00189981e9ba93300b48100004cc0f4dd4cc005204099b80371a002901fc0057184bd704590394590381bae303d303e001300100259800a51892cc004cdc4a4100026e340062660766ea4cc0252080010013303b37533001482000666e00dc6800a40ff0015c612f5c11640dd1640d91640d46eb8c0e8c0ec00566002600e6e340062660706ea4c008004cc0e0dd49980298021b8d0010014bd704590341bae303800a300348010c00d2008198010011818000a05a899180118178019bae302d00240ac6eb0c0a8c09cdd5000c5902519199119801001000912cc004006298103d87a80008992cc004cdd78021814800c4c074cc0b0c0a80052f5c1133003003302e00240a060580028150dd5981518159815981598159815981598159815981598139baa0033374a900219814180899814181498151815181518131baa30293026375400297ae04bd7045902419198008009bac30153026375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a51409910018998018019816001204c3259800cc004dd5980b98141baa301730283754003374c6605466ec0dd48031ba63302a3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb1824494500f4566002603a604e6ea8c0acc0a0dd5181598141baa30173028375400313259800981018141baa0018992cc004c088c0a4dd5000c4c8c8c8c8cc8966002606800713259800981498181baa0018991919194c004dd6981c000cdd7181c0024dd6981c001cdd7181c00124444b3001303d0058998159bab303c00e225980080144cc0b40308966002005130303303f0144bd7044c8c8cc07cc0f80084c00cc10c010dd7181f0009820001207c899191980e981e8010980198208021bae303b001303e00240f11640e8303800130370013036001303137540031640bc606600d1640c46eb8c0c4004dd5981880118188009818000981780098151baa0018b2050302c3029375400316409c603260506ea8c05cc0a0dd5000c590264530103d87a8000409860540028140452689b2b200601", - "hash": "ca6d3042d2f3ce64effbf9cf4e9eab2c1e01e41b3ed41edfbaa3b429" + "compiledCode": "5925e90101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bad0039bae00248888888889660033001300537540172232330010010032259800800c52f5c11332259800980280144cc034008cc0100100062660080080028048c030004c03400500a4dc3a4001370e90024dc4a4009370e9001488c96600266e3d22100375c601660180031300b0018b200c30020019ba5480024464660020020064466006002600400523009300a300a0019b8048006460126014003371090004dc0a4001370e90034dc3a4011374a9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a2003006402d1330050053011004402c6eb8c028004dd598058009806800a01614bd6f7b63024444444444444444453001301b012980d00948966002602460306ea800a2646464b30013020002899192cc004c05c0062b3001301e37540050068b203e8acc004c05000626464b300130240028044590211bad3022001301e3754005159800980b000c566002603c6ea800a00d16407d16407080e101c180e1baa001301f0038b203a3259800980e000c566002602660360031689809180d800a0348b203a3754603c002603c00260326ea800a2c80ba444b30010028a508994c004c966002602a60366ea800626eb4c070c07cdd5980f980e1baa0018a400080d0c0780066ebcc078c07c0066eac00d22259800800c566002600400d13300500348002294101c44c96600266ebcc0780053010140008acc004cc018010dd6980f98111bab301f001898019ba630230028a5040751598009980300224001130030078a50407480e8c08400501f0ca6002003004911980f8011980f9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0740066eacc07800660440069112cc004cdc8a441000038acc004cdc7a44100003899802980a998119ba60024bd70000c4cc015300103d87a8000006407d19800803c006446600e0046604a66ec0dd48029ba6004001401c80f8604000480f229422942294101f48896600266e2000520008a40011598009809800c520028992cc004c050cdc300124009198008024c00400e66e0c009200440111300198008024c00400e66e0cc0300092004401080c8dc1001203040612232330010010032259800800c530103d87a80008992cc004c010006260206603c00297ae089980180198100012034301e00140712300c3301a3750002660349810101004bd704888c8cc88cc008008004896600200300389919912cc004cdc8803801456600266e3c01c00a20030064079133005005302400440786eb8c074004dd6980f0009810000a03c330050040031480024464b300130130018acc004c068dd5001c00a2c80da2b30013010001899192cc004c08000a0091640746eb4c078004c068dd5001c56600260240031323259800981000140122c80e8dd6980f000980d1baa0038acc004c01c0062b3001301a37540070028b20368acc004c0180062b3001301a37540070028b20368b2030406080c1018203030183754005222598009809800c52f5bded8c113232330010014bd6f7b630112cc00400626603e66ec0dd48031ba60034bd6f7b63044ca60026eb8c0740066eacc07800660440049112cc004cdc8005001c4cc08ccdd81ba900a374c00e00b15980099b8f00a00389981199bb037520146e9801c00626604666ec0dd48019ba600233006006001407c80f8604000280f0c8cc0040052f5bded8c044b300100189980f19bb037520086ea000d2f5bded8c113298009bae301c0019bad301d00198108012444b300133720010007133022337606ea4020dd4003802c56600266e3c02000e26604466ec0dd48041ba800700189981119bb037520066ea0008cc01801800501e203c180f800a03a406122598009809180c1baa0028991919912cc004c08400e00b1640786eb4c078004dd6980f001180f000980c9baa0028b202e48888888888a6002604a0173025302600b912cc004c074c08cdd500144c8c8c966002605600513300e302a00313300e0010048b20503029001302900130243754005164089300700748888cc896600260420051329800899912cc004c0900062646644b300130320018991919912cc004c0a8c0c4dd50014566002605060626ea8c0d4c0d800e264b3001302c303237540031323232332259800981e001c4c8cc060004566002605e60706ea800a2b3001303937540051598009819001c4c966002607c0031325980098189bad303b0018acc004cdd7801cc0040de0710234051159800cc00402a6e9a600202748907434f4e54524f4c00a400480da4466e2400400902144cdc79bae303a001488107434f4e54524f4c008a5040e514a081ca2c81c8c0f40062c81d8cc08c0340462c81ba2c81d22c81b8c0ec0162c81c8dd6981c800981c801181c800981c00098199baa0018b20623035303237540051640c11640c060660026eacc0cc008c0cc004c0c8c0b8dd51818800c5902f1bab302f30303030001330263758605e002466ebcc0c0c0b4dd5181818169baa00130183302f375200a97ae0302f302f302b37540271598009810800c4cc00800c04e2b30013023001899191991194c00566002603e00313370e0033001003804522104444f574e00404914a08172660286eb0c0cc0148cdd7981a18189baa303430313754604260626ea8004c070cc0ccdd4804a5eb82605066004004660340060109112cc004c0b0c0c8dd500144c8cc8966002605e606a6ea8006264660300022b30010078acc0040162b3001003899baf0014c103d87d80008a5040d514a081aa2941035181b1919bb0303a001303a303b00137586072606c6ea80062c81a0cdc4a400530013756604860686ea8c090c0d0dd5000c032910107434f4e54524f4c00405864660020026eacc0e0c0e4c0e4c0e4c0e4c0e4024896600200314c0103d87a80008992cc004cdd7981b00098111981c981d181b9baa0044bd7044c0accc0e4dd39981c981b0009981c981b800a5eb812f5c1133003003303b00240d4607200281b8c0d8c0ccdd500145903126002005007a4410255500040446eacc0c00048966002003148002266e01200233002002303300140c0606060606060606000260566ea804e2660040060268149029205222329800800ccc058dd59817981818181818181818161baa002003a514004444b30010028800c4ca60020093033003992cc00400e266e20dd698180012400114a08170dd71817000a008303100240bc60506ea801e60506ea801e4464b300130250018acc004c0b0dd5001c00a2c816a2b300130220018acc004c0b0dd5001c00a2c816a2c815102a18151baa002488966002604a00515980098161baa00a801c5902d4566002604400515980098161baa00a801c5902d45660026048005132598009818800c4cc008c0c00040122c8170c0b0dd500545660026032005132598009818800c4cc008c0c00040122c8170c0b0dd500545902a205440a881506eb8c0acc0a0dd5002c566002603c00513233223300c009159800981218151baa001899912cc004c098c0b0dd5000c4c8c966002604a605c6ea800633001375c6064605e6ea80066eacc0c8c0cc00a53001488100a44100800a02091194c0040060070024004444b30010028800c4c8cc8a600200d303b0059919800800802912cc00400626607666ec0dd48021ba60034bd6f7b63044ca60026eb8c0e40066eacc0e8006607c0049112cc004cdc8004001c4cc0fccdd81ba9008374c00e00b15980099b8f0080038992cc0056600200314a314a081fa2005133040337606ea4024dd30008012078329800800c022006800888966002005100189919914c00401a608e00b32330010010052259800800c4cc11ccdd81ba9004375000697adef6c608994c004dd71822800cdd69823000cc1280092225980099b9000800389982599bb037520106ea001c0162b30013371e010007132598009821800c400a26609866ec0dd48049ba8001002412066e0001c00a26609666ec0dd48019ba800233006006001411c8238609000282310061bae3040001375a60820026086004820a26607e66ec0dd48019ba60023300600600140ec81d8607800281d10061bae30340013756606a002606e00481aa605c6ea803522222598009816800c4c96600260720031323232598009818181b9baa0018acc004c0b8c0dcdd5181d981e001456600266ebcc0ecc0e0dd500098161981d181d981c1baa00d3303a302c3303a980081a4cdc001aa41819e49020404497ae03303a302a3038375401a97ae08cc004dd5981d801cdd3004488cdc4800801203c8a5040d91640d91640d8607400260740026072606a6ea8c0e00062c81b0cc0b8dd6181b981c181c181a1baa01c23375e6070606a6ea8c0e0c0d4dd500098101981b9ba90064bd7044c9660026056005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a4504444f574e008a4502555000410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c660200246466002002602466e080312080897a2259800800c52f5bded8c1132330473376060880026e98c8cc004004dd59823001112cc004006297adef6c608991982519bb030470013750606c6eb4c120004cc00c00cc130008c1280050481980180198248011823800a08a9119b8900100240a114a0820229410404528208030440018b20843042303f3754004660526eacc108c10cc10c0280422c81e8c100004c100008c100004c0ecdd5008459039459039181e800981e800981e181c1baa303b0028b20723303037586072002466ebcc0e8c0dcdd5181d181b9baa001302233039375201097ae0375a6072606c6ea8050c0e4c0e4c0d4dd500ec566002605a005132332259800981e00144c8c8c966002606660746ea80062b30013031303a3754607c607e00513232332259800981c181f1baa002899912cc004c114006264b30013371e6eb8c1040056600266ebccc03800c01130103d87980008a45025550008a4504444f574e00410115980099b87375a6084002606001715980099baf304530423754010606c6608800866088606c6608800697ae033044375066e04dd698229823003005a5eb82330013756608a015374c025223371200200481422941040452820808a50410060880031641086084607e6ea8008cc0a4dd598211821982180500845903d182000098200011820000981d9baa0108b20728b2072303d001303d001303c3038375460760051640e4660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c06eb4c0e4c0d8dd500a181c981c981a9baa01d8acc004c08800a264b3001303a0018992cc004cdc3a40026eb4c0dc0062b30013371e6eb8c0d8005220107434f4e54524f4c00898181bad30293037375401914a081aa2c81a8c0e40062c81b8cc07cdd5981c181c981c981c981c981a9baa01d00689919912cc004c0f00062646644b30013033303a37540031323259800981b181e1baa002899191919912cc004c11800e266042608a00a264b3001303c0018992cc004c120006266046608e00201116411460866ea800a2b300130390018acc004c10cdd5001401e2c82222c820904118209baa0018b2086375a6086002608600460860026084002607a6ea800a2c81d84c966002605800315980099b870019800803c03a91104444f574e00407d159800cc0040126e98cc02c034c0300064466e24004009023456600266ebcc100c0f4dd50011820181e9baa0128acc004cdd79816981e9baa002302d303d375402513370e6eb4c0bcc0f4dd500119b80375a605e607a6ea8048006294103b452820768a5040ed14a081da294103b4c00401a01b489025550004078607c60766ea80062c81c8dd5981e000981e181e800981e181c1baa303b0018b20723756607260746074002660606eb0c0e40048cdd7981d181b9baa303a303737540026044660726ea40212f5c060726072606a6ea8075033206640cc446644b30013371000200514c0103d87b80008acc004cdc4001000c530103d87980008a6103d87a800040d881b0cdc11bad3039303637540046eb4c098c0d8dd500099b82375a6072606c6ea8004dd69813181b1baa00240c88b205a3031302e37546062002605a6ea8c0c0c0c4c0b4dd5181818169baa0018b2056302e302b37540026601e6eb0c0b8c0acdd5009919baf302f302c37540020071640a460580026058605a00260506ea80162c813102618129baa00322232598009817000c4c8c966002604a60566ea800626464b30013027302d375400313259800981418171baa0018992cc004c0a4c0bcdd5000c4c966002605460606ea8006264b30013370e6eb4c0d4c0c8dd500419b8200b483403e2604c66068606a60646ea8004cc0d0c088c0c8dd5000a5eb822c8180cc88c09ccc0d4dd419b82375a606c0046eb4c0d8004cc0d4dd419b82375a606c606e0046eb4c0d8c0dc0052f5c060626ea8c050dd6981a18189baa00330313754606860626ea80062c8178c8ca60026eb4c0d40066eb4c0d4c0d80066eb4c0d4c0c8dd5001a444b3001598009817001c4cdc4800a400114a0819a298103d87a80008acc004c090006260526606e60526606e6ea0cc04000c004cc0dcdd419808001000a5eb812f5c115980099b8800148002260526606e60526606e6ea0cc040008c08c004cc0dcdd4198080019811800a5eb812f5c114c010ad8799fd8799f0101ffff0040cc81990330c0c4dd50009809a40291640b8606460666066606660666066605e6ea800e2c8168c0c4c0b8dd5000c5902c180e98169baa001302f302c37540031640a86601e6eb0c074c0acdd5000918111bad302f302c3754002605a0031640ac64b300130233029375400313259800981218151baa0018991980f800912cc00400a2646600200200844b30010018a5eb822660653001371290004dc62400937009001cdc4a4011371890004dc62401137009003a444444466446605c4646b30013371e6eb8c0f80052210475d3c793008cc004888c8cc00cdd698210009bae3042304300130030019b89480426e3120109b804803e600e90082444446600a464660886ea0cde5250375c608a00266088608a608c00297ae05980098029b8d0018998219ba930020013304337526600860066e340040052f5c11640fc4646600e46608a6ea0cdc7000a40006608a6ea4cc008c0d0dc6800800a5eb808cc0208cc118dd419b8e00148000cc118dd499801981a9b8d0010014bd7011191919824981d998249ba800733049375000a66092609400297ae033049304a304b0014bd7018008012cc004c05400a2653001001a5eb82006800888966002608200312323304c374e002660986ea40092f5c065300100180252f5c080088896600200510018cc00400e60a00053304e304f002001400c826a246530010059982618268008024c0ec00e6eb8c134c138005005191919911919801194c0040066eb0c14800a6086660a260a400c660a2980103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a8000330514c103d87a80004bd702002222598008014400633001003982a8014c8c966002609800313230483305630570013305630483305630573054375400697ae030583058001305337540071598009824800c4c8c8c124cc15cc160008cc15cc160004cc15cc124cc15cc160c154dd500225eb80c164c164004c160004c14cdd5001c56600260960031323232304a33058305900333058305900233058305900133058304a3305830593056375400a97ae0305a305a00130590013058001305337540071598009820000c4c8c8c8c8c12ccc164c168010cc164c16800ccc164c168008cc164c168004cc164c12ccc164c168c15cdd500325eb80c16cc16c004c168004c164004c160004c14cdd5001c566002607e00313232323232304c3305a305b0053305a305b0043305a305b0033305a305b0023305a305b0013305a304c3305a305b3058375400e97ae0305c305c001305b001305a001305900130580013053375400715980099b87480280062646464646464609a660b660b800c660b660b800a660b660b8008660b660b8006660b660b8004660b660b8002660b6609a660b660b860b26ea80212f5c060ba60ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e9006000c4c8c8c8c8c8c8c8c138cc170c17401ccc170c174018cc170c174014cc170c174010cc170c17400ccc170c174008cc170c174004cc170c138cc170c174c168dd5004a5eb80c178c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d200e0018991919191919191918279982e982f0041982e982f0039982e982f0031982e982f0029982e982f0021982e982f0019982e982f0011982e982f0009982e98279982e982f182d9baa00a4bd70182f982f800982f000982e800982e000982d800982d000982c800982c00098299baa0038acc004cdc3a4020003132323232323232323230503305e305f0093305e305f0083305e305f0073305e305f0063305e305f0053305e305f0043305e305f0033305e305f0023305e305f0013305e30503305e305f305c375401697ae030603060001305f001305e001305d001305c001305b001305a001305900130580013053375400715980099b874804800626464646464646464646460a2660be60c0014660be60c0012660be60c0010660be60c000e660be60c000c660be60c000a660be60c0008660be60c0006660be60c0004660be60c0002660be60a2660be60c060ba6ea80312f5c060c260c200260c000260be00260bc00260ba00260b800260b600260b400260b200260b000260a66ea800e2b30013370e900a000c4c8c8c8c8c8c8c8c8c8c8c8c148cc180c18402ccc180c184028cc180c184024cc180c184020cc180c18401ccc180c184018cc180c184014cc180c184010cc180c18400ccc180c184008cc180c184004cc180c148cc180c184c178dd5006a5eb80c188c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001c56600266e1d201600189919191919191919191919191829998309831006198309831005998309831005198309831004998309831004198309831003998309831003198309831002998309831002198309831001998309831001198309831000998309829998309831182f9baa00e4bd7018319831800983100098308009830000982f800982f000982e800982e000982d800982d000982c800982c00098299baa003899191919191919191919191918299983098310061983098310059983098310051983098310049983098310041983098310039983098310031983098310029983098310021983098310019983098310011983098310009983098311831800998309829998309831182f9baa00e4bd7025eb80c188004c184004c180004c17c004c178004c174004c170004c16c004c168004c164004c160004c14cdd5001a0a24144828905120a24144828905120a24144828905118289baa0013054002400c8290dd718289829000991acc004c07800e2653001001a5eb820088008889660026094003123233055374e002660aa6ea40092f5c065300100180252f5c080088896600200510018cc00400e60b2005330573058002001400c82b2246530010059982a982b0008024c11000e6eb8c158c15c0050051802800a09e8b2098375c60a260a4008530012232598009800a40211598009800a4001148002266e39220108010204081020408000002413d1598009800a408113370490400219801801980980144cdc124101010100406600600666e00009203f413c8278dc4000c888c8cc150c00cdd6982a8009982a182a982b000a5eb80c00c006660a06ea0cdc7000a4000660a06ea4cc034c0fcdc6800800a5eb81222323298009198029191982c1ba833794940dd7182c8009982c182c982d000a5eb816600260326e340062660ae6ea4c058004cc15cdd49980c180b9b8d0010014bd704590531191801acc004c13c006298103d87a8000898251982c1ba80014bd7020a830030019bad3056003911191acc006600260a06eb4c16800694294505544cc02000c8c014c130cc168dd4000a5eb8226016600898103d87a800041546eb8c168c16c004cc160dd419b8e00148000cc160dd49980a98239b8d0010014bd7024446b3001304f00289801918259982c800a5eb822b3001304c00289801918211982c800a5eb822b3001304e00289801919ba548010cc1640052f5c1159800982180144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a400c660b26ea00052f5c1159800982100144cc01c8c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001304e371a00313305937526040002660b26ea4cc098c094dc6800800a5eb822c82a88cdd2a4010660b26ea16600266e20005208080048800c4cdc080098032404082a92f5c115980099b874802800a26006466e95200a330590014bd70456600266e1d200c002899800919ba548030cc1640052f5c0464660b46ea0c018dd6982d8009982d182d982e000a5eb80c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e900700144cc0048cdd2a401c660b200297ae02323305a375066f29281bae305b0013305a305b305c0014bd702cc004c06cdc6800c4cc164dd4980c0009982c9ba93301a3019371a00200297ae08b20aa8acc004cdc3a402000513300123374a90081982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2b30013370e9009001448c8c8cc16ccdd2a4024660b660b800297ae03305b305c305d0014bd701800801198041191982d9ba833794940dd7182e0009982d982e182e800a5eb8166002609e6e340062660b46ea4c084004cc168dd49981398131b8d0010014bd7045905612cc004c1440062980103d87980008acc004c138006298103d87a80008acc004c140006298103d87b80008acc004c114006298103d87c80008acc004c110006298103d87d80008b20ac415882b105620ac8acc004cdc3a40280051300323374a900a1982c800a5eb822b30013370e900b00144c00c8cdd2a402c660b200297ae08acc004cdc3a403000513300123374a900c1982c800a5eb808c8cc168dd419bca4a06eb8c16c004cc168c16cc1700052f5c0b3001301b371a00313305937526030002660b26ea4cc068c064dc6800800a5eb822c82aa2c82a105420a8415082a105420a8415082a105420a8415082a0dd7182c982d003096600266e2000520808080808080808080028800c4cdc0800980124100028288c00c00c6eb4c13800488cc13c008cc13cdd4800a5eb80c8cc134dd419b8e00148000cc134dd499805181e1b8d0010014bd701bae304d304e001323304c375066f29281bae304d0013304c304d304e0014bd702cc004c058dc6800c4cc12cdd49808800998259ba9330143013371a00200297ae08b208e411916410c6e3120024590391bae303e303f0015980098039b8d00189981e1ba930020013303c37526600a60086e340040052f5c11640e06eb8c0acc0e4dd5198171191acc004cdc79bae303e00148904b9011a820089191919191919199119823181c198231823803998231ba90013304630470024bd70198231823982400125eb80d660026024003125980099b89002371a00313304537526601e0040026608a6ea66002005337026e3400400a002b8c25eb822c820a2c8200dd7182298230011bae3045004375a608800264660866ea0cde5250375c6088002660866088608a00297ae059800981b9b8d0018998211ba930090013304237526601e601c6e340040052f5c11640f86eb8c108c10c004d6600294624b30013371290201b8d0018998209ba93300b48100004cc104dd4cc005204099b80371a002901fc0057184bd7045903d45903c1bae30413042001300100259800a51892cc004cdc4a4100026e3400626607e6ea4cc0252080010013303f37533001482000666e00dc6800a40ff0015c612f5c11640ed1640e91640e46eb8c0f8c0fc00566002600e6e340062660786ea4c008004cc0f0dd49980298021b8d0010014bd704590381bae303c00a300348010c00d200819801001181a000a062899180118198019bae303100240bc6eb0c0b8c0acdd5000c5902919199119801001000912cc004006298103d87a80008992cc004cdd78021816800c4c088cc0c0c0b80052f5c1133003003303200240b060600028170dd5981718179817981798179817981798179817981798159baa0033374a900219816180a99816181698171817181718151baa302d302a375400297ae04bd7045902819198008009bac301a302a375400444b30010018a6103d87a80008992cc006600266ebc00530103d87a8000a50a5140a91001899801801981800120543259800cc004dd5980e18161baa301c302c3754003374c6605c66ec0dd48031ba63302e3376098010b4a50797468205374617465004c010101004bd6f7b63025eb7bdb182449450124566002604460566ea8c0bcc0b0dd5181798161baa301c302c375400313259800981298161baa0018992cc004c09cc0b4dd5000c4c8c8c8c8cc89660026070007132598009817181a1baa0018991919194c004dd6981e000cdd7181e0024dd6981e001cdd7181e00124444b300130410058998181bab304000e225980080144cc0c8030896600200513035330430144bd7044c8c8cc07cc1080084c00cc11c010dd7182100098220012084899191980e98208010980198228021bae303f001304200241011640f8303c001303b001303a001303537540031640cc606e00d1640d46eb8c0d4004dd5981a801181a800981a000981980098171baa0018b20583030302d37540031640ac603c60586ea8c070c0b0dd5000c5902a4530103d87a800040a8605c0028160452689b2b200601", + "hash": "cdd7308205adaf89370d6f5fe5225b10876165977f2ce4836b67e645" }, { "title": "order.order.mint", @@ -103,16 +103,10 @@ "schema": { "$ref": "#/definitions/aiken~1crypto~1ScriptHash" } - }, - { - "title": "pyth_policy", - "schema": { - "$ref": "#/definitions/cardano~1assets~1PolicyId" - } } ], - "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", - "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + "compiledCode": "5912ab010100229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0024888888889660033001300437540152232330010010032259800800c52f5c11332259800980280144cc030008cc0100100062660080080028040c02c004c0300050094dc3a4001374a9000488c8cc00400400c896600200314a115980099b8f375c601600200714a3133002002300c0014018804a460106012003370e9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a20030064029133005005301000440286eb8c024004dd598050009806000a01414bd6f7b630496600200314a314a080324444646600200200a44b300100189980619bb0375200a6ea00112f5bded8c113298009bae300a0019bad300b00198078012444b300133720012007133010337606ea4024dd4004002c56600266e3c02400e33001009804400a46602266ec0dd48051ba80010028800a00e89980819bb037520066ea0008cc01801800500c20181806800a01691111919800800802912cc00400626601866ec0dd48029ba60044bd6f7b63044ca60026eb8c0280066eacc02c006601e0049112cc004cdc8004801c4cc040cdd81ba9009374c01000b15980099b8f0090038cc00402601100291980899bb037520146e9800400a2002803a26602066ec0dd48019ba60023300600600140308060601a002805a6e9520029b874801122222222222229800980a806cc050036444b30010028a508994c004c9660026020602a6ea800626eb4c058c064dd5980c980b1baa0018a400080a0c0600066ebcc060c0640066eac00d22259800800c566002600400d13300500348002294101644c96600266ebcc0600053010140008acc004cc018010dd6980c980e1bab3019001898019ba6301d0028a50405d1598009980300224001130030078a50405c80b8c06c0050190ca6002003004911980c8011980c9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c05c0066eacc06000660380069112cc004cdc8a441000038acc004cdc7a44100003899802980a1980e9ba60024bd70000c4cc015300103d87a8000006406519800803c006446600e0046603e66ec0dd48029ba6004001401c80c8603400480c2294229422941019488c8cc00400400c896600200314c0103d87a80008992cc004c0100062601e6603000297ae0899801801980d001202830180014059222598009807000c52f5bded8c113232330010014bd6f7b630112cc00400626603266ec0dd48031ba60034bd6f7b63044ca60026eb8c05c0066eacc06000660380049112cc004cdc8005001c4cc074cdd81ba900a374c00e00b15980099b8f00a00389980e99bb037520146e9801c00626603a66ec0dd48019ba600233006006001406480c8603400280c0c8cc0040052f5bded8c044b300100189980c19bb037520086ea000d2f5bded8c113298009bae30160019bad3017001980d8012444b30013372001000713301c337606ea4020dd4003802c56600266e3c02000e26603866ec0dd48041ba800700189980e19bb037520066ea0008cc0180180050182030180c800a02e40492232598009807000c56600260286ea800e0051640551598009805000c56600260286ea800e0051640551640488090c048dd5001488c966002601c003159800980a1baa00380145901545660026014003159800980a1baa0038014590154590122024301237540052259800980698091baa0028991919912cc004c06c00e00b1640606eb4c060004dd6980c001180c00098099baa0028b2022891111192cc004c04400600513003001405466e0001000d22222222233229800980d9baa002911112cc004c06cc080dd500244c018cdc199b82002375a604860426ea800cdd6980c18109baa0038acc004c06cc080dd5002c6600200348810255500080120188cc004006910104444f574e008012018407c80fa603e0169112cc004c06400e2646644b3001301c0018992cc004c09c006264b3001301e30233754003132323322598009816001c0222c8148dd698148009bae3029002302900130243754003164088604c00316409060446ea80122b300130180018acc004c088dd5002400a2c811a2c81010200acc004c068c07cdd500144cc88c8ca60026eacc09c0066eb0c09cc0a0c0a0c0a0c0a0006604e60486ea801a60080093301f3758604e004466ebcc0a0c094dd5181418129baa001301633027375200c97ae048888966002605a003159800981198141baa3301537586058010466ebcc0b4c0a8dd500080244c8c8cc8966002603a60586ea800a2b30013023302c37546060606200713259800981418169baa001899191919194c004dd6981b000cc0d8012606c007375c606c00491112cc004c0ec01626466044002266042008266040006264b3001303d001899192cc004c0c4dd6981d80145660026606602c00b159800cc00403e6e98c966002942200319800800c0766464004602c0026607c66ec0dd480126010101004bd6f7b630488888c966002606c00300289801800a0803298008024022900148888a600200b003802400a00280310352814205c40e93001004803c01a011038407922337120020048142266e3c004dca1bb30158a5040e514a081ca2c81c8dd7181c800981e000c5903a1981680a00c981d004c590380c0d8004c0d4004c0d0004c0cc004c0b8dd5000c5902c181818169baa0028b20568b2056302e0013756605c004605c002605a60526ea8c0b00062c813a2c8150604e604e002604c604c00244b30010018a4d13259800800c5268992cc004cdc81bae30233027003375c60460031330040043302600130280028b204430260014090604c0028118c080dd500744ca60020033301637566048604a604a604a604a60426ea803c00a9450011112cc00400a200313298008024c0a000e64b3001003899b88375a604a004900045282046375c60460028020c098009024203c301f37540046eb8c088c07cdd5002c566002602a0071323322332259800980f000c56600260486ea801a005164095159800980d000c56600260486ea801a005164095159800980a000c4c8c96600260540050048b204e375a605000260486ea801a2c81110222044159800980e18109baa001899912cc004c078c08cdd5000c4c8c9660026038604a6ea800633001375c6052604c6ea80066eacc0a4c0a800a44653001001801c0090011112cc00400a200313298008024c0c000f30010029bae302b0019bab302c00191111192cc004c0980060051300300140c06465300100180340150011112cc00400a200313298008024c0e800f30010029bae30350019bad3036001802a0524010607000481b1406101e2008302e00240b1232330010010022259800800c52f5bded8c11323302c3376060520026e98c8cc004004dd59815801112cc004006297adef6c608991981799bb0302c001375066e052000375a605a002660060066062004605e0028168cc00c00cc0b8008c0b000502a488c8cc00400400c896600200314a115980098019816800c528c4cc008008c0b8005028205691119199119801001000912cc00400600713233225980099b910070028acc004cdc78038014400600c816a26600a00a60660088168dd718160009bad302d001302f00140b46603e008006290004c094dd500448c0a8c0acc0acc0ac0052222222259800981400144c9660026604e6eb0c0c8c0ccc0ccc0ccc0cc004dd7180118179baa00d8cc004dd59819000cdd3198121803004004c88cdc3801000a0388a5040b46064606460646064605c6ea80722b300130240028cc00489660026054605e6ea800a264646464653001375a60700033038004981c001cdd7181c00124444b3001303d005899811981e00489981100189981080100545903a0c0e0004c0dc004c0d8004c0d4004c0c0dd500145902e48c0c8c0ccc0cc006460646066606660666066003302e375403891111991194c004c0e40066eacc0e0c0e4c0e400e6eb0c0e000d22259800981e001c4c8cc8966002605660746ea80062646644b3001302e303d37540031332233012001133012002159800cc004cdd7982198201baa0013043304037540054a14a281f22b30013375e606e60806ea800530103d87980008acc004cdd7981b98201baa0024c0103d87980008acc004cdc399b80337046eb4c10cc100dd5180898201baa001375a606e60806ea8c044c100dd500119b82375a608660806ea8c044c100dd50011bad303730403754602260806ea8004cdc11bad303730403754602260806ea8004dd6981b98201baa30113040375400519800acc004cdc49bad3010304037540046eb4c040c100dd5000c4cc108004cc108dd300399821001198211ba60044bd7044cc108008cc108dd300219821000998211ba60074bd70207cacc004c0e8c0fcdd5182198201baa0018a45025550008a4504444f574e0040f959800981d181f9baa3043304037540051489025550008a4504444f574e0040f93302c00d23375e608860826ea8c110c104dd5181c18209baa001303233043375207c97ae048888c8cc88c9660026084608e6ea801626464b300159800801c528c4cc88cc0880548c8c96600266ebcc148c13cdd518290011820198289ba90294bd7044c9660026080609e6ea80062b300198009bab30530029ba60059119b8900100240f513375e60a660a06ea800401a294104e45904e18291829800c528209a3052001304d3754002646464608c6609e60a00066609e60a00046609e60a00026609e60a060a20026609e6ea0cdc09bad301d304d375400e01097ae03050001304f001304a3754008660446eacc134018c084c0bccdc198011bad304d304a3754603660946ea8010dd6982098251baa301b304a375400882422b30013370e6530010019982000a812d20004004444b30010028800c4ca600200930520039919b80003375a609e0046eb8c1340050041828001209c59800801c520038a400282422b3001330200132325980099baf304f304c3754609e002608a6609c603e60986ea80352f5c1198009bab304f30500019ba69800824c02e00e81ba4466e2400400903945282094304b3754003159800998100099192cc004cdd7982798261baa304f00130453304e301f304c375401c97ae08cc004dd598279828000cdd34c00412601500740dd223371200200481ca294104a18259baa0018acc004cdc3cc00405208f488102555000407c00b15980099b87980080a411e91104444f574e00407c00b1330200132325980099baf304f304c3754609e002607a6609c6ea41252f5c1198009bab304f30500019ba60039119b8900100240e514a08250c12cdd5000c52820908a50412114a082422941048452820908a504120660426eacc100c124dd5182018249baa304c3049375400c605c66e00cdc198009bad304c30493754603460926ea8028dd6982018249baa301a3049375401466e0cc004dd6982618249baa301a304937540166eb4c100c124dd5180d18249baa00b370400716411866e1cdd6980b98239baa001002375a602a608a6ea8c120c124004c120014c1200111640f91640f91640f91640f86082607c6ea8004c104c0f8dd500245903c1bab303f001303f3040001303f303b3754607c607e60766ea8c0f801a2c81c8dd5981e000981e181e800981e181c1baa303b303c3038375460760091640e43302f00123375e6070606a6ea8c0e0c0d4dd51816181a9baa001302633037375201e97ae0303630360013758606a0028994c004dd61819000ccc0900200266eb4c0c8c0bcdd5008a444b300130360028992cc004c0a4dd69819800c4c8c8ca600260740033039001981c801cc0e4009222298009bae303d0049bad303d303e004acc004c0d0c0e4dd5000c566002606860726ea800a33001037a4502555000804a04a8cc0040de910104444f574e00804a04a40e11301f3370666e08024dd6981e981d1baa003375a606260746ea800d0382444b30013301300e2325980099baf3042303f375460840026070660826ea40152f5c1198009bab304230430019ba60039119b8900100240b114a081e8c0f8dd5000c566002b30013370e00401913370f3001375660806082608201f0179bae303c00b40489000c52820768a51899911980a808119192cc004cdd7982298211baa3045002303333044375203897ae08992cc004c0ccc108dd5000c56600330013756608c005374c00b22337120020048182266ebcc118c10cdd5000803452820828b2082304530460018a504100608a00260806ea8004c8c8c8c0e4cc108c10c00ccc108c10c008cc108c10c004cc108c10cc110004cc108dd419b8100500f4bd7018218009821000981e9baa01b3301501630149800802c01200d00c81d204040ed14a081d830390013038001303337540231640c4606a0051640cc30323032302e3754038816102c22c8120c0a0c094dd5181400098121baa3027302830243754604e60486ea80062c8110c094c088dd5000998071bac302530223754020466ebcc098c08cdd5000801c5902018109baa004302300130233024001301f375400b16407480e8603a603c01253001488100a44100800a00c229344d95900201", + "hash": "1d9670358959872ba038d87e894961616d1ec86c29b06eae77039134" }, { "title": "order.order.spend", @@ -134,16 +128,10 @@ "schema": { "$ref": "#/definitions/aiken~1crypto~1ScriptHash" } - }, - { - "title": "pyth_policy", - "schema": { - "$ref": "#/definitions/cardano~1assets~1PolicyId" - } } ], - "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", - "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + "compiledCode": "5912ab010100229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0024888888889660033001300437540152232330010010032259800800c52f5c11332259800980280144cc030008cc0100100062660080080028040c02c004c0300050094dc3a4001374a9000488c8cc00400400c896600200314a115980099b8f375c601600200714a3133002002300c0014018804a460106012003370e9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a20030064029133005005301000440286eb8c024004dd598050009806000a01414bd6f7b630496600200314a314a080324444646600200200a44b300100189980619bb0375200a6ea00112f5bded8c113298009bae300a0019bad300b00198078012444b300133720012007133010337606ea4024dd4004002c56600266e3c02400e33001009804400a46602266ec0dd48051ba80010028800a00e89980819bb037520066ea0008cc01801800500c20181806800a01691111919800800802912cc00400626601866ec0dd48029ba60044bd6f7b63044ca60026eb8c0280066eacc02c006601e0049112cc004cdc8004801c4cc040cdd81ba9009374c01000b15980099b8f0090038cc00402601100291980899bb037520146e9800400a2002803a26602066ec0dd48019ba60023300600600140308060601a002805a6e9520029b874801122222222222229800980a806cc050036444b30010028a508994c004c9660026020602a6ea800626eb4c058c064dd5980c980b1baa0018a400080a0c0600066ebcc060c0640066eac00d22259800800c566002600400d13300500348002294101644c96600266ebcc0600053010140008acc004cc018010dd6980c980e1bab3019001898019ba6301d0028a50405d1598009980300224001130030078a50405c80b8c06c0050190ca6002003004911980c8011980c9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c05c0066eacc06000660380069112cc004cdc8a441000038acc004cdc7a44100003899802980a1980e9ba60024bd70000c4cc015300103d87a8000006406519800803c006446600e0046603e66ec0dd48029ba6004001401c80c8603400480c2294229422941019488c8cc00400400c896600200314c0103d87a80008992cc004c0100062601e6603000297ae0899801801980d001202830180014059222598009807000c52f5bded8c113232330010014bd6f7b630112cc00400626603266ec0dd48031ba60034bd6f7b63044ca60026eb8c05c0066eacc06000660380049112cc004cdc8005001c4cc074cdd81ba900a374c00e00b15980099b8f00a00389980e99bb037520146e9801c00626603a66ec0dd48019ba600233006006001406480c8603400280c0c8cc0040052f5bded8c044b300100189980c19bb037520086ea000d2f5bded8c113298009bae30160019bad3017001980d8012444b30013372001000713301c337606ea4020dd4003802c56600266e3c02000e26603866ec0dd48041ba800700189980e19bb037520066ea0008cc0180180050182030180c800a02e40492232598009807000c56600260286ea800e0051640551598009805000c56600260286ea800e0051640551640488090c048dd5001488c966002601c003159800980a1baa00380145901545660026014003159800980a1baa0038014590154590122024301237540052259800980698091baa0028991919912cc004c06c00e00b1640606eb4c060004dd6980c001180c00098099baa0028b2022891111192cc004c04400600513003001405466e0001000d22222222233229800980d9baa002911112cc004c06cc080dd500244c018cdc199b82002375a604860426ea800cdd6980c18109baa0038acc004c06cc080dd5002c6600200348810255500080120188cc004006910104444f574e008012018407c80fa603e0169112cc004c06400e2646644b3001301c0018992cc004c09c006264b3001301e30233754003132323322598009816001c0222c8148dd698148009bae3029002302900130243754003164088604c00316409060446ea80122b300130180018acc004c088dd5002400a2c811a2c81010200acc004c068c07cdd500144cc88c8ca60026eacc09c0066eb0c09cc0a0c0a0c0a0c0a0006604e60486ea801a60080093301f3758604e004466ebcc0a0c094dd5181418129baa001301633027375200c97ae048888966002605a003159800981198141baa3301537586058010466ebcc0b4c0a8dd500080244c8c8cc8966002603a60586ea800a2b30013023302c37546060606200713259800981418169baa001899191919194c004dd6981b000cc0d8012606c007375c606c00491112cc004c0ec01626466044002266042008266040006264b3001303d001899192cc004c0c4dd6981d80145660026606602c00b159800cc00403e6e98c966002942200319800800c0766464004602c0026607c66ec0dd480126010101004bd6f7b630488888c966002606c00300289801800a0803298008024022900148888a600200b003802400a00280310352814205c40e93001004803c01a011038407922337120020048142266e3c004dca1bb30158a5040e514a081ca2c81c8dd7181c800981e000c5903a1981680a00c981d004c590380c0d8004c0d4004c0d0004c0cc004c0b8dd5000c5902c181818169baa0028b20568b2056302e0013756605c004605c002605a60526ea8c0b00062c813a2c8150604e604e002604c604c00244b30010018a4d13259800800c5268992cc004cdc81bae30233027003375c60460031330040043302600130280028b204430260014090604c0028118c080dd500744ca60020033301637566048604a604a604a604a60426ea803c00a9450011112cc00400a200313298008024c0a000e64b3001003899b88375a604a004900045282046375c60460028020c098009024203c301f37540046eb8c088c07cdd5002c566002602a0071323322332259800980f000c56600260486ea801a005164095159800980d000c56600260486ea801a005164095159800980a000c4c8c96600260540050048b204e375a605000260486ea801a2c81110222044159800980e18109baa001899912cc004c078c08cdd5000c4c8c9660026038604a6ea800633001375c6052604c6ea80066eacc0a4c0a800a44653001001801c0090011112cc00400a200313298008024c0c000f30010029bae302b0019bab302c00191111192cc004c0980060051300300140c06465300100180340150011112cc00400a200313298008024c0e800f30010029bae30350019bad3036001802a0524010607000481b1406101e2008302e00240b1232330010010022259800800c52f5bded8c11323302c3376060520026e98c8cc004004dd59815801112cc004006297adef6c608991981799bb0302c001375066e052000375a605a002660060066062004605e0028168cc00c00cc0b8008c0b000502a488c8cc00400400c896600200314a115980098019816800c528c4cc008008c0b8005028205691119199119801001000912cc00400600713233225980099b910070028acc004cdc78038014400600c816a26600a00a60660088168dd718160009bad302d001302f00140b46603e008006290004c094dd500448c0a8c0acc0acc0ac0052222222259800981400144c9660026604e6eb0c0c8c0ccc0ccc0ccc0cc004dd7180118179baa00d8cc004dd59819000cdd3198121803004004c88cdc3801000a0388a5040b46064606460646064605c6ea80722b300130240028cc00489660026054605e6ea800a264646464653001375a60700033038004981c001cdd7181c00124444b3001303d005899811981e00489981100189981080100545903a0c0e0004c0dc004c0d8004c0d4004c0c0dd500145902e48c0c8c0ccc0cc006460646066606660666066003302e375403891111991194c004c0e40066eacc0e0c0e4c0e400e6eb0c0e000d22259800981e001c4c8cc8966002605660746ea80062646644b3001302e303d37540031332233012001133012002159800cc004cdd7982198201baa0013043304037540054a14a281f22b30013375e606e60806ea800530103d87980008acc004cdd7981b98201baa0024c0103d87980008acc004cdc399b80337046eb4c10cc100dd5180898201baa001375a606e60806ea8c044c100dd500119b82375a608660806ea8c044c100dd50011bad303730403754602260806ea8004cdc11bad303730403754602260806ea8004dd6981b98201baa30113040375400519800acc004cdc49bad3010304037540046eb4c040c100dd5000c4cc108004cc108dd300399821001198211ba60044bd7044cc108008cc108dd300219821000998211ba60074bd70207cacc004c0e8c0fcdd5182198201baa0018a45025550008a4504444f574e0040f959800981d181f9baa3043304037540051489025550008a4504444f574e0040f93302c00d23375e608860826ea8c110c104dd5181c18209baa001303233043375207c97ae048888c8cc88c9660026084608e6ea801626464b300159800801c528c4cc88cc0880548c8c96600266ebcc148c13cdd518290011820198289ba90294bd7044c9660026080609e6ea80062b300198009bab30530029ba60059119b8900100240f513375e60a660a06ea800401a294104e45904e18291829800c528209a3052001304d3754002646464608c6609e60a00066609e60a00046609e60a00026609e60a060a20026609e6ea0cdc09bad301d304d375400e01097ae03050001304f001304a3754008660446eacc134018c084c0bccdc198011bad304d304a3754603660946ea8010dd6982098251baa301b304a375400882422b30013370e6530010019982000a812d20004004444b30010028800c4ca600200930520039919b80003375a609e0046eb8c1340050041828001209c59800801c520038a400282422b3001330200132325980099baf304f304c3754609e002608a6609c603e60986ea80352f5c1198009bab304f30500019ba69800824c02e00e81ba4466e2400400903945282094304b3754003159800998100099192cc004cdd7982798261baa304f00130453304e301f304c375401c97ae08cc004dd598279828000cdd34c00412601500740dd223371200200481ca294104a18259baa0018acc004cdc3cc00405208f488102555000407c00b15980099b87980080a411e91104444f574e00407c00b1330200132325980099baf304f304c3754609e002607a6609c6ea41252f5c1198009bab304f30500019ba60039119b8900100240e514a08250c12cdd5000c52820908a50412114a082422941048452820908a504120660426eacc100c124dd5182018249baa304c3049375400c605c66e00cdc198009bad304c30493754603460926ea8028dd6982018249baa301a3049375401466e0cc004dd6982618249baa301a304937540166eb4c100c124dd5180d18249baa00b370400716411866e1cdd6980b98239baa001002375a602a608a6ea8c120c124004c120014c1200111640f91640f91640f91640f86082607c6ea8004c104c0f8dd500245903c1bab303f001303f3040001303f303b3754607c607e60766ea8c0f801a2c81c8dd5981e000981e181e800981e181c1baa303b303c3038375460760091640e43302f00123375e6070606a6ea8c0e0c0d4dd51816181a9baa001302633037375201e97ae0303630360013758606a0028994c004dd61819000ccc0900200266eb4c0c8c0bcdd5008a444b300130360028992cc004c0a4dd69819800c4c8c8ca600260740033039001981c801cc0e4009222298009bae303d0049bad303d303e004acc004c0d0c0e4dd5000c566002606860726ea800a33001037a4502555000804a04a8cc0040de910104444f574e00804a04a40e11301f3370666e08024dd6981e981d1baa003375a606260746ea800d0382444b30013301300e2325980099baf3042303f375460840026070660826ea40152f5c1198009bab304230430019ba60039119b8900100240b114a081e8c0f8dd5000c566002b30013370e00401913370f3001375660806082608201f0179bae303c00b40489000c52820768a51899911980a808119192cc004cdd7982298211baa3045002303333044375203897ae08992cc004c0ccc108dd5000c56600330013756608c005374c00b22337120020048182266ebcc118c10cdd5000803452820828b2082304530460018a504100608a00260806ea8004c8c8c8c0e4cc108c10c00ccc108c10c008cc108c10c004cc108c10cc110004cc108dd419b8100500f4bd7018218009821000981e9baa01b3301501630149800802c01200d00c81d204040ed14a081d830390013038001303337540231640c4606a0051640cc30323032302e3754038816102c22c8120c0a0c094dd5181400098121baa3027302830243754604e60486ea80062c8110c094c088dd5000998071bac302530223754020466ebcc098c08cdd5000801c5902018109baa004302300130233024001301f375400b16407480e8603a603c01253001488100a44100800a00c229344d95900201", + "hash": "1d9670358959872ba038d87e894961616d1ec86c29b06eae77039134" }, { "title": "order.order.else", @@ -156,19 +144,17 @@ "schema": { "$ref": "#/definitions/aiken~1crypto~1ScriptHash" } - }, - { - "title": "pyth_policy", - "schema": { - "$ref": "#/definitions/cardano~1assets~1PolicyId" - } } ], - "compiledCode": "5909b20101002229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae0024888888888966003300130053754017223232330010010042259800800c00e2646644b30013372200e00515980099b8f0070028800c01900b44cc014014c04401100b1bae300a00137566016002601a002805852f5bded8c1370e90014dc3a4000911119194c004c028dd5000cc03801a601c0049112cc004c01800e2646644b300130090018acc004c044dd5002400a2c80922b3001300a0018acc004c044dd5002400a2c80922c807900f0acc004c01cc038dd500145a2653001001998051bab30133014301430143014301037540080054a280088896600200510018994c004012602e0073259800801c4cdc41bad30140024800229410121bae30120014010602a004809900d18071baa002375c6022601c6ea80122b30013007003899199119912cc004c02c0062b30013013375400d0028b20288acc004c0300062b30013013375400d0028b20288acc004cdc3a40080031323259800980c80140122c80b0dd6980b80098099baa0068b202240448088566002601260206ea80062646644b3001300c3013375400513232598009807980a9baa0018cc004dd7180c980b1baa0019bab3019301a00291919800800801112cc004006297adef6c608991980e19bb03019001374c64660020026eacc06c008896600200314bd6f7b63044c8cc07ccdd8180e0009ba83370290001bad301d001330030033021002301f001407466006006603c004603800280d2444b30010028a508994c004c966002602660346ea800626eb4c06cc078dd5980f180d9baa0018a400080c8c0740066ebcc074c0780066eac00d22259800800c566002600400d13300500348002294101b44c96600266ebcc07400530010140008acc004cc018010dd6980f18109bab301e001898019ba630220028a5040711598009980300224001130030078a50407080e0c08000501e0ca6002003004911980f0011980f1ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c0700066eacc07400660420069112cc004cdc8a441000038acc004cdc7a441000038998029807998111ba60024bd70000c4cc015300103d87a8000006407919800803c006446600e0046604866ec0dd48029ba6004001401c80f0603e00480ea29422942294101e4c054dd5004a44444b300130130018992cc004c8cc88cc008008004896600200314a115980099b8f375c604400200714a3133002002302300140748100dd6181018109810981098108011bae301f302030203020301c3754013198009bab301f0019ba63301630040050069119b87002001400d14a080d0c07cc07cc07cc07cc06cdd5007c5660026028003168cc004dd6980f180d9baa00e9112cc004c058006297adef6c608991919800800a5eb7bdb1808966002003133023337606ea4018dd3001a5eb7bdb1822653001375c604200337566044003302600248896600266e4002800e26604e66ec0dd48051ba60070058acc004cdc7805001c4cc09ccdd81ba900a374c00e003133027337606ea400cdd300119803003000a046408c30240014088646600200297adef6c602259800800c4cc088cdd81ba9004375000697adef6c608994c004dd71810000cdd69810800cc0940092225980099b9000800389981319bb037520106ea001c0162b30013371e010007133026337606ea4020dd4003800c4cc098cdd81ba900337500046600c00c00281110220c08c00502120389180f9810000c88c8cc00400400c896600200314a115980098019811000c528c4cc008008c08c00501d2040980f980f980d9baa00f9980a802002a4444446644b300130270038992cc004c074dd69812000c4c8c8ca60026056003302a0019815001cc0a8009222298009bae302e0049bad302e302f004acc004c08cc0a8dd5000c566002604660546ea800a33001028a4502555000808201e8cc0040a2910104444f574e00808201e40a51300a3370666e08040dd6981718159baa003375a601c60566ea800d0292444b30013301000c2325980099baf3033303037546066002603e660646ea40152f5c1198009bab303330340019ba60039119b89001002405d14a08170c0bcdd5000c566002b30013370e00402713370f3001375660626064606401f375c605a0171480012223322330010010023302b00301b2259800800c00e2646644b30013372200e00515980099b8f0070028800c01903444cc014014c0e80110341bae3033001375a6068002606c00281a09000c52820588a518999119809007119192cc004cdd7981b18199baa30360023374a90011981a9ba901d4bd7044c96600266e1d200430333754003159800cc004dd5981b8014dd3002c88cdc48008012036899baf30373034375400200d14a081922c8190c0d8c0dc0062941031181b00098189baa0013232323020330333034003330333034002330333034001330333034303500133033375066e040140592f5c060680026066002605c6ea806cca6002003018980bacc004c09cc0b8dd5002c4c038cdc199b82014375a6064605e6ea801cdd6980918179baa0078acc004c09cc0b8dd50034660020594890255500080a20268cc0040b2910104444f574e0080a202640b481690011112cc00400a2003132332298008034c0e0016646600200200a44b300100189981c19bb037520086e9800d2f5bded8c113298009bae30360019bab3037001981d8012444b30013372001000713303c337606ea4020dd3003802c56600266e3c02000e264b300159800800c528c5282078880144cc0f4cdd81ba9009374c00200481c8ca6002003008801a0022225980080144006264664530010069822002cc8cc0040040148966002003133044337606ea4010dd4001a5eb7bdb1822653001375c6084003375a6086003304700248896600266e4002000e26609066ec0dd48041ba80070058acc004cdc7804001c4c966002607e003100289982499bb037520126ea000400904519b8000700289982419bb037520066ea0008cc01801800504420881822800a08640186eb8c0f4004dd6981f0009820001207c89981e19bb037520066e98008cc0180180050382070181c800a06e40186eb8c0c4004dd59819000981a001206440b114a08160302a001302900130243754023164088604c0071640905300148900a44100800a00c37586048004406480c91640506030602a6ea8c060004c050dd5180b980c180a1baa30173014375400516404864660020026eb0c058c04cdd5003912cc004006298103d87a80008992cc004cdd7980c180a9baa001006898021980b800a5eb8226600600660320048098c05c005015180a98091baa002374a900045900f18081baa004301200130123013001300e37540091640308060601a601c002601a0088a4d13656400c01", - "hash": "43bc158bd327bab0cf06805900a492f9b5fab0197038dfee61421820" + "compiledCode": "5912ab010100229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae0024888888889660033001300437540152232330010010032259800800c52f5c11332259800980280144cc030008cc0100100062660080080028040c02c004c0300050094dc3a4001374a9000488c8cc00400400c896600200314a115980099b8f375c601600200714a3133002002300c0014018804a460106012003370e9001488c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a20030064029133005005301000440286eb8c024004dd598050009806000a01414bd6f7b630496600200314a314a080324444646600200200a44b300100189980619bb0375200a6ea00112f5bded8c113298009bae300a0019bad300b00198078012444b300133720012007133010337606ea4024dd4004002c56600266e3c02400e33001009804400a46602266ec0dd48051ba80010028800a00e89980819bb037520066ea0008cc01801800500c20181806800a01691111919800800802912cc00400626601866ec0dd48029ba60044bd6f7b63044ca60026eb8c0280066eacc02c006601e0049112cc004cdc8004801c4cc040cdd81ba9009374c01000b15980099b8f0090038cc00402601100291980899bb037520146e9800400a2002803a26602066ec0dd48019ba60023300600600140308060601a002805a6e9520029b874801122222222222229800980a806cc050036444b30010028a508994c004c9660026020602a6ea800626eb4c058c064dd5980c980b1baa0018a400080a0c0600066ebcc060c0640066eac00d22259800800c566002600400d13300500348002294101644c96600266ebcc0600053010140008acc004cc018010dd6980c980e1bab3019001898019ba6301d0028a50405d1598009980300224001130030078a50405c80b8c06c0050190ca6002003004911980c8011980c9ba60014bd7020022225980080144cc005300103d87a80004bd6f7b63044ca60026eb8c05c0066eacc06000660380069112cc004cdc8a441000038acc004cdc7a44100003899802980a1980e9ba60024bd70000c4cc015300103d87a8000006406519800803c006446600e0046603e66ec0dd48029ba6004001401c80c8603400480c2294229422941019488c8cc00400400c896600200314c0103d87a80008992cc004c0100062601e6603000297ae0899801801980d001202830180014059222598009807000c52f5bded8c113232330010014bd6f7b630112cc00400626603266ec0dd48031ba60034bd6f7b63044ca60026eb8c05c0066eacc06000660380049112cc004cdc8005001c4cc074cdd81ba900a374c00e00b15980099b8f00a00389980e99bb037520146e9801c00626603a66ec0dd48019ba600233006006001406480c8603400280c0c8cc0040052f5bded8c044b300100189980c19bb037520086ea000d2f5bded8c113298009bae30160019bad3017001980d8012444b30013372001000713301c337606ea4020dd4003802c56600266e3c02000e26603866ec0dd48041ba800700189980e19bb037520066ea0008cc0180180050182030180c800a02e40492232598009807000c56600260286ea800e0051640551598009805000c56600260286ea800e0051640551640488090c048dd5001488c966002601c003159800980a1baa00380145901545660026014003159800980a1baa0038014590154590122024301237540052259800980698091baa0028991919912cc004c06c00e00b1640606eb4c060004dd6980c001180c00098099baa0028b2022891111192cc004c04400600513003001405466e0001000d22222222233229800980d9baa002911112cc004c06cc080dd500244c018cdc199b82002375a604860426ea800cdd6980c18109baa0038acc004c06cc080dd5002c6600200348810255500080120188cc004006910104444f574e008012018407c80fa603e0169112cc004c06400e2646644b3001301c0018992cc004c09c006264b3001301e30233754003132323322598009816001c0222c8148dd698148009bae3029002302900130243754003164088604c00316409060446ea80122b300130180018acc004c088dd5002400a2c811a2c81010200acc004c068c07cdd500144cc88c8ca60026eacc09c0066eb0c09cc0a0c0a0c0a0c0a0006604e60486ea801a60080093301f3758604e004466ebcc0a0c094dd5181418129baa001301633027375200c97ae048888966002605a003159800981198141baa3301537586058010466ebcc0b4c0a8dd500080244c8c8cc8966002603a60586ea800a2b30013023302c37546060606200713259800981418169baa001899191919194c004dd6981b000cc0d8012606c007375c606c00491112cc004c0ec01626466044002266042008266040006264b3001303d001899192cc004c0c4dd6981d80145660026606602c00b159800cc00403e6e98c966002942200319800800c0766464004602c0026607c66ec0dd480126010101004bd6f7b630488888c966002606c00300289801800a0803298008024022900148888a600200b003802400a00280310352814205c40e93001004803c01a011038407922337120020048142266e3c004dca1bb30158a5040e514a081ca2c81c8dd7181c800981e000c5903a1981680a00c981d004c590380c0d8004c0d4004c0d0004c0cc004c0b8dd5000c5902c181818169baa0028b20568b2056302e0013756605c004605c002605a60526ea8c0b00062c813a2c8150604e604e002604c604c00244b30010018a4d13259800800c5268992cc004cdc81bae30233027003375c60460031330040043302600130280028b204430260014090604c0028118c080dd500744ca60020033301637566048604a604a604a604a60426ea803c00a9450011112cc00400a200313298008024c0a000e64b3001003899b88375a604a004900045282046375c60460028020c098009024203c301f37540046eb8c088c07cdd5002c566002602a0071323322332259800980f000c56600260486ea801a005164095159800980d000c56600260486ea801a005164095159800980a000c4c8c96600260540050048b204e375a605000260486ea801a2c81110222044159800980e18109baa001899912cc004c078c08cdd5000c4c8c9660026038604a6ea800633001375c6052604c6ea80066eacc0a4c0a800a44653001001801c0090011112cc00400a200313298008024c0c000f30010029bae302b0019bab302c00191111192cc004c0980060051300300140c06465300100180340150011112cc00400a200313298008024c0e800f30010029bae30350019bad3036001802a0524010607000481b1406101e2008302e00240b1232330010010022259800800c52f5bded8c11323302c3376060520026e98c8cc004004dd59815801112cc004006297adef6c608991981799bb0302c001375066e052000375a605a002660060066062004605e0028168cc00c00cc0b8008c0b000502a488c8cc00400400c896600200314a115980098019816800c528c4cc008008c0b8005028205691119199119801001000912cc00400600713233225980099b910070028acc004cdc78038014400600c816a26600a00a60660088168dd718160009bad302d001302f00140b46603e008006290004c094dd500448c0a8c0acc0acc0ac0052222222259800981400144c9660026604e6eb0c0c8c0ccc0ccc0ccc0cc004dd7180118179baa00d8cc004dd59819000cdd3198121803004004c88cdc3801000a0388a5040b46064606460646064605c6ea80722b300130240028cc00489660026054605e6ea800a264646464653001375a60700033038004981c001cdd7181c00124444b3001303d005899811981e00489981100189981080100545903a0c0e0004c0dc004c0d8004c0d4004c0c0dd500145902e48c0c8c0ccc0cc006460646066606660666066003302e375403891111991194c004c0e40066eacc0e0c0e4c0e400e6eb0c0e000d22259800981e001c4c8cc8966002605660746ea80062646644b3001302e303d37540031332233012001133012002159800cc004cdd7982198201baa0013043304037540054a14a281f22b30013375e606e60806ea800530103d87980008acc004cdd7981b98201baa0024c0103d87980008acc004cdc399b80337046eb4c10cc100dd5180898201baa001375a606e60806ea8c044c100dd500119b82375a608660806ea8c044c100dd50011bad303730403754602260806ea8004cdc11bad303730403754602260806ea8004dd6981b98201baa30113040375400519800acc004cdc49bad3010304037540046eb4c040c100dd5000c4cc108004cc108dd300399821001198211ba60044bd7044cc108008cc108dd300219821000998211ba60074bd70207cacc004c0e8c0fcdd5182198201baa0018a45025550008a4504444f574e0040f959800981d181f9baa3043304037540051489025550008a4504444f574e0040f93302c00d23375e608860826ea8c110c104dd5181c18209baa001303233043375207c97ae048888c8cc88c9660026084608e6ea801626464b300159800801c528c4cc88cc0880548c8c96600266ebcc148c13cdd518290011820198289ba90294bd7044c9660026080609e6ea80062b300198009bab30530029ba60059119b8900100240f513375e60a660a06ea800401a294104e45904e18291829800c528209a3052001304d3754002646464608c6609e60a00066609e60a00046609e60a00026609e60a060a20026609e6ea0cdc09bad301d304d375400e01097ae03050001304f001304a3754008660446eacc134018c084c0bccdc198011bad304d304a3754603660946ea8010dd6982098251baa301b304a375400882422b30013370e6530010019982000a812d20004004444b30010028800c4ca600200930520039919b80003375a609e0046eb8c1340050041828001209c59800801c520038a400282422b3001330200132325980099baf304f304c3754609e002608a6609c603e60986ea80352f5c1198009bab304f30500019ba69800824c02e00e81ba4466e2400400903945282094304b3754003159800998100099192cc004cdd7982798261baa304f00130453304e301f304c375401c97ae08cc004dd598279828000cdd34c00412601500740dd223371200200481ca294104a18259baa0018acc004cdc3cc00405208f488102555000407c00b15980099b87980080a411e91104444f574e00407c00b1330200132325980099baf304f304c3754609e002607a6609c6ea41252f5c1198009bab304f30500019ba60039119b8900100240e514a08250c12cdd5000c52820908a50412114a082422941048452820908a504120660426eacc100c124dd5182018249baa304c3049375400c605c66e00cdc198009bad304c30493754603460926ea8028dd6982018249baa301a3049375401466e0cc004dd6982618249baa301a304937540166eb4c100c124dd5180d18249baa00b370400716411866e1cdd6980b98239baa001002375a602a608a6ea8c120c124004c120014c1200111640f91640f91640f91640f86082607c6ea8004c104c0f8dd500245903c1bab303f001303f3040001303f303b3754607c607e60766ea8c0f801a2c81c8dd5981e000981e181e800981e181c1baa303b303c3038375460760091640e43302f00123375e6070606a6ea8c0e0c0d4dd51816181a9baa001302633037375201e97ae0303630360013758606a0028994c004dd61819000ccc0900200266eb4c0c8c0bcdd5008a444b300130360028992cc004c0a4dd69819800c4c8c8ca600260740033039001981c801cc0e4009222298009bae303d0049bad303d303e004acc004c0d0c0e4dd5000c566002606860726ea800a33001037a4502555000804a04a8cc0040de910104444f574e00804a04a40e11301f3370666e08024dd6981e981d1baa003375a606260746ea800d0382444b30013301300e2325980099baf3042303f375460840026070660826ea40152f5c1198009bab304230430019ba60039119b8900100240b114a081e8c0f8dd5000c566002b30013370e00401913370f3001375660806082608201f0179bae303c00b40489000c52820768a51899911980a808119192cc004cdd7982298211baa3045002303333044375203897ae08992cc004c0ccc108dd5000c56600330013756608c005374c00b22337120020048182266ebcc118c10cdd5000803452820828b2082304530460018a504100608a00260806ea8004c8c8c8c0e4cc108c10c00ccc108c10c008cc108c10c004cc108c10cc110004cc108dd419b8100500f4bd7018218009821000981e9baa01b3301501630149800802c01200d00c81d204040ed14a081d830390013038001303337540231640c4606a0051640cc30323032302e3754038816102c22c8120c0a0c094dd5181400098121baa3027302830243754604e60486ea80062c8110c094c088dd5000998071bac302530223754020466ebcc098c08cdd5000801c5902018109baa004302300130233024001301f375400b16407480e8603a603c01253001488100a44100800a00c229344d95900201", + "hash": "1d9670358959872ba038d87e894961616d1ec86c29b06eae77039134" } ], "definitions": { + "ByteArray": { + "title": "ByteArray", + "dataType": "bytes" + }, "Int": { "dataType": "integer" }, @@ -207,6 +193,27 @@ "title": "PolicyId", "dataType": "bytes" }, + "cardano/transaction/OutputReference": { + "title": "OutputReference", + "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", + "anyOf": [ + { + "title": "OutputReference", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction_id", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "output_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, "hermes_types/Direction": { "title": "Direction", "anyOf": [ @@ -384,7 +391,11 @@ "title": "Mint", "dataType": "constructor", "index": 0, - "fields": [] + "fields": [ + { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + ] }, { "title": "Burn", diff --git a/lazer/cardano/hermes/onchain/validators/market.ak b/lazer/cardano/hermes/onchain/validators/market.ak index 12f86e66..8719ece7 100644 --- a/lazer/cardano/hermes/onchain/validators/market.ak +++ b/lazer/cardano/hermes/onchain/validators/market.ak @@ -10,7 +10,8 @@ use hermes_types.{ use subvalidators/common_checks.{validate_only_burn} use subvalidators/market_checks.{ validate_claim_losings, validate_claim_winnings, validate_close_market, - validate_init_market, validate_process_match, validate_record_final_price, + validate_init_market, validate_mint_position_tokens, validate_process_match, + validate_record_final_price, } validator market(start_time: PosixTime, pyth_policy: PolicyId) { @@ -19,7 +20,7 @@ validator market(start_time: PosixTime, pyth_policy: PolicyId) { MintControlToken -> validate_init_market(pyth_policy, start_time, policy_id, self) BurnControlToken -> validate_only_burn(policy_id, self) - MintPositionToken(_dir) -> todo + MintPositionToken(_dir) -> validate_mint_position_tokens(policy_id, self) BurnPositionToken(_dir) -> validate_only_burn(policy_id, self) } } @@ -70,7 +71,8 @@ validator market(start_time: PosixTime, pyth_policy: PolicyId) { self, ) CloseMarket -> validate_close_market(own_script_hash, datum, self) - ProcessMatch -> validate_process_match() + ProcessMatch -> + validate_process_match(datum, i_val, own_script_hash, self) } } diff --git a/lazer/cardano/hermes/onchain/validators/order.ak b/lazer/cardano/hermes/onchain/validators/order.ak index 4fdd2e99..f7e1ee09 100644 --- a/lazer/cardano/hermes/onchain/validators/order.ak +++ b/lazer/cardano/hermes/onchain/validators/order.ak @@ -7,12 +7,15 @@ use hermes_types.{ Cancel, Fill, Match, OrderDatum, OrderMintRedeemer, OrderRedeemer, } use subvalidators/common_checks.{validate_only_burn} -use subvalidators/order_checks.{validate_cancel, validate_fill, validate_match} +use subvalidators/order_checks.{ + validate_cancel, validate_create_order, validate_fill, validate_match, +} validator order(market_script_hash: ScriptHash) { mint(redeemer: OrderMintRedeemer, policy_id: PolicyId, self: Transaction) { when redeemer is { - OrderMintRedeemer.Mint -> todo + OrderMintRedeemer.Mint(seed) -> + validate_create_order(seed, market_script_hash, policy_id, self) OrderMintRedeemer.Burn -> validate_only_burn(policy_id, self) } } @@ -38,7 +41,7 @@ validator order(market_script_hash: ScriptHash) { when redeemer is { Cancel -> validate_cancel(datum, own_script_hash, i_val, self) - Match -> validate_match() + Match -> validate_match(own_script_hash, market_script_hash, self) Fill(filled_amount) -> validate_fill( datum, From 4e9d0a2a1d522b5d78361be2690b91923285e309 Mon Sep 17 00:00:00 2001 From: Valentino Cerutti Date: Sun, 22 Mar 2026 20:44:41 -0300 Subject: [PATCH 4/5] Adds project link to readme --- lazer/cardano/hermes/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lazer/cardano/hermes/README.md b/lazer/cardano/hermes/README.md index 1c2599a4..db681a3f 100644 --- a/lazer/cardano/hermes/README.md +++ b/lazer/cardano/hermes/README.md @@ -11,3 +11,6 @@ Contact: luduena.nicolas.victorio@gmail.com Hermes market is a proof of concept integration of Pyth oracle information with Cardano's bleeding edge L2 [Hydra](https://hydra.family/head-protocol) that allows for real time bets on BTC price. Therefore truly giving an edge over a simple 5 minute market with up to 2 minute block finality in the L1 on the worst cases. Even on mainnet with high congestion scenarios, block confirmation is not guaranteed after several days. +## Original Repository + +The origial repository for this project can be found here: https://github.com/nicolasLuduena/pythathon \ No newline at end of file From 5d316f0b8484e6154a852321aa85c16256924287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Ludue=C3=B1a?= Date: Sun, 22 Mar 2026 20:59:33 -0300 Subject: [PATCH 5/5] finishe reamed --- lazer/cardano/hermes/README.md | 69 ++++++- lazer/cardano/hermes/doc/transactions.pdf | Bin 173788 -> 227140 bytes lazer/cardano/hermes/doc/transactions.typ | 4 +- .../infra/hydra-bootstrap/build-seed-tx.sh | 80 ++++++++ .../hydra-bootstrap/seed-output-datum.cbor | Bin 106 -> 176 bytes .../hydra-bootstrap/seed-output-datum.hex | 1 + .../infra/hydra-bootstrap/seed-spend.raw | 4 +- .../infra/hydra-bootstrap/seed.body.json | 5 + .../infra/hydra-bootstrap/seed.signed.json | 5 + .../infra/hydra-bootstrap/seed.witnessed.json | 5 + .../hermes/infra/initial-utxo-set.json | 9 +- .../hermes/infra/seed-spend.signed.json | 4 +- lazer/cardano/hermes/server/.env.example | 4 + lazer/cardano/hermes/server/package.json | 1 + lazer/cardano/hermes/server/pnpm-lock.yaml | 8 +- .../server/scripts/patch-libsodium-esm.mjs | 85 ++++++++ lazer/cardano/hermes/server/src/market.ts | 190 +++++++++++++++--- .../hermes/server/src/offchain/market.ts | 21 -- 18 files changed, 428 insertions(+), 67 deletions(-) create mode 100755 lazer/cardano/hermes/infra/hydra-bootstrap/build-seed-tx.sh create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.hex create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed.body.json create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed.signed.json create mode 100644 lazer/cardano/hermes/infra/hydra-bootstrap/seed.witnessed.json create mode 100644 lazer/cardano/hermes/server/.env.example create mode 100644 lazer/cardano/hermes/server/scripts/patch-libsodium-esm.mjs diff --git a/lazer/cardano/hermes/README.md b/lazer/cardano/hermes/README.md index db681a3f..d47e9f07 100644 --- a/lazer/cardano/hermes/README.md +++ b/lazer/cardano/hermes/README.md @@ -11,6 +11,71 @@ Contact: luduena.nicolas.victorio@gmail.com Hermes market is a proof of concept integration of Pyth oracle information with Cardano's bleeding edge L2 [Hydra](https://hydra.family/head-protocol) that allows for real time bets on BTC price. Therefore truly giving an edge over a simple 5 minute market with up to 2 minute block finality in the L1 on the worst cases. Even on mainnet with high congestion scenarios, block confirmation is not guaranteed after several days. -## Original Repository +## Motivation -The origial repository for this project can be found here: https://github.com/nicolasLuduena/pythathon \ No newline at end of file +Cardano is a powerful and very secure blockchain, but slow for the fast transactions: Cardano's consensus algorithm, while efficient, still requires massive global replication of state changes, potentially increasing transaction settlement times during peak hours. For our use case, we require real-time transaction settlement times. + +For solving this issue, we rely on Hydra L2 to provide the speed and scalability we need for this project. Hydra L2 is a layer 2 solution that is built on top of Cardano and provides a low-latency, high-throughput, and secure way to process transactions. + +For the Oracle service, we use Pyth, a service provider of real-time price feeds for various kinds of assets. For this PoC, we built a 5-minute prediction market for BTC/USD trading pair. + +## Architecture + +### Onchain + +We designed an Aiken smart contract for managing the markets lifecycle and the bets placed on them through the orders script. + +There are several operations that can be performed on the market script: +- Create a new market: every 5 minutes, a new market UTxOis created associated with a fresh order script. +- Place Buy or Sell order: a user can place a buy or sell order for receiving the appropriate position tokens. +- Record the final price of the market: the oracle service will record the final price in the market UTxO. +- Claim winnings: a winning user can claim the winnings by providing the position tokens. +- Claim losses: user provide their losing tokens for being burned. +- Close the market: the market is closed by burning the Market UTxO control token. +- Process an orders match: grab complementary orders from opposite directions, and distribute the tokens appropriately. + +You can find the diagrams for all these transactions [here](./doc/transactions.pdf) + +### Infrastructure + +Two Hydra nodes required for running one Hydra Head in offline mode. We declare the initial UTxO set for the Hydra chain, inject the appropriate scripts and assets for working with the Pyth oracle service. + +### Server & Offchain + +The server encompasses the prediction market business logic for interacting with the onchain scripts, and with the offchain services that interact with the Pyth oracle service and builds the Market script transactions. Also, we have a Hydra service that connects seamlessly with the Hydra nodes for sending and receiving transactions, and looking up for useful blockchain information. + +### Client + +The client is a simple React application to visualize the current prediction market state, with real-time updates coming from the server being shown in a nice real-time udpated chart, with buy and sell orders being shown as well. It also allows to place buy and sell orders, and to claim winnings or losses. + +### Limitations + +A key limitation for this PoC is that we use Hydra in offline mode, which means that the Hydra nodes are not connected to a Cardano Node, but we just declar a initial UTxO set for the Hydra chain. For using Pyth within Hydra in this offline mode setup, we "inject" the Pyth-related onchain entities (withdraw validator and Pyth State asset) in the initial UTxO set. + +But for a production deployment in a public testnet or mainnet, the part of injecting the Pyth-related onchain entities on the Hydra initial UTxO set presents a real challenge. We would need to spend the UTxO containing the Pyth State asset for being commited to the Hydra chain. Naturally, the Pyth contract will not allow this to happen. + +So for this idea to work in a public testnet or mainnet, either an update of the Pyth contract is needed, or an update of the Hydra protocol is needed for supporting L1 UTxOs as reference inputs (no spending allowed) inside the Hydra Head. This would be sufficient since the UTxO holding the Pyth State asset is only needed as reference inputs in the Oracle operations. + +## Tech Stack + +- App: Vite + React + TailwindCSS +- Server: Node.js + WebSocket +- Infrastructure: Docker compose, Hydra +- Onchain: Aiken, [Pyth Lazer Aiken lib](https://github.com/pyth-network/pyth-lazer-cardano) +- Offchain: Lucid Evolution + +## Setup & Run + +1. Run the infrastructure: see [infra/README.md](./infra/README.md) +2. Run the server +```bash +cd server +pnpm install +pnpm api +``` +3. Run the UI +```bash +cd ui +pnpm install +pnpm dev +``` \ No newline at end of file diff --git a/lazer/cardano/hermes/doc/transactions.pdf b/lazer/cardano/hermes/doc/transactions.pdf index 76a5845fcf6d1520c2a7f21677e5dfaf84ed049c..8afb04edc09113f68d1a7f07018a53cb6e3257ac 100644 GIT binary patch literal 227140 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 R>zuR3xAg1Rf3;oY{{hU+8KeLJ diff --git a/lazer/cardano/hermes/doc/transactions.typ b/lazer/cardano/hermes/doc/transactions.typ index 65684e9a..cc364699 100644 --- a/lazer/cardano/hermes/doc/transactions.typ +++ b/lazer/cardano/hermes/doc/transactions.typ @@ -296,7 +296,7 @@ address: "order book address", value: ( "Order Control token": "1", - "BUY/SELL": `M`, + "UP/DOWN": `M`, ), datum: ( owner: `pkh`, @@ -329,7 +329,7 @@ datum: ( owner: `pkh`, direction: "Up|Down", - operation: `Sell|Down`, + operation: `Sell|Buy`, price: `P`, ), redeemer: ("CompleteFill"), diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/build-seed-tx.sh b/lazer/cardano/hermes/infra/hydra-bootstrap/build-seed-tx.sh new file mode 100755 index 00000000..368070f5 --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/build-seed-tx.sh @@ -0,0 +1,80 @@ +#! /bin/bash +# Build + sign the Hydra offline-head seed tx for Preprod (--testnet-magic 1). +# Tx layout follows infra/hydra-bootstrap/entrypoint.sh: cardano-cli latest transaction build-raw, then sign, then cat. +# Run from repo host with Docker (entrypoint runs cardano-cli inside its image; we invoke the same CLI via docker run). +# +# No --tx-out-reference-script-file: cardano-cli’s reference-script CBOR does not match Hydra 1.3’s ledger check +# (ConwayUtxowFailure MalformedReferenceScripts). The Pyth UTxO carries inline datum + tokens only; attach Plutus +# in L2 txs explicitly (e.g. Lucid attach.WithdrawalValidator / attach.Script) instead of readFrom scriptRef. + +set -euo pipefail + +BOOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +INFRA="$(cd "${BOOT}/.." && pwd)" + +CARDANO_IMAGE="${CARDANO_IMAGE:-ghcr.io/intersectmbo/cardano-node:10.1.4}" + +cardano_cli() { + docker run --rm --user "$(id -u):$(id -g)" --entrypoint cardano-cli \ + -v "${INFRA}:/work" -w /work/hydra-bootstrap \ + "${CARDANO_IMAGE}" "$@" +} + +# Preprod (not the devnet 42 from entrypoint.sh) +testnet_magic="${TESTNET_MAGIC:-1}" + +# Define the UTxO details and amounts (initial-utxo-set.json fiction #0) +tx_in1="0000000000000000000000000000000000000000000000000000000000000000#0" +tx_in_lovelace=100000000041175 +fee=41175 +# Remaining lovelace to the Pyth script output after fee +out_lovelace=$((tx_in_lovelace - fee)) + +policy_id="d799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6" +asset_name_hex="50797468205374617465" +# Must match submit-seed-tx.sh PYTH_OUTPUT_ADDR +pyth_script_address="${PYTH_OUTPUT_ADDR:-addr_test1wrm3tr5zpw9k2nefjtsz66wfzn6flnphr5kd6ak9ufrl3wcqqfyn8}" + +tx_out="${pyth_script_address}+${out_lovelace}+1 ${policy_id}.${asset_name_hex}" + +signing_key="${SEED_SIGNING_KEY:-${INFRA}/credentials/hydra-funds.sk}" +if [[ "${signing_key}" != "${INFRA}"/* ]]; then + echo "Signing key must be under ${INFRA}" >&2 + exit 1 +fi +signing_key_container="/work/${signing_key#"${INFRA}"/}" + +# Inline datum CBOR (hex) — same as seed-output-datum.hex +datum_hex="$(tr -d ' \n\t' < "${SEED_DATUM_HEX_FILE:-${BOOT}/seed-output-datum.hex}")" +if command -v xxd >/dev/null 2>&1; then + printf '%s' "${datum_hex}" | xxd -r -p > "${BOOT}/seed-output-datum.cbor" +else + python3 -c "import sys,binascii; sys.stdout.buffer.write(binascii.unhexlify(sys.argv[1]))" "${datum_hex}" > "${BOOT}/seed-output-datum.cbor" +fi + +tx_raw="/work/hydra-bootstrap/seed.body.json" +tx_signed="/work/hydra-bootstrap/seed.witnessed.json" + +# Build the raw transaction (cf. entrypoint.sh — build-raw, then fee, then out-file) +echo "Building raw transaction..." +cardano_cli latest transaction build-raw \ + --tx-in "${tx_in1}" \ + --tx-out "${tx_out}" \ + --tx-out-inline-datum-cbor-file seed-output-datum.cbor \ + --protocol-params-file /work/protocol-parameters.json \ + --fee "${fee}" \ + --out-file "${tx_raw}" + +# Sign the transaction (Preprod testnet-magic) +echo "Signing transaction (Preprod testnet-magic ${testnet_magic})..." +cardano_cli latest transaction sign \ + --tx-body-file "${tx_raw}" \ + --signing-key-file "${signing_key_container}" \ + --testnet-magic "${testnet_magic}" \ + --out-file "${tx_signed}" + +cp "${BOOT}/seed.witnessed.json" "${INFRA}/seed-spend.signed.json" +cp "${BOOT}/seed.body.json" "${BOOT}/seed-spend.raw" + +echo "Wrote ${INFRA}/seed-spend.signed.json and ${BOOT}/seed-spend.raw" +cat "${INFRA}/seed-spend.signed.json" diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.cbor b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.cbor index 26f8b0833d9e33ce7ee0b478055a89de18665874..4d0531d7cb5b7fa720a301cef1c86727d5595d7d 100644 GIT binary patch delta 82 zcmd1Wz&OF(Q$p$g{s@JJ_Xoc;98HY+{5##&NuzG2?aJSW1G4iR?=RL2XyVb!xluVE gj2doKHT(y$s^&{GFfcCq`ni|mKS=EV|A}4-0K+CLdjJ3c delta 12 TcmdnMm^Hzjnc@F}i4zn69!3P# diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.hex b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.hex new file mode 100644 index 00000000..5362572e --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-output-datum.hex @@ -0,0 +1 @@ +d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw index 21dbe60a..a73ae32d 100644 --- a/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed-spend.raw @@ -1,5 +1,5 @@ { - "type": "Tx ConwayEra", + "type": "Unwitnessed Tx ConwayEra", "description": "Ledger Cddl Format", - "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d818586ad8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb2400ffa0a0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abe8203590ab9590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a0f5f6" + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a0f5f6" } diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed.body.json b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.body.json new file mode 100644 index 00000000..a73ae32d --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.body.json @@ -0,0 +1,5 @@ +{ + "type": "Unwitnessed Tx ConwayEra", + "description": "Ledger Cddl Format", + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a0f5f6" +} diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed.signed.json b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.signed.json new file mode 100644 index 00000000..1f0cc255 --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.signed.json @@ -0,0 +1,5 @@ +{ + "type": "Witnessed Tx ConwayEra", + "description": "Ledger Cddl Format", + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abb8203590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a100d9010281825820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e058408329f51aecab2e7cecacfd02d294d00d1050ae66c9e556cf6932254172fa8e1c410b0e098671564adeda126123d23f0ec3ad866d5df5bb1a92766f73bff30c04f5f6" +} diff --git a/lazer/cardano/hermes/infra/hydra-bootstrap/seed.witnessed.json b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.witnessed.json new file mode 100644 index 00000000..9c8d636d --- /dev/null +++ b/lazer/cardano/hermes/infra/hydra-bootstrap/seed.witnessed.json @@ -0,0 +1,5 @@ +{ + "type": "Witnessed Tx ConwayEra", + "description": "Ledger Cddl Format", + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a100d9010281825820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e058403014cf053b2687bb3e6ef63b78dd2736d3de4fcec8b3ed423c92038187e669180382c440164da59b85790d7ea5a19556c3024a4860517564bf05aa0ddbd5620af5f6" +} diff --git a/lazer/cardano/hermes/infra/initial-utxo-set.json b/lazer/cardano/hermes/infra/initial-utxo-set.json index be4b9cf5..0b1158b0 100644 --- a/lazer/cardano/hermes/infra/initial-utxo-set.json +++ b/lazer/cardano/hermes/infra/initial-utxo-set.json @@ -4,9 +4,12 @@ "value": { "lovelace": 100000000041175, "d799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6": {"50797468205374617465": 1} - }, - "referenceScript": { - "script": {"type": "PlutusScriptV3","cborHex": "590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e60001", "description": ""} + } + }, + "0000000000000000000000000000000000000000000000000000000000000000#1": { + "address": "addr_test1vzqdn97wxxuem2ukec6fswslmknuj2zlcwhuz2wfqvkdcgq9235ym", + "value": { + "lovelace": 100000000000000 } } } diff --git a/lazer/cardano/hermes/infra/seed-spend.signed.json b/lazer/cardano/hermes/infra/seed-spend.signed.json index ee2a3381..9c8d636d 100644 --- a/lazer/cardano/hermes/infra/seed-spend.signed.json +++ b/lazer/cardano/hermes/infra/seed-spend.signed.json @@ -1,5 +1,5 @@ { - "type": "Tx ConwayEra", + "type": "Witnessed Tx ConwayEra", "description": "Ledger Cddl Format", - "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d818586ad8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb2400ffa0a0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abe8203590ab9590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a100d9010281825820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e0584031f301f65559513835fb48e290bd6f0f4bfd1cf9daa2bb2765a9bf0e92383b7e110661d7e5ba33aa8c3db2d0f429285df6840b1204469128f84f3d3d6b196c08f5f6" + "cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a100d9010281825820216f72947d1b97d56825c5f9f8a2e6f14234c03171853264f2f552a2685b25e058403014cf053b2687bb3e6ef63b78dd2736d3de4fcec8b3ed423c92038187e669180382c440164da59b85790d7ea5a19556c3024a4860517564bf05aa0ddbd5620af5f6" } diff --git a/lazer/cardano/hermes/server/.env.example b/lazer/cardano/hermes/server/.env.example new file mode 100644 index 00000000..beef2df8 --- /dev/null +++ b/lazer/cardano/hermes/server/.env.example @@ -0,0 +1,4 @@ +PYTH_ACCESS_TOKEN="Complete it yourself" +PYTH_STATE_ASSET_UNIT="d799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e650797468205374617465" +HYDRA_NODE_PRIVATE_KEY="5820245120cdf333f8ea69114a2b3f05bcbc0d5c8e8486ca94c020623d5cca822e04" +CONTROL_TOKEN_POLICY_ID="186e32faa80a26810392fda6d559c7ed4721a65ce1c9d4ef3e1c87b4" diff --git a/lazer/cardano/hermes/server/package.json b/lazer/cardano/hermes/server/package.json index 40323f68..a204b370 100644 --- a/lazer/cardano/hermes/server/package.json +++ b/lazer/cardano/hermes/server/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "type": "module", "scripts": { + "postinstall": "node scripts/patch-libsodium-esm.mjs", "api": "tsx watch src/index.ts", "matcher": "tsx watch src/matcher.ts", "build": "tsc", diff --git a/lazer/cardano/hermes/server/pnpm-lock.yaml b/lazer/cardano/hermes/server/pnpm-lock.yaml index b038359c..54eea32c 100644 --- a/lazer/cardano/hermes/server/pnpm-lock.yaml +++ b/lazer/cardano/hermes/server/pnpm-lock.yaml @@ -630,8 +630,8 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + get-tsconfig@4.13.7: + resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} @@ -1732,7 +1732,7 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-tsconfig@4.13.6: + get-tsconfig@4.13.7: dependencies: resolve-pkg-maps: 1.0.0 @@ -1954,7 +1954,7 @@ snapshots: tsx@4.21.0: dependencies: esbuild: 0.27.4 - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 optionalDependencies: fsevents: 2.3.3 diff --git a/lazer/cardano/hermes/server/scripts/patch-libsodium-esm.mjs b/lazer/cardano/hermes/server/scripts/patch-libsodium-esm.mjs new file mode 100644 index 00000000..ae4ba314 --- /dev/null +++ b/lazer/cardano/hermes/server/scripts/patch-libsodium-esm.mjs @@ -0,0 +1,85 @@ +/** + * libsodium-wrappers-sumo ESM entry imports "./libsodium-sumo.mjs" from the same + * directory as libsodium-wrappers.mjs, but the published package only ships the + * wrapper file; the real module lives in libsodium-sumo. Bare Node + pnpm hit + * ERR_MODULE_NOT_FOUND without this symlink. + * + * The wrappers package may only appear under .pnpm (not hoisted to root + * node_modules), so we locate it explicitly. + */ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const serverRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); + +function findWrappersPkgRoot() { + const direct = path.join(serverRoot, "node_modules", "libsodium-wrappers-sumo"); + if (fs.existsSync(path.join(direct, "package.json"))) { + return fs.realpathSync(direct); + } + + const pnpmDir = path.join(serverRoot, "node_modules", ".pnpm"); + if (!fs.existsSync(pnpmDir)) { + return null; + } + for (const name of fs.readdirSync(pnpmDir, { withFileTypes: true })) { + if (!name.isDirectory() || !name.name.startsWith("libsodium-wrappers-sumo@")) { + continue; + } + const candidate = path.join(pnpmDir, name.name, "node_modules", "libsodium-wrappers-sumo"); + if (fs.existsSync(path.join(candidate, "package.json"))) { + return fs.realpathSync(candidate); + } + } + return null; +} + +function main() { + const wsPkgRoot = findWrappersPkgRoot(); + if (!wsPkgRoot) { + console.warn("[patch-libsodium-esm] libsodium-wrappers-sumo not found, skip"); + return; + } + + const sumoPkgRoot = path.join(wsPkgRoot, "..", "libsodium-sumo"); + + const esmDir = path.join(wsPkgRoot, "dist", "modules-sumo-esm"); + const linkPath = path.join(esmDir, "libsodium-sumo.mjs"); + const targetPath = path.join(sumoPkgRoot, "dist", "modules-sumo-esm", "libsodium-sumo.mjs"); + + if (!fs.existsSync(path.join(sumoPkgRoot, "package.json"))) { + console.warn("[patch-libsodium-esm] sibling libsodium-sumo not found:", sumoPkgRoot); + return; + } + if (!fs.existsSync(targetPath)) { + console.warn("[patch-libsodium-esm] missing target:", targetPath); + return; + } + if (!fs.existsSync(esmDir)) { + console.warn("[patch-libsodium-esm] missing dir:", esmDir); + return; + } + + const relTarget = path.relative(esmDir, targetPath); + + try { + if (fs.existsSync(linkPath)) { + const st = fs.lstatSync(linkPath); + if (st.isSymbolicLink()) { + const resolved = path.resolve(esmDir, fs.readlinkSync(linkPath)); + if (resolved === path.resolve(targetPath)) { + return; + } + } + fs.unlinkSync(linkPath); + } + fs.symlinkSync(relTarget, linkPath); + console.log("[patch-libsodium-esm] OK", linkPath, "->", relTarget); + } catch (e) { + console.error("[patch-libsodium-esm]", e); + process.exitCode = 1; + } +} + +main(); diff --git a/lazer/cardano/hermes/server/src/market.ts b/lazer/cardano/hermes/server/src/market.ts index 66fa2ca3..d956be8f 100644 --- a/lazer/cardano/hermes/server/src/market.ts +++ b/lazer/cardano/hermes/server/src/market.ts @@ -1,39 +1,117 @@ +import { HydraHandler } from "./offchain/hydra/handler.js"; +import { HydraProvider } from "./offchain/hydra/provider.js"; import type { Market } from "./types.js"; +import { CML, Lucid, Data, validatorToAddress, credentialToRewardAddress } from '@lucid-evolution/lucid' +import fs from 'fs' +import path from 'path' +import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; +import assert from "assert"; export const MARKET_DURATION_MS = 5 * 60 * 1000; // 5 minutes -// TODO: When reading the current market from the blockchain, replace -// createMarket() calls in index.ts with a fetch from the contract: -// -// import { ethers } from "ethers" -// -// const CONTRACT_ADDRESS = "0x..." // TODO: deployed market factory address -// const ABI = [...] // TODO: contract ABI -// const provider = new ethers.WebSocketProvider("wss://your-rpc-url") -// const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider) -// -// async function fetchCurrentMarket(): Promise { -// const marketId = await contract.currentMarketId() -// const marketData = await contract.markets(marketId) -// return { -// id: marketId.toString(), -// startTime: Number(marketData.startTime) * 1000, // contract: unix seconds -// endTime: Number(marketData.endTime) * 1000, -// strikePrice: Number(marketData.strikePrice) / 1e18, -// } -// } -// -// TODO: When creating a new market on-chain, replace createMarket() with: -// -// async function createOnChainMarket(strikePrice: number): Promise { -// const strikePriceWei = ethers.parseEther(strikePrice.toString()) -// const tx = await contract.createMarket(strikePriceWei) -// await tx.wait() -// return fetchCurrentMarket() -// } - -export function createMarket(strikePrice: number): Market { + +assert(process.env.PYTH_STATE_ASSET_UNIT) +assert(process.env.HYDRA_NODE_PRIVATE_KEY) +assert(process.env.CONTROL_TOKEN_POLICY_ID) + +const PYTH_STATE_ASSET_UNIT = process.env.PYTH_STATE_ASSET_UNIT; +const HYDRA_NODE_PRIVATE_KEY = process.env.HYDRA_NODE_PRIVATE_KEY; +const CONTROL_TOKEN_POLICY_ID = process.env.CONTROL_TOKEN_POLICY_ID; +const BTC_PRICE_FEED = 1; + +export async function createMarket(strikePrice: number): Promise { + // TODO: change to env var + const HYDRA_NODE_URL = "ws://localhost:4011" + const handler = new HydraHandler(HYDRA_NODE_URL) + const provider = new HydraProvider(handler) + // TODO: setup testnet id + const lucid = await Lucid(provider, "Preprod") + + // TODO: change to env var + const pythStateUtxo = await lucid.utxoByUnit(PYTH_STATE_ASSET_UNIT) + console.log("pythStateUtxo:", pythStateUtxo) + // TODO: parse pyth state datum to get withdraw script field + const pythStateDatum = Data.from(pythStateUtxo.datum ?? "", PythStateDatum) + + + // connect "admin" wallet: hydra credentials wallet + + const sk = Buffer.from(HYDRA_NODE_PRIVATE_KEY, 'hex') + const privateKey = CML.PrivateKey.from_normal_bytes(sk.subarray(2)) + lucid.selectWallet.fromPrivateKey(privateKey.to_bech32()) + console.log(await lucid.wallet().getUtxos()) + const [seedUtxo,] = await lucid.wallet().getUtxos() + + // TODO: get market script address + // instantiate market script (with timestamp parameter) + const marketScriptAddress = await lucid.wallet().address() + + const lazer = await PythLazerClient.create({ token: process.env.PYTH_ACCESS_TOKEN ?? "", webSocketPoolConfig: {} }); + + const latestPrice = await lazer.getLatestPrice({ + channel: "fixed_rate@200ms", + formats: ["solana"], + jsonBinaryEncoding: "hex", + priceFeedIds: [BTC_PRICE_FEED], + properties: ["price", "exponent", "feedUpdateTimestamp"], + }); + + if (!latestPrice.solana?.data) { + throw new Error("Missing update payload"); + } + + // const update = Data.fromJson(`0x${latestPrice.solana.data}`) + // console.log("latestPrice:", latestPrice) + // console.log("update:", update) + // + const maybeParsedPrice = latestPrice.parsed?.priceFeeds?.at(0); + assert(maybeParsedPrice, "Could not find latest price for feed",); + const price = maybeParsedPrice.price; + const exponent = maybeParsedPrice.exponent; + + assert(price && exponent, "Price not found"); + + + const rawSignature = [latestPrice.solana.data] + const update = Data.to(rawSignature as any, Data.Array(Data.Bytes())) + console.log("pythStateDatum.withdraw_script", pythStateDatum.withdraw_script) + + + // TODO: get control token policy, form plutus json ?? + const controlTokenAsset = `${CONTROL_TOKEN_POLICY_ID}${seedUtxo.txHash}` + + + const marketInlineDatum = Data.to({ + startPrice: { + numerator: BigInt(price), + denominator: BigInt((10 ** exponent).toFixed(0)), + }, + endPrice: null, + remainingShares: 0n, + }, MarketDatum) + const now = Date.now(); + const tx = await lucid + .newTx() + .readFrom([pythStateUtxo]) + .collectFrom([seedUtxo]) + .mintAssets({ [controlTokenAsset]: 1n }, Data.void()) + .attach.Script({ type: "PlutusV3", script: "46450101002499" }) + .pay.ToContract(marketScriptAddress, { kind: "inline", value: marketInlineDatum }, { [controlTokenAsset]: 1n }) + .withdraw( + credentialToRewardAddress("Preprod", { type: "Script", hash: pythStateDatum.withdraw_script }), + 0n, + update + ) + .attach.WithdrawalValidator({ type: "PlutusV3", script: "590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e60001" }) + .validFrom(now - 60_000) + .validTo(now + 60_000) + .complete() + + console.log(tx.toJSON()) + + + return { id: crypto.randomUUID(), startTime: now, @@ -41,3 +119,53 @@ export function createMarket(strikePrice: number): Market { strikePrice, }; } + +/** + * Load user's public key from credentials file + * TODO there's a better way to do this? + */ +export function loadHydraCredentialsPublicKey(): string { + console.log("loadHydraCredentialsPublicKey cwd:", process.cwd()) + const vkPath = path.join(process.cwd(), '../infra/credentials', 'hydra-funds.sk') + const vk = JSON.parse(fs.readFileSync(vkPath, 'utf8')) + const vkBytes = Buffer.from("5820245120cdf333f8ea69114a2b3f05bcbc0d5c8e8486ca94c020623d5cca822e04", 'hex') + const publicKey = CML.PublicKey.from_bytes(vkBytes.subarray(2)) + return publicKey.to_bech32() +} + +// Minimal schema matching the on-chain Pyth state datum layout. +// Only the `withdraw_script` field is used; the preceding fields +// are defined to keep positional alignment with the Plutus struct. +// biome-ignore assist/source/useSortedKeys: order-sensistive + + +const PythStateDatumSchema = Data.Object({ + governance: Data.Object({ + wormhole: Data.Bytes(), + emitter_chain: Data.Integer(), + emitter_address: Data.Bytes(), + seen_sequence: Data.Integer(), + }), + trusted_signers: Data.Map(Data.Any(), Data.Any()), + deprecated_withdraw_scripts: Data.Map(Data.Any(), Data.Any()), + withdraw_script: Data.Bytes(), +}); +type PythStateDatum = Data.Static; +const PythStateDatum = PythStateDatumSchema as unknown as PythStateDatum + + +const MarketDatumSchema = Data.Object({ + startPrice: Data.Object({ + numerator: Data.Integer(), + denominator: Data.Integer(), + }), + endPrice: Data.Nullable( + Data.Object({ + numerator: Data.Integer(), + denominator: Data.Integer(), + }) + ), + remainingShares: Data.Integer(), +}); +type MarketDatum = Data.Static; +const MarketDatum = MarketDatumSchema as unknown as MarketDatum diff --git a/lazer/cardano/hermes/server/src/offchain/market.ts b/lazer/cardano/hermes/server/src/offchain/market.ts index c1859d50..7b79d1e9 100644 --- a/lazer/cardano/hermes/server/src/offchain/market.ts +++ b/lazer/cardano/hermes/server/src/offchain/market.ts @@ -3,27 +3,6 @@ import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; import { createMarket as _createMarket } from "../market.js"; import type { Market } from "../types.js"; -// TODO: Replace with on-chain reads/writes: -// -// export async function createMarket(): Promise { -// const strikePrice = await pythOracle.getPrice(BTC_FEED_ID) // on-chain oracle read -// const tx = await contract.createMarket(ethers.parseEther(strikePrice.toString())) -// await tx.wait() -// return getCurrentMarket() -// } -// -// export async function getCurrentMarket(): Promise { -// const id = await contract.currentMarketId() -// const m = await contract.markets(id) -// return { -// id: id.toString(), -// startTime: Number(m.startTime) * 1000, -// endTime: Number(m.endTime) * 1000, -// strikePrice: Number(m.strikePrice) / 1e18, -// } -// } - -// TODO: confirm BTC/USD feed ID — same as btcPrice.ts stream const BTC_FEED_ID = 1; async function fetchBtcPrice(): Promise {