/**
 * Swap Module - Main Web Component
 *
 * A cross-chain token swap interface supporting both EVM and SVM chains.
 * Allows users to swap tokens across different blockchain networks.
 */
import { h, Host, } from "@stencil/core";
import { loadQuotes, loadState, state, applyTokenFilter } from "./store";
import { initWallet, isUsingReown, connectEvmWallet, disconnectWallet, openSolanaWalletMenu, openWalletModal, onWalletChange, executeEvmTransaction, executeSolanaTransaction, onSolanaWalletChange, cleanupWallet, getWalletAddress, } from "./utils/wallet";
import { formatEstimatedTime, formatTokenAmount, formatTokenBalance, formatWalletAddress, isValidNumericInput, } from "./utils/formatters";
import { AMOUNT_PERCENTAGES, M0_LOGO_URL, QUOTE_DEBOUNCE_DELAY, } from "./utils/constants";
export class SwapModule {
    network = "mainnet";
    disableSvm = false;
    disableEvm = false;
    rpcOverrides = {};
    radius = 0;
    highlightColor = "rgb(243, 248, 252)"; // Deprecated: use primaryColor
    primaryColor = ""; // New: accent color, falls back to highlightColor
    enableQueryParams = false;
    widgetTitle = ""; // Empty = use dynamic "Get <token>" text
    reownProjectId = "";
    sourceTokens = []; // Whitelist: ["Ethereum:0x...", "Solana:..."]
    destinationTokens = []; // Whitelist: ["Ethereum:0x...", "Solana:..."]
    buttonText = ""; // Empty = use dynamic "Pay with <token>" text
    maxSlippage = 2.5; // Max slippage percentage for swaps
    searchQuery = "";
    localSourceAssets = []; // Instance-local filtered source tokens
    localDestinationAssets = []; // Instance-local filtered destination tokens
    localFromToken; // Instance-local from token selection
    localToToken; // Instance-local to token selection
    showNetworkDropdown = false; // Network selector dropdown visibility
    showChainFilterDropdown = false; // Chain filter dropdown visibility
    showRouteDetails = false; // Route details view visibility
    showWalletDropdown = false; // Wallet dropdown visibility
    showConfirmation = false; // Confirmation screen visibility
    swapStatus = "idle"; // Swap execution status
    lastTransactionHash = ""; // Store last transaction hash for explorer link
    lastChainId = 0; // Store chain ID for explorer link
    // Helper getters to use local tokens when filtering is active
    get currentFromToken() {
        return this.localFromToken || state.fromToken;
    }
    get currentToToken() {
        return this.localToToken || state.toToken;
    }
    get currentFromChain() {
        const token = this.currentFromToken;
        return state.chains.find((c) => c.id === token?.chain);
    }
    get currentToChain() {
        const token = this.currentToToken;
        return state.chains.find((c) => c.id === token?.chain);
    }
    debounceTimer = null;
    filterDebounceTimer = null;
    // 2 second debounce for token whitelist prop changes to avoid spamming expensive
    // API calls during rapid prop updates (e.g., framework hydration or user typing)
    static FILTER_DEBOUNCE_DELAY = 2000;
    transactionId;
    async componentWillLoad() {
        // Initialize wallet system (Reown if projectId provided, else legacy)
        await initWallet(this.reownProjectId, {
            disableEvm: this.disableEvm,
            disableSvm: this.disableSvm,
        });
        await loadState(this.network, this.rpcOverrides, this.enableQueryParams, this.disableSvm, this.disableEvm);
        // Initialize local filtered assets
        this.updateLocalFilters();
        // Set up wallet change listener
        if (isUsingReown()) {
            // Reown mode - unified wallet listener
            onWalletChange((address) => {
                state.walletAddress = address || "";
            });
        }
        else {
            // Legacy mode - Solana wallet listener
            onSolanaWalletChange((adapter) => {
                state.walletAddress = adapter?.publicKey?.toString() || "";
            });
        }
        // Check if wallet is already connected (restored from previous session)
        const existingAddress = getWalletAddress();
        if (existingAddress && !state.walletAddress) {
            state.walletAddress = existingAddress;
        }
    }
    /**
     * Computes local filtered assets based on props and updates local token selections
     */
    updateLocalFilters() {
        if (state.assets.length === 0) {
            return;
        }
        // Filter assets based on disabled runtimes
        let filteredAssets = state.assets;
        if (this.disableSvm) {
            filteredAssets = filteredAssets.filter((a) => a.runtime !== "svm");
        }
        if (this.disableEvm) {
            filteredAssets = filteredAssets.filter((a) => a.runtime !== "evm");
        }
        // Apply whitelist filters for source and destination
        this.localSourceAssets = applyTokenFilter(filteredAssets, this.sourceTokens);
        this.localDestinationAssets = applyTokenFilter(filteredAssets, this.destinationTokens);
        // Set default token selections based on filtered assets
        const sourcePool = this.localSourceAssets.length > 0
            ? this.localSourceAssets
            : filteredAssets;
        const destPool = this.localDestinationAssets.length > 0
            ? this.localDestinationAssets
            : filteredAssets;
        // Check if current local selections are still valid
        const currentFromValid = this.localFromToken &&
            sourcePool.some((a) => a.chain === this.localFromToken?.chain &&
                a.address === this.localFromToken?.address);
        const currentToValid = this.localToToken &&
            destPool.some((a) => a.chain === this.localToToken?.chain &&
                a.address === this.localToToken?.address);
        if (!currentFromValid) {
            this.localFromToken = sourcePool[0];
        }
        if (!currentToValid) {
            // Find a token different from fromToken
            const differentToken = destPool.find((a) => a.chain !== this.localFromToken?.chain ||
                a.address !== this.localFromToken?.address);
            this.localToToken = differentToken || destPool[0];
        }
    }
    /**
     * Watch for changes in filter props and update token selection
     */
    handleRuntimeFilterChange() {
        // Runtime filter changes apply immediately
        this.updateLocalFilters();
    }
    handleTokenWhitelistChange() {
        // Debounce token whitelist changes (user might be typing)
        if (this.filterDebounceTimer) {
            clearTimeout(this.filterDebounceTimer);
        }
        this.filterDebounceTimer = setTimeout(() => {
            this.updateLocalFilters();
        }, SwapModule.FILTER_DEBOUNCE_DELAY);
    }
    disconnectedCallback() {
        if (this.debounceTimer) {
            clearTimeout(this.debounceTimer);
        }
        if (this.filterDebounceTimer) {
            clearTimeout(this.filterDebounceTimer);
        }
        // Cleanup wallet resources
        cleanupWallet();
    }
    /**
     * Closes dropdowns when clicking outside
     */
    handleWindowClick(event) {
        const path = event.composedPath();
        const isDropdownClick = path.some((el) => el.classList?.contains("token-dropdown") ||
            el.classList?.contains("token-card") ||
            el.classList?.contains("token-select-button") ||
            el.classList?.contains("source-token-button"));
        const isNetworkDropdownClick = path.some((el) => el.classList?.contains("network-dropdown-wrapper") ||
            el.classList?.contains("network-dropdown-trigger"));
        const isChainFilterClick = path.some((el) => el.classList?.contains("chain-filter-dropdown") ||
            el.classList?.contains("chain-filter-trigger"));
        if (!isDropdownClick) {
            state.showFromTokenList = false;
            state.showToTokenList = false;
        }
        if (!isNetworkDropdownClick) {
            this.showNetworkDropdown = false;
        }
        if (!isChainFilterClick) {
            this.showChainFilterDropdown = false;
        }
        const isWalletDropdownClick = path.some((el) => el.classList?.contains("wallet-dropdown-wrapper") ||
            el.classList?.contains("wallet-button-connected"));
        if (!isWalletDropdownClick) {
            this.showWalletDropdown = false;
        }
    }
    async handleCopyAddress() {
        if (state.walletAddress) {
            await navigator.clipboard.writeText(state.walletAddress);
            this.showWalletDropdown = false;
        }
    }
    handleChangeWallet() {
        this.showWalletDropdown = false;
        openWalletModal();
    }
    async handleDisconnectWallet() {
        this.showWalletDropdown = false;
        await disconnectWallet();
        state.walletAddress = "";
    }
    async handleWalletAction() {
        if (!state.walletAddress) {
            // Connect wallet
            if (isUsingReown()) {
                // Reown mode - opens unified modal, address comes via onWalletChange callback
                openWalletModal();
            }
            else if (state.runtime === "evm") {
                // Legacy EVM - direct connection
                const address = await connectEvmWallet();
                state.walletAddress = address;
            }
            else {
                // Legacy Solana - opens menu, address comes via onSolanaWalletChange callback
                openSolanaWalletMenu();
            }
        }
        else {
            // Disconnect wallet
            await disconnectWallet();
            state.walletAddress = "";
        }
    }
    /* ============================================
     * Token Selection Methods
     * ============================================ */
    selectFromToken(asset) {
        // Update local state for this instance
        this.localFromToken = asset;
        // Also update global state for quotes/transactions
        state.fromToken = asset;
        state.showFromTokenList = false;
        this.resetQuotes();
        if (this.enableQueryParams) {
            this.updateQueryParams();
        }
    }
    selectToToken(asset) {
        // Update local state for this instance
        this.localToToken = asset;
        // Also update global state for quotes/transactions
        state.toToken = asset;
        state.showToTokenList = false;
        this.resetQuotes();
        if (this.enableQueryParams) {
            this.updateQueryParams();
        }
    }
    toggleFromTokenList() {
        state.showFromTokenList = !state.showFromTokenList;
        state.showToTokenList = false;
        this.searchQuery = "";
        if (state.showFromTokenList) {
            const fromToken = this.currentFromToken;
            state.fromChain = fromToken?.chain || "all";
        }
    }
    /* ============================================
     * Amount Input Methods
     * ============================================ */
    handleAmountChange(inputValue) {
        if (!isValidNumericInput(inputValue)) {
            return;
        }
        state.fromAmount = inputValue;
        state.inputDirection = "source";
        // Clear existing debounce timer
        if (this.debounceTimer) {
            clearTimeout(this.debounceTimer);
        }
        // Check if we need a recipient address for cross-runtime swaps
        const isCrossRuntime = state.fromToken.runtime !== state.toToken.runtime;
        if (isCrossRuntime && !state.recipientAddress) {
            return;
        }
        // Only fetch quotes if we have a valid amount and wallet
        if (inputValue && parseFloat(inputValue) > 0) {
            state.selectedQuoteIndex = undefined;
            state.quotes = undefined;
            if (!state.walletAddress) {
                return;
            }
            state.swapLoading = true;
            this.debounceTimer = setTimeout(loadQuotes, QUOTE_DEBOUNCE_DELAY);
        }
        else {
            state.quotes = [];
            state.selectedQuoteIndex = undefined;
        }
        state.quoteError = "";
    }
    setAmountPercent(percent) {
        const balance = state.fromTokenBalance;
        const amount = (Number(balance) * percent) / 100 / 10 ** state.fromToken.decimals;
        this.handleAmountChange(amount.toString());
    }
    /* ============================================
     * Recipient Address Methods
     * ============================================ */
    handleRecipientChange(event) {
        const inputValue = event.target.value;
        state.recipientAddress = inputValue || undefined;
        // Reset quotes when recipient changes
        state.quotes = undefined;
        state.selectedQuoteIndex = undefined;
        if (state.fromAmount && state.walletAddress) {
            loadQuotes();
        }
    }
    /* ============================================
     * Swap Execution Methods
     * ============================================ */
    showSwapConfirmation() {
        if (state.selectedQuoteIndex === undefined) {
            return;
        }
        this.showConfirmation = true;
    }
    async handleSwap() {
        if (state.selectedQuoteIndex === undefined) {
            return;
        }
        try {
            state.swapLoading = true;
            this.swapStatus = "confirming";
            const selectedQuote = state.quotes[state.selectedQuoteIndex];
            for (const tx of selectedQuote.payloads) {
                let transactionHash;
                let chainId = 0;
                if (state.runtime === "evm" && tx.data.type === "evm") {
                    chainId = tx.data.chainId;
                    transactionHash = await executeEvmTransaction(tx.data);
                }
                else if (state.runtime === "svm" && tx.data.type === "svm") {
                    transactionHash = await executeSolanaTransaction(tx.data, state.rpcOverrides);
                }
                else {
                    throw new Error("Unsupported runtime for transaction");
                }
                this.lastTransactionHash = transactionHash;
                this.lastChainId = chainId;
                this.transactionId.emit({ transaction: transactionHash, chainId });
            }
            // Mark as success - don't reset quotes so confirmation screen stays visible
            this.swapStatus = "success";
        }
        catch (error) {
            this.swapStatus = "failed";
            state.quoteError =
                error instanceof Error
                    ? error.message
                    : "Error executing swap. Please try again.";
        }
        finally {
            state.swapLoading = false;
        }
    }
    resetQuotes() {
        state.fromAmount = "";
        state.quotes = undefined;
        state.selectedQuoteIndex = undefined;
        state.quoteError = undefined;
        this.showConfirmation = false;
        this.swapStatus = "idle";
        this.lastTransactionHash = "";
        this.lastChainId = 0;
    }
    handleTryAgain() {
        // Reset swap status to allow retry, keep confirmation screen open
        this.swapStatus = "idle";
        state.quoteError = undefined;
    }
    handleViewOnExplorer() {
        // Build explorer URL based on chain
        const explorerUrls = {
            1: "https://etherscan.io/tx/",
            10: "https://optimistic.etherscan.io/tx/",
            42161: "https://arbiscan.io/tx/",
            8453: "https://basescan.org/tx/",
            59144: "https://lineascan.build/tx/",
            11155111: "https://sepolia.etherscan.io/tx/",
            421614: "https://sepolia.arbiscan.io/tx/",
        };
        // For Solana (chainId 0 or non-EVM)
        if (this.lastChainId === 0 && state.runtime === "svm") {
            const solanaExplorer = "https://explorer.solana.com/tx/";
            const cluster = state.network === "devnet" ? "?cluster=devnet" : "";
            window.open(`${solanaExplorer}${this.lastTransactionHash}${cluster}`, "_blank");
            return;
        }
        const baseUrl = explorerUrls[this.lastChainId] || "https://etherscan.io/tx/";
        window.open(`${baseUrl}${this.lastTransactionHash}`, "_blank");
    }
    /* ============================================
     * Helper Methods
     * ============================================ */
    updateQueryParams() {
        if (!this.enableQueryParams)
            return;
        const url = new URL(window.location.href);
        if (state.fromToken) {
            url.searchParams.set("fromChain", state.fromToken.chain);
            url.searchParams.set("fromAddress", state.fromToken.address);
        }
        if (state.toToken) {
            url.searchParams.set("toChain", state.toToken.chain);
            url.searchParams.set("toAddress", state.toToken.address);
        }
        window.history.replaceState({}, "", url.toString());
    }
    getFilteredAssets(chain, isSource) {
        // Use local filtered assets if whitelist was provided, otherwise use all assets
        const baseAssets = isSource
            ? this.localSourceAssets.length > 0
                ? this.localSourceAssets
                : state.assets
            : this.localDestinationAssets.length > 0
                ? this.localDestinationAssets
                : state.assets;
        let assets = baseAssets.filter((a) => a.chain === chain);
        if (this.searchQuery) {
            const query = this.searchQuery.toLowerCase();
            assets = assets.filter((a) => a.symbol.toLowerCase().includes(query) ||
                a.name.toLowerCase().includes(query));
        }
        return assets;
    }
    getSelectedQuote() {
        return state.selectedQuoteIndex !== undefined
            ? state.quotes[state.selectedQuoteIndex]
            : null;
    }
    isSwapButtonDisabled() {
        return (!state.fromAmount ||
            parseFloat(state.fromAmount) <= 0 ||
            state.swapLoading ||
            !state.walletAddress ||
            state.selectedQuoteIndex === undefined);
    }
    /* ============================================
     * Render Methods
     * ============================================ */
    renderHeader() {
        const toToken = this.currentToToken;
        // Priority: Custom prop > Dynamic token text > Default
        const title = this.widgetTitle
            ? this.widgetTitle
            : toToken
                ? `Get ${toToken.symbol}`
                : "Swap";
        return (h("div", { class: "swap-header" }, h("h1", { class: "swap-title" }, title), state.walletAddress ? (h("div", { class: "wallet-dropdown-wrapper" }, h("button", { class: "wallet-button-connected", onClick: () => (this.showWalletDropdown = !this.showWalletDropdown) }, h("img", { src: "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg", class: "wallet-icon", alt: "Wallet" }), h("svg", { class: "wallet-chevron", width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor" }, h("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", "stroke-width": "1.5", fill: "none" }))), this.showWalletDropdown && (h("div", { class: "wallet-dropdown-menu" }, h("button", { class: "wallet-dropdown-item", onClick: () => this.handleCopyAddress() }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }), h("path", { d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" })), "Copy address"), h("button", { class: "wallet-dropdown-item", onClick: () => this.handleChangeWallet() }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M21 12a9 9 0 11-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }), h("path", { d: "M21 3v5h-5" })), "Change wallet"), h("button", { class: "wallet-dropdown-item wallet-dropdown-item-danger", onClick: () => this.handleDisconnectWallet() }, h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }), h("polyline", { points: "16,17 21,12 16,7" }), h("line", { x1: "21", y1: "12", x2: "9", y2: "12" })), "Disconnect"))))) : (h("button", { class: "wallet-button-header", onClick: () => this.handleWalletAction() }, "Connect wallet", h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }), h("path", { d: "M16 12h.01" }))))));
    }
    handleDestinationAmountChange(inputValue) {
        if (!isValidNumericInput(inputValue)) {
            return;
        }
        state.toAmount = inputValue;
        state.inputDirection = "destination";
        // Clear existing debounce timer
        if (this.debounceTimer) {
            clearTimeout(this.debounceTimer);
        }
        // Check if we need a recipient address for cross-runtime swaps
        const isCrossRuntime = state.fromToken.runtime !== state.toToken.runtime;
        if (isCrossRuntime && !state.recipientAddress) {
            return;
        }
        // Only fetch quotes if we have a valid amount and wallet
        if (inputValue && parseFloat(inputValue) > 0) {
            state.selectedQuoteIndex = undefined;
            state.quotes = undefined;
            if (!state.walletAddress) {
                return;
            }
            state.swapLoading = true;
            this.debounceTimer = setTimeout(loadQuotes, QUOTE_DEBOUNCE_DELAY);
        }
        else {
            state.quotes = [];
            state.selectedQuoteIndex = undefined;
        }
        state.quoteError = "";
    }
    renderDestinationHero() {
        const toToken = this.currentToToken;
        const toChain = this.currentToChain;
        const selectedQuote = this.getSelectedQuote();
        if (!toToken || !toChain)
            return null;
        // Use toAmount from state, or format from quote if available
        let displayAmount = state.toAmount || "0";
        if (state.inputDirection === "source" && selectedQuote) {
            displayAmount = formatTokenAmount(selectedQuote.amountOut, toToken.decimals);
        }
        return (h("div", { class: "destination-hero" }, h("div", { class: "destination-amount-row" }, h("img", { src: toToken.icon, class: "destination-token-icon", alt: toToken.symbol }), h("input", { type: "text", class: "destination-amount-input", placeholder: "0", value: displayAmount, onInput: (e) => this.handleDestinationAmountChange(e.target.value), onFocus: () => (state.inputDirection = "destination") }))));
    }
    handleNetworkChange(chainId) {
        // Find a destination token on the selected chain
        const destAssets = this.localDestinationAssets.length > 0
            ? this.localDestinationAssets
            : state.assets;
        const tokenOnChain = destAssets.find((a) => a.chain === chainId);
        if (tokenOnChain) {
            this.selectToToken(tokenOnChain);
        }
        this.showNetworkDropdown = false;
    }
    renderNetworkSelector() {
        const toChain = this.currentToChain;
        // Get available chains for destination tokens
        const destAssets = this.localDestinationAssets.length > 0
            ? this.localDestinationAssets
            : state.assets;
        const availableChains = state.chains.filter((c) => {
            if (this.disableEvm && c.runtime === "evm")
                return false;
            if (this.disableSvm && c.runtime === "svm")
                return false;
            return destAssets.some((a) => a.chain === c.id);
        });
        const isDisabled = availableChains.length <= 1;
        if (!toChain)
            return null;
        return (h("div", { class: "network-selector" }, h("span", { class: "network-label" }, "Network:"), h("div", { class: "network-dropdown-wrapper" }, h("button", { class: `network-dropdown-trigger ${isDisabled ? "disabled" : ""}`, onClick: isDisabled
                ? undefined
                : () => (this.showNetworkDropdown = !this.showNetworkDropdown) }, h("img", { src: toChain.logo, class: "network-chain-icon", alt: "" }), h("span", { class: "network-chain-name" }, toChain.name), !isDisabled && (h("svg", { class: "network-chevron", width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor" }, h("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", "stroke-width": "1.5", fill: "none" })))), this.showNetworkDropdown && (h("div", { class: "network-dropdown-menu" }, availableChains.map((chain) => (h("button", { class: `network-dropdown-item ${chain.id === toChain.id ? "selected" : ""}`, onClick: () => this.handleNetworkChange(chain.id) }, h("img", { src: chain.logo, class: "network-item-icon", alt: "" }), h("span", { class: "network-item-name" }, chain.name)))))))));
    }
    renderSourceCard() {
        const fromToken = this.currentFromToken;
        const fromChain = this.currentFromChain;
        const toToken = this.currentToToken;
        const selectedQuote = this.getSelectedQuote();
        if (!fromToken || !fromChain)
            return null;
        const fromBalance = formatTokenBalance(state.fromTokenBalance, fromToken.decimals);
        const sourceTokenCount = this.localSourceAssets.length > 0
            ? this.localSourceAssets.length
            : state.assets.length;
        const isDisabled = sourceTokenCount <= 1;
        // Calculate exchange rate
        let exchangeRate = "";
        if (toToken &&
            selectedQuote &&
            state.fromAmount &&
            parseFloat(state.fromAmount) > 0) {
            const amountOut = parseFloat(selectedQuote.amountOut) / 10 ** toToken.decimals;
            const amountIn = parseFloat(state.fromAmount);
            const rate = (amountIn / amountOut).toFixed(6);
            exchangeRate = `1 ${toToken.symbol} ≈ ${rate} ${fromToken.symbol}`;
        }
        // Format balance display
        const hasBalance = state.walletAddress && fromBalance !== "0";
        const balanceDisplay = hasBalance
            ? `${fromBalance} ${fromToken.symbol}`
            : `- ${fromToken.symbol}`;
        return (h("div", { class: "source-card" }, h("div", { class: "source-card-header" }, h("button", { class: `source-token-button ${isDisabled ? "disabled" : ""}`, onClick: isDisabled ? undefined : () => this.toggleFromTokenList() }, h("span", { class: "source-token-icon-container" }, h("img", { src: fromToken.icon, class: "source-token-icon", alt: "" }), h("img", { src: fromChain.logo, class: "source-chain-icon", alt: "" })), h("div", { class: "source-token-info" }, h("span", { class: "source-token-symbol" }, fromToken.symbol), h("span", { class: "source-token-chain" }, fromChain.name)), !isDisabled && (h("svg", { class: "source-chevron", width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor" }, h("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", "stroke-width": "1.5", fill: "none" })))), h("div", { class: "source-balance-section" }, h("span", { class: "source-balance" }, balanceDisplay), hasBalance && (h("div", { class: "source-percent-buttons" }, AMOUNT_PERCENTAGES.map((percent) => (h("button", { class: "source-percent-button", onClick: () => this.setAmountPercent(percent) }, percent === 100 ? "Max" : `${percent}%`))))))), h("input", { type: "text", class: "source-amount-input", placeholder: "0", value: state.fromAmount, onInput: (e) => this.handleAmountChange(e.target.value), onFocus: () => (state.inputDirection = "source") }), exchangeRate && h("div", { class: "exchange-rate" }, exchangeRate)));
    }
    renderTokenList(isFrom) {
        const selectedChain = isFrom ? state.fromChain : state.toChain;
        const selectedToken = isFrom ? this.currentFromToken : this.currentToToken;
        const onSelectToken = isFrom
            ? (asset) => this.selectFromToken(asset)
            : (asset) => this.selectToToken(asset);
        // Use local filtered assets if whitelist was provided
        const baseAssets = isFrom
            ? this.localSourceAssets.length > 0
                ? this.localSourceAssets
                : state.assets
            : this.localDestinationAssets.length > 0
                ? this.localDestinationAssets
                : state.assets;
        const tokensToShow = selectedChain === "all"
            ? baseAssets
            : this.getFilteredAssets(selectedChain, isFrom);
        const filteredTokens = tokensToShow.filter((token) => {
            if (!this.searchQuery)
                return true;
            const query = this.searchQuery.toLowerCase();
            return (token.symbol.toLowerCase().includes(query) ||
                token.name.toLowerCase().includes(query));
        });
        return (h("div", { class: "token-list" }, filteredTokens.map((token) => {
            const tokenChain = state.chains.find((c) => c.id === token.chain);
            const isSelected = selectedToken &&
                token.chain === selectedToken.chain &&
                token.address === selectedToken.address;
            return (h("div", { class: `token-list-item ${isSelected ? "selected" : ""}`, onClick: () => onSelectToken(token) }, h("span", { class: "token-icon-container" }, h("img", { src: token.icon, class: "token-icon", alt: "" }), h("img", { src: tokenChain?.logo, class: "chain-icon", alt: "" })), h("div", { class: "token-list-item-info" }, h("span", { class: "token-list-item-symbol" }, token.symbol), h("span", { class: "token-list-item-chain" }, tokenChain?.name))));
        })));
    }
    renderTokenDropdownHeader(_isFrom) {
        return (h("div", { class: "token-dropdown-header" }, h("button", { class: "back-button", onClick: () => {
                state.showFromTokenList = false;
                state.showToTokenList = false;
            } }, h("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M19 12H5M12 19l-7-7 7-7" }))), h("span", { class: "token-dropdown-title" }, "Select token and network")));
    }
    handleChainFilterChange(chainId, isFrom) {
        if (isFrom) {
            state.fromChain = chainId;
        }
        else {
            state.toChain = chainId;
        }
        this.showChainFilterDropdown = false;
    }
    renderSearchWithChainFilter(isFrom) {
        const selectedChain = isFrom ? state.fromChain : state.toChain;
        // Get the relevant local filtered assets
        const baseAssets = isFrom
            ? this.localSourceAssets.length > 0
                ? this.localSourceAssets
                : state.assets
            : this.localDestinationAssets.length > 0
                ? this.localDestinationAssets
                : state.assets;
        // Filter chains that have at least one token in the filtered assets
        const availableChains = state.chains.filter((c) => {
            if (this.disableEvm && c.runtime === "evm")
                return false;
            if (this.disableSvm && c.runtime === "svm")
                return false;
            return baseAssets.some((a) => a.chain === c.id);
        });
        // Get the selected chain object for display
        const selectedChainObj = selectedChain === "all"
            ? null
            : state.chains.find((c) => c.id === selectedChain);
        return (h("div", { class: "search-with-filter" }, h("div", { class: "search-input-wrapper" }, h("svg", { class: "search-icon-svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("circle", { cx: "11", cy: "11", r: "8" }), h("path", { d: "M21 21l-4.35-4.35" })), h("input", { type: "text", class: "search-input", placeholder: "Search tokens", value: this.searchQuery, onInput: (e) => (this.searchQuery = e.target.value) })), h("div", { class: "chain-filter-dropdown" }, h("button", { class: "chain-filter-trigger", onClick: () => (this.showChainFilterDropdown = !this.showChainFilterDropdown) }, selectedChainObj && (h("img", { src: selectedChainObj.logo, class: "chain-filter-icon", alt: "" })), h("span", { class: "chain-filter-name" }, selectedChainObj ? selectedChainObj.name : "All chains"), h("svg", { class: "chain-filter-chevron", width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor" }, h("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", "stroke-width": "1.5", fill: "none" }))), this.showChainFilterDropdown && (h("div", { class: "chain-filter-menu" }, h("button", { class: `chain-filter-item ${selectedChain === "all" ? "selected" : ""}`, onClick: () => this.handleChainFilterChange("all", isFrom) }, h("span", { class: "chain-item-name" }, "All chains")), availableChains.map((chain) => (h("button", { class: `chain-filter-item ${chain.id === selectedChain ? "selected" : ""}`, onClick: () => this.handleChainFilterChange(chain.id, isFrom) }, h("img", { src: chain.logo, class: "chain-item-icon", alt: "" }), h("span", { class: "chain-item-name" }, chain.name)))))))));
    }
    renderTokenDropdown(isFrom) {
        return (h("div", { class: "token-dropdown" }, this.renderTokenDropdownHeader(isFrom), this.renderSearchWithChainFilter(isFrom), this.renderTokenList(isFrom)));
    }
    renderTokenSelector() {
        return (h("div", { class: "token-selector-container" }, state.showFromTokenList && this.renderTokenDropdown(true), state.showToTokenList && this.renderTokenDropdown(false)));
    }
    renderRecipientInput() {
        const isCrossRuntime = state.fromToken.runtime !== state.toToken.runtime;
        if (!isCrossRuntime)
            return null;
        return (h("div", { class: "swap-section recipient-section" }, h("div", { class: "section-header" }, h("span", { class: "section-label" }, "Recipient Address")), h("input", { type: "text", class: "amount-input recipient-input", placeholder: `Enter ${state.toToken.runtime.toUpperCase()} address`, value: state.recipientAddress || "", onInput: (e) => this.handleRecipientChange(e) })));
    }
    renderErrorAlert() {
        if (!state.quoteError)
            return null;
        return (h("div", { class: "alert-box error" }, h("span", { class: "alert-message" }, state.quoteError)));
    }
    renderSwapButton() {
        // If wallet not connected, show connect button
        if (!state.walletAddress) {
            return (h("button", { class: "swap-button", onClick: () => this.handleWalletAction() }, "Connect Wallet"));
        }
        const isDisabled = this.isSwapButtonDisabled();
        const fromToken = this.currentFromToken;
        // Priority: Custom prop > Dynamic token text > Default
        const buttonLabel = this.buttonText
            ? this.buttonText
            : fromToken
                ? `Pay with ${fromToken.symbol}`
                : "Swap";
        return (h("button", { class: `swap-button ${state.swapLoading ? "loading" : ""}`, disabled: isDisabled, onClick: () => this.showSwapConfirmation() }, state.swapLoading ? "" : buttonLabel));
    }
    renderFooter() {
        const selectedQuote = this.getSelectedQuote();
        const estimatedTime = selectedQuote
            ? formatEstimatedTime(selectedQuote.estFillTime)
            : null;
        return (h("div", { class: "footer" }, h("div", { class: "powered-by" }, "Powered by ", h("img", { class: "m0-icon", src: M0_LOGO_URL, alt: "M0" })), estimatedTime && (h("button", { class: "best-route", onClick: () => (this.showRouteDetails = true) }, h("span", { class: "best-route-label" }, "Best route:"), h("span", { class: "best-route-time" }, estimatedTime, h("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("path", { d: "M12 6v6l4 2" })))))));
    }
    renderRouteDetails() {
        const selectedQuote = this.getSelectedQuote();
        const toToken = this.currentToToken;
        if (!selectedQuote || !toToken)
            return null;
        const outputAmount = formatTokenAmount(selectedQuote.amountOut, toToken.decimals);
        const estimatedTime = formatEstimatedTime(selectedQuote.estFillTime);
        return (h("div", { class: "route-details" }, h("div", { class: "route-details-header" }, h("button", { class: "back-button", onClick: () => (this.showRouteDetails = false) }, h("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M19 12H5M12 19l-7-7 7-7" }))), h("span", { class: "route-details-title" }, "Route details")), h("div", { class: "route-summary" }, h("div", { class: "route-summary-row" }, h("span", { class: "route-summary-label" }, "You receive"), h("span", { class: "route-summary-value" }, h("img", { src: toToken.icon, class: "route-summary-icon", alt: "" }), outputAmount)), h("div", { class: "route-summary-row" }, h("span", { class: "route-summary-label" }, "Estimated time"), h("span", { class: "route-summary-value" }, estimatedTime))), h("div", { class: "route-steps" }, selectedQuote.payloads.map((payload, index) => (h("div", { class: "route-step" }, h("span", { class: "route-step-indicator" }, index < selectedQuote.payloads.length - 1 ? "›" : "↳"), h("div", { class: "route-step-content" }, h("div", { class: "route-step-title" }, payload.annotation), h("div", { class: "route-step-description" }, "It may contain approving token spending transaction"))))))));
    }
    renderConfirmationScreen() {
        const fromToken = this.currentFromToken;
        const toToken = this.currentToToken;
        const selectedQuote = this.getSelectedQuote();
        const fromChain = state.chains.find((c) => c.id === fromToken?.chain);
        const toChain = state.chains.find((c) => c.id === toToken?.chain);
        if (!selectedQuote || !fromToken || !toToken || !fromChain || !toChain) {
            return null;
        }
        const amountOut = parseFloat(selectedQuote.amountOut) / 10 ** toToken.decimals;
        const estimatedTime = formatEstimatedTime(selectedQuote.estFillTime);
        const destinationAddress = state.recipientAddress || state.walletAddress;
        return (h("div", { class: "confirmation-screen" }, h("div", { class: "confirmation-header" }, h("button", { class: "confirmation-back-button", onClick: () => this.resetQuotes() }, h("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M19 12H5M12 19l-7-7 7-7" }))), h("span", { class: "confirmation-title" }, "Swap details")), h("div", { class: "confirmation-token-row" }, h("div", { class: "confirmation-token-info" }, h("span", { class: "confirmation-token-icon-container" }, h("img", { src: fromToken.icon, class: "confirmation-token-icon", alt: "" }), h("img", { src: fromChain.logo, class: "confirmation-chain-icon", alt: "" })), h("div", { class: "confirmation-token-details" }, h("span", { class: "confirmation-token-symbol" }, fromToken.symbol), h("span", { class: "confirmation-token-chain" }, fromChain.name))), h("div", { class: "confirmation-token-amount" }, h("span", { class: "confirmation-amount-value" }, state.fromAmount), h("span", { class: "confirmation-slippage" }, "Max. slippage: ", Math.min(Math.max(Number(this.maxSlippage) || 0, 0), 100), "%"))), h("div", { class: "confirmation-arrow" }, h("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M12 5v14M5 12l7 7 7-7" }))), h("div", { class: "confirmation-token-row" }, h("div", { class: "confirmation-token-info" }, h("span", { class: "confirmation-token-icon-container" }, h("img", { src: toToken.icon, class: "confirmation-token-icon", alt: "" }), h("img", { src: toChain.logo, class: "confirmation-chain-icon", alt: "" })), h("div", { class: "confirmation-token-details" }, h("span", { class: "confirmation-token-symbol" }, toToken.symbol), h("span", { class: "confirmation-token-chain" }, toChain.name))), h("div", { class: "confirmation-token-amount" }, h("span", { class: "confirmation-amount-value" }, amountOut.toLocaleString("en-US", {
            minimumFractionDigits: 2,
            maximumFractionDigits: 6,
        })))), this.swapStatus !== "success" && this.swapStatus !== "failed" && (h("div", { class: "confirmation-details" }, h("div", { class: "confirmation-detail-row" }, h("span", { class: "confirmation-detail-label" }, "You receive"), h("span", { class: "confirmation-detail-value" }, h("img", { src: toToken.icon, class: "confirmation-detail-icon", alt: "" }), amountOut.toLocaleString("en-US", {
            minimumFractionDigits: 0,
            maximumFractionDigits: 6,
        }))), h("div", { class: "confirmation-detail-row" }, h("span", { class: "confirmation-detail-label" }, "Estimated time"), h("span", { class: "confirmation-detail-value confirmation-detail-underline" }, estimatedTime)), h("div", { class: "confirmation-detail-row" }, h("span", { class: "confirmation-detail-label" }, "Destination address"), h("div", { class: "confirmation-detail-address" }, h("span", { class: "confirmation-detail-value confirmation-detail-underline" }, formatWalletAddress(destinationAddress)), h("span", { class: "confirmation-detail-sublabel" }, "Connected wallet"))))), (this.swapStatus === "success" || this.swapStatus === "failed") && (h("div", { class: "confirmation-details confirmation-details-compact" }, h("div", { class: "confirmation-detail-row" }, h("span", { class: "confirmation-detail-label" }, "Destination address"), h("div", { class: "confirmation-detail-address" }, h("span", { class: "confirmation-detail-value confirmation-detail-underline" }, formatWalletAddress(destinationAddress)), h("span", { class: "confirmation-detail-sublabel" }, "Connected wallet"))))), this.swapStatus === "success" && (h("div", { class: "confirmation-result confirmation-result-success" }, h("svg", { class: "confirmation-result-icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("path", { d: "M9 12l2 2 4-4", stroke: "white", "stroke-width": "2", fill: "none" })), h("span", { class: "confirmation-result-text" }, "Swap has been executed"), h("button", { class: "confirmation-result-link", onClick: () => this.handleViewOnExplorer() }, "View on Explorer"))), this.swapStatus === "failed" && (h("div", { class: "confirmation-result confirmation-result-failed" }, h("svg", { class: "confirmation-result-icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor" }, h("circle", { cx: "12", cy: "12", r: "10" }), h("path", { d: "M15 9l-6 6M9 9l6 6", stroke: "white", "stroke-width": "2", fill: "none" })), h("span", { class: "confirmation-result-text" }, "Swap has failed"), h("button", { class: "confirmation-result-link", onClick: () => this.handleTryAgain() }, "Try again"))), this.swapStatus !== "success" && this.swapStatus !== "failed" && (h("button", { class: `confirmation-button ${this.swapStatus === "confirming" ? "loading" : ""}`, onClick: () => this.handleSwap(), disabled: this.swapStatus === "confirming" }, this.swapStatus === "confirming"
            ? "Confirm in wallet..."
            : "Confirm Swap"))));
    }
    renderLoadingState() {
        return (h(Host, null, h("div", { class: "swap-box" }, h("div", { class: "loading-container" }), h("div", { class: "loading-container" }), h("button", { class: "swap-button", disabled: true }, this.buttonText || "Swap"), this.renderFooter())));
    }
    render() {
        if (state.stateLoading) {
            return this.renderLoadingState();
        }
        const showDropdown = state.showFromTokenList || state.showToTokenList;
        // highlightColor is for backgrounds (light colors)
        // primaryColor is for buttons (should be a darker/accent color)
        const highlightValue = this.primaryColor || this.highlightColor;
        const hostStyle = {
            "--highlight-color": highlightValue,
            "--radius": `${this.radius}px`,
        };
        // Only override primary-color if explicitly set
        if (this.primaryColor) {
            hostStyle["--primary-color"] = this.primaryColor;
        }
        // Show route details view
        if (this.showRouteDetails) {
            return (h(Host, { style: hostStyle }, h("div", { class: "swap-box" }, this.renderRouteDetails())));
        }
        // Show confirmation screen
        if (this.showConfirmation) {
            return (h(Host, { style: hostStyle }, h("div", { class: "swap-box" }, this.renderConfirmationScreen())));
        }
        return (h(Host, { style: hostStyle }, h("div", { class: "swap-box" }, this.renderHeader(), showDropdown ? (this.renderTokenSelector()) : (h("div", null, this.renderDestinationHero(), this.renderNetworkSelector(), this.renderSourceCard(), this.renderRecipientInput(), this.renderErrorAlert(), this.renderSwapButton())), this.renderFooter())));
    }
    static get is() { return "swap-module"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["swap-module.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["swap-module.css"]
        };
    }
    static get properties() {
        return {
            "network": {
                "type": "string",
                "attribute": "network",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"mainnet\""
            },
            "disableSvm": {
                "type": "boolean",
                "attribute": "disable-svm",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "disableEvm": {
                "type": "boolean",
                "attribute": "disable-evm",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "rpcOverrides": {
                "type": "unknown",
                "attribute": "rpc-overrides",
                "mutable": false,
                "complexType": {
                    "original": "{ [chain: string]: string }",
                    "resolved": "{ [chain: string]: string; }",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "defaultValue": "{}"
            },
            "radius": {
                "type": "number",
                "attribute": "radius",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "highlightColor": {
                "type": "string",
                "attribute": "highlight-color",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"rgb(243, 248, 252)\""
            },
            "primaryColor": {
                "type": "string",
                "attribute": "primary-color",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"\""
            },
            "enableQueryParams": {
                "type": "boolean",
                "attribute": "enable-query-params",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "widgetTitle": {
                "type": "string",
                "attribute": "widget-title",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"\""
            },
            "reownProjectId": {
                "type": "string",
                "attribute": "reown-project-id",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"\""
            },
            "sourceTokens": {
                "type": "unknown",
                "attribute": "source-tokens",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "destinationTokens": {
                "type": "unknown",
                "attribute": "destination-tokens",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "buttonText": {
                "type": "string",
                "attribute": "button-text",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"\""
            },
            "maxSlippage": {
                "type": "number",
                "attribute": "max-slippage",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "2.5"
            }
        };
    }
    static get states() {
        return {
            "searchQuery": {},
            "localSourceAssets": {},
            "localDestinationAssets": {},
            "localFromToken": {},
            "localToToken": {},
            "showNetworkDropdown": {},
            "showChainFilterDropdown": {},
            "showRouteDetails": {},
            "showWalletDropdown": {},
            "showConfirmation": {},
            "swapStatus": {},
            "lastTransactionHash": {},
            "lastChainId": {}
        };
    }
    static get events() {
        return [{
                "method": "transactionId",
                "name": "transactionId",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "{ transaction: string; chainId: number }",
                    "resolved": "{ transaction: string; chainId: number; }",
                    "references": {}
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "disableSvm",
                "methodName": "handleRuntimeFilterChange"
            }, {
                "propName": "disableEvm",
                "methodName": "handleRuntimeFilterChange"
            }, {
                "propName": "sourceTokens",
                "methodName": "handleTokenWhitelistChange"
            }, {
                "propName": "destinationTokens",
                "methodName": "handleTokenWhitelistChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "click",
                "method": "handleWindowClick",
                "target": "window",
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=swap-module.js.map
