Address: 0x81D7a918...6281cCC63 | Etherscan
window.dataLayer = window.dataLayer || [];
        function gtag() { dataLayer.push(arguments); }
        gtag('js', new Date());
        gtag('config','G-T1JC9RNQXV', { 'anonymize_ip': true });
//Search box text ad
        var availableAd = [];
        var gotAd = [];

        
        availableAd = ["<div class='p-2 border-bottom'><a href='https://goto.etherscan.com/rd/V1FU4H4F7PC1VI6MSG1UZWJ3H' rel='nofollow' target='_blank' data-bs-toggle='tooltip' data-bs-trigger='hover' title='Links to an External Advertiser site' class='search-panel-ads d-flex align-items-center p-2 rounded'><div class='me-2'><img width='22' src='/images/gen/blockscan.svg' alt='Blockscan'></div><div class='text-truncate'><h6 class='d-flex align-items-center fs-sm text-dark mb-0'><div class='text-truncate me-2'>Blockscan - Multichain Explorer, Portfolio & Analytics</div><span class='d-none d-sm-inline-block small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Sponsored</span><span class='d-inline-block d-sm-none small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Ad</span></h6></div></a></div>", "<div class='p-2 border-bottom'><a href='https://goto.etherscan.com/rd/RQVT45DUBNV67THPQAQ5E29DZ' rel='nofollow' target='_blank' data-bs-toggle='tooltip' data-bs-trigger='hover' title='Links to an External Advertiser site' class='search-panel-ads d-flex align-items-center p-2 rounded'><div class='me-2'><img width='22' src='/images/gen/etoro2_20.png' alt='Search Ad'></div><div class='text-truncate'><h6 class='d-flex align-items-center fs-sm text-dark mb-0'><div class='text-truncate me-2'>Trade crypto alongside stocks, ETFs and more on eToro.</div><span class='d-none d-sm-inline-block small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Sponsored</span><span class='d-inline-block d-sm-none small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Ad</span></h6></div></a></div>", "<div class='p-2 border-bottom'><a href='https://goto.etherscan.com/rd/IT3NB7TH7F4S2QVUJ8CICG368' rel='nofollow' target='_blank' data-bs-toggle='tooltip' data-bs-trigger='hover' title='Links to an External Advertiser site' class='search-panel-ads d-flex align-items-center p-2 rounded'><div class='me-2'><img width='22' src='/images/gen/etherscan_20.png' alt='Ad'></div><div class='text-truncate'><h6 class='d-flex align-items-center fs-sm text-dark mb-0'><div class='text-truncate me-2'>Etherscan API - Build with AI via MCP, CLI, and Skills</div><span class='d-none d-sm-inline-block small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Sponsored</span><span class='d-inline-block d-sm-none small bg-white text-muted rounded-1 border px-2 py-1 ms-1'>Ad</span></h6></div></a></div>"];
        gotAd = ["ShowAds					"];
        

        // Temporary fallback to prevent runtime error
        if (typeof window.updatehash !== 'function') {
            const args = [];

            // Create a simple fallback
            window.updatehash = function () {
                args.push(arguments);

                // Retry every 100ms until the updatehash function load
                const retry = setInterval(function () {
                    if (typeof window.updatehash === 'function' && window.updatehash !== fallback) {
                        clearInterval(retry);
                        try {
                            window.updatehash.apply(null, args[0]);
                        } catch (e) {
                            console.error('updatehash retry failed:', e);
                        }
                    }
                }, 100);

                //stop retry after 1s
                setTimeout(() => clearInterval(retry), 1000);
            };

            const fallback = window.updatehash;
         //end temp fallback updatehash
        }
.autolink-safari a {
            pointer-events: none !important;
            text-decoration: none !important;
            color: inherit !important;
        }

        #masterNoticeBar div.alert a{
            color:#fff !important; 
            text-decoration: underline !important;
        }
        .word-break{word-break: break-all !important;}
        .min-with50{min-width: 50px !important;}
.di3gaeet4n6 { -ms-flex-pack: center; justify-content: center; } .arz2unclh9b { border-top: 1px solid #e7eaf3 !important; } body.dark-mode .arz2unclh9b { border-color: #18365b !important; } @media (min-width: 992px) { .bznqzmrhbha { display: block !important; } } @media (min-width: 992px) { .c2w1lzxpp3t { display: inline-block !important; } }
#div-advert {line-height: 1.7}@media (max-width: 667px) {#div-advert {min-height: 62px;}}@media (max-width: 767px) {#div-advert {padding-bottom: 20px;}}
.myMarker {
            position: absolute;
            background: rgba(100,200,100,0.5);
            z-index: 20
        }

        body.dark-mode .myMarker {
            background: blue;
        }

        pre {
            resize: vertical;
            /*overflow: auto;*/
        }

        #icon {
            background-size: cover;
            background-repeat: no-repeat;
            display: inline-block;
        }

        .liA {
            font-size: 11px;
            color: #B3B6B7;
        }

        .liH {
            display: none;
        }

        #overlayMain {
            color: #666666;
            position: fixed;
            height: 100%;
            width: 100%;
            z-index: 5000;
            top: 0;
            left: 0;
            float: left;
            text-align: center;
            padding-top: 20%;
            display: none;
        }

        #qrcode img {
            display: inline-block !important;
        }

        .panel-fullscreen {
            display: block;
            z-index: 9999;
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            overflow: auto;
        }

        .tooltip-inner {
            max-width: 350px;
        }

        @keyframes fa-blink {
            0% {
                opacity: 1;
            }

            25% {
                opacity: 0.25;
            }

            40% {
                opacity: 0.5;
            }

            60% {
                opacity: 0.75;
            }
            /*100% { opacity: 0; }*/
        }

        .fa-blink {
            -webkit-animation: fa-blink .99s linear infinite;
            -moz-animation: fa-blink .99s linear infinite;
            -ms-animation: fa-blink .99s linear infinite;
            -o-animation: fa-blink .99s linear infinite;
            animation: fa-blink .99s linear infinite;
        }

        .popover-header {
            background-color: white;
        }

        .popoverHeader {
            margin-bottom: 0px !important;
        }

        .popoverList {
            padding-left: 20px !important;
        }

        .popoverEnsOwnedAddressLoading {
        }

        .popOverEnsOwnedAddressTable {
            /*display: none;*/
        }

        .popoverLoadingImg {
            width: 10% !important;
        }

        .exclamPoint {
            position: relative !important;
        }

            .exclamPoint i {
                position: absolute;
                top: 0.35em;
                left: -1.5em;
            }

            .exclamPoint::marker {
                content: '';
                /*   font-family: "Font Awesome 5 Duotone";
            content: "\10f071";*/
            }

        .grid-container {
            display: grid;
            grid-template-columns: 30% 30% 30%;
            grid-gap: 0.5em;
        }

        #analytics_pageiframe {
            min-height: 680px;
        }

        body.dark-mode input[type="date"]::-webkit-calendar-picker-indicator {
            filter: invert(1);
        }

        .ace_editor {
            font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace !important;
        }

        /*section[id$="_divSummary"] > div:first-child > div span.hash-tag:not(:is(#divDelegatedAddress *)) {
            max-width: 8rem !important;
        }*/

       /* section[id$="_divSummary"] > div:first-child > div span.hash-tag:not(:is(#divImplementationAddress *)){
            max-width: 9rem !important;
        }*/

        section[id$="_divSummary"]:has(#divDelegatedAddress) > div:first-child > div span.hash-tag {
             max-width: 8rem !important;
         }

        section[id$="_divSummary"]:has(#divImplementationAddress) > div:first-child > div span.hash-tag {
            max-width: 9rem !important;
        }

        .multichain-dropdown .dropdown .dropdown-menu .dropdown-item span.hash-tag {
            max-width: 12rem !important;
        }

         [data-bs-theme=light] .nav-pills-alt .nav-link
        {
          --bs-nav-pills-link-active-bg: var(--bs-gray-200);
          --bs-nav-pills-link-active-color: var(--bs-body-color);
        }

        [data-bs-theme=dim] .nav-pills-alt .nav-link,
        [data-bs-theme=dark] .nav-pills-alt .nav-link
        {
          --bs-nav-pills-link-active-bg: var(--bs-gray-700);
          --bs-nav-pills-link-active-color: var(--bs-body-color);
        }

        #dividcode .card-body > div:last-child {
            margin-bottom: 0px !important;
        }

        .liq-price-progress-bar {
            background-color: #7ed321;
            background-image: linear-gradient(90deg, #7ed321 0%, #f8e71c 50%, #ff8a3d 75%, #dc3545 100%);
            background-position: left center;
            background-repeat: no-repeat;
        }
.dataTables_wrapper .dataTables_length,
        .dataTables_wrapper .dataTables_paginate {
            float: none;
        }

        .datatable-form-control {
            padding-left: 1.75rem;
            width: 14rem !important;
            margin-left: 0 !important;
        }

        #asset-multichain .dataTables_filter input[type="search"],
        #asset-multichain .dataTables_filter input[type="search"]::-webkit-search-decoration,
        #asset-multichain .dataTables_filter input[type="search"]::-webkit-search-cancel-button {
            -webkit-appearance: button !important;
        }

        table.dataTable thead th {
            background: transparent !important;
            white-space: nowrap;
        }

        table.dataTable thead > tr > th.sorting:before,
        table.dataTable thead > tr > th.sorting:after,
        table.dataTable thead > tr > th.sorting_asc:before,
        table.dataTable thead > tr > th.sorting_asc:after,
        table.dataTable thead > tr > th.sorting_desc:before,
        table.dataTable thead > tr > th.sorting_desc:after {
            display: none;
        }

        table.dataTable thead .sorting span {
            background: none;
        }

        table.dataTable thead .sorting_asc span {
            background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="%236c757d" d="M551.1 47.67H312c-13.25 0-24 10.76-24 24.02c0 13.26 10.75 24.02 24 24.02h239.1c13.25 0 24-10.76 24-24.02C575.1 58.43 565.2 47.67 551.1 47.67zM360 431.1h-48c-13.25 0-24 10.76-24 24.02S298.8 480 312 480h48c13.25 0 23.1-10.76 23.1-24.02S373.2 431.1 360 431.1zM423.1 303.9H312c-13.25 0-24 10.76-24 24.02s10.75 24.02 24 24.02h111.1c13.25 0 24-10.76 24-24.02S437.2 303.9 423.1 303.9zM487.1 175.8H312c-13.25 0-24 10.76-24 24.02s10.75 24.02 24 24.02h175.1c13.25 0 24-10.76 24-24.02S501.2 175.8 487.1 175.8zM145.6 39.37c-9.062-9.82-26.19-9.82-35.25 0L14.38 143.4c-9 9.758-8.406 24.96 1.344 33.94C20.35 181.7 26.19 183.8 32 183.8c6.469 0 12.91-2.594 17.62-7.719L104 117.1v338.9C104 469.2 114.8 480 128 480S152 469.2 152 455.1V117.1l54.37 58.95C215.3 185.8 230.5 186.5 240.3 177.4C250 168.4 250.6 153.2 241.6 143.4L145.6 39.37z"/></svg>') no-repeat center right;
        }

        table.dataTable thead .sorting_desc span {
            background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="%236c757d" d="M360 432h-48c-13.25 0-24 10.75-24 24S298.8 480 312 480h48c13.25 0 23.1-10.75 23.1-24S373.2 432 360 432zM423.1 304H312C298.8 304 288 314.8 288 328S298.8 352 312 352h111.1c13.25 0 24-10.75 24-24S437.2 304 423.1 304zM487.1 176H312C298.8 176 288 186.8 288 200S298.8 224 312 224h175.1c13.25 0 24-10.75 24-24S501.2 176 487.1 176zM551.1 48H312C298.8 48 288 58.75 288 72S298.8 96 312 96h239.1c13.25 0 24-10.75 24-24S565.2 48 551.1 48zM206.4 335.1L152 394.9V56.02C152 42.76 141.3 32 128 32S104 42.76 104 56.02v338.9l-54.37-58.95c-4.719-5.125-11.16-7.719-17.62-7.719c-5.812 0-11.66 2.094-16.28 6.375c-9.75 8.977-10.34 24.18-1.344 33.94l95.1 104.1c9.062 9.82 26.19 9.82 35.25 0l95.1-104.1c9-9.758 8.406-24.96-1.344-33.94C230.5 325.5 215.3 326.2 206.4 335.1z"/></svg>') no-repeat center right;
        }

        table.dataTable thead .sorting_asc span,
        table.dataTable thead .sorting_desc span {
            margin-bottom: -0.125rem !important;
            margin-right: 0.5rem !important;
            display: inline-block;
            padding-left: 5px;
            width: 14px;
            height: 14px;
        }

        .hover\:border-secondary:hover {
            border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important;
        }

        .hover\:border-opacity-50:hover {
            --bs-border-opacity: 0.5;
        }

        #div_tabs {
          scroll-margin-top: 40px; /* adjust auto-scroll height for nav tabs */
        }

        /* Code Reader - File Browser */
        #file-browser .accordion-button
        {
          --bs-accordion-btn-padding-x: 0;
          --bs-accordion-btn-padding-y: 0;
        }

        #file-browser .accordion
        {
          --bs-accordion-bg: transparent;
          --bs-accordion-border-width: 0;
          --bs-accordion-btn-color: var(--bs-secondary-color);
          --bs-accordion-btn-icon-width: 1rem;
        }

        #file-browser .accordion-button:not(.collapsed)
        {
          --bs-accordion-active-color: var(--bs-secondary-color);
          --bs-accordion-active-bg: transparent;
          --bs-accordion-border-color: transparent;
        }

        #file-browser ul
        {
          padding-left: 1rem;
        }

        #file-browser .accordion-button::before
        {
          flex-shrink: 0;
          width: 1.25rem;
          height: 1.25rem;
          margin-top: 0.5rem;
          content: "";
          background-image: var(--bs-accordion-btn-active-icon);
          background-repeat: no-repeat;
          background-size: 0.75rem;
          transition: transform .2s ease-in-out;
        }

        #file-browser .accordion-button::after
        {
          display: none !important;
        }
.bg-hero {
            --bs-bg-hero-gradient-1: rgba(255, 255, 255, .9);
            --bs-bg-hero-gradient-2: rgba(255, 255, 255, .6);
            --bs-bg-hero-gradient-1-length: 30%;
            --bs-bg-hero-gradient-2-length: 50%;
            position: relative;
            overflow: hidden;
        }

        [data-bs-theme="dim"] .bg-hero {
            --bs-bg-hero-gradient-1: rgba(17, 26, 46, 0.9);
            --bs-bg-hero-gradient-2: rgba(17, 26, 46, 0.6);
        }

        [data-bs-theme="dark"] .bg-hero {
            --bs-bg-hero-gradient-1: rgba(0, 0, 0, .9);
            --bs-bg-hero-gradient-2: rgba(0, 0, 0, .6);
        }

        .bg-hero::after {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: linear-gradient(to right, var(--bs-bg-hero-gradient-1) var(--bs-bg-hero-gradient-1-length), var(--bs-bg-hero-gradient-2) var(--bs-bg-hero-gradient-2-length));
            z-index: 1;
        }

        .bg-hero--1 {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='%23cccccc' fill-opacity='0.6'%3E%3Cpolygon fill-rule='evenodd' points='8 4 12 6 8 8 6 12 4 8 0 6 4 4 6 0 8 4'/%3E%3C/g%3E%3C/svg%3E");
        }

        .bg-hero--2 {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 304 304' width='304' height='304'%3E%3Cpath fill='%23cccccc' fill-opacity='0.6' d='M44.1 224a5 5 0 1 1 0 2H0v-2h44.1zm160 48a5 5 0 1 1 0 2H82v-2h122.1zm57.8-46a5 5 0 1 1 0-2H304v2h-42.1zm0 16a5 5 0 1 1 0-2H304v2h-42.1zm6.2-114a5 5 0 1 1 0 2h-86.2a5 5 0 1 1 0-2h86.2zm-256-48a5 5 0 1 1 0 2H0v-2h12.1zm185.8 34a5 5 0 1 1 0-2h86.2a5 5 0 1 1 0 2h-86.2zM258 12.1a5 5 0 1 1-2 0V0h2v12.1zm-64 208a5 5 0 1 1-2 0v-54.2a5 5 0 1 1 2 0v54.2zm48-198.2V80h62v2h-64V21.9a5 5 0 1 1 2 0zm16 16V64h46v2h-48V37.9a5 5 0 1 1 2 0zm-128 96V208h16v12.1a5 5 0 1 1-2 0V210h-16v-76.1a5 5 0 1 1 2 0zm-5.9-21.9a5 5 0 1 1 0 2H114v48H85.9a5 5 0 1 1 0-2H112v-48h12.1zm-6.2 130a5 5 0 1 1 0-2H176v-74.1a5 5 0 1 1 2 0V242h-60.1zm-16-64a5 5 0 1 1 0-2H114v48h10.1a5 5 0 1 1 0 2H112v-48h-10.1zM66 284.1a5 5 0 1 1-2 0V274H50v30h-2v-32h18v12.1zM236.1 176a5 5 0 1 1 0 2H226v94h48v32h-2v-30h-48v-98h12.1zm25.8-30a5 5 0 1 1 0-2H274v44.1a5 5 0 1 1-2 0V146h-10.1zm-64 96a5 5 0 1 1 0-2H208v-80h16v-14h-42.1a5 5 0 1 1 0-2H226v18h-16v80h-12.1zm86.2-210a5 5 0 1 1 0 2H272V0h2v32h10.1zM98 101.9V146H53.9a5 5 0 1 1 0-2H96v-42.1a5 5 0 1 1 2 0zM53.9 34a5 5 0 1 1 0-2H80V0h2v34H53.9zm60.1 3.9V66H82v64H69.9a5 5 0 1 1 0-2H80V64h32V37.9a5 5 0 1 1 2 0zM101.9 82a5 5 0 1 1 0-2H128V37.9a5 5 0 1 1 2 0V82h-28.1zm16-64a5 5 0 1 1 0-2H146v44.1a5 5 0 1 1-2 0V18h-26.1zm102.2 270a5 5 0 1 1 0 2H98v14h-2v-16h124.1zM242 149.9V160h16v34h-16v62h48v48h-2v-46h-48v-66h16v-30h-16v-12.1a5 5 0 1 1 2 0zM53.9 18a5 5 0 1 1 0-2H64V2H48V0h18v18H53.9zm112 32a5 5 0 1 1 0-2H192V0h50v2h-48v48h-28.1zm-48-48a5 5 0 0 1-9.8-2h2.07a3 3 0 1 0 5.66 0H178v34h-18V21.9a5 5 0 1 1 2 0V32h14V2h-58.1zm0 96a5 5 0 1 1 0-2H137l32-32h39V21.9a5 5 0 1 1 2 0V66h-40.17l-32 32H117.9zm28.1 90.1a5 5 0 1 1-2 0v-76.51L175.59 80H224V21.9a5 5 0 1 1 2 0V82h-49.59L146 112.41v75.69zm16 32a5 5 0 1 1-2 0v-99.51L184.59 96H300.1a5 5 0 0 1 3.9-3.9v2.07a3 3 0 0 0 0 5.66v2.07a5 5 0 0 1-3.9-3.9H185.41L162 121.41v98.69zm-144-64a5 5 0 1 1-2 0v-3.51l48-48V48h32V0h2v50H66v55.41l-48 48v2.69zM50 53.9v43.51l-48 48V208h26.1a5 5 0 1 1 0 2H0v-65.41l48-48V53.9a5 5 0 1 1 2 0zm-16 16V89.41l-34 34v-2.82l32-32V69.9a5 5 0 1 1 2 0zM12.1 32a5 5 0 1 1 0 2H9.41L0 43.41V40.6L8.59 32h3.51zm265.8 18a5 5 0 1 1 0-2h18.69l7.41-7.41v2.82L297.41 50H277.9zm-16 160a5 5 0 1 1 0-2H288v-71.41l16-16v2.82l-14 14V210h-28.1zm-208 32a5 5 0 1 1 0-2H64v-22.59L40.59 194H21.9a5 5 0 1 1 0-2H41.41L66 216.59V242H53.9zm150.2 14a5 5 0 1 1 0 2H96v-56.6L56.6 162H37.9a5 5 0 1 1 0-2h19.5L98 200.6V256h106.1zm-150.2 2a5 5 0 1 1 0-2H80v-46.59L48.59 178H21.9a5 5 0 1 1 0-2H49.41L82 208.59V258H53.9zM34 39.8v1.61L9.41 66H0v-2h8.59L32 40.59V0h2v39.8zM2 300.1a5 5 0 0 1 3.9 3.9H3.83A3 3 0 0 0 0 302.17V256h18v48h-2v-46H2v42.1zM34 241v63h-2v-62H0v-2h34v1zM17 18H0v-2h16V0h2v18h-1zm273-2h14v2h-16V0h2v16zm-32 273v15h-2v-14h-14v14h-2v-16h18v1zM0 92.1A5.02 5.02 0 0 1 6 97a5 5 0 0 1-6 4.9v-2.07a3 3 0 1 0 0-5.66V92.1zM80 272h2v32h-2v-32zm37.9 32h-2.07a3 3 0 0 0-5.66 0h-2.07a5 5 0 0 1 9.8 0zM5.9 0A5.02 5.02 0 0 1 0 5.9V3.83A3 3 0 0 0 3.83 0H5.9zm294.2 0h2.07A3 3 0 0 0 304 3.83V5.9a5 5 0 0 1-3.9-5.9zm3.9 300.1v2.07a3 3 0 0 0-1.83 1.83h-2.07a5 5 0 0 1 3.9-3.9zM97 100a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-48 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 96a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-144a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM49 36a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM33 68a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 240a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm80-176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm112 176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 180a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 84a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6z'%3E%3C/path%3E%3C/svg%3E");
        }

        /* Gradient Border */
        .gradient-border {
            --bs-gradient-border-fill: #fff;
            --bs-gradient-border-angle: 45deg;
            --bs-gradient-border-1: #d5d9e6;
            --bs-gradient-border-1-length: 50%;
            --bs-gradient-border-2: #e7e9ea;
            --bs-gradient-border-2-length: 100%;
            overflow: hidden;
            border: 2px solid transparent;
            background: linear-gradient(var(--bs-gradient-border-fill), var(--bs-gradient-border-fill)) padding-box, linear-gradient(var(--bs-gradient-border-angle), var(--bs-gradient-border-1) var(--bs-gradient-border-1-length), var(--bs-gradient-border-2) var(--bs-gradient-border-2-length)) border-box;
        }

         /* Dynamic gradient border transition */
        .js-gradient-border {
            transition: all 0.3s ease;
        }

        [data-bs-theme="dim"] .gradient-border,
        [data-bs-theme="dark"] .gradient-border {
            --bs-gradient-border-1: #3d454a;
            --bs-gradient-border-2: #232f31;
        }

        .gradient-border--1 {
            --bs-gradient-border-1: #e5cefc;
        }

        [data-bs-theme="dim"] .gradient-border--1,
        [data-bs-theme="dark"] .gradient-border--1 {
            --bs-gradient-border-1: #554368;
        }

        .gradient-border--2 {
            --bs-gradient-border-1: #cac5fd;
        }

        [data-bs-theme="dim"] .gradient-border--2,
        [data-bs-theme="dark"] .gradient-border--2 {
            --bs-gradient-border-1: #4d478b;
        }

        /* Hide these iframes until they have a real src to prevent the ui gap issue */
        #crosschaintx_pageiframe,
        #authlist7702_pageiframe,
        #aatx_pageiframe {
            display: none !important;
        }

        #crosschaintx_pageiframe[src]:not([src=""]):not([src="about:blank"]),
        #authlist7702_pageiframe[src]:not([src=""]):not([src="about:blank"]),
        #aatx_pageiframe[src]:not([src=""]):not([src="about:blank"]) {
            display: block !important;
        }
ETH Price:
$2,453.85
(-0.49%)
Gas:
0.115
Gwei
/
Light
Dim
Dark
Auto (System)
Site Settings
Ethereum Mainnet
Beaconscan
ETH2
Sepolia Testnet
Hoodi Testnet
Sign In
Home
Blockchain
Transactions
Pending Transactions
Contract Internal Transactions
Cross-Chain Transactions
Beacon Deposits
Beacon Withdrawals
View Blobs
AA Transactions
EIP-7702 Authorizations
Beta
View Blocks
Forked Blocks (Reorgs)
Uncles
Top Accounts
Verified Contracts
Tokens
Top Tokens
(ERC-20)
Token Transfers
(ERC-20)
Token Flow Visualizer
Beta
NFTs
Top NFTs
Top Mints
Latest Trades
Latest Transfers
Latest Mints
Resources
Charts And Stats
Top Statistics
Leaderboard
Directory
Newsletter
Knowledge Base
API
Etherscan API
API Pricing
API Documentation
More
Developer Tools
Input Data Encoder
Beta
Input Data Decoder
Unit Converter
Download Data (CSV Export)
Account Balance Checker
Broadcast Transaction
Bytecode to Opcode
Smart Contract Tools
Code Reader
Verify Contract
Similar Contract Search
Smart Contract Search
Contract Diff Checker
Vyper Online Compiler
Explore
Gas Tracker
DEX Tracker
Node Tracker
Label Cloud
Domain Name Lookup
Services
Token Approvals
Verified Signature
Input Data Messages (IDM)
Advanced Filter
Blockscan Chat
Explorers
Ethereum Mainnet
Beaconscan
ETH2
Sepolia Testnet
Hoodi Testnet
Site Settings
Appearance
Light
Dim
Dark
Auto (System)
|
Sign In
Address
0x81D7a91860a70B312E68c075C896aA06281cCC63
Buy
Sponsored
etoro
Explore Crypto
Start Investing
Explore a diverse range of leading cryptoassets and trade them alongside stocks, ETFs, and more.
MetaMask
Trade on the go. Up to 50x leverage.
Try Now!
No new accounts, no brokers, no waiting. Trade perps in seconds.
Prediction
Sponsored
Kings.Game
Predict Crypto, Sports & the World’s Biggest Events!
Make Your Prediction!
Enjoy Tournaments, Weekly and Monthly Bonuses, High-Roller VIP manager. Turn your insights into rewards.
1win
Make Your Pick — 1win Predictions
Join Now!
Who Wins? Predict the Winner and Play on 1win.
Play
Sponsored
Сoins.game
100 free spins for registration.
Spin now!
Everyday giveaways up to 100 ETH, Lucky Spins. Deposit BONUS 300% and Cashbacks!
BC.GAME
The Best ETH Casino
Claim Now!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Stake
200% Bonus, Instant Withdrawals, 100K Daily Giveaways, BEST VIP Club
Claim Bonus!
20+ Cryptos, 3000+ Slots, Daily & Monthly Bonuses, Exclusive Sports Promos - Provably Fair!
Gaming
Sponsored
BC.GAME
- The Best ETH Casino
Claim Now!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
CryptoSlots
177% Deposit Bonus + 25 Free Spins on $1M Jackpot Slot
Play now!
Play original casino games with fast withdrawals, provably fair gameplay and anonymous ETH deposits.
Slotland
Play Exclusive Slots with ETH
Claim Now!
Deposit with crypto, play original Slotland games, and cash out fast. New players get a $40 free bonus + 200% first deposit bonus.
window.sevioads = window.sevioads || [];
	var sevioads_preferences = [];
	sevioads_preferences[0] = {};
	sevioads_preferences[0].zone = "d6bf9add-82b8-4674-888c-e54e61131431";
	sevioads_preferences[0].adType = "native";
	sevioads_preferences[0].inventoryId = "f0db8e6b-00d9-4d0d-81e5-4dd5863517d0";
	sevioads_preferences[0].accountId = "ae4111e1-f910-4f63-ade0-89e8fe771ab1";
	sevioads.push(sevioads_preferences);
API
Token Approvals
Beta
Check Previous Balance
Update Name Tag or Label
Report/Flag Address
Overview
ETH Balance
0
.
000198401211662 ETH
Eth Value
$0.49
(@ $2,453.85/ETH)
Token Holdings
$0.00
(1 Tokens)
Could not find any matches!
ERC-20 Tokens (1)
ERC-20: MECH...
(
MECHAM...
)
1,599,760 MECHAMASK
$0.00
View All Holdings
More Info
Private Name Tags
Add
Transactions Sent
Latest:
13 days ago
First:
16 days ago
Funded By
0xf1331A64...8aA65D955
|
16 days ago
Multichain Info
$54.96
(Multichain Portfolio)
2 addresses found via
Blockscan
BscScan
($52)
BaseScan
($1)
Blockscan (View All)
@media only screen and (min-width: 0px) and (min-height: 0px) {
    	div[id^="wrapper-sevio-d3a79e0c-f10a-4ec2-80e8-3ea7abc07689"] {
        	min-width: 320px;
        	min-height: 100px;
    	}
	}
	@media only screen and (min-width: 830px) and (min-height: 0px) {
    	div[id^="wrapper-sevio-d3a79e0c-f10a-4ec2-80e8-3ea7abc07689"] {
        	min-width: 728px;
        	min-height: 90px;
    	}
	}
	@media only screen and (min-width: 1140px) and (min-height: 0px) {
    	div[id^="wrapper-sevio-d3a79e0c-f10a-4ec2-80e8-3ea7abc07689"] {
        	min-width: 320px;
        	min-height: 100px;
    	}
	}
Ad
window.sevioads = window.sevioads || [];
    	var sevioads_preferences = [];
    	sevioads_preferences[0] = {};
    	sevioads_preferences[0].zone = "d3a79e0c-f10a-4ec2-80e8-3ea7abc07689";
    	sevioads_preferences[0].adType = "banner";
    	sevioads_preferences[0].inventoryId = "f0db8e6b-00d9-4d0d-81e5-4dd5863517d0";
    	sevioads_preferences[0].accountId = "ae4111e1-f910-4f63-ade0-89e8fe771ab1";
	sevioads_preferences[0].cmp = false;
    	sevioads.push(sevioads_preferences);
Transactions
Internal Transactions
Token Transfers (ERC-20)
Other Transactions
Analytics
Assets
Cards
Advanced Filter
Toggle Dropdown
Filter by Tx Type:
Tx
Internal Tx
ERC-20
Latest 7 from a total of  7 transactions
Download Page Data
View Completed Txns
View Pending Txns
View Failed Txns
View Outgoing Txns
View Incoming Txns
View Contract Creation
Transaction Hash
Method
Block
From
To
0x373a3ccd0a05b224a4d6f7f4ab08dc445a317230bb9bdbd443c2f5f430445d7e
Transfer
Transfer
25856331
2026-08-28 21:09:11
13 days ago
1787951351
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0x3C95d9e0F76e08cD9a6cb5c7dB508c4F4072B9F3
0.0956006 ETH
$234.59
0
.
00000159
0
.
07613277
0x6c68e14617a1bccb5e9390086d9d3f9683b3bafb71d87c9ba647f881b7f058e3
Transfer
Transfer
25833868
2026-08-25 18:01:23
16 days ago
1787680883
0x500ba6A9DCD58C8A973e437465CDB0e6Fc18363a
IN
0x81D7a91860a70B312E68c075C896aA06281cCC63
0.00000959 ETH
$0.02
0
.
00000471
0
.
22473734
0xef44ce03ae12ef0d23479220b8f9b5f2f40e533e7064394707c0c7048f3b3ebd
Swap
Swap
25833867
2026-08-25 18:01:11
16 days ago
1787680871
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0x4313C378Cc91eA583C91387B9216e2c03096b27f
0 ETH
$0.00
0
.
00053394
1
.
85631948
0x1073782a475da5b2a49beb1de9a9da62030dfdaa77ab61a85b5b8384f25c32b1
Approve
Approve
25833866
2026-08-25 18:00:59
16 days ago
1787680859
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0xa79892Ae5224Abb17dDd9caB3EbB5d045Ff7c579
0 ETH
$0.00
0
.
00008591
1
.
85631948
0x7d317d605a63d9aa7bca9745e985b1632b9394b8a851264f2f54a058fc51fc85
Sigma Swap
Sigma Swap
25833860
2026-08-25 17:59:47
16 days ago
1787680787
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0xb704Fcb4c43BdC030dE7EC5e0d5264B99Aa3af36
0.031 ETH
$76.07
0
.
00002967
0
.
1411044
0xa7cb4990ac2821beebe96fe98c64519f7cda240fe63e852cd594207f81fe6798
Swap
Swap
25833859
2026-08-25 17:59:35
16 days ago
1787680775
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0x4313C378Cc91eA583C91387B9216e2c03096b27f
0.03333333 ETH
$81.79
0
.
00271627
15
0x51084348de433d752df746e7c2cff5eaa5927d9db7b421a7960c7eec6c3281c6
Swap
Swap
25833859
2026-08-25 17:59:35
16 days ago
1787680775
0x81D7a91860a70B312E68c075C896aA06281cCC63
OUT
0x4313C378Cc91eA583C91387B9216e2c03096b27f
0.01666666 ETH
$40.90
0
.
00297259
15
Latest 4 internal transactions
Download Page Data
Advanced mode:
Parent Transaction Hash
Method
Block
From
To
0x2cab764b66b07dafbaf99dac0655f04591bd4c781165c710284cee379ee3eddb
Transfer
Transfer
25842591
2026-08-26 23:12:11
15 days ago
1787785931
0xf1331A64F507A1b1e0D3cFAec25aE508aA65D955
0x81D7a91860a70B312E68c075C896aA06281cCC63
0.03916575 ETH
$96.11
0xef44ce03ae12ef0d23479220b8f9b5f2f40e533e7064394707c0c7048f3b3ebd
Transfer
Transfer
25833867
2026-08-25 18:01:11
16 days ago
1787680871
0x4313C378Cc91eA583C91387B9216e2c03096b27f
0x81D7a91860a70B312E68c075C896aA06281cCC63
0.01352237 ETH
$33.18
0x7d317d605a63d9aa7bca9745e985b1632b9394b8a851264f2f54a058fc51fc85
Transfer
Transfer
25833860
2026-08-25 17:59:47
16 days ago
1787680787
0xb704Fcb4c43BdC030dE7EC5e0d5264B99Aa3af36
0x81D7a91860a70B312E68c075C896aA06281cCC63
0.00702402 ETH
$17.24
0xf57a6fed8330566a8c553fde464a6116a1c63b01b59e0e49683523f7214a380e
Transfer
Transfer
25833689
2026-08-25 17:25:35
16 days ago
1787678735
0xf1331A64F507A1b1e0D3cFAec25aE508aA65D955
0x81D7a91860a70B312E68c075C896aA06281cCC63
0.12341725 ETH
$302.85
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Cross-Chain Transactions
Block
Transaction
Difficulty
Gas Used
Reward
View All Blocks Produced
Validator Index
Block
Amount
View All Withdrawals
Transaction Hash
Block
Value
Eth2 PubKey
Valid
View All Deposits
Loading...
Loading
Custom
Read Custom
Write Custom
API
Contract Name
0 ETH
Compiler Version
0
Optimization Enabled
0 ETH
Other Settings
-NA-
License
-NA-
Custom Contract ABI
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Transaction Hash
Block
Age
Implementation
Event
Status
Proxy Contract
Transaction Hash
Block
Age
Proxy Type
Block
Uncle Number
Difficulty
Gas Used
Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Multichain Portfolio
Tokens
NFTs
0x81D7a91860a70B312E68c075C896aA06281cCC63
Net Worth in USD
$54.96
Net Worth in ETH
0.022397
Token Allocations
SPCXB
20.82%
WBNB
19.47%
GMEB
12.96%
Others
46.75%
Multichain Portfolio
|
                                            30 Chains
Display all chains
•
Last updated:
less than 1 sec ago
BNB Chain
(11)
$52
(95%)
Base
(1)
$1
(3%)
HyperEVM
(1)
0
(1%)
Ethereum
(1)
0
(1%)
Polygon
(0)
0
(0%)
Arbitrum One
(0)
0
(0%)
Optimism
(0)
0
(0%)
BTTC
(0)
0
(0%)
Celo
(0)
0
(0%)
Linea
(0)
0
(0%)
Avax C-Chain
(0)
0
(0%)
opBNB
(0)
0
(0%)
Fraxtal
(0)
0
(0%)
Blast
(0)
0
(0%)
Mantle
(0)
0
(0%)
Taiko
(0)
0
(0%)
World
(0)
0
(0%)
XDC
(0)
0
(0%)
Ape
(0)
0
(0%)
Unichain
(0)
0
(0%)
Berachain
(0)
0
(0%)
MemeCore
(0)
0
(0%)
Sonic
(0)
0
(0%)
Abstract
(0)
0
(0%)
Katana
(0)
0
(0%)
Sei
(0)
0
(0%)
Monad
(0)
0
(0%)
Plasma
(0)
0
(0%)
Stable
(0)
0
(0%)
MegaEth
(0)
0
(0%)
Show 28 more chains
Hide 28 chains
Tokens
Chain
Token
Portfolio %
Price
Amount
Value
BSC
SpaceX
(SPCXB)
20.82%
$149.14
0.0767
$11.44
BSC
Wrapped BNB
(WBNB)
19.47%
$711.68
0.015
$10.7
BSC
GameStop
(GMEB)
12.96%
$21.13
0.3371
$7.12
BSC
BNB
(BNB)
11.86%
$710.89
0.00917196
$6.52
BSC
NVIDIA Corp
(NVDAB)
6.03%
$220.09
0.0151
$3.31
BSC
Aster
(ASTER)
5.64%
$0.681235
4.5474
$3.1
BSC
SPY
(SPYB)
5.37%
$761.86
0.00387424
$2.95
BSC
Binance-Peg Litecoin Token
(LTC)
5.10%
$52.08
0.0538
$2.8
BSC
Trump Media & Technology Group Corp
(DJTB)
5.10%
$8.86
0.3162
$2.8
BSC
Pepe
(PEPE)
1.97%
$0.000003
335,983.0359
$1.09
BSC
Micron Technology Inc
(MUB)
0.99%
$983.16
0.00055624
$0.5468
BASE
Ether
(ETH)
2.65%
$2,454.28
0.00059286
$1.46
HYPEREVM
Hype
(HYPE)
1.15%
$78.79
0.00801856
$0.631744
ETH
Ether
(ETH)
0.89%
$2,453.85
0.0001984
$0.486847
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download:
CSV Export
]
[ Download:
CSV Export
]
A wallet address is a publicly available address that allows its owner to receive funds from another party. To access the funds in an address, you must have its private key. Learn more about addresses in our
Knowledge Base
.
Address QR Code
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addresses
Private Note:
A private note (up to 500 characters) can be attached to this address.
Please
DO NOT
store any passwords or private keys here.
View all Private Name Tags
Close
Save Changes
👋
Before You Continue...
📝
Connecting your wallet enables signing messages to verify ownership or signing messages to interact with smart contracts.
⚠️
This is provided as is, without guarantees or warranties of any kind.
💸
All interactions are at your own risk. Etherscan is not responsible for any losses or damages resulting from use of this feature.
🧠
Please ensure you understand what you're doing before continuing.
🔗
Learn more about
connecting your wallet on Etherscan
.
Understand and Continue
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.
Rabby Wallet
MetaMask
WalletConnect (Reown)
Coinbase Wallet
Other Wallets
No wallet found
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.
Rabby Wallet
MetaMask
WalletConnect (Reown)
Coinbase Wallet
Other Wallets
No wallet found
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.
Rabby Wallet
MetaMask
WalletConnect (Reown)
Coinbase Wallet
Other Wallets
No wallet found
Address Cards
To use this feature, please
login
to your Etherscan account and return to this page.
Add Custom ABI
Address
Custom ABI
Magic Fill
Find Similar
Apply Custom ABI to enable custom read/write functions for the current session. Save to also enable them for future sessions.
Sign in
to save this ABI to your account.
Cancel
Apply Custom ABI
×
Before You Copy
Don't show this for 30 days
Understand, Copy Address
Transaction Private Note
Transaction Hash
Private Note Description
Please
DO NOT
store any passwords or private keys here. A private note (up to 100 characters) can be saved and is useful for transaction tracking.
View All Transactions Private Notes
Cancel
Save changes
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addresses
Private Note:
A private note (up to 500 characters) can be attached to this address. Please DO NOT store any passwords or private keys here.
View all Private Name Tags
Close
Save Changes
Back to Top
Powered by Ethereum
Etherscan is a Block Explorer and Analytics Platform for Ethereum, a decentralized smart contracts platform.
Company
About Us
Brand Assets
Contact Us
Careers
We're Hiring!
Terms
&
Privacy
Bug Bounty
Trust Center
Community
API Documentation
Knowledge Base
Network Status
Newsletters
What is a Block Explorer?
Products & Services
Etherscan Premium
Advertise
Explorer as a Service (EaaS)
Etherscan API
Priority Support
Blockscan
Blockscan Chat
Etherscan © 2026  (B1)
Donations:
0x71c765...d8976f
This website
uses cookies to improve your experience
. By continuing to use this website, you agree to its
Terms
and
Privacy Policy
.
Got it!
// Global HTML encoder for safe interpolation into template literals (text content AND attribute contexts).
        // Equivalent to server-side HttpUtility.HtmlEncode(). Use this instead of filterXSS() in template literals.
        function htmlEncode(str) { var s = (str == null) ? '' : String(str); return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#x27;'); }
        // URL sanitizer for href/src attributes. Blocks dangerous URI schemes.
        function sanitizeUrl(url) { var dangerous = ['javascript:', 'data:', 'vbscript:', 'file:']; var lower = (url || '').toLowerCase().trim(); for (var i = 0; i < dangerous.length; i++) { if (lower.startsWith(dangerous[i])) return '#'; } return url; }
(function () {
            // INITIALIZATION OF CLIPBOARD
            HSCore.components.HSClipboard.init('.js-clipboard');

            let searchAttributes = {
                'name': 'title',
                'img': 'img',
                'rate': 'rate',
                'address': 'address',
                'link': 'link',
                'group': 'group',
                'groupid': 'groupid',
                'website': 'website',
                'is_verified': 'is_checked',
                'ps': 'ps',
                'desc': 'desc',
                'reputation' : 'reputation',
                'icon': 'icon'
            }

            etherSearchInit({
                id: 'search-panel',
                attributes: searchAttributes
            });


        })();
$(window).on('load', function () {
            myfn_subscribeNewsletter.startFn("#btnSubscribeNewsletter", "#signupSrEmail")
        });

        $(document).on('ready', function () {

            // Get offset timezone of enduser and set to cookie
            const date = new Date();
            const offsetMinutes = date.getTimezoneOffset();
            const offsetHours = Math.abs(offsetMinutes / 60);
            const sign = offsetMinutes > 0 ? '-' : '+';
            offsetHoursFinal = sign + offsetHours;
            writeCookie("etherscan_offset_datetime", offsetHoursFinal, 365);

            const clipboard = new ClipboardJS('.js-clipboard');
            clipboard.on('success', function (e) {
                let toolTip = bootstrap.Tooltip.getInstance(e.trigger);
                var oriTooltip = toolTip._config.originalTitle
               
                toolTip._config.title = 'Copied!';
                toolTip.setContent();
                toolTip.update();

                setTimeout(function () {
                    toolTip._config.title = oriTooltip;
                }, 1000);
            });
        });
var sid = 'ceba909ee6615a3b0e1ed88facfda156';
        var strGlobal = getCookie("etherscan_switch_age_datetime");
        var strGlobalFee = sessionStorage.getItem("ShowFee");
        var strGlobalSlotEpoch = sessionStorage.getItem("ShowSlotEpoch");
        var cookieconsent = getCookie("etherscan_cookieconsent");
        var ignoreCopyConfirmation = getCopyAddressConfirmationSetting();
        
        if (cookieconsent !== "True" && document.getElementById("divcookie")) {
            document.getElementById("divcookie").style.display = "block";
        };
          

        function getCookie(cname) {
            var name = cname + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) === ' ') {
                    c = c.substring(1);
                }
                if (c.indexOf(name) === 0) {
                    return c.substring(name.length, c.length);
                }
            }
            return "";
        }

        $("#btnCookie").click(function () {
            $("#divcookie").fadeOut("slow", function () {
                var d = new Date();
                d.setTime(d.getTime() + (1095 * 24 * 60 * 60 * 1000));
                var expires = "expires=" + d.toUTCString();
                document.cookie = "etherscan_cookieconsent=True" + ";" + expires + ";path=/";;
            });
        });

        function handleSearchText(data) {
            searchAddress = false;
            if ($("search-panel").val() == "") {
                $("#hdnSearchText").val("");
                $("#hdnSearchLabel").val("");
            }
        }

        function writeCookie(key, value, days) {
            var date = new Date();
            days = days || 365;
            date.setTime(+ date + (days * 86400000));
            window.document.cookie = key + "=" + value + "; expires=" + date.toGMTString() + "; path=/";
            return value;
        }

        function setThemeMode(mode) {
            writeCookie('displaymode', mode);
        }

        // Note: this function will be called from where need to init the "Copy Address Confirm Modal".
        function openCopyAddressConfirmModal(address, message) {
            $("#addressToCopy").text(address);
            $("#copyAddressConfirmMessage").text(message);

            const clipboard = new ClipboardJS("#btnConfirmCopyAddress");
            document.getElementById('copyAddressConfirmModal').addEventListener('hidden.bs.modal', event => {
                clipboard.destroy();
            });

            const copyAddressConfirmModal = new bootstrap.Modal('#copyAddressConfirmModal', {
                backdrop: true
            })
            copyAddressConfirmModal.show();
        }

        function saveCopyAddressConfirmationSetting(ignoreCopyConfirmation) {
            const copyAddressConfirmationSetting = {
                ignoreCopyConfirmation: ignoreCopyConfirmation,
                expiresOn: Date.now() + 1000 * 60 * 60 * 24 * 30
            };
            localStorage.setItem("copyAddressConfirmationSetting", JSON.stringify(copyAddressConfirmationSetting));
        }

        function getCopyAddressConfirmationSetting() {
            try {
                const settings = localStorage.getItem("copyAddressConfirmationSetting");
                if (settings) {
                    const copyAddressConfirmationSetting = JSON.parse(settings);

                    return copyAddressConfirmationSetting.ignoreCopyConfirmation && copyAddressConfirmationSetting.expiresOn > Date.now();
                }
                else {
                    return false;
                }
            } catch (e) {
                return false;
            }
        }
var web3ojb;
        var objProvider
        var isTestnet = 'false';
        var chain = 'Mainnet'

        ListenProviderList();
        async function addNetwork(type) {
            if (isTestnet != 'true') return;
            if ((chain != 'Sepolia') && (chain != 'Hoodi')) return;

            if (type === 'web3') {
                if (typeof ethereum !== 'undefined') {
                    objProvider = await initweb3walletProvider("MetaMask");
                    web3ojb = new Web3(objProvider.provider);
                } else if (typeof web3 !== 'undefined') {
                    web3ojb = new Web3(web3.givenProvider);
                } else {
                    alert("Please Install Metamask");
                    return;
                }
            }

            if (typeof web3ojb !== 'undefined') {
                var network = 0;
                network = await web3ojb.eth.getChainId(); //web3ojb.eth.net.getId();
                netID = network.toString();
                var params;
                if (isTestnet == 'true') {
                    if (chain == "Sepolia" || chain == "Hoodi") {
                        if (netID == "11155111" && chain == "Sepolia") {
                            alert("Sepolia Test Network has already been added to Metamask.");
                            return;
                        } else if (netID == "560048" && chain == "Hoodi") {
                            alert("Hoodi Test Network has already been added to Metamask.");
                            return;
                        } else {
                            if (chain == "Sepolia") {
                                params = [{
                                    chainId: '0xaa36a7',
                                    chainName: 'Sepolia Test Network',
                                    nativeCurrency: {
                                        name: 'Sepolia Test Network',
                                        symbol: 'ETH',
                                        decimals: 18
                                    },
                                    rpcUrls: ['https://ethereum-sepolia-rpc.publicnode.com/'],
                                    blockExplorerUrls: ['https://sepolia.etherscan.io/']
                                }]
                            } else {
                                params = [{
                                    chainId: '0x88bb0',
                                    chainName: 'Hoodi Test Network',
                                    nativeCurrency: {
                                        name: 'ETH',
                                        symbol: 'ETH',
                                        decimals: 18
                                    },
                                    rpcUrls: ['https://0xrpc.io/hoodi'],
                                    blockExplorerUrls: ['https://hoodi.etherscan.io/']
                                }]
                            }

                            if (window.ethereum.providers?.length) {
                                let indexProvider = parent.ethereum.providers.findIndex((provider) => provider.isMetaMask);

                                GeneralRequestWithProvider('wallet_addEthereumChain', params, objProvider.provider)
                                    .then(() => console.log('Success'))
                                    .catch((error) => console.log("Error", error.message));
                            } else {
                                if (window.ethereum.isMetaMask) {
                                    GeneralRequestWithProviderAlter('wallet_addEthereumChain', params, objProvider.provider)
                                        .then(() => console.log('Success'))
                                        .catch((error) => {
                                            if (error.code === -32602) { // network already added
                                                if (chain == "Sepolia") {
                                                    alert("Sepolia Test Network has already been added to Metamask.");
                                                    return;
                                                }
                                            }
                                        });
                                } else {
                                    alert("Please Install Metamask");
                                }
                            }
                        }
                    }
                } else {
                    alert('Unable to locate a compatible web3 browser!');
                }
            }
        }
var MaxLines = '0';
        var blnCheckDisqusCount = 'false';
        var strURL = '//';
        var litreadContractAddress = '0x81D7a91860a70B312E68c075C896aA06281cCC63';
        var litLanguage = 'en';
        var litMinimalProxyImplementation = '';
        var litContractABIAddressCode = '';
        var litProxyContractABIAddress = '';
        var litCustomContractABIAddress = '';
        
        var customAbiChainId = '1';
        
        var strNetwork = 'mainnet';
        var litCurrencyCode = 'USD';
        var LitAdvancedModeAvailable = 'true';
        var sid = 'ceba909ee6615a3b0e1ed88facfda156';
        var addressType = 'EOA';
        var litGotSafeLabel = '0';
        var isSignedIn = '0';
        function initPerpsTable() {
            if (!document.getElementById('perpsTable') || $.fn.dataTable.isDataTable('#perpsTable')) return;

            new DataTable('#perpsTable', {
                info: false,
                searching: false,
                ordering: false,
                pageLength: 10,
                lengthChange: true,
                paging: true,
                pagingType: 'full',
                dom: 't<\"perps-table-footer card-footer d-flex flex-wrap align-items-center justify-content-between gap-3\"lp>',
                language: {
                    paginate: {
                        next: '<i class=\"fa fa-chevron-right small\"></i>',
                        previous: '<i class=\"fa fa-chevron-left small\"></i>'
                    },
                    lengthMenu: 'Show rows: _MENU_'
                },
                drawCallback: function (settings) {
                    var tableWrapper = settings.nTableWrapper;
                    tableWrapper.classList.add('perps-table-wrapper');
                    var footer = tableWrapper.querySelector('.perps-table-footer');
                    var pagination = footer ? footer.querySelector('.dataTables_paginate') : null;
                    if (pagination) pagination.classList.add('perps-table-pagination');
                    if (footer) {
                        var lengthSelect = footer.querySelector('.dataTables_length select');
                        if (lengthSelect) {
                            lengthSelect.disabled = settings.fnRecordsDisplay() <= settings._iDisplayLength;
                            lengthSelect.className = 'form-select form-select-sm w-auto';
                        }
                        var lengthLabel = footer.querySelector('.dataTables_length label');
                        if (lengthLabel) lengthLabel.className = 'd-flex align-items-center gap-1 text-muted';
                    }
                }
            });
        }

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initPerpsTable);
        } else {
            initPerpsTable();
        }
window.customAbiLimits = {"maxAbiLength":524288,"maxAbiEntries":500,"maxAbiParameters":5000,"maxAbiDepth":16,"maxArrayLength":1024};
var isLoadedSafeOwner = false;
        const ownersDropdownToggle = document.getElementById('ownersDropdown');
        if (ownersDropdownToggle) {
            const ownersDropdownTooltipTriggerEl = ownersDropdownToggle.parentElement;
            const ownersDropdownMainTooltip = bootstrap.Tooltip.getInstance(ownersDropdownTooltipTriggerEl) || new bootstrap.Tooltip(ownersDropdownTooltipTriggerEl);

            // When the dropdown is shown, hide and disable the main tooltip
            ownersDropdownToggle.addEventListener('show.bs.dropdown', function () {
                ownersDropdownMainTooltip.hide();
                ownersDropdownMainTooltip.disable();
            });

            // When the dropdown is hidden, enable back the main tooltip
            ownersDropdownToggle.addEventListener('hide.bs.dropdown', function () {
                ownersDropdownMainTooltip.enable();
            });
        }

        function myFnGetSafeOwner() {
            if (litGotSafeLabel == "1" && isLoadedSafeOwner == false) {
                $("#owner_container").html('<li><i class="fa fa-spin fa-spinner"></i></li>');
                isLoadedSafeOwner = true;

                $.ajax({
                    url: "/address.aspx/DoOwnersAddress",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify({
                        sid: sid,  
                        strAddress: $("#hdnAddress").val()
                    }),
                    success: function (response) {
                        if (response && (response.d || !response.d.startsWith("Error"))) {
                            $("#owner_container").html(response.d); 
                        } else if (response && response.d.startsWith("Error")) {
                            $("#owner_container").html("<li>Unexpected error</li>");
                        } else {
                            $("#owner_container").html("");
                        }

                        var ownersDropdownChildTooltipTriggerList = [].slice.call(document.querySelectorAll('#owner_container [data-bs-toggle="tooltip"]'));
                        var ownersDropdownChildTooltipList = ownersDropdownChildTooltipTriggerList.map(function (ownersDropdownChildTooltipTriggerEl) {
                            return new bootstrap.Tooltip(ownersDropdownChildTooltipTriggerEl);
                        });
                    },
                    error: function (xhr, status, error) {
                        $("#owner_container").html("<li>Unexpected error</li>");
                    }
                });
            }
        }

        // INITIALIZATION OF HIGHLIGHT
        TextHighlight.init();

        window.token_transfer_loaded = false;
        window.token_nft_transfer_loaded = false;
        window.authlist7702_loaded = false;
        window.analytics_loaded = false;
        window.loans_loaded = false;
        window.events_tracker = false;
        window.writeContractLoaded = false;
        window.readContractLoaded = false;
        window.writeProxyContractLoaded = false;
        window.readProxyContractLoaded = false;
        window.multipleProxyContractLoaded = false;
        window.multipleReadProxyContractLoaded = false;
        window.multipleWriteProxyContractLoaded = false;
        window.writeCustomContractLoaded = false;
        window.readCustomContractLoaded = false;
        window.cards_loaded = false;
        window.mode = 'light';
        var iframeopt = {}

        function openWalletDisclaimerModal(opt) {
            iframeopt = opt
            $('#walletDisclaimerModal').modal('show');
        }
        function openAfterWalletDisclaimerModal() {
            if (iframeopt.source == "read") {
                try {
                    if (document.URL.indexOf('readProxyContract') != -1) {
                        openProxyModal("readproxycontractiframe");
                        document.getElementById("readContractMessageProxy").classList.add("d-flex");
                    }
                    else if (document.URL.indexOf('readCustomContract') != -1) {
                        openModal("readcustomcontractiframe");
                        var targetIframe = document.getElementById("readcustomcontractiframe");
                        document.getElementById("readContractMessage").classList.add("d-flex");
                        targetIframe.style.minHeight = '600px';
                    }
                    else {
                        var isInIFrame = (window.location != iframeopt.location);
                        if (isInIFrame) {
                            openModal("readcontractiframe");
                            var targetIframe = document.getElementById("readcontractiframe");
                            document.getElementById("readContractMessage").classList.add("d-flex");
                            targetIframe.style.minHeight = '600px';
                        } else {
                            $('#WalletModalProxyIframeNew').modal('show');
                        }
                    }
                } catch (err) { }
            } else if(iframeopt.source == "write") {
                try {
                    if (window.document.URL.indexOf('writeProxyContract') != -1) {
                        window.document.getElementById("readContractMessageProxy").classList.remove("d-flex");
                        openProxyModal("writeproxycontractiframe");
                    } else {
                        var isInIFrame = (window.location != iframeopt.location);
                        if (isInIFrame) {
                            openModal("writecontractiframe");
                            var targetIframe = window.document.getElementById("writecontractiframe")
                            targetIframe.style.minHeight = '600px';
                            window.document.getElementById("readContractMessage").classList.remove("d-flex");
                        } else {
                            $('#WalletModalProxyIframeNew').modal('show');
                        }
                    }
                } catch (err) { }
            } else if (iframeopt.source == "writecustom") {
                try {
                    var isInIFrame = (window.location != iframeopt.location);
                    if (isInIFrame) {
                        openCustomeContractModal("writecustomcontractiframe");
                        var targetIframe = window.document.getElementById("writecustomcontractiframe")
                        targetIframe.style.minHeight = '600px';
                        window.document.getElementById("readContractMessageCustomeContract").classList.remove("d-flex");
                    }
                } catch (err) { }
            } else if (iframeopt.source == "readmultiple") {
                try {
                    openProxyModal("multiplereadfacetiframe");
                } catch (err) { }
            } else if (iframeopt.source == "writemultiple") {
                try {
                    openProxyModal("multiplewritefacetiframe");
                } catch (err) { }
            }
        }
        function openModal(type) {
            var mtmStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('web3')";
            $("#btnMetamask").attr("onClick", mtmStr)

            let walletConnectStr_reown = "walletConnect_reown('" + type + "')";
            $("#btnWalletConnect_reown").attr("onClick", walletConnectStr_reown);

            var coinbaseStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('walletLink')";
            $("#btnCoinbaseWallet").attr("onClick", coinbaseStr);

            let rabbyWallet = "connectRabby('" + type + "')";
            $("#btnRabbyWallet").attr("onClick", rabbyWallet);

            let otherWallet = "switchReadWriteOtherWallet('" + type + "')"; 
            $("#btnOtherWallet").attr("onClick", otherWallet);

            $('#WalletModal').modal('show');
        }

        function closeModal() {
            $('#WalletModal').modal('hide');
        }

        function openProxyModal(type) {
            var mtmStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('web3')";
            $("#btnMetamaskProxy").attr("onClick", mtmStr)

            let walletConnectStr_reown = "walletConnect_reown('" + type + "')";
            $("#btnWalletConnect_reownProxy").attr("onClick", walletConnectStr_reown);

            var coinbaseStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('walletLink')";
            $("#btnCoinbaseWalletProxy").attr("onClick", coinbaseStr);

            let rabbyWallet = "connectRabby('" + type + "')";
            $("#btnRabbyWalletProxy").attr("onClick", rabbyWallet);

            let otherWallet = "switchProxyReadWriteOtherWallet('" + type + "')";
            $("#btnOtherWalletProxy").attr("onClick", otherWallet);

            $('#WalletModalProxyIframe').modal('show');
        }

        function openCustomeContractModal(type) {
            let mtmStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('web3')";
            $("#btnMetamaskCustomeContract").attr("onClick", mtmStr)

            var walletConnectStr_reown = "walletConnect_reown('" + type + "')";
            $("#btnWalletConnect_reownCustomeContract").attr("onClick", walletConnectStr_reown);

            let coinbaseStr = "document.getElementById('" + type + "').contentWindow.connectWeb3('walletLink')";
            $("#btnCoinbaseWalletCustomeContract").attr("onClick", coinbaseStr);

            let rabbyWallet = "connectRabby('" + type + "')";
            $("#btnRabbyWalletProxyCustomeContract").attr("onClick", rabbyWallet);

            let otherWallet = "switchCustomReadWriteOtherWallet('" + type + "')";
            $("#btnOtherWalletProxyCustomeContract").attr("onClick", otherWallet);

            $('#WalletModalCustomeContractIframe').modal('show');
        }

        function closeProxyModal() {
            $('#WalletModalProxyIframe').modal('hide');
        }

        function closeCustomeContractModal() {
            $('#WalletModalCustomeContractIframe').modal('hide');
        }


        //------------ read write connect wallet ------------------------------------

            function switchReadWriteOtherWallet(type) {
                document.getElementById("readWriteWalletList").classList.add("d-none");
                document.getElementById("otherReadWriteWalletList").classList.remove("d-none");
                document.getElementById("readWriteBackButton").classList.remove("d-none");
                document.getElementById("readWriteBackButtonInfo").classList.remove("d-none");
                document.getElementById("exampleModalLabel").innerText = "Other Wallets";

                const searchInput = document.getElementById("otherReadWriteWalletSearch");
                searchInput.value = "";

                renderOtherReadWriteWalletList(type);
                filterOtherReadWriteWalletList();
                searchInput.focus();
            }

            function showReadWriteWalletList() {
                document.getElementById("readWriteWalletList").classList.remove("d-none");
                document.getElementById("otherReadWriteWalletList").classList.add("d-none");
                document.getElementById("readWriteBackButton").classList.add("d-none");
                document.getElementById("readWriteBackButtonInfo").classList.add("d-none");
                document.getElementById("exampleModalLabel").innerText = "Connect a Wallet";

                document.getElementById("otherReadWriteWalletSearch").value = "";
                document.getElementById("otherReadWriteWalletNoSearchResult").classList.add("d-none");
            }

            function renderOtherReadWriteWalletList(type) {
                const container = document.getElementById("otherReadWriteWalletContainer");
                const noSearchResult = document.getElementById("otherReadWriteWalletNoSearchResult");

                container.innerHTML = "";
                noSearchResult.classList.add("d-none");

                //list wallet to filter out
                const excludedWallets = ["Rabby Wallet", "Coinbase Wallet", "MetaMask"];

                const uniqueProviders = [...new Map(providers.map(p => [p.info.name, p])).values()].filter(wallet => !excludedWallets.includes(wallet.info.name));

                if (uniqueProviders.length === 0) {
                    container.innerHTML = '<div class="text-muted text-center py-3">No available wallet</div>';
                    return;
                }

                uniqueProviders.forEach(wallet => {
                    container.innerHTML += `
                <button type="button" data-wallet-name="${filterXSS(wallet.info.name.toLowerCase())}" onclick="connectOther('${filterXSS(type)}','${filterXSS(wallet.info.name)}')" class="btn btn-lg btn-wallet d-flex justify-content-between align-items-center w-100 p-3 mb-2">
                    <span class="text-dark">${filterXSS(wallet.info.name)}</span>
                    <img width="25" src="${filterXSS(wallet.info.icon)}" alt="${filterXSS(wallet.info.name)}">
                </button>
            `;
                });
            }


        function filterOtherReadWriteWalletList() {
            const searchInput = document.getElementById("otherReadWriteWalletSearch");
            const container = document.getElementById("otherReadWriteWalletContainer");
            const noSearchResult = document.getElementById("otherReadWriteWalletNoSearchResult");

            const keyword = searchInput.value.trim().toLowerCase();
            const buttons = container.querySelectorAll("button");

            let visibleCount = 0;

            buttons.forEach(btn => {
                const text = btn.textContent.toLowerCase();
                const walletName = (btn.getAttribute("data-wallet-name") || "").toLowerCase();

                const isMatch = text.includes(keyword) || walletName.includes(keyword);

                if (isMatch) {
                    btn.classList.remove("d-none");
                    btn.classList.add("d-flex");
                    visibleCount++;
                } else {
                    btn.classList.remove("d-flex");
                    btn.classList.add("d-none");
                }
            });

            const hasButtons = buttons.length > 0;
            noSearchResult.classList.toggle("d-none", !(hasButtons && visibleCount === 0));
        }

        document.getElementById("otherReadWriteWalletSearch").addEventListener("input", filterOtherReadWriteWalletList);



            const walletModal = document.getElementById('WalletModal');

            walletModal.addEventListener('hidden.bs.modal', function () {
                showReadWriteWalletList();
            });


        //----------------------------------------------

        //------------ proxy read write connect wallet ------------------------------------

            function switchProxyReadWriteOtherWallet(type) {
                document.getElementById("proxyReadWriteWalletList").classList.add("d-none");
                document.getElementById("otherProxyReadWriteWalletList").classList.remove("d-none");
                document.getElementById("proxyReadWriteBackButton").classList.remove("d-none");
                document.getElementById("proxyReadWriteBackButtonInfo").classList.remove("d-none");
                document.getElementById("ProxyModalLabel").innerText = "Other Wallets";

                const searchInput = document.getElementById("otherProxyReadWriteWalletSearch");
                searchInput.value = "";

                renderOtherProxyReadWriteWalletList(type);
                filterProxyOtherReadWriteWalletList();
                searchInput.focus();
            }

            function showProxyReadWriteWalletList() {
                document.getElementById("proxyReadWriteWalletList").classList.remove("d-none");
                document.getElementById("otherProxyReadWriteWalletList").classList.add("d-none");
                document.getElementById("proxyReadWriteBackButton").classList.add("d-none");
                document.getElementById("proxyReadWriteBackButtonInfo").classList.add("d-none");
                document.getElementById("ProxyModalLabel").innerText = "Connect a Wallet";

                document.getElementById("otherProxyReadWriteWalletSearch").value = "";
                document.getElementById("otherProxyReadWriteWalletNoSearchResult").classList.add("d-none");
            }

            function renderOtherProxyReadWriteWalletList(type) {
                const container = document.getElementById("otherProxyReadWriteWalletContainer");
                const noSearchResult = document.getElementById("otherProxyReadWriteWalletNoSearchResult");
                container.innerHTML = "";

                //list wallet to filter out
                const excludedWallets = ["Rabby Wallet", "Coinbase Wallet", "MetaMask"];

                const uniqueProviders = [...new Map(providers.map(p => [p.info.name, p])).values()].filter(wallet => !excludedWallets.includes(wallet.info.name));

                if (uniqueProviders.length === 0) {
                    container.innerHTML = '<div class="text-muted text-center py-3">No available wallet</div>';
                    return;
                }


                uniqueProviders.forEach(wallet => {
                    container.innerHTML += `
                            <button type="button" data-wallet-name="${filterXSS(wallet.info.name.toLowerCase())}" onclick="connectOther('${filterXSS(type)}','${filterXSS(wallet.info.name)}')" class="btn btn-lg btn-wallet d-flex justify-content-between align-items-center w-100 p-3 mb-2">
                                <span class="text-dark">${filterXSS(wallet.info.name)}</span>
                                <img width="25" src="${filterXSS(wallet.info.icon)}" alt="${filterXSS(wallet.info.name)}">
                            </button>
                        `;
                });
        }

        function filterProxyOtherReadWriteWalletList() {
            const searchInput = document.getElementById("otherProxyReadWriteWalletSearch");
            const container = document.getElementById("otherProxyReadWriteWalletContainer");
            const noSearchResult = document.getElementById("otherProxyReadWriteWalletNoSearchResult");

            const keyword = searchInput.value.trim().toLowerCase();
            const buttons = container.querySelectorAll("button");

            let visibleCount = 0;

            buttons.forEach(btn => {
                const text = btn.textContent.toLowerCase();
                const walletName = (btn.getAttribute("data-wallet-name") || "").toLowerCase();

                const isMatch = text.includes(keyword) || walletName.includes(keyword);

                if (isMatch) {
                    btn.classList.remove("d-none");
                    btn.classList.add("d-flex");
                    visibleCount++;
                } else {
                    btn.classList.remove("d-flex");
                    btn.classList.add("d-none");
                }
            });

            const hasButtons = buttons.length > 0;
            noSearchResult.classList.toggle("d-none", !(hasButtons && visibleCount === 0));
        }

        document.getElementById("otherProxyReadWriteWalletSearch").addEventListener("input", filterProxyOtherReadWriteWalletList);

            const proxyWalletModal = document.getElementById('WalletModalProxyIframe');

            proxyWalletModal.addEventListener('hidden.bs.modal', function () {
                showProxyReadWriteWalletList();
            });
        //----------------------------------------------


        //------------ custom read write connect wallet ------------------------------------

        function switchCustomReadWriteOtherWallet(type) {
            document.getElementById("customReadWriteWalletList").classList.add("d-none");
            document.getElementById("otherCustomReadWriteWalletList").classList.remove("d-none");
            document.getElementById("customReadWriteBackButton").classList.remove("d-none");
            document.getElementById("customReadWriteBackButtonInfo").classList.remove("d-none");
            document.getElementById("CustomeContractModalLabel").innerText = "Other Wallets";

            const searchInput = document.getElementById("otherCustomReadWriteWalletSearch");
            searchInput.value = "";

            renderOtherCustomReadWriteWalletList(type);
            filterCustomOtherReadWriteWalletList();
            searchInput.focus();
        }

        function showCustomReadWriteWalletList() {
            document.getElementById("customReadWriteWalletList").classList.remove("d-none");
            document.getElementById("otherCustomReadWriteWalletList").classList.add("d-none");
            document.getElementById("customReadWriteBackButton").classList.add("d-none");
            document.getElementById("customReadWriteBackButtonInfo").classList.add("d-none");
            document.getElementById("CustomeContractModalLabel").innerText = "Connect a Wallet";

            document.getElementById("otherCustomReadWriteWalletSearch").value = "";
            document.getElementById("otherCustomReadWriteWalletNoSearchResult").classList.add("d-none");
        }

        function renderOtherCustomReadWriteWalletList(type) {
            const container = document.getElementById("otherCustomReadWriteWalletContainer");
            const noSearchResult = document.getElementById("otherCustomReadWriteWalletNoSearchResult");
            container.innerHTML = "";

            //list wallet to filter out
            const excludedWallets = ["Rabby Wallet", "Coinbase Wallet", "MetaMask"];

            const uniqueProviders = [...new Map(providers.map(p => [p.info.name, p])).values()].filter(wallet => !excludedWallets.includes(wallet.info.name));


            if (uniqueProviders.length === 0) {
                container.innerHTML = '<div class="text-muted text-center py-3">No available wallet</div>';
                return;
            }

            uniqueProviders.forEach(wallet => {
                container.innerHTML += `
                    <button type="button" data-wallet-name="${filterXSS(wallet.info.name.toLowerCase())}" onclick="connectOther('${filterXSS(type)}','${filterXSS(wallet.info.name)}')" class="btn btn-lg btn-wallet d-flex justify-content-between align-items-center w-100 p-3 mb-2">
                        <span class="text-dark">${filterXSS(wallet.info.name)}</span>
                        <img width="25" src="${filterXSS(wallet.info.icon)}" alt="${filterXSS(wallet.info.name)}">
                    </button>
                `;
            });
        }

        function filterCustomOtherReadWriteWalletList() {
            const searchInput = document.getElementById("otherCustomReadWriteWalletSearch");
            const container = document.getElementById("otherCustomReadWriteWalletContainer");
            const noSearchResult = document.getElementById("otherCustomReadWriteWalletNoSearchResult");

            const keyword = searchInput.value.trim().toLowerCase();
            const buttons = container.querySelectorAll("button");

            let visibleCount = 0;

            buttons.forEach(btn => {
                const text = btn.textContent.toLowerCase();
                const walletName = (btn.getAttribute("data-wallet-name") || "").toLowerCase();

                const isMatch = text.includes(keyword) || walletName.includes(keyword);

                if (isMatch) {
                    btn.classList.remove("d-none");
                    btn.classList.add("d-flex");
                    visibleCount++;
                } else {
                    btn.classList.remove("d-flex");
                    btn.classList.add("d-none");
                }
            });

            const hasButtons = buttons.length > 0;
            noSearchResult.classList.toggle("d-none", !(hasButtons && visibleCount === 0));
        }

        document.getElementById("otherCustomReadWriteWalletSearch").addEventListener("input", filterCustomOtherReadWriteWalletList);

        const customWalletModal = document.getElementById('WalletModalCustomeContractIframe');

        customWalletModal.addEventListener('hidden.bs.modal', function () {
            showCustomReadWriteWalletList();
        });
        //----------------------------------------------


        function resetPath() {
            window.location.href = "#auditReportId";
            var baseUrl = window.location.href.split('#')[0];
            history.replaceState("", document.title, baseUrl + '#' + 'code');
        }

        function walletConnect_reown(id) {
            var elem = document.getElementById(id);
            elem.contentWindow.connectWeb3('walletConnect_reown');
            elem.style.height = '750px';
        }

        function connectRabby(id) {
            var elem = document.getElementById(id);
            elem.contentWindow.connectWeb3('rabby');
            if (elem.offsetHeight < 750)
                elem.style.height = '750px';
        }

        //other wallet
        function connectOther(id, name) {
            var elem = document.getElementById(id);
            elem.contentWindow.connectWeb3(name, providers);
            if (elem.offsetHeight < 750)
                elem.style.height = '750px';
        }

        function removeHeight() {
            var element = document.getElementById('writecontractiframe');
            element.style.removeProperty("min-height");
        }


        //editor 
        var editor_contractJsonData = '{}'
        var editor_activeFile = ''
        EtherEditor.init({
            container: document.getElementById('editor-1'),
            localFiles: editor_contractJsonData,
            activeFile: editor_activeFile
        });
        // endeditor 
       
        window.smoothScroll = function (target) {
            var scrollContainer = target;
            do { //find scroll container
                scrollContainer = scrollContainer.parentNode;
                if (!scrollContainer) return;
                scrollContainer.scrollTop += 1;
            } while (scrollContainer.scrollTop == 0);

            var targetY = 0;
            do { //find the top of target relatively to the container
                if (target == scrollContainer) break;
                targetY += target.offsetTop;
            } while (target = target.offsetParent);

            scroll = function (c, a, b, i) {
                i++; if (i > 30) return;
                c.scrollTop = a + (b - a) / 30 * i;
                setTimeout(function () { scroll(c, a, b, i); }, 20);
            }
            // start scrolling
            scroll(scrollContainer, scrollContainer.scrollTop, targetY - 50, 0);
        }

        function initialiseKeyupOnDocReady() {
            var input = document.getElementById("txtSearchContract");
            input.addEventListener("keyup", function (event) {
                var flag = false;
                if (event.keyCode === 40 || event.keyCode === 13) { // On Enter Key Press or Down Arrow Press
                    searchContractNext();
                    flag = true;
                } else if (event.keyCode === 38) { // On Up Arrow Press
                    searchContractPrevious();
                    flag = true;
                }
                if (!flag) {
                    searchContractOnThisPage();
                }
                if ($("#txtSearchContract").val().trim() === "") {
                    searchContractOnThisPage();
                }
            });

            var ctrlDown = false, ctrlKey = 17, cmdKey = 91, vKey = 86, cKey = 67;
            $(document).keydown(function (e) {
                if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = true;
            }).keyup(function (e) {
                if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = false;
            });

            // Document Ctrl + C/V 
            $(document).keydown(function (e) {
                if (ctrlDown && (e.keyCode == vKey)) {
                    clearControls();
                }
            });
        }

        // ===== Domain Name warning messages
        const unicodeWarningMessage = 'The Domain Name tag for this address contains characters from more than one Unicode alphabet.'
        const zeroWidthWarningMessage = ''

        // ===== ENS name tag
        let otherENSNamesHtml = "";
        const ensDisplayName = '';
        function initEnsNamePopOver() {
            //required to allow bootstrap popover to support table
            $.fn.popover.Constructor.Default.allowList.table = [];
            $.fn.popover.Constructor.Default.allowList.tr = [];
            $.fn.popover.Constructor.Default.allowList.td = [];
            $.fn.popover.Constructor.Default.allowList.th = [];
            $.fn.popover.Constructor.Default.allowList.div = [];
            $.fn.popover.Constructor.Default.allowList.tbody = [];
            $.fn.popover.Constructor.Default.allowList.thead = [];

            //whitelist my inline styling for bootstrap
            $.fn.popover.Constructor.Default.allowList['*'].push('style');

            let ensUnicodeWarningHtml = "";
            if ($("#hdnIsEnsContainUnicodeChars").val() == "true") {
                ensUnicodeWarningHtml =
                    `<div class='d-flex align-items-baseline gap-1'>
                        <i class='far fa-exclamation-triangle'></i>
                        <span>${unicodeWarningMessage} Check the actual text at <a target='_blank' href='https://app.ens.domains/name/${$("#hdnEnsText").val()}'>ENS</a>.</span>
                    </div>`;
            }
            let ensZeroWidthWarningHtml = "";
            if ($("#hdnIsEnsContainZeroWidthChars").val() == "true") {
                ensZeroWidthWarningHtml =
                    `<div class='d-flex align-items-baseline gap-1'>
                        <i class='far fa-exclamation-triangle'></i>
                        <span>${zeroWidthWarningMessage} Check the actual text at <a target='_blank' href='https://app.ens.domains/name/${$("#hdnEnsText").val()}'>ENS</a>.</span>
                    </div>`;
            }

            const contentHtml =
                `<div id='popover-ens-preview'>
                    <h5 class='fs-base fw-bold mb-4'>Additional Info</h5>
                    <div>
                        <h6 class='fs-sm mb-1'>Full Name:</h6>
                        <div id='fullEnsName' class='badge border text-dark fw-normal fs-sm rounded-pill d-inline-flex align-items-center gap-1 py-1'>
                            <img width='12' src='/images/svg/icons/ENS.svg' alt='ENS Name'>
                            <div id='divENSDisplayName'></div><span id='spanCopyENSAddress'></span>
                        </div>
                    </div>
                    <hr>
                    <div class='popOverEnsOwnedAddressTable'></div>
                    <hr>
                    <h6 class='fs-sm mb-1'>Note:</h6>
                    <ul class='list-xs-space ps-4 mb-2'>
                        <li>Name tag is displayed due to forward and reverse resolution. <a href='https://info.etherscan.com/domain-names-on-etherscan/' target='_blank' rel='nofollow'>Find out more</a>.</li>
                        <li>A Domain Name is not necessarily held by a person popularly associated with the name.</li>
                    </ul>
                    ${ensUnicodeWarningHtml}
                    ${ensZeroWidthWarningHtml}
                </div>`;

            $('#ensName').popover({
                html: true,
                content: contentHtml,
                trigger: 'manual',
                placement: 'right'
            });

            $('#ensName').click(function (event) {
                $("#ensName").popover('toggle');

                event.stopPropagation();
            });

            $('#ensName').on('shown.bs.popover', async () => {
                //disable tooltip when hovering over ens name in the main page
                $("[rel='tooltipEns']").each(function () {
                    $(this).tooltip('hide');
                    $(this).tooltip('disable');
                });

                //call ajax here to get result
                if (!otherENSNamesHtml) {
                    const resolvedAddressesModel = await getEnsResolvedAddress($("#hdnAddress").val(), $("#hdnEnsText").val());

                    otherENSNamesHtml = generateEnsPopoverGrid(resolvedAddressesModel.d);
                    if (!otherENSNamesHtml) {
                        otherENSNamesHtml = "There are no other names resolving to this address."
                    }
                }
                $(".popOverEnsOwnedAddressTable").html(otherENSNamesHtml);

                $("#divENSDisplayName").html(ensDisplayName);

                // append more copy button for ENS
                let domainName = $("#hdnEnsText").val();
                const copyEnsButtonHtml = `<a class="js-clipboard link-secondary" href="javascript:;" data-clipboard-text="${domainName}" data-bs-toggle="tooltip" title="Copy Domain Name"
                                              data-hs-clipboard-options='{
                                                "type": "tooltip",
                                                "successText": "Copied!",
                                                "classChangeTarget": "#linkEns",
                                                "defaultClass": "fa-copy",
                                                "successClass": "fa-check"
                                              }'>
                                              <i id="linkEns" class="far fa-copy fa-fw"></i>
                                            </a>`;
                $("#spanCopyENSAddress").html(copyEnsButtonHtml);
                $("[data-bs-toggle='tooltip']").tooltip();

            });

            $('#ensName').on('hidden.bs.popover', () => {
                $("[rel='tooltipEns']").each(function () {
                    $(this).tooltip('enable');
                });
            });

            $('#ensName').on('hide.bs.popover', () => {
                $("[data-bs-toggle='tooltip']").tooltip('hide');
            });

            $(document).click(function (e) {
                //$("#ensName").popover('hide');
                const popoverElement = document.getElementById('popover-ens-preview');
                const popoverTrigger = document.getElementById('ensName');
                if (!popoverTrigger.contains(e.target) && (!popoverElement || !popoverElement.contains(e.target))) {
                    $("#ensName").popover('hide');
                }
            })
        }
        async function getEnsResolvedAddress(address, currentEnsText) {
            try {
                const requestModel = { "lookupAddress": address, "primaryDomainName": currentEnsText, "provider": "ENS" };
                const response = await $.ajax({
                    url: "/name-lookup-search.aspx/GetOtherDomainNameForAddress",
                    type: "POST",
                    contentType: "application/json",
                    dataType: "json",
                    data: JSON.stringify({ requestModel: requestModel })
                })

                return response;
            }
            catch {
                return "";
            }
        }
        function generateEnsPopoverGrid(model) {
            if (!model || model.DomainNames.length == 0) {
                return "";
            }

            let listOtherENSNames = "";
            model.DomainNames.forEach(x => listOtherENSNames += x.Name);

            let moreOtherENSNames = "";
            if (model.Total > 5) {
                moreOtherENSNames =
                    `<a class='d-block badge bg-light hover:bg-secondary border text-dark fw-normal text-truncate w-100 py-1.5'
                        target='_blank' href='/name-lookup-search?id=${$("#hdnAddress").val()}'>More
                        <i class='fa fa-arrow-right pos-top-n1 small ms-1'></i>
                    </a>`
            }

            const result =
                `<h6 class="fs-sm mb-1">Other names resolving to this address:</h6>
                <div class='grid-container'>
                    ${listOtherENSNames}
                    ${moreOtherENSNames}
                </div>`;

            return result;
        }
        // ===== end ENS name tag

        const tooltipForTokenHolding = '1 Token Contract';
        var adjustPosition = 0;
        $(document).ready(function () {
            switchAmountToValue(document.getElementById("headerAmountValue"), 'Value (USD)', 'Amount', true);
            switchAmountToValue(document.getElementById("headerIntAmountValue"), 'Value (USD)', 'Amount', true);
            switchMethodColumn(document.getElementById("headerMethod"), 'Method', 'Action', true);
            switchMethodColumn(document.getElementById("headerMethod_internaltx"), 'Method', 'Action', true);

            onDocumentReady();
            $("[rel='tooltip']").tooltip();
            $("[data-bs-toggle-second='tooltip']").tooltip({ trigger: 'hover' });
            $("[rel='tooltipEns']").each(function () {
                $(this).tooltip({ title: $(this).attr("tooltip-title") });
            });

            

            //if (hash != '') {
            //    activaTab(hash);
            //};

            onAddressDocReady();
            initDustCopyWarning();

            //// Note: this is causing "Copied" tooltip not showing when copy button is clicked in V3, and seems like not applicable to v3, comment out first in case there is issue
            //$('[data-bs-toggle="tooltip"]').click(function () {
            //    $('[data-bs-toggle="tooltip"]').tooltip("hide");
            //});

            if (document.getElementById("copyaddressbutton")) {
                document.getElementById("copyaddressbutton").classList.remove("disabled");
            }

            if ($("#txtSearchContract").length) {
                initialiseKeyupOnDocReady();
            }

            if (!!$('#ensName')[0]) {
                initEnsNamePopOver();
            }

            $("#btnLoginRequired").attr("href", "/login?ref=" + window.location.pathname.slice(1));

            if (window.matchMedia("(max-width: 767px)").matches) {
                // Mobile
                adjustPosition = 90;
            } else {
                // Others
                adjustPosition = 50;
            }

            if (tooltipForTokenHolding) {
              const dropdownMenuBalance = document.getElementById("dropdownMenuBalance");

              if (dropdownMenuBalance) {
                const dropdownWrapper = dropdownMenuBalance.closest(".dropdown");

                if (dropdownWrapper) {
                  dropdownWrapper.setAttribute("title", tooltipForTokenHolding);
                  new bootstrap.Tooltip(dropdownWrapper);
                }
              }
            }

            setIOState();
            setFiltersStatus();
            applyNativeBrowserSearch("[data-truncate='address']");

            $("#chkHideLowValueTransactions").change(function () {
                constructFilterUrl(this);
            });
            const currentFilters = new URLSearchParams(window.location.search);
            const hdst = currentFilters.get("hdst");
            if (hdst === "true") {
                $("#chkHideLowValueTransactions").prop("checked", true);
            }
        });

        function displayAudit() {
            $('html, body').animate({
                scrollTop: $("#auditReportId").offset().top - adjustPosition
            });
        }

        // Bootstrap Dropdown in Table Responsive
        $('.table-responsive').on('shown.bs.dropdown', function (e) {
            var t = $(this),
                m = $(e.target).find('.dropdown-menu'),
                tb = t.offset().top + t.height(),
                mb = m.offset().top + m.outerHeight(true),
                d = 20; // Space for shadow + scrollbar.
            if (t[0].scrollWidth > t.innerWidth()) {
                if (mb + d > tb) {
                    t.css('padding-bottom', ((mb + d) - tb));
                }
            }
            else {
                t.css('overflow', 'visible');
            }
        }).on('hidden.bs.dropdown', function () {
            $(this).css({ 'padding-bottom': '', 'overflow': '' });
        });

        var btn_ERC20_sort = {
            count: 0,
            reminder_count: 2,
            list: [],
            default_list: [],
            ERC20_sort_start: function (count) {
                if (document.getElementsByClassName('list-custom-divider-ERC20')[0]) {
                    var self = this
                    if (count != undefined) {
                        self.count = count
                    }

                    var before_el = document.getElementsByClassName('list-custom-divider-ERC20')[0]
                    var parent_el = before_el.parentNode
                    var element_selector = parent_el.querySelectorAll(".list-custom-ERC20");

                    if (self.list.length == 0) {
                        element_selector.forEach(function (e) {
                            self.list.push(e);
                            self.default_list.push(e);
                        });
                    }

                    $(".list-custom-ERC20").remove()
                    var type = self.count % self.reminder_count
                    self.sortList(type, parent_el, before_el);
                    self.count++
                }
            },
            sortList: function (type, parent_el, before_el) {
                var self = this
                var sorted_list = []
                var icon_el = $(before_el).find('button').find('i')

                switch (type) {
                    case 1:
                        icon_el.attr("class", "fad fa-sort-up")
                        sorted_list = self.sortUsdAsc()
                        break;
                    default:
                        icon_el.attr("class", "fad fa-sort-down")
                        sorted_list = self.sortUsdDesc()
                }

                for (var i = sorted_list.length - 1; i >= 0; i--) {
                    before_el.insertAdjacentElement('afterend', sorted_list[i])
                }
            },
            sortUsdAsc: function () {
                var self = this
                var sort_list = self.list

                sort_list.sort(function (a, b) {
                    var target_a_value = self.formatCurrencyToNumber(a.querySelector('.list-usd-value').textContent.trim() || -1);
                    var target_b_value = self.formatCurrencyToNumber(b.querySelector('.list-usd-value').textContent.trim() || -1);

                    if (target_a_value == -1 || target_b_value == -1) {
                        return 1;
                    }
                    if (target_a_value < target_b_value) {
                        return -1;
                    }
                    if (target_a_value > target_b_value) {
                        return 1;
                    }
                    return 0
                });
                return sort_list
            },
            sortUsdDesc: function () {
                var self = this
                var sort_list = self.list

                sort_list.sort(function (a, b) {
                    var target_a_value = self.formatCurrencyToNumber(a.querySelector('.list-usd-value').textContent.trim() || -1);
                    var target_b_value = self.formatCurrencyToNumber(b.querySelector('.list-usd-value').textContent.trim() || -1);

                    if (target_a_value < target_b_value) {
                        return 1;
                    }
                    if (target_a_value > target_b_value) {
                        return -1;
                    }
                    return 0
                });
                return sort_list
            },
            formatCurrencyToNumber: function (strCurrency) {
                if (typeof strCurrency == "number")
                    return strCurrency
                else
                    return Number(strCurrency.replace(/[^0-9.-]+/g, ""));
            },
        }

        $("#btn_ERC20_sort").on("click", function (event) {
            event.preventDefault();
            setTimeout(function () {
                btn_ERC20_sort.ERC20_sort_start()
            }, 10)
        })

        function hrefTokenHolding() {
            var location = "/tokenholdings?a=0x81D7a91860a70B312E68c075C896aA06281cCC63"
            var queryString = $("input.form-control.form-control-xs.search.mb-3")[0].value
            if (queryString) {
                location += "&q=" + queryString
            }
            window.location.href = location
        }

        function toggleLoginModal() {
            $('#loginRequiredModal').modal('toggle');
        }

        function setIOState() {
            const mainAddress = $("#hdnAddress").val()?.toLowerCase();
            const currentFilters = new URLSearchParams(window.location.search);
            const faddr = currentFilters.get("fadd")?.toLowerCase();
            const taddr = currentFilters.get("tadd")?.toLowerCase();

            $(".dropdown-item-io").removeClass("active");
            if (taddr) {
                if (taddr.indexOf(mainAddress) != -1) {
                    $("#btnInTxFilter").addClass("active");
                    $("#btnInIntlTxFilter").addClass("active");
                    $(".js-listbox-item").text("IN");
                }
                else {
                    $("#btnOutTxFilter").addClass("active");
                    $("#btnOutIntlTxFilter").addClass("active");
                    $(".js-listbox-item").text("OUT");
                }
            }
            else if (faddr) {
                if (faddr.indexOf(mainAddress) != -1) {
                    $("#btnOutTxFilter").addClass("active");
                    $("#btnOutIntlTxFilter").addClass("active");
                    $(".js-listbox-item").text("OUT");
                }
                else {
                    $("#btnInTxFilter").addClass("active");
                    $("#btnInIntlTxFilter").addClass("active");
                    $(".js-listbox-item").text("IN");
                }
            }
            else {
                $("#btnAnyTxFilter").addClass("active");
                $("#btnAnyIntlTxFilter").addClass("active");
                $(".js-listbox-item").text("ANY");
            }
        }

        function setFiltersStatus() {
            if (isSignedIn == "0") {
                disableControl("#dropdownMethod");
                disableControl("#dropdownAge");
                disableControl("#dropdownFrom");
                disableControl("#dropdownIO");
                disableControl("#dropdownTo");
                disableControl("#btnDropdownAmount");

                disableControl("#dropdownAgeIntlTxns");
                disableControl("#dropdownFromIntlTxns");
                disableControl("#dropdownIOIntlTxns");
                disableControl("#dropdownToIntlTxns");
                disableControl("#btnDropdownAmountIntlTxns");

                $(".dropdown-filters").tooltip();
            }
        }

        let clipboardIgnoreConfirmation = null;

        function setDustCopyWarningMode(ignoreConfirmation) {
            if (clipboardIgnoreConfirmation) {
                clipboardIgnoreConfirmation.destroy();
                clipboardIgnoreConfirmation = null;
            }

            $(".btn-show-copy-confirmation").off("click.dustCopyWarning");

            if (ignoreConfirmation) {
                clipboardIgnoreConfirmation = new ClipboardJS('.js-clipboard-required-confirmation');
                clipboardIgnoreConfirmation.on('success', function (e) {
                    $('.tooltip-inner').html('Copied!');
                    $(e.trigger).tooltip('update');
                });
            } else {
                $(".btn-show-copy-confirmation").on("click.dustCopyWarning", function () {
                    openCopyAddressConfirmModal($(this).data("address"), $(this).data("message"));
                });
            }
        }

        function initDustCopyWarning() {
            setDustCopyWarningMode(ignoreCopyConfirmation);

            $("#popupDontShowAgain")
                .off("change.dustCopyWarning")
                .on("change.dustCopyWarning", function (e) {
                    ignoreCopyConfirmation = e.currentTarget.checked;
                    saveCopyAddressConfirmationSetting(ignoreCopyConfirmation);
                    setDustCopyWarningMode(ignoreCopyConfirmation);
                });
        }

        function disableControl(selector) {
            $(selector).prop("disabled", true);
        }
$(document).ready(function () {

            btn_ERC20_sort.ERC20_sort_start()
            var mainAddress = $("#hdnAddress").val();

            // user search for method filters
            var searchFuncTimeOut;
            $("#inputMethodName").on("keyup", function ($event) {
                if (searchFuncTimeOut) {
                    clearTimeout(searchFuncTimeOut)
                }

                var searchTerm = $(this).val();
                searchFuncTimeOut = setTimeout(function () {
                    searchFunctions(searchTerm);
                }, 350);
            });

            var isSearchFunctions = false;
            $("#dropdownMethod").on("click", function (e) {
                if (isSearchFunctions === false) {
                    searchFunctions('');
                    isSearchFunctions = true;
                }
            });

            const litDefaultMethodFilterHtml = '';
            function searchFunctions(searchTerm) {
                if (searchTerm === '' || searchTerm.length > 3) {
                    const curPath = encodeURIComponent(window.location.search);
                    $.ajax({
                        type: 'Get',
                        url: `/functionSearchHandler.ashx?ca=${mainAddress}&func=${searchTerm ?? ''}&curPath=${curPath}`,
                        success: function (response) {
                            $("#searchFunctionResult").html('');
                            if (response && response.length > 0) {
                                for (var i = 0; i < response.length; i++) {
                                    var path = response[i].path
                                    $("#searchFunctionResult").append(
                                        `<li class="nav-item aFilterTransfer" data-name="${response[i].nameNormalized}" data-methodid="${response[i].methodId}">
                                            <a class="nav-link d-flex justify-content-between gap-2 px-2" href="${path}">
                                                <span class="hash-tag text-truncate" data-bs-toggle="tooltip" data-bs-title="${response[i].name}">${response[i].name}</span>
                                                <span class="badge bg-light border text-dark fw-normal p-1">${response[i].methodId}</span>
                                            </a>
                                        </li>`
                                    );
                                }
                                $("[data-bs-toggle='tooltip']").tooltip();
                            }
                            else {
                                $("#searchFunctionResult").append(
                                    `<li class="nav-item notfound">
                                        <span class="fw-normal text-muted">No matching name or ID found.</span>
                                    </li>`
                                );
                            }
                            $("#inputMethodSpinner").hide();
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            $("#searchFunctionResult").html('');
                            $("#inputMethodSpinner").hide();
                        }
                    });
                } else {
                    $("#inputMethodSpinner").hide();
                    $("#searchFunctionResult").html(litDefaultMethodFilterHtml);
                }
            }

             // clear filter inputs
            function clearAdvancedFilterInput(data, e) {
                if (data.id == "btnAgeFilterClear") {
                    $("#ContentPlaceHolder1_txtAgeDateFrom").val('');
                    $("#ContentPlaceHolder1_txtAgeDateTo").val('');
                    closeDropdown("#btnDropdownAgeFilter");
                }
                else if (data.id == "btnFromFilterClear") {
                    $("input[name='fromaddress']").val('');
                    let additionalFromAddressInputs = $("input[data-name='fromaddress']");
                    if (additionalFromAddressInputs && additionalFromAddressInputs.length > 0) {
                        additionalFromAddressInputs.each(function () {
                            $(this).val('');
                        });
                    }
                    $("#addFromAddressFieldContainer").html("");
                    closeDropdown("#btnDropdownFromFilter");
                }
                else if (data.id == "btnToFilterClear") {
                    $("input[name='toaddress']").val('');
                    let additionalToAddressInputs = $("input[data-name='toaddress']");
                    if (additionalToAddressInputs && additionalToAddressInputs.length > 0) {
                        additionalToAddressInputs.each(function () {
                            $(this).val('');
                        });
                    }
                    $("#addToAddressFieldContainer").html("");
                    closeDropdown("#btnDropdownToFilter");
                }
                else if (data.id == 'btnAmountFilterClear') {
                    $("#amount_from").val('');
                    $("#amount_to").val('');
                    closeDropdown("#btnDropdownAmountFilter");
                }
                e.stopPropagation();
            }

            function closeDropdown(selector) {
                const dropdownInstance = bootstrap.Dropdown.getOrCreateInstance(selector);
                if (dropdownInstance) {
                    dropdownInstance.hide();
                }
            }




            // detect tooltip for token holding dropdown
            if ($(".addresses-tooltip-over").length > 0) {
                if (!isMobile()) {
                    $(".addresses-tooltip-over").attr("data-bs-trigger", "hover");
                    let tooltip = bootstrap.Tooltip.getInstance(".addresses-tooltip-over");

                    tooltip?.dispose();
                    tooltip = new bootstrap.Tooltip($(".addresses-tooltip-over"));

                    tooltip._config.trigger = 'hover';
                    tooltip.update();
                }
            }


            // Quick export transaction csv
            const quickExportCsvData = '[{"Txhash":"0x373a3ccd0a05b224a4d6f7f4ab08dc445a317230bb9bdbd443c2f5f430445d7e","Status":"Success","Method":"Transfer","Blockno":"25856331","DateTime":"2026-08-28 21:09:11","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0x3C95d9e0F76e08cD9a6cb5c7dB508c4F4072B9F3","ReceiverLable":null,"Amount":"0.0956006 ETH","Value":"$234.59","TxnFee":"0.00000159"},{"Txhash":"0x6c68e14617a1bccb5e9390086d9d3f9683b3bafb71d87c9ba647f881b7f058e3","Status":"Success","Method":"Transfer","Blockno":"25833868","DateTime":"2026-08-25 18:01:23","Sender":"0x500ba6a9dcd58c8a973e437465cdb0e6fc18363a","SenderLable":null,"Receiver":"0x81D7a91860a70B312E68c075C896aA06281cCC63","ReceiverLable":null,"Amount":"0.00000959 ETH","Value":"$0.02","TxnFee":"0.00000471"},{"Txhash":"0xef44ce03ae12ef0d23479220b8f9b5f2f40e533e7064394707c0c7048f3b3ebd","Status":"Success","Method":"Swap","Blockno":"25833867","DateTime":"2026-08-25 18:01:11","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0x4313C378Cc91eA583C91387B9216e2c03096b27f","ReceiverLable":null,"Amount":"0 ETH","Value":"$0.00","TxnFee":"0.00053394"},{"Txhash":"0x1073782a475da5b2a49beb1de9a9da62030dfdaa77ab61a85b5b8384f25c32b1","Status":"Success","Method":"Approve","Blockno":"25833866","DateTime":"2026-08-25 18:00:59","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0xa79892Ae5224Abb17dDd9caB3EbB5d045Ff7c579","ReceiverLable":null,"Amount":"0 ETH","Value":"$0.00","TxnFee":"0.00008591"},{"Txhash":"0x7d317d605a63d9aa7bca9745e985b1632b9394b8a851264f2f54a058fc51fc85","Status":"Success","Method":"Sigma Swap","Blockno":"25833860","DateTime":"2026-08-25 17:59:47","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0xb704Fcb4c43BdC030dE7EC5e0d5264B99Aa3af36","ReceiverLable":null,"Amount":"0.031 ETH","Value":"$76.07","TxnFee":"0.00002967"},{"Txhash":"0xa7cb4990ac2821beebe96fe98c64519f7cda240fe63e852cd594207f81fe6798","Status":"Success","Method":"Swap","Blockno":"25833859","DateTime":"2026-08-25 17:59:35","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0x4313C378Cc91eA583C91387B9216e2c03096b27f","ReceiverLable":null,"Amount":"0.03333333 ETH","Value":"$81.79","TxnFee":"0.00271627"},{"Txhash":"0x51084348de433d752df746e7c2cff5eaa5927d9db7b421a7960c7eec6c3281c6","Status":"Success","Method":"Swap","Blockno":"25833859","DateTime":"2026-08-25 17:59:35","Sender":"0x81d7a91860a70b312e68c075c896aa06281ccc63","SenderLable":null,"Receiver":"0x4313C378Cc91eA583C91387B9216e2c03096b27f","ReceiverLable":null,"Amount":"0.01666666 ETH","Value":"$40.90","TxnFee":"0.00297259"}]';
            const quickExportCsvTitle = 'Transaction Hash,Status,Method,Blockno,"DateTime (UTC)",From,From_Nametag,To,To_Nametag,Amount,Value (USD),Txn Fee';
            let isExportFinish = true;
            if ($("#btnExportQuickTableToCSV").length > 0 && quickExportCsvData) {
                $("#btnExportQuickTableToCSV").click(function () {
                    if (isExportFinish == true) {
                        isExportFinish = false;
                        $("#btnExportQuickTableToCSV").append('<i class="fa fa-spinner fa-spin ms-1"></i>');
                        let lstTxsObj = JSON.parse(quickExportCsvData);
                        if (lstTxsObj.length > 0) {
                            let csvRows = [];
                            csvRows.push(quickExportCsvTitle.replace(/"/g, ""));
                            for (let i = 0; i < lstTxsObj.length; i++) {
                                let values = Object.values(lstTxsObj[i]).join('2SL'); // 2SL : separate line
                                values = values.replace(/2SL/g, '","')
                                csvRows.push('"' + values + '"');
                            }

                            let data = csvRows.join('\n');
                            let fileName = "export-" + $.trim($("#hdnAddress").val());
                            const blob = new Blob(["\ufeff", data], { type: 'text/csv' });
                            const url = window.URL.createObjectURL(blob)
                            const a = document.createElement('a')
                            a.setAttribute('href', url)
                            a.setAttribute('download', fileName + '.csv');
                            a.click();
                            setTimeout(function () {
                                $("#btnExportQuickTableToCSV").find(".fa-spinner").remove();
                                isExportFinish = true;
                            }, 200);
                        }
                    }
                });
            }

            // Quick export internal transaction csv
            const quickExportInternalTxsData = '[{"ParentTxnHash":"0x2cab764b66b07dafbaf99dac0655f04591bd4c781165c710284cee379ee3eddb","Status":"Success","Blockno":"25842591","DateTime":"2026-08-26 23:12:11","Sender":"0xf1331A64F507A1b1e0D3cFAec25aE508aA65D955","SenderLable":null,"Receiver":"0x81D7a91860a70B312E68c075C896aA06281cCC63","ReceiverLable":null,"Amount":"0.03916575 ETH","Value":"$96.11"},{"ParentTxnHash":"0xef44ce03ae12ef0d23479220b8f9b5f2f40e533e7064394707c0c7048f3b3ebd","Status":"Success","Blockno":"25833867","DateTime":"2026-08-25 18:01:11","Sender":"0x4313C378Cc91eA583C91387B9216e2c03096b27f","SenderLable":null,"Receiver":"0x81D7a91860a70B312E68c075C896aA06281cCC63","ReceiverLable":null,"Amount":"0.01352237 ETH","Value":"$33.18"},{"ParentTxnHash":"0x7d317d605a63d9aa7bca9745e985b1632b9394b8a851264f2f54a058fc51fc85","Status":"Success","Blockno":"25833860","DateTime":"2026-08-25 17:59:47","Sender":"0xb704Fcb4c43BdC030dE7EC5e0d5264B99Aa3af36","SenderLable":null,"Receiver":"0x81D7a91860a70B312E68c075C896aA06281cCC63","ReceiverLable":null,"Amount":"0.00702402 ETH","Value":"$17.24"},{"ParentTxnHash":"0xf57a6fed8330566a8c553fde464a6116a1c63b01b59e0e49683523f7214a380e","Status":"Success","Blockno":"25833689","DateTime":"2026-08-25 17:25:35","Sender":"0xf1331A64F507A1b1e0D3cFAec25aE508aA65D955","SenderLable":null,"Receiver":"0x81D7a91860a70B312E68c075C896aA06281cCC63","ReceiverLable":null,"Amount":"0.12341725 ETH","Value":"$302.85"}]';
            const quickExportInternalTxsTitle = 'Parent Transaction Hash,Status,Blockno,"DateTime (UTC)",From,From_Nametag,To,To_Nametag,Amount,Value (USD)';
            if ($("#ContentPlaceHolder1_btnQuickExportInternalTxs").length > 0 && quickExportInternalTxsData) {
                $("#ContentPlaceHolder1_btnQuickExportInternalTxs").click(function () {
                    if (isExportFinish == true) {
                        isExportFinish = false;
                        $("#ContentPlaceHolder1_btnQuickExportInternalTxs").append('<i class="fa fa-spinner fa-spin ms-1"></i>');
                        let lstTxsObj = JSON.parse(quickExportInternalTxsData);
                        if (lstTxsObj.length > 0) {
                            let csvRows = [];
                            csvRows.push(quickExportInternalTxsTitle.replace(/"/g, ""));
                            for (let i = 0; i < lstTxsObj.length; i++) {
                                let values = Object.values(lstTxsObj[i]).join('2SL'); // 2SL : separate line
                                values = values.replace(/2SL/g, '","')
                                csvRows.push('"' + values + '"');
                            }

                            let data = csvRows.join('\n');
                            let fileName = "export-internal-tx-" + $.trim($("#hdnAddress").val());

                            const blob = new Blob(["\ufeff", data], { type: 'text/csv' });
                            const url = window.URL.createObjectURL(blob)
                            const a = document.createElement('a')
                            a.setAttribute('href', url)
                            a.setAttribute('download', fileName + '.csv');
                            a.click();
                            setTimeout(function () {
                                $("#ContentPlaceHolder1_btnQuickExportInternalTxs").find(".fa-spinner").remove();
                                isExportFinish = true;
                            }, 200);
                        }
                    }
                });
            }
        });

        function isMobile() {
            const regex = /Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
            return regex.test(navigator.userAgent);
        }

        $("body,html").click(function (evt) {
            let elm = $(evt.target).attr("id");
            let isClickedMode = elm === "darkModaBtn" || elm === "darkModaBtnIcon";
            if (isClickedMode) {
                let isClickedSunMode = false;
                let clrBorder = "#112641";
                if (elm === "darkModaBtn") isClickedSunMode = $(evt.target).find("#darkModaBtnIcon").hasClass("fa-moon");
                if (elm === "darkModaBtnIcon") isClickedSunMode = $(evt.target).hasClass("fa-moon");
                if (isClickedSunMode) {
                    clrBorder = "#fff";
                }

                let iframes = document.getElementById('analytics_pageiframe');
                let heatcell = iframes.contentWindow.document.getElementsByClassName("ch-day").length;
                for (let i = 0; i < heatcell; i++) {
                    iframes.contentWindow.document.getElementsByClassName("ch-day")[i].style.borderColor = clrBorder;
                }
            }
        });
(function () {
            document.querySelectorAll('.nav_tabs1 a').forEach((triggerEl) => {
                new bootstrap.Tab(triggerEl);
            });

            document.querySelectorAll('.nav-subtabs li a:not(.dropdown-toggle)').forEach((triggerEl) => {
                new bootstrap.Tab(triggerEl);
            });


            if (document.getElementById('dropdownMethod') !== null) {
                document.getElementById('dropdownMethod').addEventListener('click', () => {
                    if (
                        !(
                            ('ontouchstart' in window ||
                                navigator.maxTouchPoints > 0 ||
                                navigator.msMaxTouchPoints > 0) &&
                            window.innerWidth <= 991
                        )
                    ) {
                        document.getElementById('inputMethodName').focus();
                    }
                });
            }

            if (document.getElementById("dropdownMenuBalance") !== null) {
                document.getElementById("dropdownMenuBalance").addEventListener("click", () => {
                    if (!((('ontouchstart' in window)
                        || (navigator.maxTouchPoints > 0)
                        || (navigator.msMaxTouchPoints > 0))
                        && window.innerWidth <= 991)) {
                        document.getElementById("token-balance-search").focus();
                    }
                });
            }

            if (document.getElementById('dropdownBlock') !== null) {
                document.getElementById('dropdownBlock').addEventListener('click', () => {
                    if (
                        !(
                            ('ontouchstart' in window ||
                                navigator.maxTouchPoints > 0 ||
                                navigator.msMaxTouchPoints > 0) &&
                            window.innerWidth <= 991
                        )
                    ) {
                        document.getElementById('fromblock').focus();
                    }
                });
            }

            //document.getElementById('dropdownFrom').addEventListener('click', () => {
            //    if (
            //        !(
            //            ('ontouchstart' in window ||
            //                navigator.maxTouchPoints > 0 ||
            //                navigator.msMaxTouchPoints > 0) &&
            //            window.innerWidth <= 991
            //        )
            //    ) {
            //        document.getElementById('fromaddress').focus();
            //    }
            //});

            //document.getElementById('dropdownTo').addEventListener('click', () => {
            //    if (
            //        !(
            //            ('ontouchstart' in window ||
            //                navigator.maxTouchPoints > 0 ||
            //                navigator.msMaxTouchPoints > 0) &&
            //            window.innerWidth <= 991
            //        )
            //    ) {
            //        document.getElementById('toaddress').focus();
            //    }
            //});

            // LIST.JS
            // =======================================================
            var options = {
                valueNames: ['list-name', 'list-amount', 'list-usd-value', 'list-usd-rate'],
            };

            if (document.querySelector('#availableBalance')) {
                var availableBalance = new List('availableBalance', options);
                availableBalance.on('searchComplete', function (e) {
                    if (e.matchingItems.length == 0) {
                        $('.list-not-found').show();
                    } else {
                        $('.list-not-found').hide();
                    }
                });
            }

            window.addEventListener('wheel', function (e) {
                if (document.querySelector('.bs-tooltip-auto')) {
                    let targetedElem = document.querySelector(
                        `[aria-describedby='${document
                            .querySelector('.bs-tooltip-auto')
                            .getAttribute('id')}']`
                    );
                    let tooltipTemp = bootstrap.Tooltip.getOrCreateInstance(targetedElem);
                    tooltipTemp.hide();
                }
            });

            document.getElementById('dropdownMore1').addEventListener('shown.bs.dropdown', event => {
                if (event.target.dataset.bsDisplay === 'static') {
                    let nextSibling = event.target.nextElementSibling;
                    nextSibling.classList.add('dropdown-menu-end');
                    nextSibling.removeAttribute('style');

                    let rect = nextSibling.getBoundingClientRect();

                    if (rect.left < 0) {
                        nextSibling.classList.remove('dropdown-menu-end');

                        if (window.screen.availWidth < (window.innerWidth || document.documentElement.clientWidth)) {
                            nextSibling.style.left = `-${(window.innerWidth || document.documentElement.clientWidth) - window.screen.availWidth + 5}px`;
                        }
                    }
                }
            })
        })();
$(document).ready(function () {
            initPopover();
            registerPreviewButtonEvent();

            initAdvPopover();
            registerDataPreviewButtonEvent();

            updateFilterLinksIntlTxns("#ContentPlaceHolder1_divFilteredByIntlTxns");
            updateFilterLinksIntlTxns("#ContentPlaceHolder1_divAgeFilterIntlTxns");
            updateFilterLinksIntlTxns("#ContentPlaceHolder1_divAmountFilterIntlTxns");
        });

        function updateFilterLinksIntlTxns(wrapperId) {
            const divFilterIntlTxns = $(wrapperId);
            if (divFilterIntlTxns.length) {
                divFilterIntlTxns.find("a").each(function () {
                    const aLink = $(this);
                    const currentHref = aLink.attr("href");
                    aLink.attr("href", currentHref + "#internaltx");
                });
            }
        }

        // Close tooltip when click outside of tooltip content
        $(document).on('click', function (e) {

            $('[data-bs-toggle="popover"]').each(function () {
                if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
                    $(this).popover('hide');
                }
            });
        });
var addressContract = '0x81D7a91860a70B312E68c075C896aA06281cCC63';
function resizeCardIframe(iframe, bufferHeight) {
            if (iframe && iframe.contentWindow.document.body.scrollHeight) {
                iframe.style.height = iframe.contentWindow.document.body.scrollHeight + (bufferHeight || 0) + 'px';
                iframe.parentElement.style.visibility = 'visible';
            }
        }

        window.addEventListener('message', function (event) {
            if (event.data === 'cardUpdated') {
                var iframe = document.getElementById('cardsIframe');
                resizeCardIframe(iframe);
                scrollToTabNavs();
            }
            else if (event.data === 'tokenHolding') {
                var iframe = document.getElementById('tokenHoldingIframe');
                resizeCardIframe(iframe);
            }
            else if (event.data === 'nftHolding') {
                var iframe = document.getElementById('nftHoldingIframe');
                resizeCardIframe(iframe);
            }
            else if (event.data === 'addressAnalytics') {
                var iframe = document.getElementById('analytics_pageiframe');
                resizeCardIframe(iframe);
            }
            else if (event.data === 'addressNftTransfers') {
                var iframe = document.getElementById('nfttransfers_pageiframe');
                resizeCardIframe(iframe);
            }
        });

        function scrollToTabNavs() {
            setTimeout(() => {
                document.getElementById('div_tabs').scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }, 100);
        }
// code reader
        const IsCodeReader = '0'
        if (IsCodeReader === "1") {
            // INITIALIZATION OF TOGGLE PASSWORD
            // =======================================================
            new HSTogglePassword('.js-toggle-password')

            //// TEXTAREA SIZER
            //// =======================================================
            //const tx = document.getElementsByClassName("js-textarea-type-message");
            //for (let i = 0; i < tx.length; i++) {
            //    tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px; overflow-y: hidden; resize: none; max-height: 12rem;");
            //    tx[i].addEventListener("input", OnInput, false);
            //}
            //function OnInput() {
            //    this.style.height = "auto";
            //    this.style.height = (this.scrollHeight) + "px";
            //}

            const isSevice = '0'
            const isLogin = '0'

            const oa_rolesystemcontent = $('#oa_rolesystemcontent').val()
            const oa_max_tokens = 5000
            const claude_max_tokens = 5000
            var inputMaxTokens = $('#inputMaxTokens')
            var divMaxTokens = $('#divMaxTokens')
            var oa_model = ""
            var modalSavedHistory = bootstrap.Modal.getOrCreateInstance(document.getElementById('modalSavedHistory'))
            var responseSavedHistory = []
            var gotNew = true

            var gptMode = $('#gptMode')
            var chkSaveKey = $('#saveKeySwitcher')
            var checkboxes = document.querySelectorAll('input[name="chkContractFile"]');
            var divModal = $('#divModal')
            var chkSaveHistory = $('#saveHistorySwitcher')
            var divGeneratedOpenAI = $('#divGeneratedOpenAI')
            var divAnswer = $('#divAnswer')
            var divPormt = $('#divPormt')
            var txtPrompt = $('#txtPrompt')
            var inputOpenAIApiKey = $('#inputOpenAIApiKey')
            var divApiKey = $('#divApiKey')
            var divPormtAnswer = $('#divPormtAnswer')
            var btnSavedHistory = $('#btnSavedHistory')
            var txtFeedback = $('#txtFeedback')
            var aiProvider = $('#aiProvider')
            var gptModeExtra = $('#gptModeExtra')
            var apiKeyLabel = $('#apiKeyLabel')
            var apiKeyLearnMore = $('#apiKeyLearnMore')

            var aiProviderConfig = {
                openai: {
                    apiKeyLabel: 'OpenAI API Key',
                    apiKeyStorageKey: 'openaiapikey',
                    learnMoreUrl: 'https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key',
                    useApiModels: true,
                    models: [
                        { value: 'gpt-5.5', text: 'GPT-5.5', note: 'Please ensure this API Key has access to GPT-5.5 Model.' },
                        { value: 'gpt-5.4', text: 'GPT-5.4', note: 'Please ensure this API Key has access to GPT-5.4 Model.' },
                        { value: 'gpt-4.1', text: 'GPT-4.1', note: 'Please ensure this API Key has access to GPT-4.1 Model.' },
                        { value: 'gpt-4', text: 'GPT-4', note: 'Please ensure this API Key has access to GPT-4 Model.' },
                        { value: 'gpt-3.5-turbo-16k', text: 'GPT-3.5' }
                    ]
                },
                claude: {
                    apiKeyLabel: 'Claude API Key',
                    apiKeyStorageKey: 'claudeapikey',
                    learnMoreUrl: 'https://console.anthropic.com/settings/keys',
                    useApiModels: true,
                    models: [
                        { value: 'claude-sonnet-5', text: 'Claude Sonnet 5' },
                        { value: 'claude-opus-4-8', text: 'Claude Opus 4.8' },
                        { value: 'claude-fable-5', text: 'Claude Fable 5' },
                        { value: 'claude-haiku-4-5', text: 'Claude Haiku 4.5' }
                    ]
                },
                groq: {
                    models: [
                        { value: 'llama-3.1-8b-instant', text: 'Llama 3.1 8B Instant' }
                    ]
                }
            }

            var providerModelCache = {}
            var modelFetchSeq = 0

            function getProviderConfig() {
                return aiProviderConfig[aiProvider.val()] || aiProviderConfig.openai
            }

            function getApiKeyStorageKey() {
                var providerConfig = getProviderConfig()
                return providerConfig.apiKeyStorageKey || ''
            }

            function getDefaultMaxTokens() {
                return aiProvider.val() == "claude" ? claude_max_tokens : oa_max_tokens
            }

            function getMaxTokens() {
                var v = parseInt(inputMaxTokens.val(), 10)
                return (isNaN(v) || v < 1) ? getDefaultMaxTokens() : v
            }

            function bindApiKeyStorage() {
                inputOpenAIApiKey.off("change.apiKey")
                if (chkSaveKey.prop("checked") && getApiKeyStorageKey()) {
                    inputOpenAIApiKey.on("change.apiKey", function () {
                        localStorage.setItem(getApiKeyStorageKey(), inputOpenAIApiKey.val());
                    })
                }
            }

            function syncApiKeyField() {
                var providerConfig = getProviderConfig()
                if (!providerConfig.apiKeyStorageKey) {
                    inputOpenAIApiKey.off("change.apiKey")
                    divApiKey.hide()
                    return
                }

                apiKeyLabel.text(providerConfig.apiKeyLabel)
                apiKeyLearnMore.attr('href', providerConfig.learnMoreUrl)
                inputOpenAIApiKey.val(localStorage.getItem(providerConfig.apiKeyStorageKey) || "")
                chkSaveKey.prop("checked", localStorage.getItem(providerConfig.apiKeyStorageKey) !== null)
                bindApiKeyStorage()
                divApiKey.show()
            }

            function getActiveModels() {
                var cache = providerModelCache[aiProvider.val()]
                if (cache && cache.models && cache.models.length > 0) {
                    return cache.models
                }
                return getProviderConfig().models
            }

            function renderModelOptions(selectedValue) {
                var models = getActiveModels()
                var selectedModel = null
                models.forEach(function (model) {
                    if (model.value == selectedValue) {
                        selectedModel = model
                    }
                })
                if (!selectedModel) {
                    selectedModel = models[0]
                }

                gptMode.prop('disabled', false)
                gptMode.empty()
                models.forEach(function (model) {
                    var option = $('<option></option>').val(model.value).text(model.text)
                    if (model.note) {
                        option.attr('data-note', model.note)
                    }
                    gptMode.append(option)
                })

                oa_model = selectedModel.value
                gptMode.val(oa_model)
                gptMode.trigger("change")
            }

            function filterOpenAiChatModels(models) {
                var excludedKeywords = ['embedding', 'audio', 'realtime', 'transcribe', 'tts', 'image', 'moderation', 'dall-e', 'whisper', 'davinci', 'babbage', 'instruct', 'search', 'codex', 'deep-research']
                return models.filter(function (model) {
                    var id = (model.id || "").toLowerCase()
                    var isChatModel = id.indexOf('gpt') == 0 || id.indexOf('chatgpt') == 0 || /^o\d/.test(id)
                    if (!isChatModel) {
                        return false
                    }
                    if (/-(\d{4}-\d{2}-\d{2}|\d{3,}|latest|pro)$/.test(id)) {
                        return false
                    }
                    return !excludedKeywords.some(function (keyword) {
                        return id.indexOf(keyword) !== -1
                    })
                }).sort(function (a, b) {
                    return (b.created || 0) - (a.created || 0)
                }).map(function (model) {
                    return { value: model.id, text: model.id }
                })
            }

            function fetchProviderModels(provider, apiKey, callback) {
                if (provider == "openai") {
                    $.ajax({
                        url: "https://api.openai.com/v1/models",
                        type: "GET",
                        headers: {
                            "Authorization": `Bearer ${apiKey}`
                        },
                        success: function (response) {
                            callback(filterOpenAiChatModels(response['data'] || []))
                        },
                        error: function () {
                            callback(null)
                        }
                    })
                } else if (provider == "claude") {
                    $.ajax({
                        url: "https://api.anthropic.com/v1/models?limit=100",
                        type: "GET",
                        headers: {
                            "x-api-key": apiKey,
                            "anthropic-version": "2023-06-01",
                            "anthropic-dangerous-direct-browser-access": "true"
                        },
                        success: function (response) {
                            var models = (response['data'] || []).map(function (model) {
                                return { value: model.id, text: model.display_name || model.id }
                            })
                            callback(models)
                        },
                        error: function () {
                            callback(null)
                        }
                    })
                } else {
                    callback(null)
                }
            }

            function refreshProviderModels() {
                modelFetchSeq += 1
                var requestSeq = modelFetchSeq

                var provider = aiProvider.val()
                var providerConfig = getProviderConfig()
                var apiKey = (inputOpenAIApiKey.val() || "").trim()

                if (!providerConfig.useApiModels) {
                    providerModelCache[provider] = null
                    renderModelOptions(oa_model)
                    return
                }

                if (!apiKey) {
                    providerModelCache[provider] = null
                    oa_model = ""
                    gptMode.prop('disabled', true)
                    gptMode.empty().append($('<option></option>').val('').text('Enter API Key to load models'))
                    gptModeExtra.hide().text("")
                    return
                }

                var cache = providerModelCache[provider]
                if (cache && cache.apiKey == apiKey) {
                    renderModelOptions(oa_model)
                    return
                }

                gptMode.prop('disabled', true)
                gptMode.empty().append($('<option></option>').text('Loading models...'))
                gptModeExtra.hide().text("")

                fetchProviderModels(provider, apiKey, function (models) {
                    if (requestSeq != modelFetchSeq) {
                        return
                    }

                    if (models && models.length > 0) {
                        providerModelCache[provider] = { apiKey: apiKey, models: models }
                    } else {
                        providerModelCache[provider] = null
                    }
                    renderModelOptions()

                    if (!models || models.length == 0) {
                        gptModeExtra.show()
                        gptModeExtra.text('Couldn\'t load models with this API key. Showing default models, please check that the key is correct.')
                    }
                })
            }

            function syncProviderUi() {
                syncApiKeyField()
                refreshProviderModels()
                if (aiProvider.val() == "groq") {
                    divMaxTokens.hide()
                } else {
                    inputMaxTokens.val(getDefaultMaxTokens())
                    divMaxTokens.show()
                }
            }

            function getAiResponseText(response) {
                if (response && response.choices) {
                    var openAiText = ""
                    Object.entries(response.choices).forEach(([key, value]) => {
                        if (value['message'] && value['message']['content']) {
                            openAiText += value['message']['content']
                        }
                    });
                    return openAiText
                }

                if (response && response.content) {
                    var claudeText = ""
                    response.content.forEach(function (item) {
                        if (item.type === "text" && item.text) {
                            claudeText += item.text
                        }
                    })
                    return claudeText
                }

                return ""
            }

            function getAiErrorMessage(response) {
                if (response && response.error) {
                    if (response.error.message) return response.error.message
                    if (response.error.code) return response.error.code
                }

                return "Failed"
            }

            function getStopReasonAlert(response) {
                if (!response) return { alertHtml: "", save: true }

                var msg = ""
                var save = false   // abnormal stops default to not saved

                // ================= Claude : stop_reason =================
                if (response['stop_reason'] !== undefined) {
                    var stopReason = response['stop_reason']

                    switch (stopReason) {
                        case 'end_turn':
                        case 'stop_sequence':
                            return { alertHtml: "", save: true }   // completed normally
                        case 'max_tokens':
                            msg = 'The answer was cut off at the Max Tokens limit. Increase Max Tokens and try again.'
                            save = true   // truncated answer is still saved to history
                            break
                        case 'refusal':
                            msg = 'The AI declined to answer this request. Please rephrase your question.'
                            break
                        case 'model_context_window_exceeded':
                            msg = 'The selected source code is too large for this model. Please select fewer files.'
                            break
                        default:
                            msg = 'The AI stopped before completing the answer (stop_reason: ' + stopReason + ').'
                    }

                    return { alertHtml: code_reader.renderAlertBox('warning', msg), save: save }
                }

                // ================= OpenAI : choices[0].finish_reason =================
                if (response['choices'] && response['choices'][0]) {
                    var finishReason = response['choices'][0]['finish_reason']

                    switch (finishReason) {
                        case null:
                        case undefined:
                        case 'stop':
                            return { alertHtml: "", save: true }   // completed normally
                        case 'length':
                            msg = 'The answer was cut off at the Max Tokens limit. Increase Max Tokens and try again.'
                            save = true   // truncated answer is still saved to history
                            break
                        case 'content_filter':
                            msg = 'Part of the answer was withheld by the content filter.'
                            break
                        default:
                            msg = 'The AI stopped before completing the answer (finish_reason: ' + finishReason + ').'
                    }

                    return { alertHtml: code_reader.renderAlertBox('warning', msg), save: save }
                }

                return { alertHtml: "", save: true }
            }

            var code_reader = {
                source: {},
                oaId: "",
                thumbstatus: "",
                contractAddress: '',
                renderPrompt: function (el) {
                    txtPrompt.val($(el).html())
                },
                callOpenAiApi: function (el) {
                    var $button = $(el)
                    $button.prop('disabled', true);
                    $button.html('<i class="fa fa-spin fa-spinner"></i>');

                    divAnswer.html('&nbsp;')

                    var self = this
                    self.prompt = txtPrompt.val()

                    var selectedCode = ""
                    selectedCode = JSON.stringify(self.source);

                    var requestData = {
                        model: oa_model,
                        max_completion_tokens: getMaxTokens(),
                        messages: [{
                            role: "system",
                            content: oa_rolesystemcontent
                        }, {
                            role: "user",
                            content: (selectedCode || "") + "\n\n" + self.prompt
                        }]
                    };

                    if (self.prompt) {

                        if (aiProvider.val() != "groq" && !oa_model) {
                            divPormtAnswer.show()
                            divAnswer.html(self.renderAlertBox('danger', 'Please enter your API Key and select a model.'))
                            $button.prop('disabled', false)
                            $button.html('<i class="fa fa-paper-plane-top"></i>');
                            return
                        }

                        divPormt.html(htmlEnc(self.prompt))

                        if (aiProvider.val() == "groq") {
                            $.ajax({
                                type: "POST",
                                url: "/code-readerHandler.ashx",
                                dataType: 'json',
                                data: {
                                    ssid: sid,
                                    action: "callPromptAnswer",
                                    data: requestData
                                },
                                success: function (response) {
                                    if (typeof response !== 'object') {
                                        response = JSON.parse(response)
                                    }
                                    if (response['error']) {
                                        self.oaId = ""
                                        self.thumbstatus = ""

                                        var html = ""
                                        if (response['error']['message']) {
                                            if (response['error']['message'] == "The model: `gpt-4` does not exist") {
                                                html = self.renderAlertBox('danger', "The provided API key does not have access to GPT-4. Please change to a different key or use GPT-3.5.")
                                            } else {
                                                html = self.renderAlertBox('danger', response['error']['message'])
                                            }
                                        } else {
                                            html = self.renderAlertBox('danger', response['error']['code'])
                                        }

                                        divGeneratedOpenAI.hide()
                                        divAnswer.html(html)

                                        self.storePromptAndAnswer(response, "2")
                                    } else {
                                        self.oaId = response['id']
                                        self.thumbstatus = ""

                                        var html = ""
                                        var choices = response['choices']
                                        Object.entries(choices).forEach(([key, value]) => {
                                            html += value['message']['content']
                                        });
                                        html = htmlEnc(html).replace(/\n/g, '<br/>')

                                        divGeneratedOpenAI.show()
                                        html += self.renderAnswerThumbsAction()
                                        divAnswer.html(html)

                                        self.storePromptAndAnswer(response, "1")
                                    }
                                },
                                error: function (xhr, status, error) {
                                    self.oaId = ""
                                    self.thumbstatus = ""

                                    var html = ""
                                    if (xhr['responseJSON'] && xhr['responseJSON']['error'] && xhr['responseJSON']['error']['message']) {
                                        if (xhr['responseJSON']['error']['message'] == "The model: `gpt-4` does not exist") {
                                            html = self.renderAlertBox('danger', "The provided API key does not have access to GPT-4. Please change to a different key or use GPT-3.5.")
                                        } else {
                                            html = self.renderAlertBox('danger', xhr['responseJSON']['error']['message'])
                                        }
                                        self.storePromptAndAnswer(xhr['responseJSON'], "2")
                                    } else if (xhr['responseJSON'] && xhr['responseJSON']['error'] && xhr['responseJSON']['error']['code']) {
                                        html = self.renderAlertBox('danger', xhr['responseJSON']['error']['code'])
                                        self.storePromptAndAnswer(xhr['responseJSON'], "2")
                                    } else {
                                        html = self.renderAlertBox('danger', "Failed")
                                    }

                                    divGeneratedOpenAI.hide()
                                    divAnswer.html(html)

                                },
                                complete: function () {
                                    $button.prop('disabled', false)
                                    $button.html('<i class="fa fa-paper-plane-top"></i>');
                                    txtPrompt.val('')
                                    divPormtAnswer.show()
                                }
                            });
                        } else if (aiProvider.val() == "claude") {
                            var claudeApiKey = inputOpenAIApiKey.val()

                            if (claudeApiKey) {
                                var claudeRequestData = {
                                    model: oa_model,
                                    max_tokens: getMaxTokens(),
                                    system: oa_rolesystemcontent,
                                    messages: [{
                                        role: "user",
                                        content: (selectedCode || "") + "\n\n" + self.prompt
                                    }]
                                }

                                $.ajax({
                                    url: "https://api.anthropic.com/v1/messages",
                                    type: "POST",
                                    contentType: "application/json",
                                    dataType: "json",
                                    headers: {
                                        "x-api-key": claudeApiKey,
                                        "anthropic-version": "2023-06-01",
                                        "anthropic-dangerous-direct-browser-access": "true"
                                    },
                                    data: JSON.stringify(claudeRequestData),
                                    success: function (response) {
                                        self.oaId = response['id']
                                        self.thumbstatus = ""

                                        var html = getAiResponseText(response)
                                        html = htmlEnc(html).replace(/\n/g, '<br/>')

                                        var stopAlert = getStopReasonAlert(response)
                                        html += stopAlert.alertHtml

                                        divGeneratedOpenAI.show()
                                        html += self.renderAnswerThumbsAction()
                                        divAnswer.html(html)

                                        if (stopAlert.save) {
                                            self.storePromptAndAnswer(response, "1")
                                        }
                                    },
                                    error: function (xhr, status, error) {
                                        self.oaId = ""
                                        self.thumbstatus = ""

                                        var response = xhr['responseJSON'] || {}
                                        if (!response.error && xhr['responseText']) {
                                            try {
                                                response = JSON.parse(xhr['responseText'])
                                            } catch (e) {
                                                response = {
                                                    error: {
                                                        message: xhr['responseText']
                                                    }
                                                }
                                            }
                                        }
                                        if (!response.error) {
                                            response = {
                                                error: {
                                                    message: error || status || "Failed"
                                                }
                                            }
                                        }
                                        var html = self.renderAlertBox('danger', getAiErrorMessage(response))

                                        divGeneratedOpenAI.hide()
                                        divAnswer.html(html)

                                        self.storePromptAndAnswer(response, "2")
                                    },
                                    complete: function () {
                                        $button.prop('disabled', false)
                                        $button.html('<i class="fa fa-paper-plane-top"></i>');
                                        txtPrompt.val('')
                                        divPormtAnswer.show()
                                    }
                                });
                            } else {
                                divPormtAnswer.show()
                                divAnswer.html(self.renderAlertBox('danger', 'Please enter a Claude API Key.'))
                                $button.prop('disabled', false)
                                $button.html('<i class="fa fa-paper-plane-top"></i>');
                            }
                        } else {
                            var openAIApikey = inputOpenAIApiKey.val()

                            if (openAIApikey) {

                                $.ajax({
                                    url: "https://api.openai.com/v1/chat/completions",
                                    type: "POST",
                                    headers: {
                                        "Content-Type": "application/json",
                                        "Authorization": `Bearer ${openAIApikey}`
                                    },
                                    data: JSON.stringify(requestData),
                                    success: function (response) {
                                        self.oaId = response['id']
                                        self.thumbstatus = ""

                                        var html = ""
                                        var choices = response['choices']
                                        Object.entries(choices).forEach(([key, value]) => {
                                            html += value['message']['content']
                                        });
                                        html = htmlEnc(html).replace(/\n/g, '<br/>')

                                        var stopAlert = getStopReasonAlert(response)
                                        html += stopAlert.alertHtml

                                        divGeneratedOpenAI.show()
                                        html += self.renderAnswerThumbsAction()
                                        divAnswer.html(html)

                                        if (stopAlert.save) {
                                            self.storePromptAndAnswer(response, "1")
                                        }
                                    },
                                    error: function (xhr, status, error) {
                                        self.oaId = ""
                                        self.thumbstatus = ""

                                        var html = ""
                                        if (xhr['responseJSON'] && xhr['responseJSON']['error'] && xhr['responseJSON']['error']['message']) {
                                            if (xhr['responseJSON']['error']['message'] == "The model: `gpt-4` does not exist") {
                                                html = self.renderAlertBox('danger', "The provided API key does not have access to GPT-4. Please change to a different key or use GPT-3.5.")
                                            } else {
                                                html = self.renderAlertBox('danger', xhr['responseJSON']['error']['message'])
                                            }
                                            self.storePromptAndAnswer(xhr['responseJSON'], "2")
                                        } else if (xhr['responseJSON'] && xhr['responseJSON']['error'] && xhr['responseJSON']['error']['code']) {
                                            html = self.renderAlertBox('danger', xhr['responseJSON']['error']['code'])
                                            self.storePromptAndAnswer(xhr['responseJSON'], "2")
                                        } else { 
                                            html = self.renderAlertBox('danger', "Failed")
                                        }

                                        divGeneratedOpenAI.hide()
                                        divAnswer.html(html)

                                    },
                                    complete: function () {
                                        $button.prop('disabled', false)
                                        $button.html('<i class="fa fa-paper-plane-top"></i>');
                                        txtPrompt.val('')
                                        divPormtAnswer.show()
                                    }
                                });
                            } else {
                                divPormtAnswer.show()
                                if (!openAIApikey) {
                                    divAnswer.html(self.renderAlertBox('danger', 'Please enter an OpenAI API Key.'))

                                } else if (!self.prompt) {
                                    divAnswer.html(self.renderAlertBox('danger', 'Please enter a prompt.'))
                                }
                                $button.prop('disabled', false)
                                $button.html('<i class="fa fa-paper-plane-top"></i>');
                            }
                        }
                    } else {
                        divPormtAnswer.show()
                        if (!self.prompt) {
                            divAnswer.html(self.renderAlertBox('danger', 'Please enter a prompt.'))
                        }
                        $button.prop('disabled', false)
                        $button.html('<i class="fa fa-paper-plane-top"></i>');
                    }
                },
                getCodeReaderPromptHistory(e) {
                    if (isSevice != "1") {
                        divModal.html('<span>To use this feature, please <a href="/login">login</a> to your Etherscan account and return to this page</span>')
                        modalSavedHistory.show()
                    } else {
                        btnSavedHistory.prop('disabled', true);
                        btnSavedHistory.html('<i class="fa fa-spin fa-spinner"></i>');

                        if (isSevice == "1" && gotNew) {
                            divModal.html("")
                            responseSavedHistory = []
                            var self = this

                            $.ajax({
                                type: "POST",
                                url: "/code-readerHandler.ashx",
                                dataType: 'json',
                                data: {
                                    ssid: sid,
                                    contractAddress: self.contractAddress,
                                    action: "getCodeReaderPromptHistory",
                                },
                                success: function (response) {
                                    if (response == "error") {
                                        var html = code_reader.renderAlertBox('danger', 'Fail to get history')
                                        divModal.html(html)
                                    } else {
                                        if (response.length == 0) {
                                            divModal.html("No record found.")
                                        } else {
                                            responseSavedHistory = response
                                            var html = ""
                                            for (let i = 0; i < responseSavedHistory.length; i++) {
                                                var hitem = responseSavedHistory[i]
                                                html += '<button class="list-group-item list-group-item-action d-flex align-items-center gap-2 p-3" onclick="code_reader.renderHistory(this, ' + i + ')">'

                                                html += '<div class="container row">'
                                                html += '<div class="text-truncate">' + htmlEnc(hitem['prompt']) + '</div>'
                                                html += '<span>' + getTruncatedAddress(htmlEnc(hitem['contractAddress'])) + ' <span class="small text-muted">(' + htmlEnc(hitem['dt']) + ')</span></span>'
                                                html += '</div>'

                                                html += '<i class="far fa-angle-right mx-1"></i>'

                                                html += '</button>'
                                            }
                                            divModal.html(html)
                                        }
                                        gotNew = false
                                    }
                                },
                                error: function (xhr, status, error) {
                                    var html = code_reader.renderAlertBox('danger', 'Fail to get history')
                                    divModal.html(html)
                                },
                                complete: function () {
                                    modalSavedHistory.show()
                                    btnSavedHistory.prop('disabled', false)
                                    btnSavedHistory.html('<i class="far fa-book-open"></i>');
                                }
                            });
                        } else {
                            modalSavedHistory.show()
                            btnSavedHistory.prop('disabled', false)
                            btnSavedHistory.html('<i class="far fa-book-open"></i>');
                        }
                    }
                },
                renderAlertBox: function (type, msg) {
                    return `<div class="alert alert-${type} text-break alert-dismissible fade show mt-2" role="alert">
                        <div class="d-flex align-items-baseline gap-2">
                            ${htmlEnc(msg)}
                        </div>
                        <button type='button' class='btn-close' data-bs-dismiss='alert' aria-label='Close'></button>
                    </div>`
                },
                renderAnswerThumbsAction: function (feedback) {
                    if ((isSevice == "1" && chkSaveHistory.prop("checked") == true) || feedback != null) {
                        return `<div class="d-flex align-items-center gap-1 mt-4">
                             <button type="button" class="btn btn-sm ${feedback == '1' ? 'btn-primary' : 'btn-white'}" id="btnThumbUp" data-bs-toggle="modal" data-bs-target="#shareFeedback" onclick="code_reader.setAnswerThumbAction(this, '1')">
                                 <i class="far fa-thumbs-up"></i>
                             </button>
                             <button type="button" class="btn btn-sm ${feedback == '2' ? 'btn-primary' : 'btn-white'}" id="btnThumbDown" data-bs-toggle="modal" data-bs-target="#shareFeedback" onclick="code_reader.setAnswerThumbAction(this, '2')">
                                 <i class="far fa-thumbs-down"></i>
                             </button>
                         </div>`
                    } else {
                        return ""
                    }
                },
                setAnswerThumbAction: function (el, status) {
                    if (isSevice == "1") {
                        var $buttonUp = $("#btnThumbUp")
                        var $buttonDown = $("#btnThumbDown")

                        $buttonUp.prop('disabled', true);
                        $buttonDown.prop('disabled', true);
                        $buttonUp.attr('class', 'btn btn-sm btn-white')
                        $buttonDown.attr('class', 'btn btn-sm btn-white')

                        var self = this
                        if (self.thumbstatus == status) {
                            self.thumbstatus = "0"
                        } else {
                            self.thumbstatus = status
                        }

                        $.ajax({
                            type: "POST",
                            url: "/code-readerHandler.ashx",
                            data: {
                                ssid: sid,
                                oaId: self.oaId,
                                status: self.thumbstatus,
                                action: "storeThumb",
                            },
                            complete: function () {
                                if (self.thumbstatus == "1") {
                                    $buttonUp.attr('class', 'btn btn-sm btn-primary')
                                } else if (self.thumbstatus == "2") {
                                    $buttonDown.attr('class', 'btn btn-sm btn-primary')
                                } else if (self.thumbstatus == "0") {
                                    $buttonUp.attr('class', 'btn btn-sm btn-white')
                                    $buttonDown.attr('class', 'btn btn-sm btn-white')
                                }

                                gotNew = true

                                $buttonUp.prop('disabled', false)
                                $buttonDown.prop('disabled', false)
                            }
                        })
                    }
                },
                storFeedbackAction: function (el) {
                    if (isSevice == "1") {
                        var self = this

                        $.ajax({
                            type: "POST",
                            url: "/code-readerHandler.ashx",
                            data: {
                                ssid: sid,
                                oaId: self.oaId,
                                txtFeedback: txtFeedback.val(),
                                action: "storeFeedback",
                            },
                            complete: function () {
                                $('#shareFeedback').modal('toggle')
                                $('#shareFeedbackComplete').modal('toggle')
                                txtFeedback.val("")
                            }
                        })
                    }
                },
                storePromptAndAnswer: function (result, status) {
                    if (isSevice == "1" && chkSaveHistory.prop("checked") == true) {
                        var self = this

                        $.ajax({
                            type: "POST",
                            url: "/code-readerHandler.ashx",
                            data: {
                                ssid: sid,
                                prompt: divPormt.html(),
                                oaId: self.oaId,
                                contractAddress: self.contractAddress,
                                selectedFiles: JSON.stringify(self.source),
                                model: oa_model,
                                setting: JSON.stringify({
                                    provider: aiProvider.val(),
                                    systemrole: oa_rolesystemcontent,
                                }),
                                result: JSON.stringify(result),
                                status: status,
                                action: "storePrompt",
                            },
                            complete: function () {
                                gotNew = true
                            }
                        })
                    }
                },
                renderHistory(el, index) {
                    var hitem = responseSavedHistory[index]
                    var self = this

                    if (hitem['oaId']) {
                        self.oaId = hitem['oaId']
                    } else {
                        self.oaId = ""
                    }

                    divPormt.html(htmlEnc(hitem['prompt']))

                    var hitem_result = JSON.parse(hitem['result'])
                    if (hitem['status'] == '2') {
                        var html = ""
                        if (hitem_result['error']['message']) {
                            if (hitem_result['error']['message'] == "The model: `gpt-4` does not exist") {
                                html = self.renderAlertBox('danger', "The provided API key does not have access to GPT-4. Please change to a different key or use GPT-3.5.")
                            } else {
                                html = self.renderAlertBox('danger', hitem_result['error']['message'])
                            }
                        } else {
                            html = self.renderAlertBox('danger', hitem_result['error']['code'])
                        }

                        divGeneratedOpenAI.hide()
                        divAnswer.html(html)
                    } else if (hitem['status'] == '1' && hitem['oaId']) {
                        var html = getAiResponseText(hitem_result)
                        html = htmlEnc(html).replace(/\n/g, '<br/>')
                        html += getStopReasonAlert(hitem_result).alertHtml

                        self.thumbstatus = htmlEnc(hitem['feedback'])
                        html += self.renderAnswerThumbsAction(htmlEnc(hitem['feedback']))

                        divAnswer.html(html)
                        divGeneratedOpenAI.show()
                    } else {
                        divAnswer.html("")
                    }
                    divPormtAnswer.show()

                    if (hitem['contractAddress']) {
                        self.source = JSON.parse(hitem['selectedFiles'])
                        var allCheckboxes = document.querySelectorAll('input[name="chkContractFile"]');
                        for (const checkbox of allCheckboxes) {
                            checkbox.checked = false;
                        }

                        for (const sourceName in code_reader.source) {
                            const checkbox = document.querySelector(`input[name="chkContractFile"][data-cname="${sourceName}"]`);
                            if (checkbox) {
                                checkbox.checked = true;
                            } else {
                            }
                        }
                    }

                    modalSavedHistory.hide()
                },
            }

            if (isLogin == "1") {
                $("#aiProvider_opt_groq").prop("disabled", false)
                aiProvider.val("groq")
            } else {
                $("#aiProvider_opt_groq").prop("title", "To use this feature, please login to your Etherscan account and return to this page")
            }
            if (isSevice != "3") {
                $('#divHistory').show()
            } 

            if (isSevice == "1") {
                chkSaveHistory.change(function () {
                    if ($(this).is(":checked")) {
                        localStorage.setItem("codereader_history", "1");
                    } else {
                        localStorage.removeItem("codereader_history");
                    }
                });
                if (localStorage.getItem("codereader_history") !== null) {
                    if (localStorage.getItem("codereader_history") == "1") {
                        chkSaveHistory.prop("checked", true)
                    }
                }
                chkSaveHistory.prop("disabled", false)
                btnSavedHistory.show()
            } else {
                var divSaveHistory = document.getElementById('divSaveHistory')
                var tooltip = new bootstrap.Popover(divSaveHistory, {
                    content: 'To use this feature, please login to your Etherscan account and return to this page',
                    trigger: "hover"
                })
            }

            aiProvider.change(function () {
                syncProviderUi()
            })

            gptMode.change(function () {
                oa_model = $(this).val()
                var note = $(this).find(':selected').data('note') || ""
                if (note) {
                    gptModeExtra.show()
                    gptModeExtra.text(note)
                } else {
                    gptModeExtra.hide()
                    gptModeExtra.text("")
                }
            })

            var modelRefreshTimer = null
            inputOpenAIApiKey.on("input.models change.models", function () {
                clearTimeout(modelRefreshTimer)
                modelRefreshTimer = setTimeout(refreshProviderModels, 600)
            })

            chkSaveKey.change(function () {
                var storageKey = getApiKeyStorageKey()
                if (!storageKey) {
                    return
                }

                if ($(this).is(":checked")) {
                    localStorage.setItem(storageKey, inputOpenAIApiKey.val());
                } else {
                    localStorage.removeItem(storageKey);
                }
                bindApiKeyStorage()
            });

            syncProviderUi()

            for (const checkbox of checkboxes) {
                const cname = checkbox.getAttribute('data-cname');
                const csource = checkbox.getAttribute('data-csource');

                if (checkbox.checked) {
                    code_reader.source[cname] = {
                        cname: csource,
                    };
                }

                checkbox.addEventListener('change', function () {
                    const cname = this.getAttribute('data-cname');
                    const csource = this.getAttribute('data-csource');
                    const checkboxId = this.id;

                    if (this.checked) {
                        code_reader.source[cname] = {
                            cname: csource,
                        };
                    } else {
                        delete code_reader.source[cname];
                    }
                });
            }
        }



        // Process for sub dropdown menu
(function ($bs) {
    if (!$bs) return;

    const CLASS_NAME = 'has-child-dropdown-show';

    $bs.Dropdown.prototype.toggle = (function (_original) {
        return function () {
            if (this._element.classList.contains('multilevelddl')) {
                document.querySelectorAll('.' + CLASS_NAME).forEach(function (e) {
                    e.classList.remove(CLASS_NAME);
                });

                let dd = this._element.closest('.dropdown')?.parentNode?.closest('.dropdown');
                for (; dd && dd !== document; dd = dd.parentNode?.closest('.dropdown')) {
                    dd.classList.add(CLASS_NAME);
                }
            }
            return _original.call(this);
        };
    })($bs.Dropdown.prototype.toggle);

    document.addEventListener('DOMContentLoaded', function () {
        document.querySelectorAll('.dropdown').forEach(function (dd) {
            dd.addEventListener('hide.bs.dropdown', function (e) {
                if (this.classList.contains(CLASS_NAME)) {
                    this.classList.remove(CLASS_NAME);
                    e.preventDefault();
                }
                e.stopPropagation();
            });
        });

        document.querySelectorAll('.dropdown-hover, .dropdown-hover-all .dropdown').forEach(function (dd) {
            dd.addEventListener('mouseenter', function (e) {
                let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
                if (toggle && !toggle.classList.contains('show')) {
                    $bs.Dropdown.getOrCreateInstance(toggle).toggle();
                    dd.classList.add(CLASS_NAME);
                }
            });
            dd.addEventListener('mouseleave', function (e) {
                let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
                if (toggle && toggle.classList.contains('show')) {
                    $bs.Dropdown.getOrCreateInstance(toggle).toggle();
                }
            });
        });
    });
})(window.bootstrap);
(function () {
            const form = document.getElementById('customAbiForm');
            const modal = document.getElementById('modaladdcustomabi');
            const applyButton = document.getElementById('btnApplyCustomABI');
            const magicFillButton = document.getElementById('btnMagicFillCustomABI');
            const modalLabel = document.getElementById('customAbiModalLabel');
            const triggerButton = document.getElementById('btnCustomAbiModalTrigger');
            const loginLink = document.getElementById('customAbiLoginLink');
            if (!form || !modal || !applyButton) return;

            const buttonText = applyButton.querySelector('.btn-text');
            const spinner = applyButton.querySelector('.spinner-border');
            const magicFillButtonText = magicFillButton ? magicFillButton.querySelector('.btn-text') : null;
            const magicFillSpinner = magicFillButton ? magicFillButton.querySelector('.spinner-border') : null;
            const customAbiValue = document.getElementById('customAbiValue');
            const customAbiAddress = document.getElementById('customAbiAddress');
            const customAbiName = document.getElementById('customAbiName');
            const customAbiNameGroup = document.getElementById('customAbiNameGroup');
            const saveCheckbox = document.getElementById('customAbiSaveToAccount');
            const modalStatus = document.getElementById('CustomABIStatusResult');
            const pageStatus = document.getElementById('CustomABIPageStatusResult');
            const openCustomAbiModal = false;
            const loginReturnKey = 'customAbiLoginReturn:' + customAbiChainId + ':' + customAbiAddress.value.toLowerCase();

            function updateAddEditButtonState(hasAbi) {
                if (hasAbi) {
                    if (triggerButton) triggerButton.innerHTML = '<i class="far fa-pen-to-square me-1"></i>Edit Custom ABI';
                    if (modalLabel) modalLabel.textContent = 'Edit Custom ABI';
                } else {
                    if (triggerButton) triggerButton.innerHTML = '<i class="fa fa-plus me-1"></i>Add Custom ABI';
                    if (modalLabel) modalLabel.textContent = 'Add Custom ABI';
                }
            }

            function showCustomAbiStatus(message, type) {
                modalStatus.replaceChildren();
                if (!message) return;

                const alert = document.createElement('div');
                alert.className = 'alert alert-' + type + ' mb-0';
                if (type === 'danger') alert.setAttribute('role', 'alert');
                alert.textContent = message;
                modalStatus.appendChild(alert);
            }

            function showCustomAbiPageStatus(message, type) {
                const alert = document.createElement('div');
                alert.className = 'alert alert-' + type;
                alert.textContent = message;
                pageStatus.replaceChildren(alert);
                pageStatus.classList.remove('d-none');
            }

            const customAbiStorage = window.CustomAbiStorage;
            const requiredStorageMethods = ['apply', 'current', 'consumeHandoff', 'normalize', 'postToIframe'];
            if (!customAbiStorage || !requiredStorageMethods.every(function (method) {
                return typeof customAbiStorage[method] === 'function';
            })) {
                const message = 'Custom ABI tools are out of date or failed to load. Reload this page once and try again.';
                showCustomAbiStatus(message, 'danger');
                showCustomAbiPageStatus(message, 'danger');
                setCustomAbiActionsDisabled(true);
                if (openCustomAbiModal) bootstrap.Modal.getOrCreateInstance(modal).show();
                return;
            }

            function isSavingToAccount() {
                return !!(saveCheckbox && saveCheckbox.checked);
            }

            // Magic Fill and Apply each own the modal while their request is in flight, so either one blocks the
            // other. Kept in one place because both handlers were testing the same pair of busy flags in different
            // orders and toggling the same buttons line by line.
            function isCustomAbiBusy() {
                return applyButton.dataset.busy === '1' || (magicFillButton && magicFillButton.dataset.busy === '1');
            }

            function setCustomAbiActionsDisabled(disabled) {
                applyButton.disabled = disabled;
                if (magicFillButton) magicFillButton.disabled = disabled;
            }

            function postCustomAbiRequest(url, body, timeoutMs) {
                const controller = new AbortController();
                const timeoutId = window.setTimeout(function () { controller.abort(); }, timeoutMs);

                return fetch(url, {
                    method: 'POST',
                    credentials: 'same-origin',
                    headers: { 'Content-Type': 'application/json; charset=utf-8' },
                    body: JSON.stringify(body),
                    signal: controller.signal
                })
                    .then(function (response) {
                        if (!response.ok) throw new Error('request failed');
                        return response.json();
                    })
                    .finally(function () {
                        window.clearTimeout(timeoutId);
                    });
            }

            function updateSaveUi() {
                const saveToAccount = isSavingToAccount();
                if (customAbiNameGroup) customAbiNameGroup.classList.toggle('d-none', !saveToAccount);
                if (customAbiName) customAbiName.required = saveToAccount;
                if (applyButton.dataset.busy !== '1') {
                    buttonText.textContent = saveToAccount ? 'Save & Apply Custom ABI' : 'Apply Custom ABI';
                }
            }

            const serverCustomAbiPanel = document.getElementById('serverCustomAbiPanel');
            const clientCustomAbiPanel = document.getElementById('localCustomAbiPanel');
            const clientCustomAbiPanelTitle = document.getElementById('clientCustomAbiPanelTitle');
            const clientCustomAbiDisplay = document.getElementById('localCustomAbiValue');
            const customAbiLabel = 'Contract ABI';
            // Whether the account already has an ABI saved for this contract, read once to label the trigger
            // button Add or Edit. A save reloads nothing, but renderCustomAbi sets that label directly, so this
            // does not need to track later changes.
            const savedCustomAbi = serverCustomAbiPanel ? customAbiValue.value.trim() : '';
            // Why a handed-over ABI was rejected, if it was. Held here because show.bs.modal clears the modal status
            // on every open, which would otherwise wipe the reason just as the user goes to read it.
            let localCustomAbiRejection = '';

            function updateCustomAbiPageUrl() {
                const nextUrl = new URL(window.location.href);
                nextUrl.searchParams.delete('customabi');
                nextUrl.hash = 'code';
                window.history.replaceState(null, '', nextUrl.pathname + nextUrl.search + nextUrl.hash);
            }

            function ensureCustomAbiNavigation() {
                if (!document.getElementById('ContentPlaceHolder1_li_contracts')) {
                    const contractTabItem = document.createElement('li');
                    contractTabItem.id = 'localCustomAbiContractTab';
                    contractTabItem.className = 'nav-item snap-align-start';

                    const contractTabLink = document.createElement('a');
                    contractTabLink.className = 'nav-link position-relative';
                    contractTabLink.href = 'javascript:;';
                    contractTabLink.textContent = 'Contract';
                    contractTabLink.setAttribute('data-bs-toggle', 'pill');
                    contractTabLink.setAttribute('data-bs-target', '#contracts');
                    contractTabLink.setAttribute('role', 'tab');
                    contractTabLink.setAttribute('aria-controls', 'contracts');
                    contractTabLink.setAttribute('aria-selected', 'false');
                    contractTabLink.addEventListener('click', function () { updatehash('code'); });

                    contractTabItem.appendChild(contractTabLink);
                    document.getElementById('nav_tabs').appendChild(contractTabItem);
                }

                if (!document.getElementById('li_CustomContract') && !document.getElementById('localCustomAbiNavItem')) {
                    let customAbiNav = document.getElementById('nav_subtabs');
                    if (!customAbiNav) {
                        const navWrapper = document.createElement('div');
                        navWrapper.id = 'localCustomAbiNavWrapper';
                        navWrapper.className = 'd-flex align-items-center flex-wrap gap-2';
                        const navContainer = document.createElement('div');
                        navContainer.className = 'pb-4';
                        customAbiNav = document.createElement('ul');
                        customAbiNav.id = 'nav_subtabs';
                        customAbiNav.className = 'nav nav-pills nav-sm-segment text-nowrap snap-x-mandatory overflow-x-auto flex-nowrap flex-grow-1 flex-sm-grow-0 border-2 rounded gap-1 p-0.5 nav-subtabs';
                        customAbiNav.setAttribute('role', 'tablist');
                        navContainer.appendChild(customAbiNav);
                        navWrapper.appendChild(navContainer);
                        document.getElementById('code').before(navWrapper);

                        const codeTabItem = document.createElement('li');
                        codeTabItem.id = 'localCustomAbiCodeNavItem';
                        codeTabItem.className = 'nav-item snap-align-start';
                        const codeTabLink = document.createElement('a');
                        codeTabLink.className = 'nav-link rounded-sm active';
                        codeTabLink.href = 'javascript:;';
                        codeTabLink.textContent = 'Code';
                        codeTabLink.setAttribute('data-bs-toggle', 'pill');
                        codeTabLink.setAttribute('data-bs-target', '#code');
                        codeTabLink.setAttribute('role', 'tab');
                        codeTabLink.setAttribute('aria-controls', 'code');
                        codeTabLink.setAttribute('aria-selected', 'true');
                        codeTabLink.addEventListener('click', function () { updatehash('code'); });
                        codeTabItem.appendChild(codeTabLink);
                        customAbiNav.appendChild(codeTabItem);
                    }

                    const customAbiNavTemplate = document.getElementById('localCustomAbiNavTemplate');
                    customAbiNav.appendChild(customAbiNavTemplate.content.cloneNode(true));
                    customAbiNav.style.removeProperty('display');
                    if (customAbiNav.parentElement) customAbiNav.parentElement.style.removeProperty('display');
                }
            }

            function resetCustomAbiIframes() {
                window.readCustomContractLoaded = false;
                window.writeCustomContractLoaded = false;
                ['readcustomcontractiframe', 'writecustomcontractiframe'].forEach(function (iframeId) {
                    const iframe = document.getElementById(iframeId);
                    if (iframe) iframe.removeAttribute('src');
                });
            }

            function renderCustomAbi(customAbi, isLocal) {
                localCustomAbiRejection = '';
                customAbiValue.value = customAbi;
                litCustomContractABIAddress = customAbiAddress.value.trim();
                ensureCustomAbiNavigation();
                resetCustomAbiIframes();
                updateAddEditButtonState(true);

                if (!isLocal && serverCustomAbiPanel) {
                    serverCustomAbiPanel.classList.remove('d-none');
                    clientCustomAbiPanel.classList.add('d-none');
                    return;
                }

                if (serverCustomAbiPanel) serverCustomAbiPanel.classList.add('d-none');
                clientCustomAbiPanelTitle.textContent = 'Custom ' + customAbiLabel;
                clientCustomAbiDisplay.textContent = customAbi;
                clientCustomAbiPanel.classList.remove('d-none');
            }

            function showCustomAbiCodeTab() {
                const contractTab = document.querySelector('#nav_tabs [data-bs-target="#contracts"]');
                if (contractTab) bootstrap.Tab.getOrCreateInstance(contractTab).show();

                const codeTab = document.querySelector('#nav_subtabs [data-bs-target="#code"]');
                if (codeTab) bootstrap.Tab.getOrCreateInstance(codeTab).show();

                const codePane = document.getElementById('code');
                const readCustomPane = document.getElementById('readCustomContract');
                const writeCustomPane = document.getElementById('writeCustomContract');
                if (readCustomPane) {
                    readCustomPane.classList.remove('active', 'show');
                    readCustomPane.style.display = 'none';
                }
                if (writeCustomPane) {
                    writeCustomPane.classList.remove('active', 'show');
                    writeCustomPane.style.display = 'none';
                }
                if (codePane) {
                    codePane.classList.add('active', 'show');
                    codePane.style.removeProperty('display');
                }
                updateCustomAbiPageUrl();
            }

            // Consume the single-use ABI handoff from Similar Contracts.
            const handedOverCustomAbiState = customAbiStorage.consumeHandoff(customAbiChainId, customAbiAddress.value);
            if (handedOverCustomAbiState.abi) {
                renderCustomAbi(handedOverCustomAbiState.abi, true);
            } else {
                if (handedOverCustomAbiState.present) {
                    // Already discarded on arrival, so there is nothing left to undo - just say why it could not
                    // be applied. show.bs.modal repeats the reason inside the modal.
                    localCustomAbiRejection = handedOverCustomAbiState.error;
                    showCustomAbiPageStatus('This custom ABI could not be applied: ' + handedOverCustomAbiState.error, 'danger');
                }
                updateAddEditButtonState(!!savedCustomAbi);
            }

            if (saveCheckbox) saveCheckbox.addEventListener('change', updateSaveUi);
            if (loginLink) {
                loginLink.addEventListener('click', function (event) {
                    try {
                        if (customAbiValue.value.length > customAbiValue.maxLength) throw new Error('ABI too large');
                        sessionStorage.setItem(loginReturnKey, JSON.stringify({ abi: customAbiValue.value, at: Date.now() }));
                    } catch (_) {
                        event.preventDefault();
                        showCustomAbiStatus('Unable to keep your ABI while signing in. Copy it before leaving, or enable browser storage and try again.', 'danger');
                    }
                });
            }
            modal.addEventListener('show.bs.modal', function () {
                // Restore the outstanding rejection reason rather than blanking it, so a handed-over ABI that was
                // discarded still explains itself when the user opens the modal to try again.
                showCustomAbiStatus(localCustomAbiRejection, 'danger');
                updateSaveUi();
            });
            updateSaveUi();

            if (magicFillButton) {
                magicFillButton.addEventListener('click', function () {
                    if (isCustomAbiBusy()) return;

                    magicFillButton.dataset.busy = '1';
                    setCustomAbiActionsDisabled(true);
                    magicFillButtonText.textContent = 'Finding...';
                    magicFillSpinner.classList.remove('d-none');

                    showCustomAbiStatus('', '');
                    postCustomAbiRequest('/address.aspx/MagicFillCustomAbi', {
                        contractAddress: customAbiAddress.value.trim(),
                        sid: sid
                    }, 20000)
                        .then(function (payload) {
                            const result = payload && typeof payload.d !== 'undefined' ? payload.d : payload;
                            if (!result || result.success !== true) {
                                showCustomAbiStatus(result && result.error ? result.error : 'Unable to find a same-chain similar contract with a valid ABI.', 'danger');
                                return;
                            }

                            customAbiValue.value = result.customabi;
                            if (customAbiName && result.sourceAddress) {
                                customAbiName.value = 'ABI from ' + result.sourceAddress;
                            }
                            const sourceChain = result.sourceChainName || magicFillButton.getAttribute('data-chain-name') || 'this chain';

                            const alert = document.createElement('div');
                            alert.className = 'alert alert-success mb-0';
                            alert.appendChild(document.createTextNode('Custom ABI added based on the most similar verified contract on ' + sourceChain + ': '));

                            const addressLink = document.createElement('a');
                            addressLink.href = '/address/' + encodeURIComponent(result.sourceAddress) + '#code';
                            addressLink.target = '_blank';
                            addressLink.rel = 'noopener noreferrer';
                            addressLink.textContent = result.sourceAddress;
                            addressLink.style.textDecoration = 'underline';
                            alert.appendChild(addressLink);

                            alert.appendChild(document.createTextNode('.'));
                            modalStatus.replaceChildren(alert);
                        })
                        .catch(function () {
                            showCustomAbiStatus('Unable to find a same-chain similar contract with a valid ABI. Please try again.', 'danger');
                        })
                        .finally(function () {
                            magicFillButton.dataset.busy = '0';
                            setCustomAbiActionsDisabled(false);
                            magicFillButtonText.textContent = 'Magic Fill';
                            magicFillSpinner.classList.add('d-none');
                        });
                });
            }

            form.addEventListener('submit', function (event) {
                event.preventDefault();
                if (isCustomAbiBusy()) return;

                const address = customAbiAddress.value.trim();
                const saveToAccount = isSavingToAccount();
                const name = customAbiName ? customAbiName.value.trim() : '';
                let customAbi;

                if (!address) {
                    showCustomAbiStatus('Contract address is required.', 'danger');
                    return;
                }

                try {
                    customAbi = customAbiStorage.normalize(customAbiValue.value.trim());
                } catch (error) {
                    // normalize() reports which limit was hit; keep the textarea untouched so nothing is lost.
                    showCustomAbiStatus(error && error.message ? error.message : 'Custom ABI is invalid.', 'danger');
                    return;
                }

                if (!saveToAccount) {
                    try {
                        // Held in memory for this page only. Leaving or reloading drops it, which is why the modal
                        // offers Save to My Custom ABI for an ABI the user wants to keep.
                        const appliedAbi = customAbiStorage.apply(customAbiChainId, address, customAbi);
                        renderCustomAbi(appliedAbi, true);
                        bootstrap.Modal.getOrCreateInstance(modal).hide();
                        showCustomAbiCodeTab();
                    } catch (error) {
                        showCustomAbiStatus('Unable to apply the custom ABI. Please try again.', 'danger');
                    }
                    return;
                }

                if (!name) {
                    showCustomAbiStatus('Enter a title before saving to My Custom ABI.', 'danger');
                    if (customAbiName) customAbiName.focus();
                    return;
                }

                applyButton.dataset.busy = '1';
                setCustomAbiActionsDisabled(true);
                if (saveCheckbox) saveCheckbox.disabled = true;
                buttonText.textContent = 'Saving...';
                spinner.classList.remove('d-none');

                postCustomAbiRequest('/address.aspx/SaveCustomAbi', {
                    formData: {
                        name: name,
                        address: address,
                        customabi: customAbi,
                        saveToAccount: true
                    },
                    sid: sid
                }, 20000)
                    .then(function (payload) {
                        const result = payload && typeof payload.d !== 'undefined' ? payload.d : payload;
                        if (!result || result.success !== true) {
                            showCustomAbiStatus(result && result.error ? result.error : 'Unable to save the custom ABI.', 'danger');
                            return;
                        }

                        // Applied in memory as well as saved, so this page shows the ABI just stored rather than the
                        // one the server rendered at load. A reload picks the saved copy up from the account.
                        let appliedLocally = true;
                        try {
                            result.customabi = customAbiStorage.apply(customAbiChainId, result.address, result.customabi);
                        } catch (error) {
                            appliedLocally = false;
                        }

                        renderCustomAbi(result.customabi, appliedLocally);
                        bootstrap.Modal.getOrCreateInstance(modal).hide();
                        showCustomAbiCodeTab();
                        showCustomAbiPageStatus(result.updated ? 'Custom ABI updated and applied.' : 'Custom ABI saved and applied.', 'success');
                    })
                    .catch(function () {
                        showCustomAbiStatus('Unable to save the custom ABI. Please try again.', 'danger');
                    })
                    .finally(function () {
                        applyButton.dataset.busy = '0';
                        setCustomAbiActionsDisabled(false);
                        if (saveCheckbox) saveCheckbox.disabled = false;
                        spinner.classList.add('d-none');
                        updateSaveUi();
                    });
            });

            let reopenAfterLogin = false;
            if (saveCheckbox) {
                try {
                    const storedLoginReturn = sessionStorage.getItem(loginReturnKey);
                    if (storedLoginReturn) {
                        sessionStorage.removeItem(loginReturnKey);
                        const loginReturn = JSON.parse(storedLoginReturn);
                        // Allow time for login and 2FA; consume once on return to the same chain and address.
                        if (triggerButton && loginReturn && typeof loginReturn.abi === 'string' &&
                            loginReturn.abi.length <= customAbiValue.maxLength &&
                            Number.isFinite(loginReturn.at) && loginReturn.at <= Date.now() &&
                            Date.now() - loginReturn.at <= 30 * 60 * 1000) {
                            reopenAfterLogin = true;
                            customAbiValue.value = loginReturn.abi;
                            if (loginReturn.abi.trim()) {
                                try {
                                    const restoredAbi = customAbiStorage.apply(customAbiChainId, customAbiAddress.value, loginReturn.abi);
                                    renderCustomAbi(restoredAbi, true);
                                } catch (_) {
                                    localCustomAbiRejection = 'Your ABI was restored, but could not be applied. Review it before applying again.';
                                }
                            }
                        }
                    }
                } catch (_) {
                    showCustomAbiPageStatus('Unable to restore your ABI after signing in. Paste it again to continue.', 'warning');
                }
            }

            if (openCustomAbiModal || reopenAfterLogin) {
                bootstrap.Modal.getOrCreateInstance(modal).show();
            }
        })();
(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a3964facae390c87',t:'MTc4OTEyNTkyMA=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();