@latchprotocol/widgets 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwapWidget-CwkRtOfn.js","sources":["../../src/components/portal.tsx","../../src/styles/css.ts","../../src/components/primitives.tsx","../../src/components/LaunchWidget.tsx","../../src/components/LiquidityWidget.tsx","../../src/components/swap/SwapSettings.tsx","../../src/components/swap/TokenSelect.tsx","../../src/components/SwapWidget.tsx"],"sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * Where overlays render. Radix portals default to `document.body`, which is\n * outside a shadow root and outside the `.latch-widget` theme scope. The shell\n * provides its own element instead, so dialogs and popovers inherit the theme\n * variables and stay styled inside the web component.\n */\n\nimport { createContext, useContext } from \"react\";\n\nconst PortalContainerContext = createContext<HTMLElement | null>(null);\n\nexport const PortalContainerProvider = PortalContainerContext.Provider;\n\n/** The element overlays should portal into, or `undefined` for Radix's default. */\nexport function usePortalContainer(): HTMLElement | undefined {\n return useContext(PortalContainerContext) ?? undefined;\n}\n","// SPDX-License-Identifier: MIT\n/**\n * The stylesheet, as a string.\n *\n * It lives in TypeScript rather than a `.css` file for one reason: the web\n * component renders into a shadow root, and a shadow root cannot see the host\n * page's stylesheets. The same source therefore has to be injectable in three\n * places - a `<style>` in the document head for React hosts, a\n * `CSSStyleSheet` adopted by each shadow root, and `dist/styles.css` for hosts\n * that prefer a `<link>`. One source, no drift.\n *\n * ## Theming\n *\n * Every colour, radius and font is a `--latch-*` custom property declared on\n * `.latch-widget`. Overriding one from the host page is enough to restyle the\n * widget; nothing is hardcoded inside a rule. Light is the base, dark is applied\n * by `[data-latch-theme=\"dark\"]` and by `prefers-color-scheme` when the theme is\n * left on `system`.\n *\n * The layout is single-column and fluid from 280px up, because these widgets\n * are expected to live in narrow sidebars.\n */\n\n/** The complete widget stylesheet. */\nexport const WIDGET_CSS = `\n.latch-widget {\n /* Palette */\n --latch-bg: #ffffff;\n --latch-bg-elevated: #f6f7f9;\n --latch-bg-sunken: #eceef2;\n --latch-border: #dfe3e8;\n --latch-border-strong: #c4cad3;\n --latch-text: #10131a;\n --latch-text-muted: #5c6472;\n --latch-text-inverted: #ffffff;\n --latch-accent: #3b5bdb;\n --latch-accent-hover: #2f49b2;\n --latch-accent-text: #ffffff;\n --latch-success: #157347;\n --latch-warning: #9a6700;\n --latch-warning-bg: #fff8e1;\n --latch-danger: #b42318;\n --latch-danger-bg: #fef3f2;\n --latch-focus: #3b5bdb;\n /* The compact swap's Buy side: the CVD-safe \"up\" colour, with a dark label (6:1). */\n --latch-buy: #1f9e89;\n --latch-buy-hover: #23b39b;\n --latch-buy-text: #04060c;\n\n /* Shape and type */\n --latch-radius: 14px;\n --latch-radius-sm: 9px;\n --latch-font: \"IBM Plex Sans\", system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n --latch-font-mono: \"IBM Plex Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace;\n --latch-font-size: 14px;\n --latch-font-size-sm: 12px;\n --latch-font-size-lg: 22px;\n --latch-gap: 12px;\n --latch-padding: 16px;\n --latch-control-height: 44px;\n --latch-shadow: 0 1px 2px rgba(16, 19, 26, 0.06), 0 8px 24px rgba(16, 19, 26, 0.06);\n\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--latch-gap);\n width: 100%;\n min-width: 0;\n max-width: 480px;\n padding: var(--latch-padding);\n background: var(--latch-bg);\n color: var(--latch-text);\n border: 1px solid var(--latch-border);\n border-radius: var(--latch-radius);\n box-shadow: var(--latch-shadow);\n font-family: var(--latch-font);\n font-size: var(--latch-font-size);\n line-height: 1.45;\n}\n\n.latch-widget *,\n.latch-widget *::before,\n.latch-widget *::after {\n box-sizing: inherit;\n}\n\n/* Text takes the WIDGET's ink, not the host page's. A host rule such as\n \\`h2 { color: var(--ink) }\\` otherwise beats inheritance: a dark-themed widget\n on a light page drew its title in the page's near-black on the widget's\n near-black (1.1:1, axe, the locker embed 2026-09-26). Specificity (0,1,0)\n beats any element selector; every widget class rule below comes later and\n still sets its own colour. A host's own content in a slot is left alone. */\n.latch-widget :where(h1, h2, h3, h4, h5, h6, p, label, legend, dt, dd, li, th, td, figcaption, caption):where(:not(.latch-slot *)) {\n color: inherit;\n}\n\n.latch-widget[data-latch-theme=\"dark\"] {\n --latch-bg: #14161b;\n --latch-bg-elevated: #1c1f26;\n --latch-bg-sunken: #23262f;\n --latch-border: #2b2f38;\n --latch-border-strong: #3d4350;\n --latch-text: #f2f4f8;\n --latch-text-muted: #98a1b1;\n --latch-text-inverted: #14161b;\n --latch-accent: #6b8afd;\n --latch-accent-hover: #849dff;\n --latch-accent-text: #0b0d12;\n --latch-success: #4ade80;\n --latch-warning: #fbbf5c;\n --latch-warning-bg: #33280f;\n --latch-danger: #ff8a80;\n --latch-danger-bg: #3a1a17;\n --latch-focus: #849dff;\n --latch-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);\n}\n\n@media (prefers-color-scheme: dark) {\n .latch-widget[data-latch-theme=\"system\"] {\n --latch-bg: #14161b;\n --latch-bg-elevated: #1c1f26;\n --latch-bg-sunken: #23262f;\n --latch-border: #2b2f38;\n --latch-border-strong: #3d4350;\n --latch-text: #f2f4f8;\n --latch-text-muted: #98a1b1;\n --latch-text-inverted: #14161b;\n --latch-accent: #6b8afd;\n --latch-accent-hover: #849dff;\n --latch-accent-text: #0b0d12;\n --latch-success: #4ade80;\n --latch-warning: #fbbf5c;\n --latch-warning-bg: #33280f;\n --latch-danger: #ff8a80;\n --latch-danger-bg: #3a1a17;\n --latch-focus: #849dff;\n --latch-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);\n }\n}\n\n.latch-header {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.latch-title {\n margin: 0;\n font-size: 16px;\n font-weight: 650;\n}\n\n.latch-subtitle {\n margin: 0;\n color: var(--latch-text-muted);\n font-size: var(--latch-font-size-sm);\n}\n\n.latch-mock-banner {\n display: flex;\n gap: 8px;\n align-items: flex-start;\n padding: 10px 12px;\n border: 1px solid var(--latch-warning);\n border-radius: var(--latch-radius-sm);\n background: var(--latch-warning-bg);\n color: var(--latch-warning);\n font-size: var(--latch-font-size-sm);\n font-weight: 600;\n}\n\n.latch-mock-banner span {\n font-weight: 500;\n}\n\n.latch-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--latch-bg-elevated);\n border: 1px solid var(--latch-border);\n border-radius: var(--latch-radius-sm);\n}\n\n.latch-field-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.latch-label {\n display: block;\n color: var(--latch-text-muted);\n font-size: var(--latch-font-size-sm);\n font-weight: 600;\n letter-spacing: 0.01em;\n}\n\n.latch-amount-input {\n flex: 1 1 120px;\n min-width: 0;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--latch-text);\n font-family: var(--latch-font);\n font-size: var(--latch-font-size-lg);\n font-weight: 600;\n line-height: 1.2;\n}\n\n.latch-amount-input::placeholder {\n color: var(--latch-text-muted);\n font-weight: 500;\n}\n\n.latch-amount-input:focus-visible,\n.latch-select:focus-visible,\n.latch-button:focus-visible,\n.latch-icon-button:focus-visible,\n.latch-slider:focus-visible,\n.latch-chip:focus-visible {\n outline: 2px solid var(--latch-focus);\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.latch-select {\n flex: 0 1 auto;\n max-width: 100%;\n height: 34px;\n padding: 0 8px;\n background: var(--latch-bg);\n color: var(--latch-text);\n border: 1px solid var(--latch-border-strong);\n border-radius: 999px;\n font-family: inherit;\n font-size: var(--latch-font-size);\n font-weight: 600;\n cursor: pointer;\n}\n\n.latch-meta {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n color: var(--latch-text-muted);\n font-size: var(--latch-font-size-sm);\n}\n\n.latch-meta-value {\n font-variant-numeric: tabular-nums;\n}\n\n.latch-switch-row {\n display: flex;\n justify-content: center;\n margin: -6px 0;\n}\n\n.latch-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: var(--latch-bg);\n color: var(--latch-text);\n border: 1px solid var(--latch-border-strong);\n border-radius: 999px;\n cursor: pointer;\n font-size: 15px;\n line-height: 1;\n}\n\n.latch-icon-button:hover {\n background: var(--latch-bg-sunken);\n}\n\n.latch-summary {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--latch-bg-sunken);\n border-radius: var(--latch-radius-sm);\n font-size: var(--latch-font-size-sm);\n}\n\n.latch-summary dl {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n}\n\n.latch-summary-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 10px;\n}\n\n.latch-summary-row dt {\n color: var(--latch-text-muted);\n min-width: 0;\n}\n\n.latch-summary-row dd {\n margin: 0;\n text-align: right;\n font-variant-numeric: tabular-nums;\n overflow-wrap: anywhere;\n}\n\n.latch-summary-row[data-latch-emphasis=\"fee\"] dd {\n color: var(--latch-accent);\n font-weight: 650;\n}\n\n.latch-summary-row[data-latch-severity=\"high\"] dd,\n.latch-summary-row[data-latch-severity=\"severe\"] dd {\n color: var(--latch-danger);\n font-weight: 650;\n}\n\n.latch-route {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n font-size: var(--latch-font-size-sm);\n color: var(--latch-text-muted);\n}\n\n.latch-route-token {\n padding: 2px 8px;\n background: var(--latch-bg);\n border: 1px solid var(--latch-border);\n border-radius: 999px;\n color: var(--latch-text);\n font-weight: 600;\n}\n\n.latch-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n min-height: var(--latch-control-height);\n padding: 0 16px;\n background: var(--latch-accent);\n color: var(--latch-accent-text);\n border: 1px solid transparent;\n border-radius: var(--latch-radius-sm);\n font-family: inherit;\n font-size: 15px;\n font-weight: 650;\n cursor: pointer;\n}\n\n.latch-button:hover:not(:disabled) {\n background: var(--latch-accent-hover);\n}\n\n.latch-button:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.latch-button[data-latch-variant=\"secondary\"] {\n background: var(--latch-bg-elevated);\n color: var(--latch-text);\n border-color: var(--latch-border-strong);\n}\n\n.latch-button[data-latch-variant=\"danger\"] {\n background: var(--latch-danger);\n color: var(--latch-text-inverted);\n}\n\n.latch-status {\n min-height: 18px;\n margin: 0;\n font-size: var(--latch-font-size-sm);\n color: var(--latch-text-muted);\n}\n\n.latch-status[data-latch-tone=\"error\"] {\n color: var(--latch-danger);\n}\n\n.latch-status[data-latch-tone=\"success\"] {\n color: var(--latch-success);\n}\n\n.latch-error {\n padding: 10px 12px;\n background: var(--latch-danger-bg);\n border: 1px solid var(--latch-danger);\n border-radius: var(--latch-radius-sm);\n color: var(--latch-danger);\n font-size: var(--latch-font-size-sm);\n overflow-wrap: anywhere;\n}\n\n.latch-tabs {\n display: flex;\n gap: 4px;\n padding: 3px;\n background: var(--latch-bg-sunken);\n border-radius: 999px;\n}\n\n.latch-chip {\n flex: 1 1 0;\n min-width: 0;\n padding: 7px 10px;\n background: transparent;\n color: var(--latch-text-muted);\n border: 0;\n border-radius: 999px;\n font-family: inherit;\n font-size: var(--latch-font-size-sm);\n font-weight: 650;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.latch-chip[aria-selected=\"true\"],\n.latch-chip[aria-pressed=\"true\"] {\n background: var(--latch-bg);\n color: var(--latch-text);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.latch-progress {\n height: 8px;\n background: var(--latch-bg-sunken);\n border-radius: 999px;\n overflow: hidden;\n}\n\n.latch-progress-fill {\n height: 100%;\n background: var(--latch-accent);\n border-radius: 999px;\n transition: width 200ms ease;\n}\n\n.latch-slider {\n width: 100%;\n accent-color: var(--latch-accent);\n}\n\n.latch-range-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n\n.latch-range-grid input {\n width: 100%;\n min-width: 0;\n height: 36px;\n padding: 0 10px;\n background: var(--latch-bg);\n color: var(--latch-text);\n border: 1px solid var(--latch-border-strong);\n border-radius: var(--latch-radius-sm);\n font-family: var(--latch-font-mono);\n font-size: var(--latch-font-size);\n}\n\n.latch-curve {\n display: block;\n width: 100%;\n height: auto;\n border-radius: var(--latch-radius-sm);\n background: var(--latch-bg-sunken);\n}\n\n.latch-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n}\n\n.latch-footer {\n display: flex;\n justify-content: space-between;\n gap: 8px;\n color: var(--latch-text-muted);\n font-size: 11px;\n}\n\n.latch-footer a {\n color: inherit;\n}\n\n.latch-launch-legs {\n display: grid;\n gap: 16px;\n}\n\n.latch-empty {\n margin: 0;\n color: var(--latch-text-muted);\n font-size: 13px;\n line-height: 1.5;\n}\n\n@media (max-width: 380px) {\n .latch-widget {\n --latch-padding: 12px;\n --latch-font-size-lg: 20px;\n }\n\n .latch-range-grid {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .latch-progress-fill {\n transition: none;\n }\n}\n\n/* ============================================================================\n Swap surface (SwapWidget): panels, big inputs, token buttons, dialog,\n popover, CTA, details. Every colour is a --latch-* token above.\n ============================================================================ */\n\n.latch-swap { max-width: 480px; }\n.latch-swap__form { display: flex; flex-direction: column; gap: 4px; }\n\n.latch-panel {\n background: var(--latch-bg-elevated);\n border: 1px solid transparent;\n border-radius: var(--latch-radius);\n padding: 14px 16px 12px;\n transition: border-color 120ms ease, background 120ms ease;\n}\n.latch-panel:focus-within { border-color: var(--latch-border-strong); background: var(--latch-bg); }\n/* The amount field draws no outline of its own (it is the panel's big number), so the PANEL carries\n the keyboard focus ring; the border-strong change alone was invisible on a dark theme (WCAG 2.4.7). */\n.latch-panel:has(.latch-big-input:focus-visible) { border-color: var(--latch-focus); box-shadow: 0 0 0 1px var(--latch-focus); }\n.latch-panel__top { display: flex; justify-content: space-between; align-items: center; min-height: 18px; }\n.latch-panel__balance { font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); display: inline-flex; gap: 8px; align-items: center; }\n/* Quick amounts under \"You pay\": real fractions of the balance just read, one row of equal chips. */\n.latch-portions { display: grid; grid-template-columns: repeat(auto-fit, minmax(52px, 1fr)); gap: 8px; margin-top: 12px; }\n.latch-portion {\n font: inherit; font-size: var(--latch-font-size-sm); font-weight: 600; min-height: 36px; padding: 0 8px; border-radius: var(--latch-radius-sm);\n border: 1px solid var(--latch-border); background: var(--latch-bg); color: var(--latch-text); cursor: pointer;\n transition: border-color 120ms, color 120ms;\n}\n.latch-portion:hover { border-color: var(--latch-accent); color: var(--latch-accent); }\n.latch-portion:focus-visible { outline: 2px solid var(--latch-focus); outline-offset: 2px; }\n\n/* The compact variant's Buy / Sell pill, in the header where the title was. */\n.latch-sides {\n flex: 1 1 auto; display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; min-width: 0;\n border: 1px solid var(--latch-border); border-radius: 999px; background: var(--latch-bg-sunken);\n}\n.latch-sides__btn {\n min-height: 40px; border: 0; border-radius: 999px; background: transparent; color: var(--latch-text);\n font: inherit; font-weight: 600; cursor: pointer; transition: background 120ms, color 120ms;\n}\n.latch-sides__btn:hover { background: var(--latch-bg-elevated); }\n.latch-sides__btn:focus-visible { outline: 2px solid var(--latch-focus); outline-offset: 2px; }\n.latch-sides__btn[data-latch-side=\"buy\"][aria-pressed=\"true\"] { background: var(--latch-buy); color: var(--latch-buy-text); }\n.latch-sides__btn[data-latch-side=\"sell\"][aria-pressed=\"true\"] { background: var(--latch-accent); color: var(--latch-accent-text); }\n.latch-swap .latch-header:has(.latch-sides) { align-items: center; flex-wrap: nowrap; }\n\n/* The compact variant's lines, always visible above the button, one fee per line. */\n.latch-lines { margin: 8px 0 0; padding: 4px 4px 0; display: grid; gap: 8px; }\n.latch-lines .latch-details__row { font-size: 13px; }\n.latch-lines output { font: inherit; transition: opacity 150ms; }\n.latch-lines output.is-refreshing { opacity: 0.55; }\n.latch-swap__form[data-latch-variant=\"compact\"][data-latch-swap-side=\"buy\"] .latch-cta { background: var(--latch-buy); color: var(--latch-buy-text); }\n.latch-swap__form[data-latch-variant=\"compact\"][data-latch-swap-side=\"buy\"] .latch-cta:hover:not(:disabled) { background: var(--latch-buy-hover); }\n.latch-panel__main { display: flex; align-items: center; gap: 12px; margin-top: 6px; }\n.latch-big-input {\n flex: 1 1 auto; min-width: 0; width: 100%;\n font-family: var(--latch-font); font-size: 32px; font-weight: 500; letter-spacing: -0.01em;\n background: transparent; border: 0; color: var(--latch-text); padding: 4px 0; outline: none;\n}\n.latch-big-input::placeholder, .latch-big-input__placeholder { color: var(--latch-text-muted); opacity: 0.7; }\n.latch-big-input--out { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity 150ms; }\n.latch-big-input--out.is-refreshing { opacity: 0.55; }\n.latch-panel__error { margin: 6px 0 0; font-size: var(--latch-font-size-sm); color: var(--latch-danger); }\n.latch-panel__note { margin: 6px 0 0; font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); }\n\n.latch-token-button {\n flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px;\n padding: 6px 10px 6px 6px; border-radius: 999px; font: inherit; font-weight: 650; cursor: pointer;\n background: var(--latch-bg); color: var(--latch-text); border: 1px solid var(--latch-border);\n box-shadow: 0 1px 2px rgba(0,0,0,0.06); transition: border-color 120ms, transform 80ms;\n}\n.latch-token-button:hover { border-color: var(--latch-border-strong); }\n.latch-token-button:active { transform: scale(0.98); }\n.latch-token-button__chevron { color: var(--latch-text-muted); font-size: 12px; }\n.latch-token-button--locked { cursor: default; box-shadow: none; background: var(--latch-bg-sunken); }\n.latch-token-button--locked:hover { border-color: var(--latch-border); }\n.latch-slot { display: block; }\n.latch-slot--header { margin-top: -4px; }\n.latch-token-logo { border-radius: 50%; object-fit: cover; flex-shrink: 0; background: var(--latch-bg-sunken); }\n.latch-token-logo--initials {\n display: inline-flex; align-items: center; justify-content: center; font-weight: 700;\n color: #fff; letter-spacing: 0.01em; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);\n background: linear-gradient(140deg, hsl(var(--latch-mono-hue, 215) 62% 52%), hsl(calc(var(--latch-mono-hue, 215) + 28) 58% 34%));\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);\n}\n\n.latch-flip { display: flex; justify-content: center; height: 0; position: relative; z-index: 1; }\n.latch-flip__button {\n position: relative; top: -16px; width: 36px; height: 36px; border-radius: 12px; cursor: pointer;\n background: var(--latch-bg); border: 4px solid var(--latch-bg); color: var(--latch-text);\n box-shadow: 0 0 0 1px var(--latch-border); font-size: 16px; line-height: 1;\n display: inline-flex; align-items: center; justify-content: center; transition: transform 160ms ease, background 120ms;\n}\n.latch-flip__button:hover { background: var(--latch-bg-sunken); transform: rotate(180deg); }\n\n.latch-cta {\n margin-top: 8px; width: 100%; height: 52px; border: 0; border-radius: var(--latch-radius);\n background: var(--latch-accent); color: var(--latch-accent-text); font: inherit; font-size: 17px; font-weight: 700;\n cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 10px;\n transition: background 120ms, transform 80ms, opacity 120ms;\n}\n.latch-cta:hover:not(:disabled) { background: var(--latch-accent-hover); }\n.latch-cta:active:not(:disabled) { transform: scale(0.995); }\n.latch-cta:disabled { background: var(--latch-bg-sunken); color: var(--latch-text-muted); cursor: not-allowed; }\n.latch-cta[data-latch-busy=\"true\"] { opacity: 0.85; cursor: progress; }\n.latch-spinner {\n width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent;\n animation: latch-spin 0.8s linear infinite;\n}\n@keyframes latch-spin { to { transform: rotate(360deg); } }\n\n.latch-ack {\n display: flex; gap: 10px; align-items: flex-start; margin-top: 6px; padding: 10px 12px;\n border-radius: var(--latch-radius-sm); background: var(--latch-warning-bg); color: var(--latch-text); font-size: var(--latch-font-size-sm);\n}\n.latch-ack input { margin-top: 2px; }\n\n.latch-details { margin-top: 8px; border: 1px solid var(--latch-border); border-radius: var(--latch-radius-sm); overflow: hidden; }\n.latch-details__toggle {\n width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 8px;\n padding: 10px 12px; background: transparent; border: 0; font: inherit; color: var(--latch-text); cursor: pointer; text-align: left;\n}\n.latch-details__toggle:hover { background: var(--latch-bg-elevated); }\n.latch-details__rate { font-weight: 600; cursor: pointer; }\n.latch-details__hint { display: inline-flex; gap: 10px; align-items: center; color: var(--latch-text-muted); font-size: var(--latch-font-size-sm); }\n.latch-details__list { margin: 0; padding: 4px 12px 10px; display: grid; gap: 6px; border-top: 1px solid var(--latch-border); }\n.latch-details__row { display: flex; justify-content: space-between; gap: 12px; font-size: var(--latch-font-size-sm); }\n.latch-details__row dt { color: var(--latch-text-muted); }\n.latch-details__row dd { margin: 0; text-align: right; color: var(--latch-text); overflow-wrap: anywhere; }\n[data-latch-severity=\"high\"] { color: var(--latch-danger) !important; }\n[data-latch-severity=\"medium\"] { color: var(--latch-warning) !important; }\n\n.latch-settings-trigger { display: inline-flex; align-items: center; gap: 6px; width: auto; padding: 0 10px; border-radius: 999px; }\n.latch-settings-trigger__value { font-size: var(--latch-font-size-sm); font-weight: 600; }\n\n/* Overlays. Portalled into .latch-widget, so they inherit the tokens. */\n.latch-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); backdrop-filter: blur(2px); animation: latch-fade 120ms ease; z-index: 50; }\n.latch-dialog {\n position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 51;\n width: min(420px, calc(100vw - 32px)); max-height: min(640px, calc(100vh - 32px));\n display: flex; flex-direction: column; gap: 10px;\n background: var(--latch-bg); color: var(--latch-text); border: 1px solid var(--latch-border);\n border-radius: var(--latch-radius); box-shadow: var(--latch-shadow); padding: 14px 14px 8px;\n font-family: var(--latch-font); font-size: var(--latch-font-size); animation: latch-pop 140ms ease;\n}\n@keyframes latch-fade { from { opacity: 0; } }\n@keyframes latch-pop { from { opacity: 0; transform: translate(-50%, -48%) scale(0.98); } }\n.latch-dialog__head { display: flex; justify-content: space-between; align-items: center; }\n.latch-dialog__title { margin: 0; font-size: 17px; font-weight: 700; display: inline-flex; align-items: center; gap: 8px; }\n.latch-dialog__count {\n font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; font-variant-numeric: tabular-nums;\n color: var(--latch-text-muted); background: var(--latch-bg-elevated); border: 1px solid var(--latch-border);\n}\n.latch-search-wrap { position: relative; display: flex; align-items: center; }\n.latch-search-wrap__icon { position: absolute; left: 14px; color: var(--latch-text-muted); pointer-events: none; }\n.latch-search-wrap__clear {\n position: absolute; right: 8px; width: 28px; height: 28px; border-radius: 999px; border: 0; cursor: pointer;\n background: var(--latch-bg-sunken); color: var(--latch-text-muted); font-size: 16px; line-height: 1;\n}\n.latch-search-wrap__clear:hover { color: var(--latch-text); }\n.latch-search {\n width: 100%; font: inherit; font-size: 16px; padding: 12px 40px; border-radius: 999px;\n border: 1px solid var(--latch-border); background: var(--latch-bg-elevated); color: var(--latch-text); outline: none;\n transition: border-color 120ms, box-shadow 120ms;\n}\n.latch-search:focus { border-color: var(--latch-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--latch-accent) 22%, transparent); }\n.latch-common { display: flex; flex-wrap: wrap; gap: 8px; padding-bottom: 4px; }\n.latch-chip--token {\n flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 14px 0 6px;\n border-radius: 999px; border: 1px solid var(--latch-border); background: var(--latch-bg-elevated); color: var(--latch-text);\n font-weight: 600; transition: border-color 120ms, background 120ms;\n}\n.latch-chip--token:hover { border-color: color-mix(in srgb, var(--latch-accent) 55%, var(--latch-border)); }\n.latch-chip--token[aria-pressed=\"true\"] { border-color: var(--latch-accent); background: color-mix(in srgb, var(--latch-accent) 14%, var(--latch-bg-elevated)); }\n.latch-token-list { list-style: none; margin: 0 -14px; padding: 6px 8px 8px; overflow-y: auto; border-top: 1px solid var(--latch-border); }\n.latch-token-row {\n width: 100%; display: flex; align-items: center; gap: 12px; padding: 10px; min-height: 56px; background: transparent; border: 0;\n border-radius: 12px; font: inherit; color: var(--latch-text); cursor: pointer; text-align: left; transition: background 100ms;\n}\n.latch-token-row:hover:not(:disabled), .latch-token-row:focus-visible { background: var(--latch-bg-elevated); outline: none; }\n.latch-token-row:focus-visible { box-shadow: inset 0 0 0 2px var(--latch-accent); }\n.latch-token-row[aria-selected=\"true\"] { background: color-mix(in srgb, var(--latch-accent) 10%, transparent); }\n.latch-token-row:disabled { opacity: 0.4; cursor: not-allowed; }\n.latch-token-row--note { color: var(--latch-text-muted); font-size: var(--latch-font-size-sm); cursor: default; min-height: 0; }\n.latch-token-row--empty { justify-content: center; text-align: center; padding: 28px 16px; }\n.latch-token-row__main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }\n.latch-token-row__symbol { font-weight: 650; font-size: 15px; display: inline-flex; align-items: center; flex-wrap: wrap; }\n.latch-token-row__name { font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.latch-token-row__balance { display: flex; flex-direction: column; align-items: flex-end; font-variant-numeric: tabular-nums; color: var(--latch-text); font-weight: 600; }\n.latch-token-row__balance-sym { font-size: 11px; font-weight: 500; color: var(--latch-text-muted); }\n.latch-token-row__check { color: var(--latch-accent); font-weight: 700; font-size: 15px; margin-left: 4px; }\n@media (prefers-reduced-motion: reduce) {\n .latch-token-row, .latch-chip--token, .latch-search { transition: none; }\n}\n.latch-token-row--unlisted { background: color-mix(in srgb, var(--latch-warning) 8%, transparent); }\n.latch-token-row__badges { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 8px; vertical-align: middle; }\n.latch-badge {\n display: inline-block; padding: 1px 6px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 16px; letter-spacing: 0.01em;\n border: 1px solid var(--latch-border); background: var(--latch-bg-elevated); color: var(--latch-text-muted); white-space: nowrap;\n}\n.latch-badge[data-latch-tone=\"info\"] { color: var(--latch-accent); border-color: color-mix(in srgb, var(--latch-accent) 35%, transparent); }\n.latch-badge[data-latch-tone=\"warn\"] { color: var(--latch-warning); border-color: color-mix(in srgb, var(--latch-warning) 45%, transparent); }\n.latch-token-group { list-style: none; }\n.latch-token-group__label {\n display: block; padding: 8px 14px 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--latch-text-muted); border-top: 1px solid var(--latch-border);\n}\n.latch-token-group:first-child .latch-token-group__label { border-top: 0; }\n.latch-token-group__list { list-style: none; margin: 0; padding: 0; }\n\n.latch-popover {\n z-index: 51; width: min(320px, calc(100vw - 32px)); background: var(--latch-bg); color: var(--latch-text);\n border: 1px solid var(--latch-border); border-radius: var(--latch-radius); box-shadow: var(--latch-shadow); padding: 12px;\n display: flex; flex-direction: column; gap: 8px; font-family: var(--latch-font); font-size: var(--latch-font-size); animation: latch-fade 120ms ease;\n}\n.latch-popover__row { display: flex; justify-content: space-between; align-items: center; }\n.latch-popover__value { font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); }\n.latch-custom-slippage { display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto; }\n.latch-custom-slippage input {\n width: 56px; font: inherit; font-size: var(--latch-font-size-sm); padding: 6px 8px; border-radius: 999px;\n border: 1px solid var(--latch-border); background: var(--latch-bg); color: var(--latch-text); text-align: right; outline: none;\n}\n.latch-custom-slippage input:focus { border-color: var(--latch-accent); }\n.latch-note { margin: 0; font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); }\n.latch-note--warn { color: var(--latch-warning); }\n.latch-footer--brand { justify-content: center; color: var(--latch-text-muted); font-size: 11px; }\n.latch-footer a { color: var(--latch-accent); text-decoration: none; }\n\n/* ============================================================================\n Locks (LocksBadge, LocksPanel): the locked share and a countdown. Every\n colour is a --latch-* token above.\n ============================================================================ */\n.latch-locks { gap: 6px; }\n.latch-locks--badge { display: inline-flex; flex-direction: column; width: auto; max-width: 100%; padding: 10px 14px; box-shadow: none; border-radius: var(--latch-radius-sm); }\n.latch-locks--panel { max-width: none; }\n.latch-locks__headline { margin: 0; display: flex; align-items: baseline; gap: 8px; font-weight: 600; overflow-wrap: anywhere; }\n.latch-locks__headline--muted { color: var(--latch-text-muted); font-weight: 500; }\n.latch-locks__headline--error { color: var(--latch-danger); font-weight: 500; }\n.latch-locks__dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--latch-text-muted); transform: translateY(-1px); }\n.latch-locks__dot--locked { background: var(--latch-success); }\n.latch-locks__dot--open { background: var(--latch-warning); }\n.latch-locks__dot--none { background: var(--latch-border-strong); }\n.latch-locks__countdown { margin: 0; font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); overflow-wrap: anywhere; }\n.latch-locks__timer { font-family: var(--latch-font-mono); font-variant-numeric: tabular-nums; color: var(--latch-text); }\n.latch-locks__link { font-size: var(--latch-font-size-sm); color: var(--latch-accent); text-decoration: none; font-weight: 600; }\n.latch-locks__link:hover { text-decoration: underline; }\n.latch-locks__link:focus-visible { outline: 2px solid var(--latch-focus); outline-offset: 2px; border-radius: 4px; }\n.latch-locks__list { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; }\n.latch-locks__item { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid var(--latch-border); border-radius: var(--latch-radius-sm); background: var(--latch-bg-elevated); min-width: 0; }\n.latch-locks__item[data-status=\"withdrawn\"], .latch-locks__item[data-status=\"claimed\"] { opacity: 0.72; }\n.latch-locks__row { display: flex; justify-content: space-between; align-items: center; gap: 8px; }\n.latch-locks__status { flex: 0 0 auto; padding: 1px 8px; border: 1px solid currentColor; border-radius: 999px; font-size: 11px; font-weight: 650; white-space: nowrap; }\n.latch-locks__status--locked, .latch-locks__status--cliff, .latch-locks__status--vesting { color: var(--latch-success); }\n.latch-locks__status--unlockable, .latch-locks__status--vested { color: var(--latch-warning); }\n.latch-locks__status--withdrawn, .latch-locks__status--claimed { color: var(--latch-text-muted); }\n.latch-locks__status--permanent { color: var(--latch-accent, var(--latch-success)); }\n.latch-locks__facts { margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 6px 12px; font-size: var(--latch-font-size-sm); }\n.latch-locks__facts div { min-width: 0; }\n.latch-locks__facts dt { color: var(--latch-text-muted); }\n.latch-locks__facts dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }\n\n/* Lock charts (lockCharts.tsx): a locked-share bar that grows in, and a release\n schedule that draws on. Motion off under prefers-reduced-motion. */\n.latch-sharebar { display: grid; gap: 6px; min-width: 0; }\n.latch-locks--badge .latch-sharebar { min-width: 180px; }\n.latch-sharebar__track { height: 8px; border-radius: 999px; overflow: hidden; background: var(--latch-bg-sunken); }\n.latch-sharebar__grow { display: flex; height: 100%; transform-origin: left center; animation: latch-grow 0.9s cubic-bezier(0.22, 1, 0.36, 1) both; }\n.latch-sharebar__part { flex: 0 0 auto; height: 100%; }\n.latch-sharebar__part + .latch-sharebar__part { box-shadow: inset 2px 0 0 var(--latch-bg); }\n.latch-sharebar__part--permanent, .latch-sharebar__part--lp { background: var(--latch-success); }\n.latch-sharebar__part--time, .latch-sharebar__part--unvested { background: var(--latch-accent); }\n.latch-sharebar__part--vested { background: var(--latch-accent); opacity: 0.45; }\n.latch-sharebar__key { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: 11px; color: var(--latch-text-muted); font-variant-numeric: tabular-nums; }\n.latch-sharebar__key li { display: inline-flex; align-items: center; gap: 5px; }\n.latch-sharebar__sw { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }\n.latch-spark { margin: 2px 0 0; display: grid; gap: 4px; }\n.latch-spark__svg { display: block; width: 100%; height: 44px; overflow: visible; cursor: crosshair; border-radius: 4px; }\n.latch-spark__svg:focus-visible { outline: 2px solid var(--latch-focus); outline-offset: 2px; }\n.latch-spark__base { stroke: var(--latch-border); stroke-width: 1; }\n.latch-spark__line { stroke: var(--latch-accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; stroke-dasharray: 2000; animation: latch-draw 1.3s cubic-bezier(0.22, 1, 0.36, 1) both; }\n.latch-spark__now { stroke: var(--latch-text-muted); stroke-width: 1; stroke-dasharray: 3 3; }\n.latch-spark__cross { stroke: var(--latch-accent); stroke-width: 1; opacity: 0.6; }\n.latch-spark__cap { font-size: 11px; color: var(--latch-text-muted); overflow-wrap: anywhere; }\n.latch-locks .latch-progress-fill, .latch-locker .latch-progress-fill { transform-origin: left center; animation: latch-grow 0.9s cubic-bezier(0.22, 1, 0.36, 1) both; }\n@keyframes latch-grow { from { transform: scaleX(0.02); } to { transform: scaleX(1); } }\n@keyframes latch-draw { from { stroke-dashoffset: 2000; } to { stroke-dashoffset: 0; } }\n@media (prefers-reduced-motion: reduce) {\n .latch-sharebar__grow, .latch-spark__line, .latch-locks .latch-progress-fill, .latch-locker .latch-progress-fill { animation: none; transform: none; stroke-dashoffset: 0; }\n}\n\n/* ============================================================================\n Token trust (TokenTrustPanel): labelled rows, each with its source.\n ============================================================================ */\n.latch-trust { max-width: none; gap: 8px; }\n.latch-trust__list { margin: 0; display: grid; gap: 0; }\n.latch-trust__row { display: grid; grid-template-columns: minmax(120px, 180px) 1fr; gap: 4px 14px; padding: 9px 0; border-top: 1px solid var(--latch-border); min-width: 0; }\n.latch-trust__row:first-child { border-top: 0; }\n@media (max-width: 520px) { .latch-trust__row { grid-template-columns: 1fr; } }\n.latch-trust__label { color: var(--latch-text-muted); font-size: var(--latch-font-size-sm); font-weight: 600; }\n.latch-trust__value { margin: 0; min-width: 0; display: grid; gap: 3px; }\n.latch-trust__headline { margin: 0; display: flex; align-items: baseline; gap: 8px; font-weight: 600; overflow-wrap: anywhere; }\n.latch-trust__detail { margin: 0; font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); overflow-wrap: anywhere; }\n.latch-trust__source { margin: 0; display: flex; flex-wrap: wrap; gap: 2px 10px; font-family: var(--latch-font-mono); font-size: 11px; color: var(--latch-text-muted); overflow-wrap: anywhere; }\n.latch-trust__source a { color: inherit; text-decoration: underline; text-decoration-color: var(--latch-border-strong); }\n.latch-trust__source a:hover { color: var(--latch-accent); }\n.latch-trust__dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--latch-border-strong); transform: translateY(-1px); }\n.latch-trust__dot--locked { background: var(--latch-success); }\n.latch-trust__dot--neutral { background: var(--latch-text-muted); }\n.latch-trust__dot--caution { background: var(--latch-warning); }\n.latch-trust__dot--flagged, .latch-trust__dot--error { background: var(--latch-danger); }\n.latch-trust__row[data-tone=\"flagged\"] .latch-trust__headline, .latch-trust__row[data-tone=\"error\"] .latch-trust__headline { color: var(--latch-danger); }\n.latch-trust__subhead { margin: 6px 0 0; font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--latch-text-muted); }\n.latch-trust__pool { display: grid; gap: 4px; padding: 10px 12px; border: 1px solid var(--latch-border); border-radius: var(--latch-radius-sm); background: var(--latch-bg-elevated); min-width: 0; }\n.latch-trust__pool-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }\n.latch-trust__pool-head code { font-family: var(--latch-font-mono); font-size: 11px; color: var(--latch-text-muted); }\n.latch-trust__found { margin: 0; font-size: 11px; color: var(--latch-text-muted); }\n.latch-trust__link { font-size: var(--latch-font-size-sm); color: var(--latch-accent); text-decoration: none; font-weight: 600; margin-left: auto; }\n.latch-trust__link:hover { text-decoration: underline; }\n.latch-trust__state { margin: 0; color: var(--latch-text-muted); }\n.latch-trust__state--error { color: var(--latch-danger); }\n.latch-trust__retry { font: inherit; background: none; border: 0; padding: 0; color: var(--latch-accent); cursor: pointer; text-decoration: underline; }\n\n/* ============================================================================\n Locker (LockerWidget): lock a position, lock or vest tokens, manage locks.\n ============================================================================ */\n.latch-locker { gap: 10px; }\n.latch-locker__tabs { display: flex; gap: 4px; padding: 3px; border-radius: 999px; background: var(--latch-bg-sunken); }\n.latch-locker__tab { flex: 1; font: inherit; font-size: var(--latch-font-size-sm); font-weight: 600; padding: 7px 10px; border: 0; border-radius: 999px; background: transparent; color: var(--latch-text-muted); cursor: pointer; }\n.latch-locker__tab[aria-selected=\"true\"] { background: var(--latch-bg); color: var(--latch-text); box-shadow: var(--latch-shadow); }\n.latch-locker__field { display: grid; gap: 4px; font-size: var(--latch-font-size-sm); }\n.latch-locker__field > span { color: var(--latch-text-muted); font-weight: 600; }\n.latch-locker__input { width: 100%; font: inherit; padding: 10px 12px; border-radius: var(--latch-radius-sm); border: 1px solid var(--latch-border); background: var(--latch-bg-elevated); color: var(--latch-text); outline: none; min-width: 0; }\n.latch-locker__input:focus { border-color: var(--latch-accent); }\n.latch-locker__row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n@media (max-width: 420px) { .latch-locker__row2 { grid-template-columns: 1fr; } }\n.latch-locker__issues { margin: 0; padding-left: 18px; color: var(--latch-danger); font-size: var(--latch-font-size-sm); }\n.latch-locker__fee { margin: 0; padding: 8px 10px; border-radius: var(--latch-radius-sm); background: var(--latch-bg-elevated); font-size: var(--latch-font-size-sm); display: grid; gap: 2px; }\n.latch-locker__fee strong { font-variant-numeric: tabular-nums; }\n.latch-locker__steps { margin: 0; padding-left: 18px; display: grid; gap: 2px; font-size: var(--latch-font-size-sm); color: var(--latch-text-muted); }\n.latch-locker__steps li[data-state=\"done\"] { color: var(--latch-success); }\n.latch-locker__steps li[data-state=\"active\"] { color: var(--latch-text); font-weight: 600; }\n.latch-locker__status { margin: 0; font-size: var(--latch-font-size-sm); overflow-wrap: anywhere; }\n.latch-locker__status[data-kind=\"error\"] { color: var(--latch-danger); }\n.latch-locker__status[data-kind=\"success\"] { color: var(--latch-success); }\n.latch-locker__actions { display: flex; flex-wrap: wrap; gap: 6px; }\n.latch-locker__btn { font: inherit; font-size: var(--latch-font-size-sm); font-weight: 600; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--latch-border-strong); background: var(--latch-bg); color: var(--latch-text); cursor: pointer; }\n.latch-locker__btn:hover:not(:disabled) { border-color: var(--latch-accent); color: var(--latch-accent); }\n.latch-locker__btn:disabled { opacity: 0.5; cursor: not-allowed; }\n.latch-locker__choice { display: flex; gap: 12px; flex-wrap: wrap; font-size: var(--latch-font-size-sm); }\n.latch-locker__choice label { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }\n\n/* ============================================================================\n The Latch mark (brand kit masters/latch-mark.svg, loaded as shipped, never\n redrawn). 24 px wide is the kit's minimum; the margin is its clear space\n (the height of the hook's eye at this size).\n ============================================================================ */\n.latch-brand { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 11px; color: var(--latch-text-muted); }\n.latch-brand__mark { flex: 0 0 auto; width: 24px; height: auto; margin: 4px; display: block; }\n.latch-brand__spacer { flex: 1; }\n\n\n/* ============================================================================\n Touch (pointer: coarse): 44px targets, and inputs at 16px so iOS Safari does\n not zoom the host page when a field is focused.\n ============================================================================ */\n@media (pointer: coarse) {\n .latch-widget input:not([type=\"checkbox\"]):not([type=\"radio\"]):not([type=\"range\"]),\n .latch-widget select,\n .latch-widget textarea,\n .latch-locker input:not([type=\"checkbox\"]):not([type=\"radio\"]):not([type=\"range\"]),\n .latch-locker select { font-size: max(16px, 1em); }\n .latch-portion, .latch-chip, .latch-select, .latch-settings-trigger, .latch-icon-button,\n .latch-locker__tab, .latch-locker__input, .latch-locker__btn, .latch-button, .latch-token-button { min-height: 44px; }\n .latch-locker__choice label { min-height: 44px; }\n}\n`;\n\nconst STYLE_ELEMENT_ID = \"latch-widgets-styles\";\n\n/**\n * Injects the stylesheet into the document once.\n *\n * React hosts call this automatically the first time a styled widget mounts.\n * Hosts that bundle CSS themselves can import `@latchprotocol/widgets/styles.css`\n * instead and never call it.\n */\nexport function injectWidgetStyles(target: Document | ShadowRoot | null = globalThis.document ?? null): void {\n if (target === null) return;\n const root: Document | ShadowRoot = target;\n if (root.getElementById(STYLE_ELEMENT_ID) !== null) return;\n\n const doc = \"createElement\" in root ? root : root.ownerDocument;\n if (doc === null) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ELEMENT_ID;\n style.textContent = WIDGET_CSS;\n const parent = \"head\" in root && root.head !== null ? root.head : root;\n parent.appendChild(style);\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Presentational primitives shared by the three styled widgets.\n *\n * Nothing here holds protocol state. Each piece is a thin, accessible shell\n * over native form elements: a real `<label>` for every input, a real `<button>`\n * for every action, and one polite live region per widget so a screen reader\n * hears quote and transaction changes without the focus moving.\n */\n\nimport {\n useEffect,\n useId,\n useMemo,\n useState,\n type ChangeEvent,\n type ReactNode,\n} from \"react\";\nimport { PortalContainerProvider } from \"./portal.js\";\nimport type { TokenInfo } from \"../adapters/protocol.js\";\nimport { useWidgetContext } from \"../context/WidgetProvider.js\";\nimport { formatAmount } from \"../core/format.js\";\nimport { injectWidgetStyles } from \"../styles/css.js\";\nimport { describeError } from \"../core/errors.js\";\n\n/** Props for {@link WidgetShell}. */\nexport interface WidgetShellProps {\n readonly title: string;\n readonly subtitle?: string;\n readonly children: ReactNode;\n /** Rendered at the top-right of the header, e.g. a settings control. */\n readonly headerAction?: ReactNode;\n /**\n * Rendered in the header in place of the visible title (the swap widget's\n * Buy / Sell pill). The title stays the section's name and its heading, for\n * assistive technology only.\n */\n readonly headerContent?: ReactNode;\n readonly className?: string;\n}\n\n/**\n * The outer frame: theme attribute, stylesheet injection and the mock warning.\n *\n * The mock banner is rendered from `adapter.isMock` and takes no prop, so an\n * integrator cannot configure it away while still showing fabricated numbers.\n */\nexport function WidgetShell(props: WidgetShellProps): JSX.Element {\n const { theme, adapter } = useWidgetContext();\n /* Overlays portal into the widget itself, so they inherit its theme and\n stay inside a shadow root (see portal.tsx). */\n const [root, setRoot] = useState<HTMLElement | null>(null);\n\n useEffect(() => {\n injectWidgetStyles();\n }, []);\n\n return (\n <PortalContainerProvider value={root}>\n <section\n ref={setRoot}\n className={`latch-widget${props.className ? ` ${props.className}` : \"\"}`}\n data-latch-theme={theme}\n aria-label={props.title}\n >\n <header className=\"latch-header\">\n {props.headerContent !== undefined ? (\n <>\n <h2 className=\"latch-visually-hidden\">{props.title}</h2>\n {props.headerContent}\n </>\n ) : (\n <div>\n <h2 className=\"latch-title\">{props.title}</h2>\n {props.subtitle !== undefined ? (\n <p className=\"latch-subtitle\">{props.subtitle}</p>\n ) : null}\n </div>\n )}\n {props.headerAction}\n </header>\n {adapter.isMock ? <MockBanner /> : null}\n {props.children}\n </section>\n </PortalContainerProvider>\n );\n}\n\n/** Permanent, non-dismissible warning shown whenever the adapter is a mock. */\nexport function MockBanner(): JSX.Element {\n return (\n <div className=\"latch-mock-banner\" role=\"note\">\n <strong>Mock data</strong>\n <span>\n No contracts are deployed. Every price, balance and route shown here is\n simulated by the development adapter and is not a market quote.\n </span>\n </div>\n );\n}\n\n/** Props for {@link AmountField}. */\nexport interface AmountFieldProps {\n readonly label: string;\n readonly value: string;\n readonly onValueChange?: (value: string) => void;\n readonly readOnly?: boolean;\n readonly token: TokenInfo | null;\n readonly tokens: readonly TokenInfo[];\n readonly onTokenChange?: (token: TokenInfo) => void;\n readonly balance?: bigint | null;\n readonly onUseMax?: () => void;\n readonly error?: string | null;\n readonly secondaryText?: string;\n readonly placeholder?: string;\n}\n\n/** An amount input paired with a token selector and a balance line. */\nexport function AmountField(props: AmountFieldProps): JSX.Element {\n const inputId = useId();\n const selectId = useId();\n const errorId = useId();\n\n const handleAmount = (event: ChangeEvent<HTMLInputElement>): void => {\n props.onValueChange?.(event.target.value);\n };\n\n const handleToken = (event: ChangeEvent<HTMLSelectElement>): void => {\n const next = props.tokens.find((token) => token.address === event.target.value);\n if (next !== undefined) props.onTokenChange?.(next);\n };\n\n return (\n <div className=\"latch-field\">\n <label className=\"latch-label\" htmlFor={inputId}>\n {props.label}\n </label>\n <div className=\"latch-field-row\">\n <input\n id={inputId}\n className=\"latch-amount-input\"\n type=\"text\"\n inputMode=\"decimal\"\n autoComplete=\"off\"\n spellCheck={false}\n placeholder={props.placeholder ?? \"0.0\"}\n value={props.value}\n readOnly={props.readOnly ?? false}\n onChange={handleAmount}\n aria-invalid={props.error ? true : undefined}\n aria-describedby={props.error ? errorId : undefined}\n />\n <label className=\"latch-visually-hidden\" htmlFor={selectId}>\n {`${props.label} token`}\n </label>\n <select\n id={selectId}\n className=\"latch-select\"\n value={props.token?.address ?? \"\"}\n onChange={handleToken}\n disabled={props.onTokenChange === undefined}\n >\n {props.token === null ? <option value=\"\">Select</option> : null}\n {props.tokens.map((token) => (\n <option key={token.address} value={token.address}>\n {token.symbol}\n </option>\n ))}\n </select>\n </div>\n <div className=\"latch-meta\">\n <span>{props.secondaryText ?? \"\"}</span>\n {props.balance !== undefined && props.balance !== null && props.token !== null ? (\n <span className=\"latch-meta-value\">\n Balance {formatAmount(props.balance, props.token.decimals)}\n {props.onUseMax !== undefined ? (\n <>\n {\" \"}\n <button\n type=\"button\"\n className=\"latch-chip\"\n style={{ display: \"inline\", flex: \"none\", padding: \"0 6px\" }}\n onClick={props.onUseMax}\n >\n Max\n </button>\n </>\n ) : null}\n </span>\n ) : (\n <span />\n )}\n </div>\n {props.error ? (\n <p id={errorId} className=\"latch-status\" data-latch-tone=\"error\">\n {props.error}\n </p>\n ) : null}\n </div>\n );\n}\n\n/** One label/value pair inside a summary block. */\nexport interface SummaryRowProps {\n readonly label: string;\n readonly value: ReactNode;\n readonly emphasis?: \"fee\";\n readonly severity?: \"low\" | \"elevated\" | \"high\" | \"severe\" | \"unknown\";\n readonly title?: string;\n}\n\n/** A `<dt>`/`<dd>` pair. Must be rendered inside {@link SummaryList}. */\nexport function SummaryRow(props: SummaryRowProps): JSX.Element {\n return (\n <div\n className=\"latch-summary-row\"\n data-latch-emphasis={props.emphasis}\n data-latch-severity={props.severity}\n >\n <dt title={props.title}>{props.label}</dt>\n <dd>{props.value}</dd>\n </div>\n );\n}\n\n/** A definition list wrapper for {@link SummaryRow}s. */\nexport function SummaryList(props: { readonly children: ReactNode }): JSX.Element {\n return (\n <div className=\"latch-summary\">\n <dl>{props.children}</dl>\n </div>\n );\n}\n\n/** Props for {@link StatusRegion}. */\nexport interface StatusRegionProps {\n readonly message: string;\n readonly tone?: \"neutral\" | \"error\" | \"success\";\n /** `assertive` for errors that need to interrupt; `polite` otherwise. */\n readonly assertive?: boolean;\n}\n\n/**\n * The widget's single live region.\n *\n * Quote refreshes and transaction transitions are announced here rather than by\n * moving focus, so a keyboard user is never yanked out of the amount field\n * mid-typing by a background re-quote.\n */\nexport function StatusRegion(props: StatusRegionProps): JSX.Element {\n return (\n <p\n className=\"latch-status\"\n data-latch-tone={props.tone ?? \"neutral\"}\n role=\"status\"\n aria-live={props.assertive === true ? \"assertive\" : \"polite\"}\n >\n {props.message}\n </p>\n );\n}\n\n/** Props for {@link ActionButton}. */\nexport interface ActionButtonProps {\n readonly children: ReactNode;\n readonly onClick?: () => void;\n readonly disabled?: boolean;\n readonly busy?: boolean;\n readonly type?: \"button\" | \"submit\";\n readonly variant?: \"primary\" | \"secondary\" | \"danger\";\n /**\n * True while the widget is waiting for a wallet. The button then becomes\n * the connect call to action: enabled and calling `onConnectRequest` when\n * the host gave one, otherwise the disabled label it always was. `type`,\n * `disabled` and `onClick` are ignored in that state.\n */\n readonly needsConnect?: boolean;\n /** See {@link connectCtaProps}. */\n readonly onConnectRequest?: () => void;\n}\n\n/**\n * The attributes of a primary button while no wallet is connected.\n *\n * With a handler the button is a real button that asks the host to open its\n * connect flow; without one it is disabled, so a host that renders its own\n * connect control somewhere else keeps exactly the behaviour it had. Never a\n * submit: pressing it must not run the form's swap/add/buy handler.\n */\nexport function connectCtaProps(onConnectRequest: (() => void) | undefined): {\n readonly type: \"button\";\n readonly disabled: boolean;\n readonly onClick: (() => void) | undefined;\n} {\n return { type: \"button\", disabled: onConnectRequest === undefined, onClick: onConnectRequest };\n}\n\n/** The widget's primary call to action. */\nexport function ActionButton(props: ActionButtonProps): JSX.Element {\n const connect = props.needsConnect === true ? connectCtaProps(props.onConnectRequest) : null;\n return (\n <button\n type={connect !== null ? connect.type : (props.type ?? \"button\")}\n className=\"latch-button\"\n data-latch-variant={props.variant ?? \"primary\"}\n disabled={connect !== null ? connect.disabled : props.disabled === true || props.busy === true}\n aria-busy={props.busy === true ? true : undefined}\n onClick={connect !== null ? connect.onClick : props.onClick}\n >\n {props.children}\n </button>\n );\n}\n\n/** A labelled progress bar backed by a real `progressbar` role. */\nexport function ProgressBar(props: {\n readonly label: string;\n readonly percent: number;\n}): JSX.Element {\n const clamped = Math.max(0, Math.min(100, props.percent));\n return (\n <div\n className=\"latch-progress\"\n role=\"progressbar\"\n aria-label={props.label}\n aria-valuenow={Math.round(clamped)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className=\"latch-progress-fill\" style={{ width: `${clamped}%` }} />\n </div>\n );\n}\n\n/** A radio-style segmented control. */\nexport function SegmentedControl<T extends string>(props: {\n readonly label: string;\n readonly value: T;\n readonly options: readonly { readonly value: T; readonly label: string }[];\n readonly onChange: (value: T) => void;\n}): JSX.Element {\n const groupLabelId = useId();\n return (\n <>\n <span id={groupLabelId} className=\"latch-visually-hidden\">\n {props.label}\n </span>\n <div className=\"latch-tabs\" role=\"tablist\" aria-labelledby={groupLabelId}>\n {props.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"tab\"\n className=\"latch-chip\"\n aria-selected={option.value === props.value}\n tabIndex={option.value === props.value ? 0 : -1}\n onClick={() => props.onChange(option.value)}\n >\n {option.label}\n </button>\n ))}\n </div>\n </>\n );\n}\n\n/** Renders a route as a chain of token chips. */\nexport function RouteSummary(props: {\n readonly tokens: readonly string[];\n readonly detail?: string;\n}): JSX.Element {\n const chips = useMemo(\n () =>\n props.tokens.flatMap((symbol, index) => {\n const chip = (\n <span key={`token-${symbol}-${index}`} className=\"latch-route-token\">\n {symbol}\n </span>\n );\n return index === 0\n ? [chip]\n : [\n <span key={`arrow-${index}`} aria-hidden=\"true\">\n {\"→\"}\n </span>,\n chip,\n ];\n }),\n [props.tokens],\n );\n\n return (\n <div className=\"latch-route\">\n {chips}\n {props.detail !== undefined ? <span>{props.detail}</span> : null}\n </div>\n );\n}\n\n/** An error panel with `role=\"alert\"`. */\nexport function ErrorPanel(props: { readonly error: Error | null; readonly context?: \"quote\" | \"swap\" | \"liquidity\" | \"transaction\" }): JSX.Element | null {\n if (props.error === null) return null;\n /* The raw error (viem's multi-paragraph report, the package tag) is for\n logs; the panel prints one sentence a trader can act on. */\n return (\n <div className=\"latch-error\" role=\"alert\">\n {describeError(props.error, props.context)}\n </div>\n );\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Drop-in launch widget: a launch-aware swap panel.\n *\n * A Latch launch is a pool with `LaunchGuardHook` attached and an LP fee that\n * decays from `initialFeePips` to `finalFeePips` over the launch window (seconds\n * on the timestamp hook, contract blocks on the block-numbered one).\n * Buying into one is an ordinary swap, so the bottom half of this component is\n * the swap path — the same router, the same plan, the same integrator fee step.\n *\n * The top half is the only part that is launch-specific, and it exists because\n * the thing a buyer needs to know before pressing Buy is *when* they are:\n *\n * - Trading may not be open. Before the start every swap reverts.\n * - The fee right now may be enormous. That is the sniper tax working as\n * designed, and quoting it as though it were the pool's normal fee would\n * invite people to pay 25% without noticing.\n * - `maxBuyPerTx` caps a TRANSACTION, not a wallet. The hook's own source says\n * splitting a buy across transactions or wallets \"is NOT prevented and cannot\n * be\", and a UI that showed it as \"your remaining allocation\" would be\n * claiming a protection nobody has.\n *\n * Everything rendered here was read from the hook. Nothing is defaulted: where\n * a value is missing, the widget says which value and why.\n */\n\nimport { useCallback, useMemo, useState, type FormEvent } from \"react\";\nimport type { PoolId } from \"@latchprotocol/sdk\";\nimport type { Address } from \"viem\";\nimport { useWidgetContext } from \"../context/WidgetProvider.js\";\nimport { formatBps } from \"../config/integrator.js\";\nimport {\n formatAmount,\n formatPercentFromBps,\n formatPercentFromPips,\n formatRate,\n parseAmount,\n shortAddress,\n} from \"../core/format.js\";\nimport { humanDuration } from \"@latchprotocol/sdk\";\nimport {\n launchFeeAt,\n type DurationClock,\n type LaunchGuard,\n type LaunchSchedule,\n} from \"../callpath/launch.js\";\n\n/** A span on the hook's clock, in words: exact seconds, or contract blocks. */\nfunction clockSpan(clock: DurationClock, units: bigint | number): string {\n return clock === \"timestamp\" ? humanDuration(Number(units)) : `${units.toLocaleString()} blocks`;\n}\n\n/** A point on the hook's clock: a UTC time with its raw value, or a contract block. */\nfunction pointOnClock(clock: DurationClock, value: bigint): string {\n return clock === \"timestamp\"\n ? `${new Date(Number(value) * 1000).toISOString().replace(\"T\", \" \").slice(0, 19)} UTC`\n : `block ${value.toLocaleString()}`;\n}\nimport {\n buildLaunchView,\n resolveLaunchDataState,\n useLaunch,\n useLaunchBuy,\n useLaunchList,\n useLaunchesForToken,\n type LaunchDataState,\n type LaunchView,\n} from \"../hooks/useLaunch.js\";\nimport { useAccount, useTokenBalance } from \"../hooks/useTokens.js\";\nimport {\n ActionButton,\n AmountField,\n ErrorPanel,\n ProgressBar,\n StatusRegion,\n SummaryList,\n SummaryRow,\n WidgetShell,\n} from \"./primitives.js\";\nimport type { LaunchInfo } from \"../adapters/protocol.js\";\n\n/** Props for {@link LaunchWidget}. */\nexport interface LaunchWidgetProps {\n /**\n * The launch pool, by pool id. When omitted, the first launch the adapter\n * lists is used.\n *\n * A pool id, not a contract address: `LaunchGuardHook` serves many pools and\n * keys everything it knows by `PoolId`.\n */\n readonly poolId?: PoolId;\n readonly title?: string;\n readonly onPurchaseConfirmed?: (hash: string) => void;\n /**\n * Makes the \"Connect wallet\" call to action a working button that opens\n * the host's connect flow. Absent (and absent on the provider too), the CTA\n * is a disabled label and the visitor connects through the host's control.\n */\n readonly onConnectRequest?: () => void;\n}\n\n/** The styled launch widget. */\nexport function LaunchWidget(props: LaunchWidgetProps): JSX.Element {\n const { chain, integrator, onConnectRequest: providerConnect } = useWidgetContext();\n const onConnectRequest = props.onConnectRequest ?? providerConnect;\n\n const list = useLaunchList();\n const poolId = props.poolId ?? list.data?.[0]?.poolId ?? null;\n const launchResource = useLaunch(poolId);\n const launch = launchResource.data;\n\n const listState = resolveLaunchDataState(list);\n const launchState = resolveLaunchDataState(launchResource);\n const state: LaunchDataState =\n props.poolId !== undefined ? launchState : listState !== \"ready\" ? listState : launchState;\n\n const accountResource = useAccount();\n const account = accountResource.data;\n\n const [amountText, setAmountText] = useState(\"\");\n const parsed =\n launch === null || amountText.trim() === \"\"\n ? null\n : parseAmount(amountText, launch.quoteToken.decimals);\n const amountIn = parsed !== null && parsed.ok ? parsed.value : null;\n\n const balance = useTokenBalance(launch?.quoteToken ?? null, account);\n\n const buy = useLaunchBuy({\n launch,\n amountIn,\n ...(props.onPurchaseConfirmed ? { onSuccess: props.onPurchaseConfirmed } : {}),\n });\n\n const view = useMemo<LaunchView | null>(\n () => (launch === null ? null : buildLaunchView(launch)),\n [launch],\n );\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (buy.execution.needsApproval) {\n void buy.execution.approve();\n return;\n }\n void buy.execution.execute();\n },\n [buy.execution],\n );\n\n const title = props.title ?? (launch === null ? \"Launch\" : `${launch.launchToken.symbol} launch`);\n const subtitle = `Latch Protocol · ${chain.name}`;\n\n if (launch === null || view === null) {\n return (\n <WidgetShell title={title} subtitle={subtitle}>\n <LaunchUnavailable\n state={state}\n chainName={chain.name}\n error={props.poolId !== undefined ? launchResource.error : (list.error ?? launchResource.error)}\n />\n </WidgetShell>\n );\n }\n\n const { schedule } = view;\n const insufficientBalance =\n amountIn !== null && balance.data !== null && amountIn > balance.data;\n\n const busy =\n buy.execution.step === \"approving\" ||\n buy.execution.step === \"building\" ||\n buy.execution.step === \"awaiting-signature\" ||\n buy.execution.step === \"pending\";\n\n const buttonLabel = buy.execution.needsApproval\n ? `Approve ${buy.execution.approvals[0]?.token.symbol ?? launch.quoteToken.symbol}`\n : account === null\n ? \"Connect wallet\"\n : buy.gate.message !== null\n ? buy.gate.message\n : insufficientBalance\n ? `Insufficient ${launch.quoteToken.symbol}`\n : `Buy ${launch.launchToken.symbol}`;\n\n const canSubmit =\n account !== null &&\n !insufficientBalance &&\n (buy.execution.needsApproval || (buy.canBuy && (parsed === null || parsed.ok)));\n\n const statusMessage =\n buy.execution.statusMessage !== \"\"\n ? buy.execution.statusMessage\n : buy.gate.message !== null\n ? `${buy.gate.message}${buy.gate.revert === null ? \"\" : ` — the hook reverts ${buy.gate.revert}`}`\n : buy.quoteStatus === \"loading\"\n ? \"Fetching a quote\"\n : insufficientBalance\n ? `Insufficient ${launch.quoteToken.symbol}`\n : \"\";\n\n const statusTone =\n buy.execution.step === \"error\" ||\n buy.quoteStatus === \"error\" ||\n buy.gate.reason !== null ||\n insufficientBalance\n ? \"error\"\n : buy.execution.step === \"success\"\n ? \"success\"\n : \"neutral\";\n\n return (\n <WidgetShell title={title} subtitle={subtitle}>\n <LaunchSchedulePanel view={view} />\n\n <FeeDecayChart guard={launch.guard} schedule={schedule} />\n\n <MaxBuyNotice launch={launch} schedule={schedule} />\n\n <form onSubmit={handleSubmit} noValidate>\n <AmountField\n label={`You pay (${launch.quoteToken.symbol})`}\n value={amountText}\n onValueChange={setAmountText}\n token={launch.quoteToken}\n tokens={[launch.quoteToken]}\n balance={balance.data}\n error={\n parsed !== null && !parsed.ok\n ? parsed.message\n : insufficientBalance\n ? \"Insufficient balance\"\n : null\n }\n />\n\n <AmountField\n label={`You receive (${launch.launchToken.symbol})`}\n value={\n buy.breakdown === null\n ? \"\"\n : formatAmount(buy.breakdown.netAmountOut, launch.launchToken.decimals)\n }\n readOnly\n token={launch.launchToken}\n tokens={[launch.launchToken]}\n secondaryText={buy.quoteIsRefreshing ? \"Updating quote...\" : \"\"}\n />\n\n {buy.breakdown !== null ? (\n <SummaryList>\n <SummaryRow\n label=\"Rate\"\n value={formatRate(buy.rate, launch.quoteToken.symbol, launch.launchToken.symbol)}\n />\n <SummaryRow\n label=\"Price impact\"\n value={formatPercentFromBps(buy.breakdown.priceImpactBps)}\n severity={buy.breakdown.priceImpactSeverity}\n />\n <SummaryRow\n label=\"Launch fee charged\"\n value={formatPercentFromPips(launch.currentFeePips)}\n title=\"The LP fee the hook is overriding this pool with right now. It goes to the pool's liquidity providers, not to the hook.\"\n />\n {integrator.active ? (\n <SummaryRow\n label={`Integrator fee (${formatBps(integrator.feeBps)})`}\n value={`${formatAmount(buy.breakdown.integratorFee, launch.launchToken.decimals)} ${launch.launchToken.symbol} → ${shortAddress(integrator.referrer)}`}\n emphasis=\"fee\"\n title=\"Paid to the site hosting this widget, inside the same transaction as the buy.\"\n />\n ) : null}\n <SummaryRow\n label=\"Minimum received\"\n value={`${formatAmount(buy.breakdown.minAmountOutNet, launch.launchToken.decimals)} ${launch.launchToken.symbol}`}\n title=\"Guaranteed floor after slippage and the integrator fee. The transaction reverts below this.\"\n />\n </SummaryList>\n ) : null}\n\n <StatusRegion message={statusMessage} tone={statusTone} />\n\n <ActionButton type=\"submit\" disabled={!canSubmit} busy={busy} needsConnect={account === null} {...(onConnectRequest === undefined ? {} : { onConnectRequest })}>\n {buttonLabel}\n </ActionButton>\n </form>\n\n <ErrorPanel error={buy.execution.error ?? buy.quoteError} />\n\n {buy.execution.txHash !== null ? (\n <p className=\"latch-footer\">\n <span>Transaction</span>\n <span>{shortAddress(buy.execution.txHash)}</span>\n </p>\n ) : null}\n </WidgetShell>\n );\n}\n\n/**\n * The four not-ready states, each with its own sentence.\n *\n * `not-configured` is the one worth being careful about. On a chain where no\n * `LaunchGuardHook` is deployed there is no address to read and none may be\n * invented, so the honest answer is that the feature is absent here — not that\n * something failed, and not an example launch.\n */\nexport function LaunchUnavailable(props: {\n readonly state: LaunchDataState;\n readonly chainName: string;\n readonly error: Error | null;\n}): JSX.Element {\n switch (props.state) {\n case \"loading\":\n return <StatusRegion message=\"Loading the launch schedule…\" tone=\"neutral\" />;\n case \"not-configured\":\n return (\n <div className=\"latch-summary\">\n <StatusRegion\n message={`Launches are coming soon on ${props.chainName}.`}\n tone=\"neutral\"\n />\n </div>\n );\n case \"empty\":\n return (\n <div className=\"latch-summary\">\n <StatusRegion message=\"No launch is registered for this pool.\" tone=\"neutral\" />\n <p className=\"latch-subtitle\">\n The hook answered and holds no launch record. A pool id is only claimed when someone\n calls <code>configureLaunch</code>, and the hook refuses to let a pool be initialized\n before that happens.\n </p>\n </div>\n );\n case \"error\":\n return (\n <div className=\"latch-summary\">\n <StatusRegion\n message={props.error?.message ?? \"Couldn't load this launch. Try again.\"}\n tone=\"error\"\n assertive\n />\n <p className=\"latch-subtitle\">\n Nothing is shown in place of the schedule. Retry when the chain is reachable.\n </p>\n </div>\n );\n default:\n return <StatusRegion message=\"Loading\" tone=\"neutral\" />;\n }\n}\n\n/** The schedule, in the unit the hook stores it in. */\nexport function LaunchSchedulePanel(props: { readonly view: LaunchView }): JSX.Element {\n const { launch, schedule, feeSpanProgressBps, feeProjectionDriftPips } = props.view;\n\n return (\n <>\n <SummaryList>\n <SummaryRow label=\"Phase\" value={describePhase(schedule)} />\n <SummaryRow\n label=\"Fee right now\"\n value={formatPercentFromPips(launch.currentFeePips)}\n title=\"Live from the chain.\"\n />\n <SummaryRow\n label=\"Fee schedule\"\n value={\n schedule.initialFeePips === null || schedule.finalFeePips === null\n ? \"unknown\"\n : `${formatPercentFromPips(schedule.initialFeePips)} → ${formatPercentFromPips(schedule.finalFeePips)} over ${clockSpan(schedule.durationClock, launch.guard.window)}`\n }\n />\n <SummaryRow\n label=\"Opens at\"\n value={schedule.start === null ? \"unknown\" : pointOnClock(schedule.durationClock, schedule.start)}\n title=\"Trading opens at this time; swaps before it are refused.\"\n />\n <SummaryRow\n label={schedule.untilOpen !== null ? \"Until open\" : \"Left in decay\"}\n value={\n schedule.untilOpen !== null\n ? clockSpan(schedule.durationClock, schedule.untilOpen)\n : schedule.remaining !== null\n ? clockSpan(schedule.durationClock, schedule.remaining)\n : \"none — the fee has settled\"\n }\n />\n <SummaryRow\n label=\"Launch owner\"\n value={shortAddress(launch.guard.owner)}\n title=\"Set when the launch was configured. It cannot change anything once trading opens.\"\n />\n </SummaryList>\n\n {feeSpanProgressBps !== null ? (\n <div className=\"latch-field\">\n <span className=\"latch-label\">Fee decay</span>\n <ProgressBar label=\"Fee decay progress\" percent={feeSpanProgressBps / 100} />\n <div className=\"latch-meta\">\n <span>{(feeSpanProgressBps / 100).toFixed(1)}% of the way to the final fee</span>\n </div>\n </div>\n ) : null}\n\n {feeProjectionDriftPips !== null && feeProjectionDriftPips !== 0 ? (\n <StatusRegion\n message={\n `The chain reports ${formatPercentFromPips(launch.currentFeePips)} but this page ` +\n `projects ${formatPercentFromPips(launch.currentFeePips - feeProjectionDriftPips)}. ` +\n \"The figure above is the chain's; the curve below may be off.\"\n }\n tone=\"error\"\n />\n ) : null}\n </>\n );\n}\n\nfunction describePhase(schedule: LaunchSchedule): string {\n switch (schedule.phase) {\n case \"unclaimed\":\n return \"No launch configured\";\n case \"disabled\":\n return \"Guard disabled — LP fee pinned, no launch gate\";\n case \"pending\":\n return \"Not open yet\";\n case \"decaying\":\n // The guard's LP fee, not the creator tax (a separate, optional buy/sell rate): never call this a tax.\n return \"Open — LP fee decaying to its floor\";\n case \"settled\":\n return \"Open — fee settled\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * The per-transaction cap, said the way the contract means it.\n *\n * This block is not decoration. `maxBuyPerTx` is the field most likely to be\n * mistaken for an allocation, and the hook is explicit that it is not one:\n * \"Splitting a buy across N wallets or N transactions in the same block is NOT\n * prevented and cannot be.\"\n */\nexport function MaxBuyNotice(props: {\n readonly launch: LaunchInfo;\n readonly schedule: LaunchSchedule;\n}): JSX.Element | null {\n const { launch, schedule } = props;\n if (schedule.maxBuyPerTx === null) {\n return (\n <SummaryList>\n <SummaryRow label=\"Per-transaction cap\" value=\"None configured\" />\n </SummaryList>\n );\n }\n const amount = `${formatAmount(schedule.maxBuyPerTx, launch.quoteToken.decimals)} ${launch.quoteToken.symbol}`;\n return (\n <>\n <SummaryList>\n <SummaryRow\n label=\"Per-transaction cap\"\n value={schedule.maxBuyPerTxEnforced ? amount : `${amount} (not enforced right now)`}\n title=\"Checked by the hook on each individual swap.\"\n />\n </SummaryList>\n <p className=\"latch-subtitle\">\n This caps one transaction. It is <strong>not</strong> a per-wallet cap and cannot be made\n into one: the hook only ever sees the router as the caller, so it cannot tell two buyers\n apart. Splitting a buy across several transactions or several wallets defeats it, and the\n cap stops applying once the decay window ends.\n </p>\n </>\n );\n}\n\n/**\n * The fee decay, plotted by evaluating the hook's own function.\n *\n * Each sample is {@link ../callpath/launch.js | launchFeeAt}, an exact\n * mirror of `LaunchGuardHook.feeAt` including its integer flooring — so this is\n * the schedule, not an impression of it. No axis implies a price and no point\n * is a prediction: every value is what the contract will charge in that block.\n */\nexport function FeeDecayChart(props: {\n readonly guard: LaunchGuard;\n readonly schedule: LaunchSchedule;\n}): JSX.Element | null {\n const { guard, schedule } = props;\n const width = 320;\n const height = 72;\n const samples = 48;\n\n const points = useMemo(() => {\n if (guard.window <= 0) return [];\n const values: number[] = [];\n for (let i = 0; i <= samples; i += 1) {\n const at = guard.start + (BigInt(guard.window) * BigInt(i)) / BigInt(samples);\n values.push(launchFeeAt(guard, at) ?? guard.finalFeePips);\n }\n return values;\n }, [guard]);\n\n if (points.length === 0 || schedule.phase === \"unclaimed\" || schedule.phase === \"disabled\") {\n return null;\n }\n\n const min = Math.min(...points);\n const max = Math.max(...points);\n const span = max - min || 1;\n\n const path = points\n .map((value, index) => {\n const x = (index / samples) * width;\n const y = height - ((value - min) / span) * (height - 8) - 4;\n return `${index === 0 ? \"M\" : \"L\"}${x.toFixed(1)},${y.toFixed(1)}`;\n })\n .join(\" \");\n\n const progressBps = schedule.decayProgressBps ?? 0;\n const markerX = (Math.max(0, Math.min(10_000, progressBps)) / 10_000) * width;\n const caption =\n `${formatPercentFromPips(guard.initialFeePips)} at the open, ` +\n `${formatPercentFromPips(guard.finalFeePips)} after ${clockSpan(guard.durationClock, guard.window)}`;\n\n return (\n <figure style={{ margin: 0 }}>\n <svg\n className=\"latch-curve\"\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label={`Launch fee decay: ${caption}. Currently ${(progressBps / 100).toFixed(0)} percent through the window.`}\n >\n <path d={path} fill=\"none\" stroke=\"var(--latch-accent)\" strokeWidth={2} />\n <line\n x1={markerX}\n y1={0}\n x2={markerX}\n y2={height}\n stroke=\"var(--latch-border-strong)\"\n strokeWidth={1}\n strokeDasharray=\"3 3\"\n />\n </svg>\n <figcaption className=\"latch-subtitle\">{caption}</figcaption>\n </figure>\n );\n}\n\n/** Re-exported so hosts can type a launch prop without reaching into adapters. */\nexport type { LaunchInfo };\n\n/** Props for {@link LaunchV2Widget}. */\nexport interface LaunchV2WidgetProps {\n /**\n * The launch TOKEN, as `LaunchpadKitV2` minted it. The kit's `legsOf(token)`\n * names every pool the launch opened, so one address finds them all; each\n * is then read from its own guard (CL or Bin) and rendered as its own buy\n * surface, because each pool has its own quote, fee and gate.\n */\n readonly token: Address;\n readonly title?: string;\n readonly onPurchaseConfirmed?: (hash: string) => void;\n /** Passed to every leg's {@link LaunchWidget}; see {@link LaunchWidgetProps.onConnectRequest}. */\n readonly onConnectRequest?: () => void;\n}\n\n/**\n * A locked launch (`LaunchpadKitV2`), looked up by its token.\n *\n * One `LaunchWidget` per leg. Nothing is aggregated across legs on purpose:\n * a CL leg and a Bin leg against the same quote are two pools with two\n * prices, two fee schedules and two per-transaction caps, and a single number\n * for \"the\" price would be an average of things that are not fungible.\n */\nexport function LaunchV2Widget(props: LaunchV2WidgetProps): JSX.Element {\n const { chain } = useWidgetContext();\n const legs = useLaunchesForToken(props.token);\n const state = resolveLaunchDataState(legs);\n const subtitle = `Latch Protocol · ${chain.name}`;\n\n if (state !== \"ready\" || legs.data === null || legs.data.length === 0) {\n return (\n <WidgetShell title={props.title ?? \"Launch\"} subtitle={subtitle}>\n {state === \"ready\" || state === \"empty\" ? (\n <p className=\"latch-empty\">\n The kit lists no pools for <code>{shortAddress(props.token)}</code>. Either it was not\n launched through this kit, or the token address is wrong.\n </p>\n ) : (\n <LaunchUnavailable state={state} chainName={chain.name} error={legs.error} />\n )}\n </WidgetShell>\n );\n }\n\n const symbol = legs.data[0]?.launchToken.symbol ?? shortAddress(props.token);\n return (\n <div className=\"latch-launch-legs\">\n {legs.data.map((leg, index) => (\n <LaunchWidget\n key={leg.poolId}\n poolId={leg.poolId}\n title={`${props.title ?? `${symbol} launch`} · ${leg.pool.poolType === \"CL\" ? \"concentrated\" : \"bin\"} pool vs ${leg.quoteToken.symbol}${legs.data === null || legs.data.length === 1 ? \"\" : ` (${index + 1} of ${legs.data.length})`}`}\n {...(props.onPurchaseConfirmed ? { onPurchaseConfirmed: props.onPurchaseConfirmed } : {})}\n {...(props.onConnectRequest ? { onConnectRequest: props.onConnectRequest } : {})}\n />\n ))}\n </div>\n );\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Drop-in liquidity widget, covering both pool types.\n *\n * The add/remove split is a tab; the CL/BIN split is not. The pool determines\n * which range editor renders, and the rest of the component - amounts, quote,\n * approvals, execution - is identical either way. That is the point of routing\n * both pool types through one `LiquidityRange` union.\n */\n\nimport { useCallback, useEffect, useMemo, useState, type FormEvent } from \"react\";\nimport type { LiquidityRange, PoolInfo, PositionInfo } from \"../adapters/protocol.js\";\nimport { useWidgetContext } from \"../context/WidgetProvider.js\";\nimport { formatUnits } from \"viem\";\nimport { formatAmount, formatPercentFromPips, parseAmount } from \"../core/format.js\";\nimport { clRangeSide, pairedAmountForRange, type ClRangeSide } from \"../core/clMath.js\";\nimport {\n adjustRange,\n defaultRangeFor,\n describeRange,\n useAddLiquidityExecute,\n useAddLiquidityQuote,\n usePositions,\n useRemoveLiquidity,\n} from \"../hooks/useLiquidity.js\";\nimport { useAccount, usePoolState, usePools } from \"../hooks/useTokens.js\";\nimport { binStepOf, tickSpacingOf } from \"../core/pool.js\";\nimport { bumpOnConfirmed, reconcileSelection, withdrawablePositions } from \"../core/liquidityRefresh.js\";\nimport { isDynamicLPFee } from \"@latchprotocol/sdk\";\nimport {\n ActionButton,\n AmountField,\n ErrorPanel,\n SegmentedControl,\n StatusRegion,\n SummaryList,\n SummaryRow,\n WidgetShell,\n} from \"./primitives.js\";\n\n/** Props for {@link LiquidityWidget}. */\nexport interface LiquidityWidgetProps {\n /** Pre-selects a pool by id. */\n readonly defaultPoolId?: string;\n readonly title?: string;\n /** Which tab opens first. */\n readonly defaultMode?: LiquidityMode;\n /**\n * Makes the \"Connect wallet\" call to action a working button that opens\n * the host's connect flow. Absent (and absent on the provider too), the CTA\n * is a disabled label and the visitor connects through the host's control.\n */\n readonly onConnectRequest?: () => void;\n /**\n * Called with the hash once an add or a removal CONFIRMS (a status-1\n * receipt), so the host can re-read what it shows beside the widget - the\n * wallet's positions, the pool's depth.\n */\n readonly onLiquidityChanged?: (hash: `0x${string}`) => void;\n}\n\n/** Add or remove. */\nexport type LiquidityMode = \"add\" | \"remove\";\n\n/** The styled liquidity widget. */\nexport function LiquidityWidget(props: LiquidityWidgetProps): JSX.Element {\n const { chain, onConnectRequest: providerConnect } = useWidgetContext();\n const onConnectRequest = props.onConnectRequest ?? providerConnect;\n const pools = usePools();\n const accountResource = useAccount();\n const [mode, setMode] = useState<LiquidityMode>(props.defaultMode ?? \"add\");\n const [pool, setPool] = useState<PoolInfo | null>(null);\n /* Confirmed adds and removals, counted. The positions list, the pool state\n and the balances depend on it, so a confirmation re-reads them. */\n const [refreshKey, setRefreshKey] = useState(0);\n const hostChanged = props.onLiquidityChanged;\n const onChanged = useMemo(\n () => bumpOnConfirmed<`0x${string}`>(() => setRefreshKey((k) => k + 1), hostChanged),\n [hostChanged],\n );\n\n useEffect(() => {\n const list = pools.data ?? [];\n if (list.length === 0) return;\n setPool((current) => {\n if (current !== null) return current;\n const preferred = props.defaultPoolId\n ? list.find((candidate) => candidate.id === props.defaultPoolId)\n : undefined;\n return preferred ?? list[0] ?? null;\n });\n }, [pools.data, props.defaultPoolId]);\n\n return (\n <WidgetShell\n title={props.title ?? \"Liquidity\"}\n subtitle={`Latch Protocol · ${chain.name}`}\n >\n <SegmentedControl<LiquidityMode>\n label=\"Liquidity action\"\n value={mode}\n options={[\n { value: \"add\", label: \"Add\" },\n { value: \"remove\", label: \"Remove\" },\n ]}\n onChange={setMode}\n />\n\n <PoolSelect pools={pools.data ?? []} value={pool} onChange={setPool} />\n\n {pool === null ? (\n <StatusRegion message=\"No pools are configured for this deployment.\" />\n ) : mode === \"add\" ? (\n <AddLiquidityPanel pool={pool} account={accountResource.data} refreshKey={refreshKey} onChanged={onChanged} {...(onConnectRequest === undefined ? {} : { onConnectRequest })} />\n ) : (\n <RemoveLiquidityPanel pool={pool} account={accountResource.data} refreshKey={refreshKey} onChanged={onChanged} {...(onConnectRequest === undefined ? {} : { onConnectRequest })} />\n )}\n </WidgetShell>\n );\n}\n\nfunction PoolSelect(props: {\n readonly pools: readonly PoolInfo[];\n readonly value: PoolInfo | null;\n readonly onChange: (pool: PoolInfo) => void;\n}): JSX.Element {\n return (\n <div className=\"latch-field\">\n <label className=\"latch-label\" htmlFor=\"latch-pool-select\">\n Pool\n </label>\n <select\n id=\"latch-pool-select\"\n className=\"latch-select\"\n style={{ width: \"100%\", borderRadius: \"var(--latch-radius-sm)\" }}\n value={props.value?.id ?? \"\"}\n onChange={(event) => {\n const next = props.pools.find((pool) => pool.id === event.target.value);\n if (next !== undefined) props.onChange(next);\n }}\n >\n {props.pools.length === 0 ? <option value=\"\">No pools available</option> : null}\n {props.pools.map((pool) => (\n <option key={pool.id} value={pool.id}>\n {pool.token0.symbol}/{pool.token1.symbol} · {pool.poolType} ·{\" \"}\n {/* The dynamic-fee flag is not a rate: a hook sets the fee per swap. */}\n {isDynamicLPFee(pool.lpFeePips) ? \"dynamic fee\" : formatPercentFromPips(pool.lpFeePips)}\n </option>\n ))}\n </select>\n </div>\n );\n}\n\nfunction AddLiquidityPanel(props: {\n readonly pool: PoolInfo;\n readonly account: `0x${string}` | null;\n readonly refreshKey: number;\n readonly onConnectRequest?: () => void;\n readonly onChanged: (hash: `0x${string}`) => void;\n}): JSX.Element {\n const { pool, refreshKey } = props;\n const poolState = usePoolState(pool);\n /* A confirmed deposit (here or in the Remove tab) changed the pool's\n liquidity: re-read its state. The first render is the initial read. */\n const refetchPoolState = poolState.refetch;\n useEffect(() => {\n if (refreshKey > 0) refetchPoolState();\n }, [refreshKey, refetchPoolState]);\n const [range, setRange] = useState<LiquidityRange | null>(null);\n /* The amount the user typed, and on which side. For a CL range the other\n side is DERIVED from it at the pool's price (a position takes both tokens\n in the ratio the price and the range fix, so a free second field would\n only ever mint the smaller of the two); for a bin range both are free. */\n const [edited, setEdited] = useState<{ readonly side: 0 | 1; readonly text: string }>({ side: 0, text: \"\" });\n const [freeText, setFreeText] = useState<{ readonly t0: string; readonly t1: string }>({ t0: \"\", t1: \"\" });\n\n // Reset the range whenever the pool changes, then seed it from live state.\n useEffect(() => {\n setRange(null);\n }, [pool.id]);\n\n useEffect(() => {\n if (range !== null) return;\n const state = poolState.data;\n const seeded = defaultRangeFor(\n pool,\n state?.currentTick ?? null,\n state?.activeId ?? null,\n );\n if (seeded !== null) setRange(seeded);\n }, [pool, poolState.data, range]);\n\n useEffect(() => {\n setEdited({ side: 0, text: \"\" });\n setFreeText({ t0: \"\", t1: \"\" });\n }, [pool.id]);\n\n const sqrtPriceX96 = poolState.data?.sqrtPriceX96 ?? null;\n const clRange = range !== null && range.type === \"CL\" && sqrtPriceX96 !== null ? range : null;\n const side: ClRangeSide | null = clRange === null || sqrtPriceX96 === null ? null : clRangeSide(sqrtPriceX96, clRange.tickLower, clRange.tickUpper);\n\n /* The texts the two fields show. CL: the typed side verbatim, the other\n derived (or pinned to zero when the range cannot take it). Bin: both free. */\n const { amount0Text, amount1Text } = useMemo(() => {\n if (clRange === null || sqrtPriceX96 === null || side === null) return { amount0Text: freeText.t0, amount1Text: freeText.t1 };\n const decimalsIn = edited.side === 0 ? pool.token0.decimals : pool.token1.decimals;\n const decimalsOther = edited.side === 0 ? pool.token1.decimals : pool.token0.decimals;\n const typed = edited.text;\n let other = \"\";\n if (side === \"both\") {\n const parsed = typed.trim() === \"\" ? null : parseAmount(typed, decimalsIn);\n if (parsed !== null && parsed.ok) {\n const paired = pairedAmountForRange(sqrtPriceX96, clRange.tickLower, clRange.tickUpper, edited.side === 0 ? \"token0\" : \"token1\", parsed.value);\n other = paired === null ? \"\" : formatUnits(paired, decimalsOther);\n }\n }\n /* Out of range, only one side can hold anything; the typed text moves to it\n if it was typed on the side the range cannot take. */\n if (side === \"token0-only\") return { amount0Text: edited.side === 0 ? typed : \"\", amount1Text: \"0\" };\n if (side === \"token1-only\") return { amount0Text: \"0\", amount1Text: edited.side === 1 ? typed : \"\" };\n return edited.side === 0 ? { amount0Text: typed, amount1Text: other } : { amount0Text: other, amount1Text: typed };\n }, [clRange, sqrtPriceX96, side, edited, freeText, pool.token0.decimals, pool.token1.decimals]);\n\n const setAmount0Text = useCallback((text: string) => {\n setEdited({ side: 0, text });\n setFreeText((current) => ({ ...current, t0: text }));\n }, []);\n const setAmount1Text = useCallback((text: string) => {\n setEdited({ side: 1, text });\n setFreeText((current) => ({ ...current, t1: text }));\n }, []);\n\n const parsed0 = amount0Text.trim() === \"\" ? null : parseAmount(amount0Text, pool.token0.decimals);\n const parsed1 = amount1Text.trim() === \"\" ? null : parseAmount(amount1Text, pool.token1.decimals);\n const amount0 = parsed0 !== null && parsed0.ok ? parsed0.value : null;\n const amount1 = parsed1 !== null && parsed1.ok ? parsed1.value : null;\n const rangeNote =\n side === \"token0-only\"\n ? `This range sits above the current price, so it holds only ${pool.token0.symbol}.`\n : side === \"token1-only\"\n ? `This range sits below the current price, so it holds only ${pool.token1.symbol}.`\n : side === \"both\"\n ? \"In range: enter either amount and the other is filled at the pool's current price.\"\n : null;\n\n const quote = useAddLiquidityQuote({\n pool,\n range,\n amount0Desired: amount0,\n amount1Desired: amount1,\n });\n\n const execution = useAddLiquidityExecute({ quote: quote.data ?? null, onSuccess: props.onChanged });\n const insufficient = execution.insufficient;\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (execution.insufficient !== null) return;\n if (execution.needsApproval) {\n void execution.approve();\n return;\n }\n void execution.execute();\n },\n [execution],\n );\n\n /* The balance check comes before the approval: never ask for an allowance on\n a deposit the wallet cannot pay (core/liquidityGuards). */\n const buttonLabel =\n props.account === null\n ? \"Connect wallet\"\n : insufficient !== null\n ? `Insufficient ${insufficient.symbol}`\n : execution.needsApproval\n ? `Approve ${execution.approvals[0]?.token.symbol ?? \"\"}`\n : \"Add liquidity\";\n\n const busy =\n execution.step === \"approving\" ||\n execution.step === \"building\" ||\n execution.step === \"awaiting-signature\" ||\n execution.step === \"pending\";\n\n return (\n <form onSubmit={handleSubmit} noValidate>\n {range === null ? (\n <StatusRegion message=\"Waiting for pool state to seed a default range.\" />\n ) : (\n <RangeEditor\n pool={pool}\n range={range}\n onChange={setRange}\n currentTick={poolState.data?.currentTick ?? null}\n activeId={poolState.data?.activeId ?? null}\n />\n )}\n\n {rangeNote !== null ? <p className=\"latch-panel__note\">{rangeNote}</p> : null}\n <AmountField\n label={`Deposit ${pool.token0.symbol}`}\n value={amount0Text}\n onValueChange={setAmount0Text}\n readOnly={side === \"token1-only\"}\n token={pool.token0}\n tokens={[pool.token0]}\n error={parsed0 !== null && !parsed0.ok ? parsed0.message : null}\n />\n <AmountField\n label={`Deposit ${pool.token1.symbol}`}\n value={amount1Text}\n onValueChange={setAmount1Text}\n readOnly={side === \"token0-only\"}\n token={pool.token1}\n tokens={[pool.token1]}\n error={parsed1 !== null && !parsed1.ok ? parsed1.message : null}\n />\n\n {quote.data !== null && quote.data !== undefined ? (\n <SummaryList>\n <SummaryRow\n label={`${pool.token0.symbol} deposited`}\n value={formatAmount(quote.data.amount0, pool.token0.decimals)}\n />\n <SummaryRow\n label={`${pool.token1.symbol} deposited`}\n value={formatAmount(quote.data.amount1, pool.token1.decimals)}\n />\n <SummaryRow label=\"Liquidity\" value={quote.data.liquidity.toString()} />\n <SummaryRow label=\"Range\" value={describeRange(quote.data.range)} />\n {quote.data.binDistribution !== undefined ? (\n <SummaryRow\n label=\"Bins used\"\n value={`${quote.data.binDistribution.length}`}\n />\n ) : null}\n </SummaryList>\n ) : null}\n\n <StatusRegion\n message={execution.statusMessage}\n tone={execution.step === \"error\" ? \"error\" : execution.step === \"success\" ? \"success\" : \"neutral\"}\n />\n\n <ActionButton\n type=\"submit\"\n disabled={quote.data === null || quote.data === undefined || busy || insufficient !== null}\n busy={busy}\n needsConnect={props.account === null}\n {...(props.onConnectRequest === undefined ? {} : { onConnectRequest: props.onConnectRequest })}\n >\n {buttonLabel}\n </ActionButton>\n\n <ErrorPanel error={execution.error !== null ? null : quote.error} context=\"liquidity\" />\n </form>\n );\n}\n\n/**\n * The one place the pool types genuinely diverge in the UI.\n *\n * Concentrated liquidity gets a tick pair snapped to the pool's tick spacing;\n * the liquidity book gets a bin span around the active id. Both emit the same\n * `LiquidityRange` union, so nothing downstream branches again.\n */\nfunction RangeEditor(props: {\n readonly pool: PoolInfo;\n readonly range: LiquidityRange;\n readonly onChange: (range: LiquidityRange) => void;\n readonly currentTick: number | null;\n readonly activeId: number | null;\n}): JSX.Element {\n const { pool, range } = props;\n\n if (range.type === \"CL\") {\n return (\n <fieldset className=\"latch-field\" style={{ margin: 0 }}>\n <legend className=\"latch-label\" style={{ padding: \"0 4px\" }}>\n Price range (ticks, spacing {tickSpacingOf(pool)})\n </legend>\n <div className=\"latch-range-grid\">\n <label className=\"latch-visually-hidden\" htmlFor=\"latch-tick-lower\">\n Lower tick\n </label>\n <input\n id=\"latch-tick-lower\"\n type=\"number\"\n step={tickSpacingOf(pool)}\n value={range.tickLower}\n onChange={(event) =>\n props.onChange({\n type: \"CL\",\n tickLower: Number(event.target.value),\n tickUpper: range.tickUpper,\n })\n }\n />\n <label className=\"latch-visually-hidden\" htmlFor=\"latch-tick-upper\">\n Upper tick\n </label>\n <input\n id=\"latch-tick-upper\"\n type=\"number\"\n step={tickSpacingOf(pool)}\n value={range.tickUpper}\n onChange={(event) =>\n props.onChange({\n type: \"CL\",\n tickLower: range.tickLower,\n tickUpper: Number(event.target.value),\n })\n }\n />\n </div>\n <div className=\"latch-meta\">\n <span>\n {props.currentTick === null\n ? \"Current tick unknown\"\n : `Current tick ${props.currentTick}`}\n </span>\n <span>\n <button\n type=\"button\"\n className=\"latch-chip\"\n onClick={() => props.onChange(adjustRange(range, pool, 5))}\n >\n Widen\n </button>{\" \"}\n <button\n type=\"button\"\n className=\"latch-chip\"\n onClick={() => props.onChange(adjustRange(range, pool, -5))}\n >\n Narrow\n </button>\n </span>\n </div>\n </fieldset>\n );\n }\n\n const binCount = range.binIdUpper - range.binIdLower + 1;\n return (\n <fieldset className=\"latch-field\" style={{ margin: 0 }}>\n <legend className=\"latch-label\" style={{ padding: \"0 4px\" }}>\n Bin range (step {binStepOf(pool)})\n </legend>\n <label className=\"latch-label\" htmlFor=\"latch-bin-width\">\n Bins each side of active: {Math.floor((binCount - 1) / 2)}\n </label>\n <input\n id=\"latch-bin-width\"\n className=\"latch-slider\"\n type=\"range\"\n min={0}\n max={30}\n value={Math.floor((binCount - 1) / 2)}\n onChange={(event) => {\n const half = Number(event.target.value);\n props.onChange({\n type: \"BIN\",\n activeIdDesired: range.activeIdDesired,\n binIdLower: range.activeIdDesired - half,\n binIdUpper: range.activeIdDesired + half,\n idSlippage: range.idSlippage,\n });\n }}\n />\n <div className=\"latch-meta\">\n <span>{describeRange(range)}</span>\n <span>\n {props.activeId === null ? \"Active bin unknown\" : `Active bin ${props.activeId}`}\n </span>\n </div>\n </fieldset>\n );\n}\n\nfunction RemoveLiquidityPanel(props: {\n readonly pool: PoolInfo;\n readonly account: `0x${string}` | null;\n readonly refreshKey: number;\n readonly onConnectRequest?: () => void;\n readonly onChanged: (hash: `0x${string}`) => void;\n}): JSX.Element {\n /* Re-read on every confirmed add or removal (refreshKey), and offer only\n positions with something to withdraw: one removed to zero disappears. */\n const positions = usePositions(props.account, props.pool, props.refreshKey);\n const [selected, setSelected] = useState<PositionInfo | null>(null);\n const [percentBps, setPercentBps] = useState(5_000);\n\n const list = useMemo(() => withdrawablePositions(positions.data ?? []), [positions.data]);\n\n useEffect(() => {\n setSelected((current) => reconcileSelection(current, list));\n }, [list]);\n\n const removal = useRemoveLiquidity({ position: selected, percentBps, onSuccess: props.onChanged });\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n void removal.execute();\n },\n [removal],\n );\n\n if (props.account === null) {\n return (\n <>\n <StatusRegion message=\"Connect a wallet to see your positions.\" />\n <ActionButton needsConnect {...(props.onConnectRequest === undefined ? {} : { onConnectRequest: props.onConnectRequest })}>\n Connect wallet\n </ActionButton>\n </>\n );\n }\n\n if (list.length === 0) {\n return (\n <StatusRegion\n message={\n positions.status === \"loading\"\n ? \"Loading your positions\"\n : positions.status === \"error\"\n ? (positions.error?.message ?? \"Could not load positions\")\n : \"You have no positions in this pool.\"\n }\n tone={positions.status === \"error\" ? \"error\" : \"neutral\"}\n />\n );\n }\n\n return (\n <form onSubmit={handleSubmit} noValidate>\n <div className=\"latch-field\">\n <label className=\"latch-label\" htmlFor=\"latch-position-select\">\n Position\n </label>\n <select\n id=\"latch-position-select\"\n className=\"latch-select\"\n style={{ width: \"100%\", borderRadius: \"var(--latch-radius-sm)\" }}\n value={selected?.id ?? \"\"}\n onChange={(event) => {\n const next = list.find((position) => position.id === event.target.value);\n setSelected(next ?? null);\n }}\n >\n {list.map((position) => (\n <option key={position.id} value={position.id}>\n {describeRange(position.range)}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"latch-field\">\n <label className=\"latch-label\" htmlFor=\"latch-remove-percent\">\n Amount to withdraw: {(percentBps / 100).toFixed(0)}%\n </label>\n <input\n id=\"latch-remove-percent\"\n className=\"latch-slider\"\n type=\"range\"\n min={1}\n max={100}\n value={Math.round(percentBps / 100)}\n onChange={(event) => setPercentBps(Number(event.target.value) * 100)}\n />\n </div>\n\n {removal.quote !== null ? (\n <SummaryList>\n <SummaryRow\n label={`${props.pool.token0.symbol} returned`}\n value={formatAmount(removal.quote.amount0, props.pool.token0.decimals)}\n />\n <SummaryRow\n label={`${props.pool.token1.symbol} returned`}\n value={formatAmount(removal.quote.amount1, props.pool.token1.decimals)}\n />\n </SummaryList>\n ) : null}\n\n <StatusRegion\n message={removal.statusMessage}\n tone={removal.step === \"error\" ? \"error\" : removal.step === \"success\" ? \"success\" : \"neutral\"}\n />\n\n <ActionButton\n type=\"submit\"\n disabled={selected === null || removal.quote === null}\n busy={removal.step === \"pending\" || removal.step === \"awaiting-signature\"}\n >\n Remove liquidity\n </ActionButton>\n\n <ErrorPanel error={removal.error} />\n </form>\n );\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Swap settings in a Radix Popover: slippage tolerance (auto, presets, custom)\n * and the high-impact acknowledgement. Nothing here is hidden from the\n * summary: the chosen tolerance is always printed in the details.\n */\n\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { useState } from \"react\";\nimport { formatPercentFromBps } from \"../../core/format.js\";\nimport { MAX_SLIPPAGE_BPS } from \"../../core/math.js\";\nimport { usePortalContainer } from \"../portal.js\";\n\nconst PRESETS = [10, 50, 100] as const;\n\nexport interface SwapSettingsProps {\n readonly slippageBps: number;\n readonly defaultSlippageBps: number;\n readonly onSlippageChange: (bps: number) => void;\n}\n\nexport function SwapSettings(props: SwapSettingsProps): JSX.Element {\n const container = usePortalContainer();\n const [custom, setCustom] = useState(\"\");\n const isAuto = props.slippageBps === props.defaultSlippageBps && custom === \"\";\n\n const applyCustom = (text: string): void => {\n setCustom(text);\n const pct = Number.parseFloat(text);\n if (!Number.isFinite(pct) || pct < 0) return;\n const bps = Math.round(pct * 100);\n if (bps > MAX_SLIPPAGE_BPS) return;\n props.onSlippageChange(bps);\n };\n const high = props.slippageBps > 100;\n const low = props.slippageBps < 5;\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button type=\"button\" className=\"latch-icon-button latch-settings-trigger\" aria-label=\"Swap settings\">\n <span aria-hidden=\"true\">⚙</span>\n <span className=\"latch-settings-trigger__value\">{formatPercentFromBps(props.slippageBps)}</span>\n </button>\n </Popover.Trigger>\n <Popover.Portal container={container}>\n <Popover.Content className=\"latch-popover\" align=\"end\" sideOffset={8}>\n <div className=\"latch-popover__row\">\n <span className=\"latch-label\">Max slippage</span>\n <span className=\"latch-popover__value\">{isAuto ? \"Auto\" : \"Custom\"}</span>\n </div>\n <div className=\"latch-field-row\">\n <button\n type=\"button\"\n className=\"latch-chip\"\n aria-pressed={isAuto}\n onClick={() => {\n setCustom(\"\");\n props.onSlippageChange(props.defaultSlippageBps);\n }}\n >\n Auto\n </button>\n {PRESETS.map((p) => (\n <button\n key={p}\n type=\"button\"\n className=\"latch-chip\"\n aria-pressed={!isAuto && custom === \"\" && props.slippageBps === p}\n onClick={() => {\n setCustom(\"\");\n props.onSlippageChange(p);\n }}\n >\n {formatPercentFromBps(p)}\n </button>\n ))}\n <label className=\"latch-custom-slippage\">\n <input type=\"text\" inputMode=\"decimal\" placeholder=\"0.50\" aria-label=\"Custom slippage, percent\" value={custom} onChange={(e) => applyCustom(e.target.value)} />\n <span>%</span>\n </label>\n </div>\n {high ? <p className=\"latch-note latch-note--warn\">Above 1%: a transaction may be front-run for the difference.</p> : null}\n {low ? <p className=\"latch-note latch-note--warn\">Below 0.05%: the transaction is likely to revert on a moving price.</p> : null}\n <p className=\"latch-note\">\n The transaction reverts if the received amount falls below the minimum shown in the details. Auto is {formatPercentFromBps(props.defaultSlippageBps)}.\n </p>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","// SPDX-License-Identifier: MIT\n/**\n * The token selector: a Radix Dialog with search, common tokens, balances for\n * the connected account and paste-an-address lookup through the adapter.\n *\n * Tokens carry their provenance. An entry that came from a token list\n * (`SwapWidget`'s `tokenLists`) is grouped under that list's name and says\n * which other lists also carry it; the adapter's own tokens - the tokens of the\n * pools this site routes through - come first, ungrouped. A tokenised stock\n * (`extensions.stock`) gets an issuer badge, and a REBASING one a warning,\n * because the issuer's control over the token is the thing a trader has to\n * know before choosing it. A pasted address that is in no list is looked up on\n * chain and labelled as unlisted; it is never silently promoted.\n *\n * Portals render INTO the widget root (see `PortalContainer`) rather than\n * `document.body`, so the same component works inside the shadow-root web\n * component, where body-level portals would render unstyled.\n */\n\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { Address } from \"viem\";\nimport type { TokenInfo } from \"../../adapters/protocol.js\";\nimport { useWidgetContext } from \"../../context/WidgetProvider.js\";\nimport { formatAmount, shortAddress } from \"../../core/format.js\";\nimport { groupBySource, resolveLogoUrl } from \"../../core/tokenLists.js\";\nimport { useAccount } from \"../../hooks/useTokens.js\";\nimport { usePortalContainer } from \"../portal.js\";\n\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n\n/**\n * A token's logo, or a monogram of its symbol. `https://` loads directly;\n * `ipfs://` resolves through the SDK's first allow-listed gateway; a URL that\n * fails to load falls back to the monogram rather than a broken image.\n */\nexport function TokenLogo(props: { readonly token: TokenInfo | null; readonly size?: number }): JSX.Element {\n const size = props.size ?? 24;\n const t = props.token;\n const src = resolveLogoUrl(t?.logoUrl);\n const [failed, setFailed] = useState<string | null>(null);\n if (src !== null && failed !== src) {\n return <img className=\"latch-token-logo\" src={src} alt=\"\" width={size} height={size} referrerPolicy=\"no-referrer\" onError={() => setFailed(src)} />;\n }\n const label = (t?.symbol ?? \"?\").slice(0, 4).toUpperCase();\n return (\n <span\n className=\"latch-token-logo latch-token-logo--initials\"\n style={{ width: size, height: size, fontSize: Math.round(size * (label.length > 3 ? 0.3 : 0.38)), [\"--latch-mono-hue\" as string]: String(hueOf(t?.address ?? label)) }}\n aria-hidden=\"true\"\n >\n {label}\n </span>\n );\n}\n\n/** A stable hue per token (0-359), so a token without a logo is still recognisable at a glance. */\nexport function hueOf(key: string): number {\n let h = 2166136261;\n const k = key.toLowerCase();\n for (let i = 0; i < k.length; i++) h = Math.imul(h ^ k.charCodeAt(i), 16777619);\n return (h >>> 0) % 360;\n}\n\nfunction SearchGlyph(): JSX.Element {\n return (\n <svg className=\"latch-search-wrap__icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\n/** The badges a row carries: the issuer of a stock, a rebasing warning, a test-token mark. */\nexport function TokenBadges(props: { readonly token: TokenInfo }): JSX.Element | null {\n const t = props.token;\n const badges: { key: string; label: string; tone: \"info\" | \"warn\" | \"muted\"; title: string }[] = [];\n if (t.stock !== undefined) {\n badges.push({ key: \"stock\", label: `${t.stock.issuer} · ${t.stock.ticker}`, tone: \"info\", title: `Tokenised stock issued by ${t.stock.issuer} (underlying ${t.stock.ticker}). The issuer can pause transfers and upgrade the token.` });\n if (t.stock.rebasing) badges.push({ key: \"rebasing\", label: \"rebasing\", tone: \"warn\", title: \"The issuer rescales balances. Not usable as a Latch pool currency.\" });\n }\n if (t.tags?.includes(\"test\")) badges.push({ key: \"test\", label: \"test token\", tone: \"muted\", title: \"A throwaway token with no economic meaning.\" });\n if (t.tags?.includes(\"launch\")) badges.push({ key: \"launch\", label: \"launch\", tone: \"muted\", title: \"Launched on Latch; its launch pools are locked forever.\" });\n if (badges.length === 0) return null;\n return (\n <span className=\"latch-token-row__badges\">\n {badges.map((b) => (\n <span key={b.key} className=\"latch-badge\" data-latch-tone={b.tone} title={b.title}>\n {b.label}\n </span>\n ))}\n </span>\n );\n}\n\n/**\n * The read-only form of the selector, for a pinned pair (`SwapWidget`'s\n * `lockPair`): the same chip, the token it shows, no chevron and no dialog.\n * A `<span>`, not a disabled button, so it is not announced as a control that\n * happens to be off; the label says the pair is fixed.\n */\nexport function TokenChip(props: { readonly value: TokenInfo | null; readonly label: string }): JSX.Element {\n return (\n <span className=\"latch-token-button latch-token-button--locked\" role=\"img\" aria-label={`${props.label}: ${props.value?.symbol ?? \"loading\"} (fixed)`} title=\"This pair is fixed on this page\">\n <TokenLogo token={props.value} />\n <span className=\"latch-token-button__symbol\">{props.value?.symbol ?? \"…\"}</span>\n </span>\n );\n}\n\nexport interface TokenSelectProps {\n readonly value: TokenInfo | null;\n readonly tokens: readonly TokenInfo[];\n readonly onChange: (token: TokenInfo) => void;\n /** The other side of the pair, greyed out in the list. */\n readonly exclude?: TokenInfo | null;\n readonly label: string;\n /** Lists that were asked for and did not load, shown as a note so an empty group is explained. */\n readonly listFailures?: readonly { readonly url: string; readonly message: string }[];\n /** `true` while lists are still loading. */\n readonly listsLoading?: boolean;\n}\n\n/** The trigger button plus its dialog. */\nexport function TokenSelect(props: TokenSelectProps): JSX.Element {\n const { adapter } = useWidgetContext();\n const container = usePortalContainer();\n const account = useAccount();\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [balances, setBalances] = useState<Record<string, bigint>>({});\n const [pasted, setPasted] = useState<TokenInfo | null | \"loading\" | \"none\">(\"none\");\n\n /* Balances for the list, read once per open per account. Read, never guessed:\n a row without a balance shows nothing there. */\n useEffect(() => {\n if (!open || account.data === null || account.data === undefined) return;\n let cancelled = false;\n const owner = account.data;\n void Promise.all(\n props.tokens.map(async (t) => {\n try {\n return [t.address.toLowerCase(), await adapter.getBalance(t, owner)] as const;\n } catch {\n return null;\n }\n }),\n ).then((rows) => {\n if (cancelled) return;\n const next: Record<string, bigint> = {};\n for (const r of rows) if (r !== null) next[r[0]] = r[1];\n setBalances(next);\n });\n return () => {\n cancelled = true;\n };\n }, [open, account.data, props.tokens, adapter]);\n\n /* A pasted address that is not in the list is looked up on chain through the adapter. */\n useEffect(() => {\n const q = query.trim();\n if (!ADDRESS_RE.test(q)) {\n setPasted(\"none\");\n return;\n }\n if (props.tokens.some((t) => t.address.toLowerCase() === q.toLowerCase())) {\n setPasted(\"none\");\n return;\n }\n let cancelled = false;\n setPasted(\"loading\");\n void adapter\n .getToken(q as Address)\n .then((t) => !cancelled && setPasted(t))\n .catch(() => !cancelled && setPasted(null));\n return () => {\n cancelled = true;\n };\n }, [query, props.tokens, adapter]);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n const list =\n q === \"\"\n ? props.tokens\n : props.tokens.filter(\n (t) =>\n t.symbol.toLowerCase().includes(q) ||\n t.name.toLowerCase().includes(q) ||\n t.address.toLowerCase() === q ||\n (t.stock !== undefined && (t.stock.ticker.toLowerCase().includes(q) || t.stock.issuer.toLowerCase().includes(q))),\n );\n /* Held tokens first, then the list's own order. */\n return [...list].sort((a, b) => {\n const ba = balances[a.address.toLowerCase()] ?? 0n;\n const bb = balances[b.address.toLowerCase()] ?? 0n;\n return ba === bb ? 0 : ba > bb ? -1 : 1;\n });\n }, [props.tokens, query, balances]);\n\n /* Groups only when at least one entry came from a list; a plain adapter list stays flat. */\n const grouped = useMemo(() => (filtered.some((t) => t.listSource !== undefined) ? groupBySource(filtered) : null), [filtered]);\n\n const common = props.tokens.slice(0, 5);\n const pick = (t: TokenInfo): void => {\n props.onChange(t);\n setOpen(false);\n setQuery(\"\");\n };\n\n const row = (t: TokenInfo): JSX.Element => {\n const bal = balances[t.address.toLowerCase()];\n const disabled = props.exclude?.address.toLowerCase() === t.address.toLowerCase();\n const alsoIn = t.listSource?.alsoIn ?? [];\n return (\n <li key={t.address}>\n <button type=\"button\" className=\"latch-token-row\" onClick={() => pick(t)} disabled={disabled} aria-selected={props.value?.address === t.address} role=\"option\">\n <TokenLogo token={t} size={32} />\n <span className=\"latch-token-row__main\">\n <span className=\"latch-token-row__symbol\">\n {t.symbol}\n <TokenBadges token={t} />\n </span>\n <span className=\"latch-token-row__name\">\n {t.name}\n {t.isNative ? \"\" : ` · ${shortAddress(t.address)}`}\n {alsoIn.length > 0 ? ` · also in ${alsoIn.join(\", \")}` : \"\"}\n </span>\n </span>\n {bal !== undefined && bal > 0n ? (\n <span className=\"latch-token-row__balance\">\n <span>{formatAmount(bal, t.decimals)}</span>\n <span className=\"latch-token-row__balance-sym\">{t.symbol}</span>\n </span>\n ) : null}\n {props.value?.address.toLowerCase() === t.address.toLowerCase() ? (\n <span className=\"latch-token-row__check\" aria-hidden=\"true\">\n ✓\n </span>\n ) : null}\n </button>\n </li>\n );\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={setOpen}>\n <Dialog.Trigger asChild>\n <button type=\"button\" className=\"latch-token-button\" aria-label={`${props.label}: ${props.value?.symbol ?? \"choose a token\"}`}>\n <TokenLogo token={props.value} />\n <span className=\"latch-token-button__symbol\">{props.value?.symbol ?? \"Select\"}</span>\n <span className=\"latch-token-button__chevron\" aria-hidden=\"true\">\n ▾\n </span>\n </button>\n </Dialog.Trigger>\n <Dialog.Portal container={container}>\n <Dialog.Overlay className=\"latch-overlay\" />\n <Dialog.Content className=\"latch-dialog\" aria-describedby={undefined}>\n <div className=\"latch-dialog__head\">\n <Dialog.Title className=\"latch-dialog__title\">\n Select a token <span className=\"latch-dialog__count\">{props.tokens.length}</span>\n </Dialog.Title>\n <Dialog.Close className=\"latch-icon-button\" aria-label=\"Close\">\n ×\n </Dialog.Close>\n </div>\n <div className=\"latch-search-wrap\">\n <SearchGlyph />\n <input\n className=\"latch-search\"\n type=\"text\"\n autoFocus\n placeholder=\"Search or paste an address\"\n aria-label=\"Search tokens\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n spellCheck={false}\n autoComplete=\"off\"\n />\n {query !== \"\" ? (\n <button type=\"button\" className=\"latch-search-wrap__clear\" aria-label=\"Clear search\" onClick={() => setQuery(\"\")}>\n ×\n </button>\n ) : null}\n </div>\n {query === \"\" && common.length > 0 ? (\n <div className=\"latch-common\">\n {common.map((t) => (\n <button key={t.address} type=\"button\" className=\"latch-chip latch-chip--token\" onClick={() => pick(t)} aria-pressed={props.value?.address === t.address}>\n <TokenLogo token={t} size={18} /> {t.symbol}\n </button>\n ))}\n </div>\n ) : null}\n <ul className=\"latch-token-list\" role=\"listbox\" aria-label=\"Tokens\">\n {pasted === \"loading\" ? <li className=\"latch-token-row latch-token-row--note\">Loading the token…</li> : null}\n {pasted === null ? <li className=\"latch-token-row latch-token-row--note\">That address does not answer as an ERC-20.</li> : null}\n {pasted !== \"none\" && pasted !== \"loading\" && pasted !== null ? (\n <li>\n <button type=\"button\" className=\"latch-token-row latch-token-row--unlisted\" onClick={() => pick(pasted)}>\n <TokenLogo token={pasted} size={32} />\n <span className=\"latch-token-row__main\">\n <span className=\"latch-token-row__symbol\">\n {pasted.symbol}\n <span className=\"latch-token-row__badges\">\n <span className=\"latch-badge\" data-latch-tone=\"warn\" title=\"Read off the contract at this address. It is in none of this site's lists: check the address yourself before trading.\">\n unlisted\n </span>\n </span>\n </span>\n <span className=\"latch-token-row__name\">\n {pasted.name} · {shortAddress(pasted.address)} · not in any of this site&rsquo;s lists\n </span>\n </span>\n </button>\n </li>\n ) : null}\n {grouped === null\n ? (() => {\n const held = filtered.filter((t) => (balances[t.address.toLowerCase()] ?? 0n) > 0n);\n const rest = filtered.filter((t) => (balances[t.address.toLowerCase()] ?? 0n) === 0n);\n if (held.length === 0) return filtered.map(row);\n return (\n <>\n <li className=\"latch-token-group\">\n <span className=\"latch-token-group__label\" role=\"presentation\">\n Your tokens\n </span>\n <ul className=\"latch-token-group__list\" role=\"group\" aria-label=\"Your tokens\">\n {held.map(row)}\n </ul>\n </li>\n {rest.length > 0 ? (\n <li className=\"latch-token-group\">\n <span className=\"latch-token-group__label\" role=\"presentation\">\n All tokens\n </span>\n <ul className=\"latch-token-group__list\" role=\"group\" aria-label=\"All tokens\">\n {rest.map(row)}\n </ul>\n </li>\n ) : null}\n </>\n );\n })()\n : grouped.map((g) => (\n <li key={g.source ?? \"__adapter\"} className=\"latch-token-group\">\n <span className=\"latch-token-group__label\" role=\"presentation\">\n {g.source ?? \"Pools on this site\"}\n </span>\n <ul className=\"latch-token-group__list\" role=\"group\" aria-label={g.source ?? \"Pools on this site\"}>\n {g.tokens.map(row)}\n </ul>\n </li>\n ))}\n {filtered.length === 0 && pasted === \"none\" ? (\n <li className=\"latch-token-row latch-token-row--note latch-token-row--empty\">\n No token matches &ldquo;{query.trim()}&rdquo;. Paste a contract address to look it up.\n </li>\n ) : null}\n {props.listsLoading === true ? <li className=\"latch-token-row latch-token-row--note\">Loading token lists…</li> : null}\n {(props.listFailures ?? []).map((f) => (\n <li key={f.url} className=\"latch-token-row latch-token-row--note\" title={f.message}>\n A token list did not load: {f.url}\n </li>\n ))}\n </ul>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","// SPDX-License-Identifier: MIT\n/**\n * Drop-in swap widget.\n *\n * Everything below the presentation is the headless layer: `useSwapQuote` and\n * `useSwapExecute` do the work, this file only renders it. An integrator who\n * wants their own look imports those two hooks and deletes this component from\n * their bundle.\n *\n * The presentation is the one people expect from a swap: two large amount\n * panels (You pay / You receive) with a token selector dialog each, a flip button between\n * them, one call-to-action that always says what the next step is (connect,\n * enter an amount, insufficient balance, approve, swap, confirming), and a\n * details disclosure with the rate, price impact, every fee, the guaranteed\n * minimum and the route. Overlays are Radix primitives (MIT) portalled into the\n * widget so they work inside the shadow-root embed.\n *\n * The integrator fee, when configured, is shown as its own line in the details.\n * That is a deliberate product decision, not a legal one: a fee the user can see\n * is a fee that does not become a scandal, and an integrator whose users trust\n * the widget keeps earning from it.\n *\n * There is no dollar figure anywhere. Nothing in the adapter prices a token in\n * USD, and a number that looks priced and is not would be an invented one.\n *\n * A host that frames the widget - a token page with Buy / Sell tabs, a swap\n * page that deep-links a pair - drives it through props rather than remounts:\n * `pair` pins the pair (`lockPair` makes the selectors read-only chips), `side`\n * orients it, `onQuote` reports every quote, `slots` add the host's own chrome,\n * and a `ref` gives an imperative handle for the host's own percent chips. All\n * of it is opt-in; without those props the widget is the one it always was.\n *\n * `variant=\"compact\"` is the token page's trade box: a Buy / Sell pill where\n * the title and the flip button were, one \"You pay\" panel with its quick-amount\n * chips, and every line - you receive, price impact, pool fee, the creator tax\n * when the host passes it, minimum received - always visible, each on its own\n * line, above the call to action. Same quote, same simulation, same button.\n * The state behind them is pure (`swap/state.ts`) and tested without a DOM.\n */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ForwardedRef,\n type FormEvent,\n type ReactNode,\n} from \"react\";\nimport { formatUnits, type Address } from \"viem\";\nimport type { TokenInfo } from \"../adapters/protocol.js\";\nimport { useWidgetContext } from \"../context/WidgetProvider.js\";\nimport { explorerTxUrl } from \"../config/chain.js\";\nimport { formatBps } from \"../config/integrator.js\";\nimport { combineTokens, type TokenListInput } from \"../core/tokenLists.js\";\nimport {\n formatAmount,\n formatPercentFromBps,\n formatPercentFromPips,\n formatRate,\n parseAmount,\n shortAddress,\n} from \"../core/format.js\";\nimport { describeError } from \"../core/errors.js\";\nimport { useSwapExecute } from \"../hooks/useSwapExecute.js\";\nimport { useSwapQuote } from \"../hooks/useSwapQuote.js\";\nimport { useTokenLists } from \"../hooks/useTokenLists.js\";\nimport { useAccount, useTokenBalance, useTokenList } from \"../hooks/useTokens.js\";\nimport { ErrorPanel, StatusRegion, WidgetShell, connectCtaProps } from \"./primitives.js\";\nimport { SwapSettings } from \"./swap/SwapSettings.js\";\nimport {\n buildSwapQuoteView,\n initialSwapState,\n normalizePair,\n normalizePortions,\n oppositeSide,\n orientPair,\n pairKey,\n portionAmountText,\n portionLabel,\n resolvePairEntry,\n routeSymbols,\n swapWidgetReducer,\n type AnchoredPair,\n type SwapPair,\n type SwapQuoteView,\n type SwapSide,\n} from \"./swap/state.js\";\nimport { TokenChip, TokenSelect } from \"./swap/TokenSelect.js\";\n\n\n/** Props for {@link SwapWidget}. */\nexport interface SwapWidgetProps {\n /** Pre-selects the input token by address. */\n readonly defaultTokenIn?: string;\n /** Pre-selects the output token by address. */\n readonly defaultTokenOut?: string;\n readonly title?: string;\n /** Show the slippage control. Defaults to `true`. */\n readonly showSlippageControl?: boolean;\n readonly onSwapConfirmed?: (hash: string) => void;\n /**\n * Token lists (Uniswap Token Lists standard) to offer beside the adapter's\n * own tokens: documents already in hand, or URLs fetched and schema-validated\n * through the SDK. Order is precedence - the first list to name an address\n * wins - and the picker groups entries by list and badges tokenised stocks.\n * The adapter's tokens (the pools this site routes through) always come first.\n */\n readonly tokenLists?: readonly TokenListInput[];\n /**\n * Makes the \"Connect wallet\" call to action a working button that opens\n * the host's connect flow. Absent (and absent on the provider too), the CTA\n * is a disabled label and the visitor connects through the host's control.\n */\n readonly onConnectRequest?: () => void;\n\n /**\n * The pair to trade, pinned: by address (resolved against the token list,\n * then read off the contract when the list lacks it) or as `TokenInfo`s\n * (selected on the first frame). `{ token, quote }` is anchored - `side`\n * says which way it is traded; `{ tokenIn, tokenOut }` is the same pair in\n * its buy orientation. A change of `pair` re-pins without a remount, so the\n * typed amount survives a host switching legs. Without `lockPair` the\n * visitor may still pick other tokens; the pin returns when the prop changes.\n */\n readonly pair?: SwapPair;\n /**\n * With `pair`: the token selectors become read-only chips (the token, no\n * dropdown) and the pair cannot be changed from inside the widget. The flip\n * button stays - it flips the side, not the pair. Defaults to `false`.\n */\n readonly lockPair?: boolean;\n /**\n * The direction, controlled: `buy` pays the quote and receives the token,\n * `sell` the reverse. When set, the widget's flip button only reports through\n * `onSideChange` and the host decides; when absent the widget owns its side\n * and still reports. A side change keeps the typed amount as the amount you\n * pay and re-quotes - it never clears the field.\n */\n readonly side?: SwapSide;\n /** Fired by the flip button and by `flip()`, with the side the widget wants to be on. */\n readonly onSideChange?: (side: SwapSide) => void;\n /**\n * The balance portions offered as chips under the input, as fractions in\n * `(0, 1]`; `1` renders as \"Max\". Defaults to `[0.25, 0.5, 0.75, 1]`; an empty\n * list hides the chips. The chips only show once a balance has been read -\n * without a wallet there is no balance to take a portion of.\n */\n readonly portions?: readonly number[];\n /**\n * Called when a portion is asked for (a chip, or `setPortion` on the handle)\n * and there is no balance to take it from because no wallet is connected.\n * The widget never estimates a balance; the host may open its connect flow\n * here. Absent, the request is a no-op.\n */\n readonly onNeedsWallet?: () => void;\n /**\n * Reports every quote the widget holds - the net output, the guaranteed\n * minimum, the price impact (`null` when the pool's fee is hook-set), the LP\n * fee label and the route - and `null` when there is none (empty amount, no\n * route, unmounted). Fires when the quote changes, including on refresh.\n */\n readonly onQuote?: (quote: SwapQuoteView | null) => void;\n /**\n * The host's own chrome, rendered inside the widget: `header` between the\n * title row and the panels (a leg switcher, a note), `aboveButton` between\n * the panels and the call to action, `footer` after the details and before\n * the brand line. The brand line itself is not a slot.\n */\n readonly slots?: {\n readonly header?: ReactNode;\n readonly aboveButton?: ReactNode;\n readonly footer?: ReactNode;\n };\n /**\n * `\"default\"` (two panels, the flip button, a details disclosure under the\n * button) or `\"compact\"`: a Buy / Sell pill in the header in place of the\n * title and the flip button, one \"You pay\" panel, and the lines always\n * visible above the button. Meant with a pinned `pair`; the pill changes the\n * side exactly as `side` / `onSideChange` do, never the pair.\n */\n readonly variant?: \"default\" | \"compact\";\n /**\n * The pool's creator tax as the host read it from the launch guard: the rate\n * a buy and a sell pay NOW, in bps (pass 0 once the tax has expired - it\n * ends with no transaction). Rendered as its own line for the current side,\n * never folded into the pool fee or the price impact. Absent, there is no\n * line; `null` says the pool takes none.\n */\n readonly creatorTax?: { readonly buyBps: number; readonly sellBps: number } | null;\n}\n\n/**\n * What a `ref` on {@link SwapWidget} gives the host: the amount, the balance\n * portions and the direction, so a page can draw its own percent chips or\n * Buy / Sell tabs and still leave the trade to the widget.\n */\nexport interface SwapWidgetHandle {\n /** Writes the input amount, as the user would type it (`\"1.5\"`). */\n setAmountIn(text: string): void;\n /**\n * Writes a fraction of the input balance (`0.75`, `1` for Max with the\n * native gas sliver kept back). Returns `false` - and calls `onNeedsWallet` -\n * when there is no balance to take it from; nothing is written then.\n */\n setPortion(fraction: number): boolean;\n /** Flips the direction, exactly like the widget's own flip button. */\n flip(): void;\n /** Re-reads the quote now rather than on the next interval. */\n refreshQuote(): void;\n}\n\n/** Price impact above which the user must acknowledge before the button arms. */\nconst IMPACT_ACK_BPS = 1_500;\n\n/**\n * Resolves a `pair` prop to tokens. Entries given as `TokenInfo` are taken as\n * is; addresses are looked up in the list and, when the list lacks one, read\n * off the token contract through the adapter (the same path the selector uses\n * for a pasted address). `null` entries are still loading or unreadable.\n */\nfunction usePinnedPair(pair: SwapPair | undefined, tokens: readonly TokenInfo[]): AnchoredPair<TokenInfo | null> | null {\n const { adapter } = useWidgetContext();\n const key = pairKey(pair);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed on the pair's addresses, not the object\n const anchored = useMemo(() => (pair === undefined ? null : normalizePair(pair)), [key]);\n const [fetched, setFetched] = useState<Record<string, TokenInfo | null>>({});\n /* Each address is asked for once per adapter; a result landing after unmount is dropped. */\n const requested = useRef<{ adapter: unknown; addresses: Set<string> }>({ adapter, addresses: new Set() });\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const fromList = useMemo(() => {\n if (anchored === null) return null;\n return { token: resolvePairEntry(anchored.token, tokens), quote: resolvePairEntry(anchored.quote, tokens) };\n }, [anchored, tokens]);\n\n useEffect(() => {\n if (anchored === null || fromList === null) return;\n if (requested.current.adapter !== adapter) requested.current = { adapter, addresses: new Set() };\n for (const k of [\"token\", \"quote\"] as const) {\n const entry = anchored[k];\n if (fromList[k] !== null || typeof entry !== \"string\") continue;\n const address = entry.toLowerCase();\n if (requested.current.addresses.has(address)) continue;\n requested.current.addresses.add(address);\n void adapter\n .getToken(address as Address)\n .then((token) => mounted.current && setFetched((current) => ({ ...current, [address]: token })))\n .catch(() => mounted.current && setFetched((current) => ({ ...current, [address]: null })));\n }\n }, [adapter, anchored, fromList]);\n\n return useMemo(() => {\n if (anchored === null || fromList === null) return null;\n const pick = (k: \"token\" | \"quote\"): TokenInfo | null => fromList[k] ?? (typeof anchored[k] === \"string\" ? (fetched[(anchored[k] as string).toLowerCase()] ?? null) : null);\n return { token: pick(\"token\"), quote: pick(\"quote\") };\n }, [anchored, fromList, fetched]);\n}\n\n/** The styled swap widget. */\nexport const SwapWidget = forwardRef(function SwapWidget(props: SwapWidgetProps, ref: ForwardedRef<SwapWidgetHandle>): JSX.Element {\n const { integrator, defaultSlippageBps, chain, onConnectRequest: providerConnect } = useWidgetContext();\n const onConnectRequest = props.onConnectRequest ?? providerConnect;\n const tokenList = useTokenList();\n const lists = useTokenLists(props.tokenLists);\n const accountResource = useAccount();\n const tokens = useMemo(() => combineTokens(tokenList.data ?? [], lists.tokens), [tokenList.data, lists.tokens]);\n const portions = normalizePortions(props.portions);\n const locked = props.pair !== undefined && props.lockPair === true;\n const compact = props.variant === \"compact\";\n\n const [state, dispatch] = useReducer(swapWidgetReducer, { ...(props.pair === undefined ? {} : { pair: props.pair }), ...(props.side === undefined ? {} : { side: props.side }) }, initialSwapState);\n /* Controlled when the host gives `side`; the widget's own otherwise. */\n const side: SwapSide = props.side ?? state.side;\n const { tokenIn, tokenOut } = orientPair(state.anchor, side);\n const { amountText, impactAck } = state;\n const [slippageBps, setSlippageBps] = useState(defaultSlippageBps);\n const [detailsOpen, setDetailsOpen] = useState(false);\n const [rateFlipped, setRateFlipped] = useState(false);\n\n // A controlled side change resets the impact acknowledgement like a flip does.\n useEffect(() => {\n if (props.side === undefined) return;\n /* A host that accepted our own flip gets the carried amount; a side the\n host changed on its own keeps the typed amount (documented behaviour). */\n const carry = carryRef.current;\n carryRef.current = null;\n dispatch({ type: \"set-side\", side: props.side, ...(carry !== null && carry.side === props.side ? { amountText: carry.text } : {}) });\n }, [props.side]);\n\n // The pinned pair, once its tokens resolve; re-pins when the prop changes.\n const pinned = usePinnedPair(props.pair, tokens);\n useEffect(() => {\n if (pinned !== null) dispatch({ type: \"pin\", anchor: pinned });\n }, [pinned]);\n\n // Initial selection, once the token list arrives. A pinned pair never seeds:\n // the wrong token must not show while the pin is still resolving.\n useEffect(() => {\n if (props.pair !== undefined || tokens.length === 0) return;\n dispatch({\n type: \"seed\",\n tokens,\n side,\n ...(props.defaultTokenIn === undefined ? {} : { defaultTokenIn: props.defaultTokenIn }),\n ...(props.defaultTokenOut === undefined ? {} : { defaultTokenOut: props.defaultTokenOut }),\n });\n }, [tokens, props.pair, props.defaultTokenIn, props.defaultTokenOut, side]);\n\n const setAmountText = useCallback((text: string) => dispatch({ type: \"amount\", text }), []);\n const setImpactAck = useCallback((value: boolean) => dispatch({ type: \"ack\", value }), []);\n\n const parsed = useMemo(() => {\n if (tokenIn === null || amountText.trim() === \"\") return null;\n return parseAmount(amountText, tokenIn.decimals);\n }, [amountText, tokenIn]);\n\n const amountIn = parsed !== null && parsed.ok ? parsed.value : null;\n const amountError = parsed !== null && !parsed.ok ? parsed.message : null;\n\n const balanceIn = useTokenBalance(tokenIn, accountResource.data);\n const balanceOut = useTokenBalance(tokenOut, accountResource.data);\n\n const quote = useSwapQuote({ tokenIn, tokenOut, amountIn, slippageBps });\n /* The resource keeps its last data once the request is disabled (amount\n cleared, same token both sides). An idle quote is no quote: nothing of\n the old one is shown or reported. */\n const quoteLive = quote.status !== \"idle\";\n const breakdown = quoteLive ? quote.breakdown : null;\n const quoted = quoteLive ? quote.quote : null;\n\n const execution = useSwapExecute({\n tokenIn,\n tokenOut,\n amountIn,\n quote: quoted,\n breakdown,\n ...(props.onSwapConfirmed ? { onSuccess: props.onSwapConfirmed } : {}),\n });\n\n /* A flip is a side change: the pair stays, the typed amount stays as the\n amount you pay. Controlled, the host is told and decides; otherwise the\n widget moves and tells. */\n const onSideChangeRef = useRef(props.onSideChange);\n onSideChangeRef.current = props.onSideChange;\n const controlledSide = props.side !== undefined;\n /* What the flip carries across: the amount you would have RECEIVED becomes\n the amount you pay, so the panels read as the same trade turned around\n (the widget is exact-input, so the typed number cannot stay on the side it\n was typed for). Without a current quote there is nothing honest to carry\n and the field is cleared; either way the old quote is never shown. */\n const carryRef = useRef<{ side: SwapSide; text: string } | null>(null);\n const switchTokens = useCallback(() => {\n const next = oppositeSide(side);\n const text = breakdown !== null && tokenOut !== null && breakdown.netAmountOut > 0n ? formatUnits(breakdown.netAmountOut, tokenOut.decimals) : \"\";\n if (!controlledSide) dispatch({ type: \"set-side\", side: next, amountText: text });\n else carryRef.current = { side: next, text };\n setRateFlipped(false);\n onSideChangeRef.current?.(next);\n }, [side, controlledSide, breakdown, tokenOut]);\n\n /* The pill: a side change that keeps the typed amount as the amount you pay\n (unlike the flip button, which carries the received amount across).\n Controlled, the host is told and decides; otherwise the widget moves. */\n const chooseSide = useCallback(\n (next: SwapSide) => {\n if (next === side) return;\n if (!controlledSide) dispatch({ type: \"set-side\", side: next });\n setRateFlipped(false);\n onSideChangeRef.current?.(next);\n },\n [side, controlledSide],\n );\n\n const onNeedsWalletRef = useRef(props.onNeedsWallet);\n onNeedsWalletRef.current = props.onNeedsWallet;\n const usePortion = useCallback(\n (fraction: number): boolean => {\n const text = portionAmountText(tokenIn, balanceIn.data, fraction);\n if (text === null) {\n onNeedsWalletRef.current?.();\n return false;\n }\n setAmountText(text);\n return true;\n },\n [tokenIn, balanceIn.data, setAmountText],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n setAmountIn: setAmountText,\n setPortion: (fraction: number) => {\n normalizePortions([fraction]);\n return usePortion(fraction);\n },\n flip: switchTokens,\n refreshQuote: quote.refetch,\n }),\n [setAmountText, usePortion, switchTokens, quote.refetch],\n );\n\n /* The quote as the host sees it. Memoised on the quote's own identity so\n `onQuote` fires when the quote changes, not on every render. */\n const quoteView = useMemo(\n () =>\n buildSwapQuoteView({\n tokenIn,\n tokenOut,\n quote: quoted,\n breakdown,\n rate: quote.rate,\n status: quote.status,\n isRefreshing: quote.isRefreshing,\n isMock: quote.isMock,\n updatedAt: quote.updatedAt,\n }),\n [tokenIn, tokenOut, quoted, breakdown, quote.rate, quote.status, quote.isRefreshing, quote.isMock, quote.updatedAt],\n );\n const onQuoteRef = useRef(props.onQuote);\n onQuoteRef.current = props.onQuote;\n useEffect(() => {\n onQuoteRef.current?.(quoteView);\n }, [quoteView]);\n useEffect(\n () => () => {\n onQuoteRef.current?.(null);\n },\n [],\n );\n\n const insufficientBalance = amountIn !== null && balanceIn.data !== null && amountIn > balanceIn.data;\n const impactBps = breakdown?.priceImpactBps ?? null;\n const needsAck = impactBps !== null && impactBps >= IMPACT_ACK_BPS && !impactAck;\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (execution.needsApproval) {\n void execution.approve();\n return;\n }\n void execution.execute();\n },\n [execution],\n );\n\n const outputText = breakdown === null || tokenOut === null ? \"\" : formatAmount(breakdown.netAmountOut, tokenOut.decimals);\n\n const routeTokens = useMemo(() => (quoted === null ? [] : routeSymbols(quoted.route)), [quoted]);\n\n const statusMessage =\n execution.statusMessage !== \"\"\n ? execution.statusMessage\n : quote.status === \"error\"\n ? (quote.error === null ? \"No route for this pair.\" : describeError(quote.error, \"quote\"))\n : \"\";\n const statusTone = execution.step === \"error\" || quote.status === \"error\" ? \"error\" : execution.step === \"success\" ? \"success\" : \"neutral\";\n\n const busy = execution.step === \"approving\" || execution.step === \"building\" || execution.step === \"awaiting-signature\" || execution.step === \"pending\";\n\n let buttonLabel: string;\n let canSubmit = false;\n const needsConnect = accountResource.data === null || accountResource.data === undefined;\n if (needsConnect) {\n buttonLabel = \"Connect wallet\";\n } else if (tokenIn === null || tokenOut === null) {\n buttonLabel = \"Select a token\";\n } else if (amountIn === null || amountIn === 0n) {\n buttonLabel = \"Enter an amount\";\n } else if (amountError !== null) {\n buttonLabel = amountError;\n } else if (insufficientBalance) {\n buttonLabel = `Insufficient ${tokenIn.symbol}`;\n } else if ((quote.status === \"loading\" || (quote.status === \"idle\" && quote.isRefreshing)) && breakdown === null) {\n /* `idle` + refreshing is the first read after the request was disabled (the amount was cleared and retyped). */\n buttonLabel = \"Fetching quote…\";\n } else if (quote.status === \"error\") {\n buttonLabel = \"Cannot quote this trade\";\n } else if (execution.needsApproval) {\n buttonLabel = `Approve ${execution.approvals[0]?.token.symbol ?? tokenIn.symbol}`;\n canSubmit = !busy;\n } else if (busy) {\n buttonLabel = execution.step === \"pending\" ? \"Confirming on chain…\" : execution.step === \"awaiting-signature\" ? \"Confirm in your wallet…\" : \"Preparing…\";\n } else if (needsAck) {\n buttonLabel = \"Acknowledge the price impact\";\n } else {\n buttonLabel = \"Swap\";\n canSubmit = execution.canExecute && quote.status === \"success\";\n }\n\n const rateLine = (() => {\n if (quote.rate === null || tokenIn === null || tokenOut === null || quote.rate === 0) return null;\n return rateFlipped ? formatRate(1 / quote.rate, tokenOut.symbol, tokenIn.symbol) : formatRate(quote.rate, tokenIn.symbol, tokenOut.symbol);\n })();\n\n /* An empty explorer is no explorer (explorerTxUrl): a devnet has none, and a link to \"\" is a link to this page. */\n const txUrl = execution.txHash === null ? null : explorerTxUrl(chain, execution.txHash);\n\n /* The creator tax line: the current side's rate, as the host read it. */\n const taxBps = props.creatorTax === undefined ? undefined : props.creatorTax === null ? null : side === \"buy\" ? props.creatorTax.buyBps : props.creatorTax.sellBps;\n const taxText = taxBps === undefined ? \"\" : taxBps === null || taxBps === 0 ? \"none\" : formatPercentFromBps(taxBps);\n const taxHint = \"Taken by the launch pool's hook on this swap, for the creator and the protocol. The quoted output already includes it.\";\n\n const settings = props.showSlippageControl !== false ? <SwapSettings slippageBps={slippageBps} defaultSlippageBps={defaultSlippageBps} onSlippageChange={setSlippageBps} /> : undefined;\n const sidePill = compact ? (\n <div className=\"latch-sides\" role=\"group\" aria-label=\"Buy or sell\">\n <button type=\"button\" className=\"latch-sides__btn\" data-latch-side=\"buy\" aria-pressed={side === \"buy\"} onClick={() => chooseSide(\"buy\")}>\n Buy\n </button>\n <button type=\"button\" className=\"latch-sides__btn\" data-latch-side=\"sell\" aria-pressed={side === \"sell\"} onClick={() => chooseSide(\"sell\")}>\n Sell\n </button>\n </div>\n ) : undefined;\n\n /* Quick amounts: real fractions of the balance just read, so they exist only once there is one. */\n const portionChips =\n portions.length > 0 && balanceIn.data !== null && tokenIn !== null ? (\n <div className=\"latch-portions\" role=\"group\" aria-label=\"Quick amounts\">\n {portions.map((fraction) => {\n const label = portionLabel(fraction);\n return (\n <button key={fraction} type=\"button\" className=\"latch-portion\" aria-label={`${label} of your ${tokenIn.symbol} balance`} onClick={() => usePortion(fraction)}>\n {label}\n </button>\n );\n })}\n </div>\n ) : null;\n\n return (\n <WidgetShell\n title={props.title ?? \"Swap\"}\n className=\"latch-swap\"\n headerAction={settings}\n {...(sidePill === undefined ? {} : { headerContent: sidePill })}\n >\n {props.slots?.header !== undefined ? <div className=\"latch-slot latch-slot--header\">{props.slots.header}</div> : null}\n <form onSubmit={handleSubmit} noValidate className=\"latch-swap__form\" data-latch-swap-side={side} data-latch-variant={compact ? \"compact\" : \"default\"} data-latch-pair-locked={locked ? \"true\" : undefined}>\n <div className=\"latch-panel\" data-latch-side=\"sell\">\n <div className=\"latch-panel__top\">\n <span className=\"latch-label\">You pay</span>\n {balanceIn.data !== null && tokenIn !== null ? <span className=\"latch-panel__balance\">Balance {formatAmount(balanceIn.data, tokenIn.decimals)}</span> : null}\n </div>\n <div className=\"latch-panel__main\">\n <input\n className=\"latch-big-input\"\n type=\"text\"\n inputMode=\"decimal\"\n autoComplete=\"off\"\n spellCheck={false}\n placeholder=\"0\"\n aria-label={`Amount of ${tokenIn?.symbol ?? \"the input token\"} to sell`}\n value={amountText}\n onChange={(e) => setAmountText(e.target.value.replace(/,/g, \".\"))}\n />\n {locked ? (\n <TokenChip label=\"Sell\" value={tokenIn} />\n ) : (\n <TokenSelect label=\"Sell\" value={tokenIn} tokens={tokens} exclude={tokenOut} listFailures={lists.failures} listsLoading={lists.status === \"loading\"} onChange={(t) => dispatch({ type: \"select-in\", token: t, side })} />\n )}\n </div>\n {portionChips}\n {amountError !== null ? <p className=\"latch-panel__error\">{amountError}</p> : null}\n </div>\n\n {compact ? (\n <>\n <dl className=\"latch-lines\">\n <Row label=\"You receive\">\n <output aria-live=\"polite\" className={quote.isRefreshing ? \"is-refreshing\" : undefined}>\n {outputText === \"\" || tokenOut === null ? \"—\" : `${outputText} ${tokenOut.symbol}`}\n </output>\n </Row>\n <Row label=\"Price impact\" hint=\"How much worse this trade's rate is than the pool's current rate.\" {...(breakdown === null ? {} : { severity: breakdown.priceImpactSeverity })}>\n {breakdown === null ? \"—\" : formatPercentFromBps(breakdown.priceImpactBps)}\n </Row>\n <Row\n label=\"Pool fee\"\n hint={breakdown?.lpFeeUnknown === true ? \"This pool's hook decides the fee inside the swap. The quoted output already includes it.\" : \"Set by the pool, paid to its liquidity providers, taken from the input.\"}\n >\n {breakdown === null ? \"—\" : breakdown.lpFeeUnknown ? \"set by hook\" : formatPercentFromPips(breakdown.lpFeePips)}\n </Row>\n {taxBps !== undefined ? (\n <Row label={`Creator tax (${side})`} hint={taxHint}>\n {taxText}\n </Row>\n ) : null}\n {integrator.active && breakdown !== null && tokenOut !== null ? (\n <Row label={`${integrator.label ?? \"Integrator\"} fee (${formatBps(integrator.feeBps)})`} hint=\"Paid to the site hosting this widget, inside the same transaction.\">\n {formatAmount(breakdown.integratorFee, tokenOut.decimals)} {tokenOut.symbol} → {shortAddress(integrator.referrer)}\n </Row>\n ) : null}\n <Row label={`Min. received (${formatPercentFromBps(slippageBps)})`} hint=\"Guaranteed floor after slippage and the integrator fee. The transaction reverts below it.\">\n {breakdown === null || tokenOut === null ? \"—\" : `${formatAmount(breakdown.minAmountOutNet, tokenOut.decimals)} ${tokenOut.symbol}`}\n </Row>\n </dl>\n {quote.isMock ? <p className=\"latch-panel__note\">Simulated by the mock adapter</p> : null}\n </>\n ) : (\n <>\n <div className=\"latch-flip\">\n <button type=\"button\" className=\"latch-flip__button\" onClick={switchTokens} aria-label=\"Swap the input and output tokens\" title=\"Switch tokens\">\n <span aria-hidden=\"true\">↓</span>\n </button>\n </div>\n\n <div className=\"latch-panel\" data-latch-side=\"buy\">\n <div className=\"latch-panel__top\">\n <span className=\"latch-label\">You receive</span>\n {balanceOut.data !== null && tokenOut !== null ? <span className=\"latch-panel__balance\">Balance {formatAmount(balanceOut.data, tokenOut.decimals)}</span> : null}\n </div>\n <div className=\"latch-panel__main\">\n <output className={`latch-big-input latch-big-input--out${quote.isRefreshing ? \" is-refreshing\" : \"\"}`} aria-live=\"polite\" aria-label={`Amount of ${tokenOut?.symbol ?? \"the output token\"} you receive`}>\n {outputText === \"\" ? <span className=\"latch-big-input__placeholder\">0</span> : outputText}\n </output>\n {locked ? (\n <TokenChip label=\"Buy\" value={tokenOut} />\n ) : (\n <TokenSelect label=\"Buy\" value={tokenOut} tokens={tokens} exclude={tokenIn} listFailures={lists.failures} listsLoading={lists.status === \"loading\"} onChange={(t) => dispatch({ type: \"select-out\", token: t, side })} />\n )}\n </div>\n {quote.isMock ? <p className=\"latch-panel__note\">Simulated by the mock adapter</p> : null}\n </div>\n </>\n )}\n\n {needsAck || (impactBps !== null && impactBps >= IMPACT_ACK_BPS) ? (\n <label className=\"latch-ack\">\n <input type=\"checkbox\" checked={impactAck} onChange={(e) => setImpactAck(e.target.checked)} />\n <span>\n This trade moves the pool price by <strong>{formatPercentFromBps(impactBps)}</strong>. I understand I am paying that.\n </span>\n </label>\n ) : null}\n\n {props.slots?.aboveButton !== undefined ? <div className=\"latch-slot latch-slot--above-button\">{props.slots.aboveButton}</div> : null}\n\n {needsConnect ? (\n <button {...connectCtaProps(onConnectRequest)} className=\"latch-cta\" data-latch-busy=\"false\">\n {buttonLabel}\n </button>\n ) : (\n <button type=\"submit\" className=\"latch-cta\" disabled={!canSubmit} data-latch-busy={busy ? \"true\" : \"false\"}>\n {busy ? <span className=\"latch-spinner\" aria-hidden=\"true\" /> : null}\n {buttonLabel}\n </button>\n )}\n\n {!compact && breakdown !== null && tokenIn !== null && tokenOut !== null ? (\n <div className=\"latch-details\" data-open={detailsOpen ? \"true\" : \"false\"}>\n <button type=\"button\" className=\"latch-details__toggle\" aria-expanded={detailsOpen} onClick={() => setDetailsOpen((o) => !o)}>\n <span\n className=\"latch-details__rate\"\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n setRateFlipped((f) => !f);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n setRateFlipped((f) => !f);\n }\n }}\n title=\"Flip the rate\"\n >\n {rateLine ?? \"Rate unavailable\"}\n </span>\n <span className=\"latch-details__hint\">\n {impactBps !== null ? <span data-latch-severity={breakdown.priceImpactSeverity}>{formatPercentFromBps(impactBps)} impact</span> : null}\n <span aria-hidden=\"true\">{detailsOpen ? \"▴\" : \"▾\"}</span>\n </span>\n </button>\n {detailsOpen ? (\n <dl className=\"latch-details__list\">\n <Row label=\"Price impact\" hint=\"How much worse this trade's rate is than the pool's current rate.\" severity={breakdown.priceImpactSeverity}>\n {formatPercentFromBps(breakdown.priceImpactBps)}\n </Row>\n <Row label=\"Max slippage\" hint=\"Set in the settings. The transaction reverts if the received amount falls below the minimum.\">\n {formatPercentFromBps(breakdown.slippageBps)}\n </Row>\n <Row label=\"Minimum received\" hint=\"Guaranteed floor after slippage and the integrator fee.\">\n {formatAmount(breakdown.minAmountOutNet, tokenOut.decimals)} {tokenOut.symbol}\n </Row>\n <Row\n label=\"Pool fee\"\n hint={breakdown.lpFeeUnknown ? \"This pool's hook decides the fee inside the swap. The quoted output already includes it.\" : \"Set by the pool, paid to its liquidity providers, taken from the input.\"}\n >\n {breakdown.lpFeeUnknown ? \"dynamic (hook-set)\" : formatPercentFromPips(breakdown.lpFeePips)}\n </Row>\n {taxBps !== undefined ? (\n <Row label={`Creator tax (${side})`} hint={taxHint}>\n {taxText}\n </Row>\n ) : null}\n {integrator.active ? (\n <Row label={`${integrator.label ?? \"Integrator\"} fee (${formatBps(integrator.feeBps)})`} hint=\"Paid to the site hosting this widget, inside the same transaction.\">\n {formatAmount(breakdown.integratorFee, tokenOut.decimals)} {tokenOut.symbol} → {shortAddress(integrator.referrer)}\n </Row>\n ) : null}\n {routeTokens.length > 1 ? (\n <Row label=\"Route\" hint=\"The pools this swap goes through, in order.\">\n {routeTokens.join(\" → \")}\n {quoted !== null ? ` · ${quoted.route.length} hop${quoted.route.length > 1 ? \"s\" : \"\"} · ${quoted.route.map((s) => s.poolType).join(\", \")}` : \"\"}\n </Row>\n ) : null}\n {quote.updatedAt !== null ? (\n <Row label=\"Quote\" hint=\"Quotes refresh on an interval; the chain recomputes the output at execution.\">\n {quote.isRefreshing ? \"refreshing…\" : `read ${Math.max(0, Math.round((Date.now() - quote.updatedAt) / 1000))}s ago`}\n </Row>\n ) : null}\n </dl>\n ) : null}\n </div>\n ) : null}\n\n <StatusRegion message={statusMessage} tone={statusTone} />\n </form>\n\n {/* The execution error is already the status line above, in its error tone. */}\n <ErrorPanel error={execution.error !== null || quote.status === \"error\" ? null : quote.error} context=\"quote\" />\n\n {props.slots?.footer !== undefined ? <div className=\"latch-slot latch-slot--footer\">{props.slots.footer}</div> : null}\n\n {execution.txHash !== null ? (\n <p className=\"latch-footer\">\n <span>{execution.step === \"success\" ? \"Swapped\" : \"Transaction\"}</span>\n {txUrl !== null ? (\n <a href={txUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {shortAddress(execution.txHash)} ↗\n </a>\n ) : (\n <span>{shortAddress(execution.txHash)}</span>\n )}\n </p>\n ) : null}\n <p className=\"latch-footer latch-footer--brand\">\n <span>Latch Protocol · {chain.name}</span>\n </p>\n </WidgetShell>\n );\n});\n\nfunction Row(props: { readonly label: string; readonly hint?: string; readonly severity?: string; readonly children: ReactNode }): JSX.Element {\n return (\n <div className=\"latch-details__row\" title={props.hint}>\n <dt>{props.label}</dt>\n <dd data-latch-severity={props.severity}>{props.children}</dd>\n </div>\n );\n}\n"],"names":["PortalContainerContext","createContext","PortalContainerProvider","usePortalContainer","useContext","WIDGET_CSS","STYLE_ELEMENT_ID","injectWidgetStyles","target","root","doc","style","WidgetShell","props","theme","adapter","useWidgetContext","setRoot","useState","useEffect","jsx","jsxs","Fragment","MockBanner","AmountField","inputId","useId","selectId","errorId","handleAmount","event","handleToken","next","token","formatAmount","SummaryRow","SummaryList","StatusRegion","connectCtaProps","onConnectRequest","ActionButton","connect","ProgressBar","clamped","SegmentedControl","groupLabelId","option","RouteSummary","chips","useMemo","symbol","index","chip","ErrorPanel","describeError","clockSpan","clock","units","humanDuration","pointOnClock","value","LaunchWidget","chain","integrator","providerConnect","list","useLaunchList","poolId","launchResource","useLaunch","launch","listState","resolveLaunchDataState","launchState","state","account","useAccount","amountText","setAmountText","parsed","parseAmount","amountIn","balance","useTokenBalance","buy","useLaunchBuy","view","buildLaunchView","handleSubmit","useCallback","title","subtitle","LaunchUnavailable","schedule","insufficientBalance","busy","buttonLabel","canSubmit","statusMessage","statusTone","LaunchSchedulePanel","FeeDecayChart","MaxBuyNotice","formatRate","formatPercentFromBps","formatPercentFromPips","formatBps","shortAddress","feeSpanProgressBps","feeProjectionDriftPips","describePhase","amount","guard","width","height","samples","points","values","i","at","launchFeeAt","min","span","path","x","y","progressBps","markerX","caption","LaunchV2Widget","legs","useLaunchesForToken","leg","LiquidityWidget","pools","usePools","accountResource","mode","setMode","pool","setPool","refreshKey","setRefreshKey","hostChanged","onChanged","bumpOnConfirmed","k","current","candidate","PoolSelect","AddLiquidityPanel","RemoveLiquidityPanel","isDynamicLPFee","poolState","usePoolState","refetchPoolState","range","setRange","edited","setEdited","freeText","setFreeText","seeded","defaultRangeFor","sqrtPriceX96","clRange","side","clRangeSide","amount0Text","amount1Text","decimalsIn","decimalsOther","typed","other","paired","pairedAmountForRange","formatUnits","setAmount0Text","text","setAmount1Text","parsed0","parsed1","amount0","amount1","rangeNote","quote","useAddLiquidityQuote","execution","useAddLiquidityExecute","insufficient","RangeEditor","describeRange","tickSpacingOf","adjustRange","binCount","binStepOf","half","positions","usePositions","selected","setSelected","percentBps","setPercentBps","withdrawablePositions","reconcileSelection","removal","useRemoveLiquidity","position","PRESETS","SwapSettings","container","custom","setCustom","isAuto","applyCustom","pct","bps","MAX_SLIPPAGE_BPS","high","low","Popover","p","e","ADDRESS_RE","TokenLogo","size","t","src","resolveLogoUrl","failed","setFailed","label","hueOf","key","h","SearchGlyph","TokenBadges","badges","b","TokenChip","TokenSelect","open","setOpen","query","setQuery","balances","setBalances","pasted","setPasted","cancelled","owner","rows","r","q","filtered","a","ba","bb","grouped","groupBySource","common","pick","row","bal","disabled","alsoIn","Dialog","held","rest","g","f","IMPACT_ACK_BPS","usePinnedPair","pair","tokens","pairKey","anchored","normalizePair","fetched","setFetched","requested","useRef","mounted","fromList","resolvePairEntry","entry","address","SwapWidget","forwardRef","ref","defaultSlippageBps","tokenList","useTokenList","lists","useTokenLists","combineTokens","portions","normalizePortions","locked","compact","dispatch","useReducer","swapWidgetReducer","initialSwapState","tokenIn","tokenOut","orientPair","impactAck","slippageBps","setSlippageBps","detailsOpen","setDetailsOpen","rateFlipped","setRateFlipped","carry","carryRef","pinned","setImpactAck","amountError","balanceIn","balanceOut","useSwapQuote","quoteLive","breakdown","quoted","useSwapExecute","onSideChangeRef","controlledSide","switchTokens","oppositeSide","chooseSide","onNeedsWalletRef","usePortion","fraction","portionAmountText","useImperativeHandle","quoteView","buildSwapQuoteView","onQuoteRef","impactBps","needsAck","outputText","routeTokens","routeSymbols","needsConnect","rateLine","txUrl","explorerTxUrl","taxBps","taxText","taxHint","settings","sidePill","portionChips","portionLabel","Row","o","s"],"mappings":";;;;;;;AAUA,MAAMA,KAAyBC,GAAkC,IAAI,GAExDC,KAA0BF,GAAuB;AAGvD,SAASG,KAA8C;AAC5D,SAAOC,GAAWJ,EAAsB,KAAK;AAC/C;ACOO,MAAMK,KAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}