Search
Search

Transaction: Aogpkmu...th2b

Receiver
Status
Succeeded
Transaction Fee
0.01078 
Deposit Value
0 
Gas Used
108 Tgas
Attached Gas
300 Tgas
Created
March 13, 2024 at 4:29:46am
Hash
AogpkmutNeN26qv8aNVY6gK7NLBa6fbK2oNUtZRSth2b

Actions

Called method: 'set' in contract: social.near
Arguments:
{ "data": { "nearblocks.near": { "widget": { "bos-components.components.FT.Transfers": { "": "/**\n * Component: FTTransfers\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Tranfers List.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {string} [id] - The token identifier passed as a string\n * @param {Object.<string, string>} [filters] - Key-value pairs for filtering transactions. (Optional)\n * Example: If provided, method=batch will filter the blocks with method=batch.\n * @param {function} [onFilterClear] - Function to clear a specific or all filters. (Optional)\n * Example: onFilterClear={handleClearFilter} where handleClearFilter is a function to clear the applied filters.\n\n */\n\n\n\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\nconst FaCheckCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z\"\n fill=\"#50C878\"\n />\n </svg>\n );\n};\nconst FaTimesCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"\n fill=\"#ff0000\"\n />\n </svg>\n );\n};\nconst FaHourglassStart = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 384 512\">\n <path\n d=\"M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM288 437v11H96V437c0-25.5 10.1-49.9 28.1-67.9L192 301.3l67.9 67.9c18 18 28.1 42.4 28.1 67.9z\"\n fill=\"#FFEB3B\"\n />\n </svg>\n );\n};\n\nconst getOptions = (status) => {\n switch (status) {\n case null:\n return {\n bg: 'bg-yellow-50',\n text: 'text-yellow-500',\n icon: FaHourglassStart,\n label: 'Pending',\n };\n case false:\n return {\n bg: 'bg-red-50',\n text: 'text-red-500',\n icon: FaTimesCircle,\n label: 'Failure',\n };\n\n default:\n return {\n bg: 'bg-emerald-50',\n text: 'text-emerald-500',\n icon: FaCheckCircle,\n label: 'Success',\n };\n }\n};\n\nconst TxnStatus = (props) => {\n const option = getOptions(props.status);\n const Icon = option.icon;\n\n return (\n <div className=\"w-full md:w-3/4 break-words\">\n <span\n className={`inline-flex items-center text-xs rounded py-1 ${\n option.bg\n } ${option.text} ${props.showLabel ? ' px-2' : ' px-1'}`}\n >\n <Icon />\n {props.showLabel && <span className=\"ml-2\">{option.label}</span>}\n </span>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Clock = (props) => (\n <svg\n viewBox=\"64 64 896 896\"\n focusable=\"false\"\n data-icon=\"clock-circle\"\n width=\"1em\"\n height=\"1em\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n <path d=\"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z\"></path>\n </svg>\n);/* END_INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/CloseCircle.jsx\" */\nconst CloseCircle = (props) => {\n const handleClick = () => {\n if (props.onClick) {\n props.onClick('All');\n }\n };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n className={props.className}\n onClick={handleClick}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm0-9.414l2.828-2.829 1.415 1.415L13.414 12l2.829 2.828-1.415 1.415L12 13.414l-2.828 2.829-1.415-1.415L10.586 12 7.757 9.172l1.415-1.415L12 10.586z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/CloseCircle.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\nconst FaLongArrowAltRight = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\">\n <path\n d=\"M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216\"\n fill=\"#ffffff\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, t, id, filters, onFilterClear }) {\n const [showAge, setShowAge] = useState(true);\n const [txnLoading, setTxnLoading] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [address, setAddress] = useState('');\n const config = getConfig(network);\n const errorMessage = 'No transactions found!';\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n setTxnLoading(true);\n asyncFetch(`${config?.backendUrl}fts/${id}/txns/count${queryParams}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count);\n setTxnLoading(false);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTxnsData(page, qs) {\n const queryParams = qs ? qs + '&' : '';\n setIsLoading(true);\n asyncFetch(\n `${config?.backendUrl}fts/${id}/txns?${queryParams}page=${page}&per_page=25`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then((data) => {\n const resp = data?.body?.txns;\n if (data.status === 200 && Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(data, () => fetchTxnsData(page, qs));\n }\n })\n .catch(() => {});\n }\n\n let urlString = '';\n if (filters && Object.keys(filters).length > 0) {\n urlString = Object.keys(filters)\n .map(\n (key) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(filters[key])}`,\n )\n .join('&');\n }\n\n fetchTotalTxns(urlString);\n fetchTxnsData(currentPage, urlString);\n }, [config?.backendUrl, currentPage, id, filters]);\n\n const onHandleMouseOver = (e, id) => {\n e.preventDefault();\n\n setAddress(id);\n };\n\n const columns = [\n {\n header: '',\n key: '',\n cell: (row) => (\n <>\n <TxnStatus status={row?.outcomes?.status} showLabel={false} />\n </>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-end',\n },\n {\n header: <span>{t ? t('hash') : 'HASH'}</span>,\n key: 'transaction_hash',\n cell: (row) => (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/txns/${row?.transaction_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.transaction_hash}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>BLOCK</span>,\n key: 'block.block_height',\n cell: (row) => (\n <>\n <a\n className=\"hover:no-underline\"\n href={`/blocks/${row?.included_in_block_hash}`}\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.block?.block_height\n ? localFormat(row?.block?.block_height)\n : row?.block?.block_height ?? ''}\n </a>\n </a>\n </>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>{t ? t('type') : 'TYPE'}</span>,\n key: 'cause',\n cell: (row) => (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"bg-blue-900/10 text-xs text-nearblue-600 rounded-xl px-2 py-1 max-w-[120px] inline-flex truncate\">\n <span className=\"block truncate\">{row?.cause}</span>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.cause}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>Affected</span>,\n key: 'affected_account_id',\n cell: (row) => (\n <>\n {row?.affected_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.affected_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.affected_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.affected_account_id)\n }\n >\n {row?.affected_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.affected_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: '',\n key: '',\n cell: (row) =>\n row?.involved_account_id === row?.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 inline-flex items-center justify-center bg-green-200 text-white text-sm font-semibold\">\n {t ? t('txnSelf') : 'Self'}\n </span>\n ) : Number(row?.delta_amount) > 0 ? (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white rotate-180\">\n <FaLongArrowAltRight />\n </div>\n ) : (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white\">\n <FaLongArrowAltRight />\n </div>\n ),\n tdClassName: 'text-center',\n },\n {\n header: <span>Involved</span>,\n key: 'involved_account_id',\n cell: (row) => (\n <span>\n {row?.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.involved_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.involved_account_id)\n }\n >\n {row?.involved_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.involved_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>Quantity</span>,\n key: 'amount',\n cell: (row) => (\n <>\n {row?.delta_amount\n ? localFormat(\n tokenAmount(\n Big(row.delta_amount).abs().toString(),\n row?.ft?.decimals,\n true,\n ),\n )\n : ''}\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n onClick={toggleShowAge}\n className=\"text-left text-xs px-5 py-4 w-full flex items-center font-semibold uppercase tracking-wider text-green-500 focus:outline-none flex-row whitespace-nowrap\"\n >\n {showAge ? (\n <>\n {t ? t('token:fts.age') : 'AGE'}\n <Clock className=\"text-green-500 ml-2\" />\n </>\n ) : (\n <> {t ? t('token:fts.ageDT') : 'DATE TIME (UTC)'}</>\n )}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"top\"\n >\n {showAge\n ? 'Click to show Datetime Format'\n : 'Click to show Age Format'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n key: 'block_timestamp',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {!showAge\n ? row?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(row?.block_timestamp),\n )\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {showAge\n ? row?.block_timestamp\n ? formatTimestampToString(nanoToMilli(row?.block_timestamp))\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n },\n ];\n\n return (\n <>\n {txnLoading ? (\n <div className=\"pl-3 max-w-sm py-5 h-[60px]\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions found\n </p>\n </div>\n <div className=\" flex items-center px-2 text-sm mb-4 text-nearblue-600 lg:ml-auto\">\n {filters && Object?.keys(filters)?.length > 0 && (\n <div className=\"flex items-center px-2 text-sm text-gray-500 lg:ml-auto\">\n Filtered By:\n <span className=\"flex items-center bg-gray-100 rounded-full px-3 py-1 ml-1 space-x-2\">\n {filters &&\n Object?.keys(filters)?.map((key) => (\n <span className=\"flex\" key={key}>\n {capitalizeFirstLetter(key)}:{' '}\n <span className=\"inline-block truncate max-w-[120px]\">\n <span className=\"font-semibold\">{filters[key]}</span>\n </span>\n </span>\n ))}\n <CloseCircle\n className=\"w-4 h-4 fill-current cursor-pointer\"\n onClick={onFilterClear}\n />\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: txns[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Info": { "": "/**\n * Component: FTInfo\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Information About Fungible Token On Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\n\nfunction MainComponent({ token, id, network }) {\n const [tokens, setTokens] = useState({} );\n const config = getConfig(network);\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n\n if (!token && token === undefined) {\n fetchFTData();\n }\n }, [config?.backendUrl, id, token]);\n\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n\n return (\n <div className=\"px-3 pt-2 pb-5 text-sm text-gray\">\n {tokens?.description && (\n <>\n <h3 className=\"text-nearblue-600 text-sm font-semibold py-2 underline\">\n Overview\n </h3>\n <p className=\"text-sm py-2 text-nearblue-600\">\n {tokens?.description}\n </p>\n </>\n )}\n <h3 className=\"text-nearblue-600 text-sm font-semibold py-2 underline\">\n Market\n </h3>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Volume (24H):</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.volume_24h !== null && tokens?.volume_24h !== undefined ? (\n `$${dollarNonCentFormat(tokens?.volume_24h)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Circulating MC:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.market_cap !== null && tokens?.market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens?.market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">On-chain MC:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.onchain_market_cap !== null &&\n tokens?.onchain_market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens?.onchain_market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Circulating Supply:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.circulating_supply !== null &&\n tokens?.circulating_supply !== undefined ? (\n `${localFormat(tokens?.circulating_supply)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 pt-6 text-gray-400 text-xs\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Market Data Source:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.coingecko_id && (\n <a\n className=\"text-green-500 mr-4\"\n href=\"https://www.coingecko.com/\"\n target=\"_blank\"\n rel=\"noreferrer nofollow noopener\"\n >\n CoinGecko\n </a>\n )}\n {tokens?.coinmarketcap_id && (\n <a\n className=\"text-green-500 mr-4\"\n href=\"https://coinmarketcap.com/\"\n target=\"_blank\"\n rel=\"noreferrer nofollow noopener\"\n >\n Coinmarketcap\n </a>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.List": { "": "/**\n * Component: FTList\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Top Tokens on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet.\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {number} [currentPage] - The current page number being displayed. (Optional)\n * Example: If provided, currentPage=3 will display the third page of blocks.\n * @param {function} [setPage] - A function used to set the current page. (Optional)\n * Example: setPage={handlePageChange} where handlePageChange is a function to update the page.\n */\n\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n\n/* INCLUDE COMPONENT: \"includes/icons/ArrowDown.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\nconst ArrowDown = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/ArrowDown.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/SortIcon.jsx\" */\nconst ArrowUp = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 10.828l-4.95 4.95-1.414-1.414L12 8l6.364 6.364-1.414 1.414z\" />\n </svg>\n );\n};\n\nconst SortIcon = (props) => {\n return (\n <ArrowUp\n className={`h-3 w-3 fill-current transition-transform mr-1 duration-700 ${\n props.order !== 'asc' ? 'transform rotate-180' : 'transform rotate-0'\n }`}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/SortIcon.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Question = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v2h-2v-2zm2-1.645V14h-2v-1.5a1 1 0 011-1 1.5 1.5 0 10-1.471-1.794l-1.962-.393A3.501 3.501 0 1113 13.355z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n\nconst initialSorting = {\n sort: 'onchain_market_cap',\n order: 'desc',\n};\nconst initialPagination = {\n per_page: 50,\n};\nfunction MainComponent({ t, network, currentPage, setPage }) {\n const [searchResults, setSearchResults] = useState([]);\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [tokens, setTokens] = useState({});\n\n const [sorting, setSorting] = useState(initialSorting);\n const errorMessage = t ? t('token:fts.top.empty') : 'No tokens found!';\n const config = getConfig(network);\n const ArrowUp = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n className=\"h-3 w-3 fill-current mr-1\"\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 10.828l-4.95 4.95-1.414-1.414L12 8l6.364 6.364-1.414 1.414z\" />\n </svg>\n );\n };\n\n useEffect(() => {\n function fetchTotalTokens(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(`${config?.backendUrl}fts/count${queryParams}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.tokens?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTokens(qs));\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTokens(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}fts?${queryParams}order=${sqs?.order}&sort=${sqs?.sort}&page=${page}&per_page=50`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.tokens;\n if (data.status === 200) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTokens(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n if (sorting) {\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n }\n }, [config?.backendUrl, currentPage, sorting]);\n\n const onOrder = (sortKey) => {\n setSorting((state) => ({\n ...state,\n sort: sortKey,\n order:\n state.sort === sortKey\n ? state.order === 'asc'\n ? 'desc'\n : 'asc'\n : 'desc',\n }));\n };\n const debouncedSearch = useMemo(() => {\n return debounce(500, (value) => {\n if (!value || value.trim() === '') {\n setSearchResults([]);\n return;\n }\n asyncFetch(`${config?.backendUrl}fts?search=${value}&per_page=5`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((data) => {\n const resp = data?.body?.tokens;\n setSearchResults(resp);\n })\n .catch(() => {});\n });\n }, [config?.backendUrl]);\n\n const onChange = (e) => {\n const value = e.target.value;\n debouncedSearch(value);\n };\n const columns = [\n {\n header: <span>#</span>,\n key: '',\n cell: (_row, index) => (\n <span>\n {serialNumber(index, currentPage, initialPagination.per_page)}\n </span>\n ),\n tdClassName:\n 'pl-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.token') : 'TOKEN'}</span>,\n key: 'name',\n cell: (row) => (\n <>\n <div className=\"flex items-center\">\n <TokenImage\n src={row?.icon}\n alt={row?.name}\n appUrl={config?.appUrl}\n className=\"w-5 h-5 mr-2\"\n />\n <a href={`/token/${row?.contract}`} className=\"hover:no-underline\">\n <a className=\" text-green-500 hover:no-underline\">\n <span className=\"truncate max-w-[200px] mr-1\">{row?.name}</span>\n <span className=\"text-nearblue-700 truncate max-w-[80px]\">\n {row?.symbol}\n </span>\n </a>\n </a>\n </div>\n </>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 w-80 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.price') : 'PRICE'}</span>,\n key: 'price',\n cell: (row) => (\n <span>\n {row?.price === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n ` $${localFormat(row?.price)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.change') : 'CHANGE'} (%)</span>,\n key: 'change_24',\n cell: (row) => (\n <span>\n {row?.change_24 === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : Number(row?.change_24) > 0 ? (\n <div className=\"text-neargreen flex flex-row items-center\">\n <ArrowUp />+{dollarFormat(row?.change_24)}%\n </div>\n ) : (\n <div className=\"text-red-500 flex flex-row items-center\">\n <ArrowDown className=\"h-3 w-3 fill-current mr-1\" />\n {row?.change_24 ? dollarFormat(row?.change_24) + '%' : ''}\n </div>\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.volume') : 'VOLUME'} (24H)</span>,\n key: 'volume_24h',\n cell: (row) => (\n <span>\n {row?.volume_24h === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${dollarNonCentFormat(row?.volume_24h)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <span className=\"flex\">\n <span className=\"uppercase whitespace-nowrap\">Circulating MC</span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\" h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 \"\n align=\"start\"\n side=\"bottom\"\n >\n {\n 'Calculated by multiplying the number of tokens in circulating supply across all chains with the current market price per token.'\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n key: 'market_cap',\n cell: (row) => (\n <span>\n {row?.market_cap === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${dollarNonCentFormat(row?.market_cap)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <span>\n {' '}\n <button\n type=\"button\"\n onClick={() => onOrder('onchain_market_cap')}\n className=\"w-full px-6 py-2 text-left text-xs font-semibold tracking-wider text-green-500 focus:outline-none flex flex-row\"\n >\n {sorting?.sort === 'onchain_market_cap' && (\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting?.order} />\n </div>\n )}\n <span className=\"uppercase whitespace-nowrap\">On-Chain MC</span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\" h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {\n \"Calculated by multiplying the token's Total Supply on Near with the current market price per token\"\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </button>\n </span>\n ),\n key: 'onchain_market_cap',\n cell: (row) => (\n <span>\n {row?.onchain_market_cap === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${\n row?.onchain_market_cap\n ? dollarNonCentFormat(row?.onchain_market_cap)\n : row?.onchain_market_cap ?? ''\n }`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n },\n // {\n // header: (\n // <span>\n // <button\n // type=\"button\"\n // onClick={() => onOrder('holders')}\n // className=\"w-full px-6 py-2 text-left text-xs font-semibold uppercase tracking-wider text-green-500 focus:outline-none flex flex-row\"\n // >\n // {sorting?.sort === 'holders' && (\n // <div className=\"text-nearblue-600 font-semibold\">\n // <SortIcon order={sorting?.order} />\n // </div>\n // )}\n // Holders\n // </button>{' '}\n // </span>\n // ),\n // key: 'holders',\n // cell: (row: Token) => (\n // <span>{row?.holders ? localFormat(row?.holders) : ''}</span>\n // ),\n // tdClassName:\n // 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n // },\n ];\n\n return (\n <div className=\" bg-white border soft-shadow rounded-xl pb-1 \">\n <div className=\"flex flex-row items-center justify-between text-left text-sm text-nearblue-600 px-3 py-2\">\n {isLoading ? (\n <div className=\"max-w-lg w-full pl-3\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <p className=\"pl-3\">\n {t\n ? t('token:fts.top.listing', { count: totalCount })\n : `A total of ${totalCount} Token Contracts found`}\n </p>\n )}\n <div className={`flex w-full h-10 sm:w-80 mr-2`}>\n <div className=\"flex-grow\">\n <label htmlFor=\"token-search\" id=\"token-search\">\n <input\n name=\"search\"\n autoComplete=\"off\"\n placeholder=\"Search\"\n className=\"search ml-2 pl-8 token-search bg-white w-full h-full text-sm py-2 outline-none border rounded-xl\"\n onChange={onChange}\n />\n </label>\n {searchResults?.length > 0 && (\n <div className=\"z-50 relative\">\n <div className=\"text-xs rounded-b-md -mr-2 ml-2 -mt-1 bg-white py-2 shadow\">\n {searchResults.map((token) => (\n <div\n key={token?.contract}\n className=\"mx-2 px-2 py-2 hover:bg-gray-100 cursor-pointer hover:border-gray-500 truncate\"\n >\n <a\n href={`/token/${token?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"hover:no-underline flex items-center my-1 whitespace-nowrap \">\n <div className=\"flex-shrink-0 h-5 w-5 mr-2\">\n <TokenImage\n src={token?.icon}\n alt={token?.name}\n appUrl={config?.appUrl}\n className=\"w-5 h-5\"\n />\n </div>\n <p className=\"font-semibold text-sm truncate\">\n {token?.name}\n <span className=\"text-nearblue-700 ml-2\">\n {token?.symbol}\n </span>\n </p>\n </a>\n </a>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: tokens[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 50,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.TokenFilter": { "": "/**\n * Component: FTTokenFilter\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Filter on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {string} [tokenFilter] - The token filter identifier passed as a string\n */\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaAddressBook.jsx\" */\nconst FaAddressBook = () => {\n return (\n <svg\n stroke=\"currentColor\"\n fill=\"currentColor\"\n stroke-width=\"0\"\n viewBox=\"0 0 448 512\"\n color=\"#db9a04\"\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-228-32c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H118.4C106 384 96 375.4 96 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z\"\n fill=\"#db9a04\"\n ></path>\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaAddressBook.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction decodeArgs(args) {\n if (!args || typeof args === 'undefined') return {};\n\n return JSON.parse(Buffer.from(args, 'base64').toString());\n}\n\nfunction txnMethod(\n actions,\n t,\n) {\n const count = actions?.length || 0;\n\n if (!count) return t ? t('txns:unknownType') : 'Unknown';\n if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction';\n\n const action = actions[0];\n\n if (action.action === 'FUNCTION_CALL') {\n return action.method;\n }\n\n return action.action;\n}\n\nfunction gasPrice(yacto) {\n const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString();\n\n return `${localFormat(near)} Ⓝ / Tgas`;\n}\n\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction encodeArgs(args) {\n if (!args || typeof args === 'undefined') return '';\n\n return Buffer.from(JSON.stringify(args)).toString('base64');\n}\n\nfunction decodeArgs(args) {\n if (!args || typeof args === 'undefined') return {};\n\n return JSON.parse(Buffer.from(args, 'base64').toString());\n}\n\nfunction txnMethod(\n actions,\n t,\n) {\n const count = actions?.length || 0;\n\n if (!count) return t ? t('txns:unknownType') : 'Unknown';\n if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction';\n\n const action = actions[0];\n\n if (action.action === 'FUNCTION_CALL') {\n return action.method;\n }\n\n return action.action;\n}\n\nfunction gasPrice(yacto) {\n const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString();\n\n return `${localFormat(near)} Ⓝ / Tgas`;\n}\n\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction MainComponent({ network, id, tokenFilter }) {\n const [ft, setFT] = useState({} );\n const [inventoryLoading, setInventoryLoading] = useState(false);\n const [inventoryData, setInventoryData] = useState(\n {} ,\n );\n\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchInventoryData() {\n setInventoryLoading(true);\n asyncFetch(`${config?.backendUrl}account/${tokenFilter}/inventory`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const response = data?.body?.inventory;\n if (data.status === 200) {\n setInventoryData(response);\n setInventoryLoading(false);\n } else {\n handleRateLimit(data, fetchInventoryData, () =>\n setInventoryLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n fetchInventoryData();\n }, [config.backendUrl, tokenFilter]);\n\n useEffect(() => {\n function ftBalanceOf(contracts, account_id) {\n return asyncFetch(`${config?.rpcUrl}`, {\n method: 'POST',\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 'dontcare',\n method: 'query',\n params: {\n request_type: 'call_function',\n finality: 'final',\n account_id: contracts,\n method_name: 'ft_balance_of',\n args_base64: encodeArgs({ account_id }),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (res\n\n\n\n) => {\n return res;\n },\n )\n .then(\n (data\n\n\n\n) => {\n const resp = data?.body?.result;\n return decodeArgs(resp.result);\n },\n )\n .catch(() => {});\n }\n\n function loadBalances() {\n setInventoryLoading(true);\n const fts =\n inventoryData?.fts &&\n inventoryData?.fts.filter((f) => id == f.contract);\n\n if (!fts?.length) {\n if (fts?.length === 0) setInventoryLoading(false);\n return;\n }\n\n let total = Big(0);\n\n const tokens = [];\n\n const pricedTokens = [];\n\n Promise.all(\n fts.map((ft) => {\n return ftBalanceOf(ft.contract, tokenFilter).then((rslt) => {\n return { ...ft, amount: rslt };\n });\n }),\n ).then((results) => {\n results.forEach((rslt) => {\n const ftrslt = rslt;\n const amount = rslt?.amount;\n\n let sum = Big(0);\n\n let rpcAmount = Big(0);\n\n if (amount) {\n rpcAmount = ftrslt.ft_meta?.decimals\n ? Big(amount).div(Big(10).pow(ftrslt.ft_meta?.decimals))\n : 0;\n }\n\n if (ftrslt.ft_meta?.price) {\n sum = rpcAmount.mul(Big(ftrslt.ft_meta?.price));\n total = total.add(sum);\n\n return pricedTokens.push({\n ...ftrslt,\n amountUsd: sum.toString(),\n rpcAmount: rpcAmount.toString(),\n });\n }\n\n return tokens.push({\n ...ftrslt,\n amountUsd: sum.toString(),\n rpcAmount: rpcAmount.toString(),\n });\n });\n\n setFT({\n amount: total.toString(),\n tokens: [...pricedTokens, ...tokens],\n });\n\n setInventoryLoading(false);\n });\n }\n\n loadBalances();\n }, [inventoryData?.fts, id, tokenFilter, config?.rpcUrl]);\n\n const filterToken = ft?.tokens?.length\n ? ft?.tokens[0]\n : ({} );\n\n return (\n <>\n {tokenFilter && (\n <div className=\"py-2\">\n <div className=\"bg-white soft-shadow rounded-xl px-2 py-3\">\n <div className=\"grid md:grid-cols-3 grid-cols-1 divide-y md:divide-y-0 md:divide-x\">\n <div className=\"px-4 md:py-0 py-2\">\n <div className=\"flex items-center\">\n <FaAddressBook />\n <h5 className=\"text-xs my-1 font-bold ml-1 \">\n FILTERED BY TOKEN HOLDER\n </h5>\n </div>\n <h5 className=\"text-sm my-1 font-bold text-green-500 truncate md:max-w-[200px] lg:max-w-[310px] xl:max-w-full max-w-full inline-block\">\n <a\n href={`/address/${tokenFilter}`}\n className=\"hover:no-underline\"\n >\n <a className=\"hover:no-underline\">{tokenFilter}</a>\n </a>\n </h5>\n </div>\n <div className=\"px-4 md:py-0 py-2\">\n <p className=\"text-xs my-1 text-nearblue-600\">BALANCE</p>\n\n {inventoryLoading ? (\n <Skeleton className=\"w-40\" />\n ) : (\n <p className=\"text-sm my-1\">\n {Number(filterToken?.rpcAmount)\n ? localFormat(filterToken?.rpcAmount)\n : ''}\n </p>\n )}\n </div>\n <div className=\"px-4 md:py-0 py-2\">\n <p className=\"text-xs my-1 text-nearblue-600\">VALUE</p>\n\n {inventoryLoading ? (\n <Skeleton className=\"w-40\" />\n ) : (\n <p className=\"text-sm my-1 flex\">\n ${ft?.amount ? dollarFormat(ft?.amount) : ft?.amount ?? ''}\n <span>\n {filterToken?.ft_meta?.price && (\n <div className=\"text-gray-400 ml-2\">\n @{filterToken?.ft_meta?.price}\n </div>\n )}\n </span>\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Overview": { "": "/**\n * Component: FTOverview\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Overview on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {string} [id] - The token identifier passed as a string\n * @param {string} [tokenFilter] - The token filter identifier passed as a string\n * @param {Object.<string, string>} [filters] - Key-value pairs for filtering transactions. (Optional)\n * Example: If provided, method=batch will filter the blocks with method=batch.\n * @param {function} [onFilterClear] - Function to clear a specific or all filters. (Optional)\n * Example: onFilterClear={handleClearFilter} where handleClearFilter is a function to clear the applied filters.\n */\n\n\n\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Links.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\nconst Links = (props) => {\n const { meta } = props;\n const twitter = urlHostName(meta?.twitter);\n const facebook = urlHostName(meta?.facebook);\n const telegram = urlHostName(meta?.telegram);\n\n return (\n <div className=\"flex space-x-4\">\n {meta?.twitter && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !twitter\n ? `https://twitter.com/${meta.twitter}`\n : meta.twitter\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/twitter_icon.svg\"\n alt=\"Twitter\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Twitter\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.facebook && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !facebook\n ? `https://facebook.com/${meta.facebook}`\n : meta.facebook\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/facebook_icon.svg\"\n alt=\"Facebook\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Facebook\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.telegram && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !telegram ? `https://t.me/${meta.telegram}` : meta.telegram\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/telegram_icon.svg\"\n alt=\"Telegram\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Telegram\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.coingecko_id && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={`https://www.coingecko.com/en/coins/${meta.coingecko_id}`}\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/coingecko_icon.svg\"\n alt=\"coingecko\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n CoinGecko\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Links.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Question = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v2h-2v-2zm2-1.645V14h-2v-1.5a1 1 0 011-1 1.5 1.5 0 10-1.471-1.794l-1.962-.393A3.501 3.501 0 1113 13.355z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\n\nfunction MainComponent({\n network,\n t,\n id,\n tokenFilter,\n filters,\n onFilterClear,\n}) {\n const tabs = [\n t ? t('token:fts.ft.transfers') : 'Transfers',\n t ? t('token:fts.ft.holders') : 'Holders',\n 'Info',\n 'FAQ',\n 'Comments',\n ];\n const [isLoading, setIsLoading] = useState(false);\n const [txnLoading, setTxnLoading] = useState(false);\n const [holderLoading, setHolderLoading] = useState(false);\n const [stats, setStats] = useState({} );\n const [token, setToken] = useState({} );\n const [transfers, setTransfers] = useState('');\n const [holders, setHolders] = useState('');\n const [pageTab, setPageTab] = useState('Transfers');\n const [showMarketCap, setShowMarketCap] = useState(false);\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchFTData() {\n setIsLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setToken(resp);\n setIsLoading(false);\n } else {\n handleRateLimit(data, fetchFTData, () => setIsLoading(false));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsCount() {\n setTxnLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}/txns/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTransfers(resp.count);\n setTxnLoading(false);\n } else {\n handleRateLimit(data, fetchTxnsCount, () => setTxnLoading(false));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchStatsData() {\n asyncFetch(`${config?.backendUrl}stats`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => {\n const data = res.body;\n if (res.status === 200) {\n setStats(data.stats[0]);\n } else {\n handleRateLimit(data, fetchStatsData);\n }\n })\n .catch(() => {})\n .finally(() => {});\n }\n function fetchHoldersCount() {\n setHolderLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}/holders/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setHolders(resp.count);\n setHolderLoading(false);\n } else {\n handleRateLimit(data, fetchHoldersCount, () =>\n setHolderLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n fetchStatsData();\n fetchFTData();\n fetchTxnsCount();\n fetchHoldersCount();\n }, [config.backendUrl, id]);\n\n const onTab = (index) => {\n setPageTab(tabs[index]);\n onFilterClear && onFilterClear('');\n };\n\n const onToggle = () => setShowMarketCap((o) => !o);\n return (\n <>\n <div className=\"flex items-center justify-between flex-wrap pt-4\">\n {isLoading ? (\n <div className=\"w-80 max-w-xs px-3 py-5\">\n <Skeleton className=\"h-7\" />\n </div>\n ) : (\n <h1 className=\"break-all space-x-2 text-xl text-gray-700 leading-8 py-4 px-2\">\n <span className=\"inline-flex align-middle h-7 w-7\">\n <TokenImage\n src={token?.icon}\n alt={token?.name}\n className=\"w-7 h-7\"\n />\n </span>\n <span className=\"inline-flex align-middle \">Token: </span>\n <span className=\"inline-flex align-middle font-semibold\">\n {token?.name}\n </span>\n </h1>\n )}\n </div>\n <div>\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-2 md:mb-2\">\n <div className=\"w-full\">\n <div className=\"h-full bg-white soft-shadow rounded-xl overflow-hidden\">\n <h2 className=\"border-b p-3 text-nearblue-600 text-sm font-semibold\">\n Overview\n </h2>\n\n <div className=\"px-3 divide-y text-sm text-nearblue-600\">\n <div className=\"flex divide-x my-2\">\n <div className=\"flex-col flex-1 flex-wrap py-1\">\n <div className=\"w-full text-nearblue-700 text-xs uppercase mb-1 text-[80%]\">\n Price\n </div>\n {isLoading ? (\n <div className=\"w-20\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : token?.price !== null && token?.price !== undefined ? (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n ${dollarFormat(token?.price)}\n {stats?.near_price && (\n <div className=\"text-nearblue-700 mx-1 text-sm flex flex-row items-center\">\n @{' '}\n {localFormat(\n (\n Big(token?.price) / Big(stats?.near_price)\n ).toString(),\n )}{' '}\n Ⓝ\n </div>\n )}\n {token?.change_24 !== null &&\n token?.change_24 !== undefined ? (\n Number(token?.change_24) > 0 ? (\n <div className=\"text-neargreen text-sm flex flex-row items-center\">\n {' '}\n (+{dollarFormat(token?.change_24)}%)\n </div>\n ) : (\n <div className=\"text-red-500 text-sm flex flex-row items-center\">\n {' '}\n ({dollarFormat(token?.change_24)}%)\n </div>\n )\n ) : null}\n </div>\n ) : (\n 'N/A'\n )}\n </div>\n <div className=\"flex-col flex-1 flex-wrap py-1 px-3\">\n <div className=\"w-full text-nearblue-700 text-xs mb-1 flex text-[80%]\">\n <span className=\"uppercase\">\n {showMarketCap\n ? 'CIRCULATING SUPPLY MARKET CAP'\n : 'FULLY DILUTED MARKET CAP'}\n </span>\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {\n 'Calculated by multiplying the tokens Total Supply on Near with the current market price per token.'\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n </div>\n {isLoading ? (\n <div className=\"w-20\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (token?.fully_diluted_market_cap !== null &&\n token?.fully_diluted_market_cap !== undefined) ||\n (token?.market_cap !== null &&\n token?.market_cap !== undefined) ? (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n {token?.fully_diluted_market_cap !== null &&\n token?.fully_diluted_market_cap !== undefined &&\n token?.market_cap !== null &&\n token?.market_cap !== undefined ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <p\n className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\"\n onClick={onToggle}\n >\n $\n {showMarketCap\n ? dollarNonCentFormat(token?.market_cap)\n : dollarNonCentFormat(\n token?.fully_diluted_market_cap,\n )}\n </p>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {showMarketCap\n ? 'Click to switch back'\n : 'Click to switch'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n <p className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\">\n $\n {dollarNonCentFormat(\n Number(token?.market_cap)\n ? token?.market_cap\n : token?.fully_diluted_market_cap,\n )}\n </p>\n )}\n </div>\n ) : (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n {token?.onchain_market_cap ? (\n <p className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\">\n ${dollarNonCentFormat(token?.onchain_market_cap)}\n </p>\n ) : (\n 'N/A'\n )}\n </div>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Max Total Supply:\n </div>\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {token?.total_supply\n ? dollarNonCentFormat(token?.total_supply)\n : token?.total_supply ?? ''}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Transfers:\n </div>\n {txnLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {transfers ? localFormat(transfers) : transfers ?? ''}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Holders:</div>\n {holderLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {holders ? localFormat(holders) : holders ?? ''}\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n <div className=\"w-full\">\n <div className=\"h-full bg-white soft-shadow rounded-xl overflow-hidden\">\n <h2 className=\"border-b p-3 text-nearblue-600 text-sm font-semibold\">\n Profile Summary\n </h2>\n <div className=\"px-3 divide-y text-sm text-nearblue-600\">\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Contract:</div>\n {isLoading ? (\n <div className=\"w-full md:w-3/4 break-words\">\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n </div>\n ) : (\n <div className=\"w-full text-green-500 md:w-3/4 break-words\">\n <a href={`/address/${token?.contract}`}>\n <a className=\"text-green-500\">{token?.contract}</a>\n </a>\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Decimals:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n token?.decimals\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Official Site:\n </div>\n <div className=\"w-full md:w-3/4 text-green-500 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <a\n href={`${token?.website}`}\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n >\n {token?.website}\n </a>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Social Profiles:\n </div>\n <div className=\"w-full md:w-3/4 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <Links meta={token} />\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div className=\"py-6\"></div>\n {tokenFilter && (\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.TokenFilter`}\n props={{\n network: network,\n id: id,\n tokenFilter: tokenFilter,\n }}\n />\n )}\n <div className=\"block lg:flex lg:space-x-2 mb-4\">\n <div className=\"w-full\">\n <Tabs.Root defaultValue={pageTab}>\n <Tabs.List>\n {tabs &&\n tabs.map((tab, index) => (\n <Tabs.Trigger\n key={index}\n onClick={() => onTab(index)}\n className={`text-nearblue-600 text-sm font-medium overflow-hidden inline-block cursor-pointer p-2 mb-3 mr-2 focus:outline-none ${\n pageTab === tab\n ? 'rounded-lg bg-green-600 text-white'\n : 'hover:bg-neargray-800 bg-neargray-700 rounded-lg hover:text-nearblue-600'\n }`}\n value={tab}\n >\n <h2>{tab}</h2>\n </Tabs.Trigger>\n ))}\n </Tabs.List>\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n <Tabs.Content value={tabs[0]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Transfers`}\n props={{\n network: network,\n id: id,\n t: t,\n filters: filters,\n onFilterClear: onFilterClear,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content value={tabs[1]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Holders`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content clssName=\"border-t\" value={tabs[2]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Info`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content value={tabs[3]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.FAQ`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>{' '}\n <Tabs.Content value={tabs[4]}>\n <div className=\"py-3\">\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.Comments.Feed`}\n props={{\n network: network,\n path: `nearblocks.io/ft/${id}`,\n limit: 10,\n }}\n />\n }\n </div>\n </Tabs.Content>\n </div>\n </Tabs.Root>\n </div>\n </div>\n </div>\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Holders": { "": "/**\n * Component: FTHolders\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Holders List.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, id, token }) {\n const [isLoading, setIsLoading] = useState(false);\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n const [totalCount, setTotalCount] = useState(0);\n const [holder, setHolder] = useState(\n {},\n );\n const [tokens, setTokens] = useState({} );\n const config = getConfig(network);\n const errorMessage = 'No token holders found!';\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchTotalHolders() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders/count`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count);\n } else {\n handleRateLimit(data, fetchTotalHolders);\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchHoldersData(page) {\n setIsLoading(true);\n\n asyncFetch(\n `${config?.backendUrl}fts/${id}/holders?page=${currentPage}&per_page=25`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then(\n (data) => {\n const resp = data?.body?.holders;\n if (data.status === 200 && Array.isArray(resp) && resp.length > 0) {\n setHolder((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchHoldersData(page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n if (!token && token === undefined) {\n fetchFTData();\n }\n fetchTotalHolders();\n fetchHoldersData(currentPage);\n }, [config?.backendUrl, currentPage, id, token]);\n\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n\n const columns = [\n {\n header: 'Rank',\n key: '',\n cell: (_row, index) => (\n <span>{serialNumber(index, currentPage, 25)}</span>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 w-[50px]',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider w-[50]',\n },\n {\n header: 'Address',\n key: 'account',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[200px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/address/${row.account}`}\n className=\"hover:no-undeline\"\n >\n <a className=\"text-green-500 font-medium hover:no-undeline\">\n {row.account}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row.account}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Quantity',\n key: '',\n cell: (row) => (\n <>\n {' '}\n {row.amount && tokens?.decimals\n ? tokenAmount(row.amount, tokens?.decimals, true)\n : ''}\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Percentage',\n key: 'total_supply',\n cell: (row) => {\n const percentage = token?.total_supply\n ? tokenPercentage(token.total_supply, row.amount, token.decimals)\n : null;\n return (\n <>\n {percentage === null ? 'N/A' : `${percentage}%`}\n {percentage !== null && percentage <= 100 && percentage >= 0 && (\n <div className=\"h-0.5 mt-1 w-full bg-gray-100\">\n <div\n style={{ width: `${percentage}%` }}\n className=\"h-0.5 bg-green-500\"\n />\n </div>\n )}\n </>\n );\n },\n tdClassName:\n 'px-5 py-3 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Value',\n key: 'tokens',\n cell: (row) => {\n return (\n <span>\n {row.amount && tokens?.decimals && tokens?.price\n ? '$' + price(row.amount, tokens?.decimals, tokens?.price)\n : ''}\n </span>\n );\n },\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'x-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n ];\n\n return (\n <>\n {isLoading ? (\n <div className=\"pl-3 max-w-sm py-5 h-[60px]\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions found\n </p>\n </div>\n </div>\n )}\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: holder[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.FAQ": { "": "/**\n * Component: FTFAQ\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: FAQ About Fungible Token On Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\n\n\n\n\n\nfunction MainComponent({ network, id, token }) {\n const [account, setAccount] = useState({} );\n const [contract, setContract] = useState(\n {} ,\n );\n const [transfers, setTransfers] = useState('');\n const [holders, setHolders] = useState('');\n const [largestHolder, setLargestHolder] = useState(\n {} ,\n );\n const [tokens, setTokens] = useState({} );\n\n const name = tokens?.name;\n const tokenTicker = tokens?.symbol;\n const config = getConfig(network);\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchAccountData() {\n asyncFetch(`${config?.backendUrl}account/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const accountResp = data?.body?.account?.[0];\n if (data.status === 200) {\n setAccount(accountResp);\n } else {\n handleRateLimit(data, fetchAccountData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchContractData() {\n asyncFetch(`${config?.backendUrl}account/${id}/contract/deployments`)\n .then(\n (data\n\n\n\n\n) => {\n const depResp = data?.body?.deployments?.[0];\n if (data.status === 200) {\n setContract(depResp);\n } else {\n handleRateLimit(data, fetchContractData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchTotalTxns() {\n asyncFetch(`${config?.backendUrl}fts/${id}/txns/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTransfers(resp?.count);\n } else {\n handleRateLimit(data, fetchTotalTxns);\n }\n },\n )\n .catch(() => {});\n }\n function fetchHoldersdata() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setLargestHolder(resp);\n } else {\n handleRateLimit(data, fetchHoldersdata);\n }\n },\n )\n .catch(() => {});\n }\n function fetchHoldersCount() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setHolders(resp?.count);\n } else {\n handleRateLimit(data, fetchHoldersCount);\n }\n },\n )\n .catch(() => {});\n }\n if (!token && token === undefined) {\n fetchFTData();\n }\n fetchAccountData();\n fetchContractData();\n fetchHoldersCount();\n fetchTotalTxns();\n fetchHoldersdata();\n }, [id, config?.backendUrl, token]);\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n return (\n <div itemScope itemType=\"http://schema.org/FAQPage\">\n <div className=\"px-3 pb-2 text-sm divide-y divide-gray-200 space-y-2\">\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n What is {name} price now?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div itemProp=\"text\" className=\"text-sm text-nearblue-600 py-2\">\n The live price of {name} is{' '}\n {tokens?.price !== null && tokens?.price !== undefined ? (\n `$${dollarFormat(tokens?.price)} (${tokenTicker} / USD)`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}{' '}\n today with a current circulating market cap of{' '}\n {tokens?.market_cap !== null &&\n tokens?.market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens.market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . The on-chain marketcap of {name} is{' '}\n {tokens.onchain_market_cap !== null &&\n tokens.onchain_market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens.onchain_market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . {name}&apos;s 24-hour trading volume is{' '}\n {tokens.volume_24h !== null && tokens.volume_24h !== undefined ? (\n `$${dollarNonCentFormat(tokens.volume_24h)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . {tokenTicker} to USD price is updated in real-time. {name} is{' '}\n {tokens.change_24 !== null && tokens.change_24 !== undefined ? (\n Number(tokens.change_24) > 0 ? (\n dollarFormat(tokens.change_24) + '%'\n ) : (\n dollarFormat(tokens.change_24) + '%'\n )\n ) : (\n <span>N/A</span>\n )}{' '}\n in the last 24 hours.\n </div>\n </div>\n </div>\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n When was {name} created on Near Protocol?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div className=\"text-sm text-nearblue-600 py-2\" itemProp=\"text\">\n The{' '}\n <a href={`/address/${id}`}>\n <a className=\"underline\">{name}</a>\n </a>{' '}\n contract was created on Near Protocol at{' '}\n {account?.created?.transaction_hash\n ? convertToUTC(\n nanoToMilli(account?.created.block_timestamp),\n false,\n )\n : account?.code_hash\n ? 'Genesis'\n : 'N/A'}{' '}\n by{' '}\n {contract?.receipt_predecessor_account_id && (\n <a href={`/address/${contract.receipt_predecessor_account_id}`}>\n <a className=\"underline\">\n {shortenAddress(contract.receipt_predecessor_account_id)}\n </a>\n </a>\n )}{' '}\n through this{' '}\n {contract?.transaction_hash && (\n <a href={`/txns/${contract.transaction_hash}`}>\n <a className=\"underline\">transaction</a>\n </a>\n )}\n . Since the creation of {name}, there has been{' '}\n {transfers ? localFormat(transfers) : 0} on-chain transfers.\n </div>\n </div>\n </div>\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n How many {name} tokens are there?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div className=\"text-sm text-nearblue-600 py-2\" itemProp=\"text\">\n There are currently{' '}\n {tokens?.circulating_supply !== null ? (\n `${\n tokens?.circulating_supply\n ? localFormat(tokens?.circulating_supply)\n : 0\n }`\n ) : (\n <span>N/A</span>\n )}{' '}\n {tokenTicker} in circulation for a total supply of{' '}\n {tokens?.total_supply !== null &&\n tokens?.total_supply !== undefined &&\n `${dollarNonCentFormat(tokens?.total_supply)}`}\n {tokenTicker}. {tokenTicker}&apos;s supply is split between{' '}\n {holders ? localFormat(holders) : 0} different wallet addresses.{' '}\n {largestHolder?.account && (\n <span>\n The largest {tokenTicker} holder is currently{' '}\n {largestHolder?.account && (\n <a href={`/address/${largestHolder.account}`}>\n <a className=\"underline\">\n {shortenAddress(largestHolder.account)}\n </a>\n </a>\n )}\n , who currently holds{' '}\n {tokenAmount(largestHolder?.amount, tokens?.decimals, true)}{' '}\n {tokenTicker} of all {tokenTicker}.\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.TransfersList": { "": "/**\n * Component: FTTransfersList\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Tokens transfers list on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet.\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {number} [currentPage] - The current page number being displayed. (Optional)\n * Example: If provided, currentPage=3 will display the third page of blocks.\n * @param {function} [setPage] - A function used to set the current page. (Optional)\n * Example: setPage={handlePageChange} where handlePageChange is a function to update the page.\n */\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\nconst FaCheckCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z\"\n fill=\"#50C878\"\n />\n </svg>\n );\n};\nconst FaTimesCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"\n fill=\"#ff0000\"\n />\n </svg>\n );\n};\nconst FaHourglassStart = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 384 512\">\n <path\n d=\"M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM288 437v11H96V437c0-25.5 10.1-49.9 28.1-67.9L192 301.3l67.9 67.9c18 18 28.1 42.4 28.1 67.9z\"\n fill=\"#FFEB3B\"\n />\n </svg>\n );\n};\n\nconst getOptions = (status) => {\n switch (status) {\n case null:\n return {\n bg: 'bg-yellow-50',\n text: 'text-yellow-500',\n icon: FaHourglassStart,\n label: 'Pending',\n };\n case false:\n return {\n bg: 'bg-red-50',\n text: 'text-red-500',\n icon: FaTimesCircle,\n label: 'Failure',\n };\n\n default:\n return {\n bg: 'bg-emerald-50',\n text: 'text-emerald-500',\n icon: FaCheckCircle,\n label: 'Success',\n };\n }\n};\n\nconst TxnStatus = (props) => {\n const option = getOptions(props.status);\n const Icon = option.icon;\n\n return (\n <div className=\"w-full md:w-3/4 break-words\">\n <span\n className={`inline-flex items-center text-xs rounded py-1 ${\n option.bg\n } ${option.text} ${props.showLabel ? ' px-2' : ' px-1'}`}\n >\n <Icon />\n {props.showLabel && <span className=\"ml-2\">{option.label}</span>}\n </span>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Clock = (props) => (\n <svg\n viewBox=\"64 64 896 896\"\n focusable=\"false\"\n data-icon=\"clock-circle\"\n width=\"1em\"\n height=\"1em\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n <path d=\"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z\"></path>\n </svg>\n);/* END_INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\nconst FaLongArrowAltRight = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\">\n <path\n d=\"M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216\"\n fill=\"#ffffff\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, t, currentPage, setPage }) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [showAge, setShowAge] = useState(true);\n const errorMessage = t ? t('txns:noTxns') : 'No transactions found!';\n const [tokens, setTokens] = useState(\n {},\n );\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchTotalTokens() {\n asyncFetch(`${config?.backendUrl}fts/txns/count`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, fetchTotalTokens);\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTokens(page) {\n setIsLoading(true);\n asyncFetch(`${config?.backendUrl}fts/txns?page=${page}&per_page=25`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns;\n if (data.status === 200) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTokens(page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n fetchTotalTokens();\n fetchTokens(currentPage);\n }, [config?.backendUrl, currentPage]);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n const onHandleMouseOver = (e, id) => {\n e.preventDefault();\n\n setAddress(id);\n };\n\n const columns = [\n {\n header: <span></span>,\n key: '',\n cell: (row) => (\n <>\n <TxnStatus status={row?.outcomes?.status} showLabel={false} />\n </>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-end',\n },\n {\n header: <span>{t ? t('token:fts.hash') : 'HASH'}</span>,\n key: 'transaction_hash',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/txns/${row?.transaction_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.transaction_hash}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span> {t ? t('type') : 'TYPE'}</span>,\n key: 'actions',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"bg-blue-900/10 text-xs text-nearblue-600 rounded-xl px-2 py-1 max-w-[120px] inline-flex truncate\">\n <span className=\"block truncate\">{row?.cause}</span>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.cause}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>Affected</span>,\n key: 'affected_account_id',\n cell: (row) => (\n <span>\n {row?.affected_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.affected_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.affected_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.affected_account_id)\n }\n >\n {row?.affected_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.affected_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span></span>,\n key: '',\n cell: (row) => {\n return row?.involved_account_id === row?.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 inline-flex items-center justify-center bg-green-200 text-white text-sm font-semibold\">\n {t('txns:txnSelf')}\n </span>\n ) : Number(row?.delta_amount) > 0 ? (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white rotate-180\">\n <FaLongArrowAltRight />\n </div>\n ) : (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white\">\n <FaLongArrowAltRight />\n </div>\n );\n },\n tdClassName: 'text-center',\n },\n {\n header: <span>Involved</span>,\n key: 'involved_account_id',\n cell: (row) => (\n <span>\n {row?.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.involved_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.involved_account_id)\n }\n >\n {row?.involved_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.involved_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span> Quantity</span>,\n key: 'block_height',\n cell: (row) => (\n <span>\n {row?.delta_amount\n ? localFormat(\n tokenAmount(\n Big(row.delta_amount).abs().toString(),\n row?.ft?.decimals,\n true,\n ),\n )\n : ''}\n </span>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>Token</span>,\n key: 'block_height',\n cell: (row) => {\n return (\n row?.ft && (\n <div className=\"flex flex-row items-center\">\n <span className=\"inline-flex mr-1\">\n <TokenImage\n src={row?.ft?.icon}\n alt={row?.ft?.name}\n className=\"w-4 h-4\"\n appUrl={config?.appUrl}\n />\n </span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-nearblue-600 max-w-[110px] inline-block truncate whitespace-nowrap\">\n <a\n href={`/token/${row?.ft?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.ft?.name}\n </a>\n </a>\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.ft?.name}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n {row?.ft?.symbol && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-gray-400 max-w-[80px] inline-block truncate whitespace-nowrap\">\n &nbsp; {row?.ft?.symbol}\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.ft?.symbol}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n </div>\n )\n );\n },\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <div className=\"w-full inline-flex px-5 py-4\">\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n onClick={toggleShowAge}\n className=\"text-left text-xs w-full flex items-center font-semibold uppercase tracking-wider text-green-500 focus:outline-none whitespace-nowrap\"\n >\n {showAge\n ? t\n ? t('token:fts.age')\n : 'AGE'\n : t\n ? t('token:fts.ageDT')\n : 'DATE TIME (UTC)'}\n {showAge && <Clock className=\"text-green-500 ml-2\" />}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"top\"\n >\n {showAge\n ? 'Click to show Datetime Format'\n : 'Click to show Age Format'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </div>\n ),\n key: 'block_timestamp',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {!showAge\n ? row?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(row?.block_timestamp),\n )\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {showAge\n ? row?.block_timestamp\n ? formatTimestampToString(nanoToMilli(row?.block_timestamp))\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName: 'inline-flex whitespace-nowrap',\n },\n ];\n\n return (\n <>\n <div className=\"bg-white border soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"max-w-lg w-full pl-3 py-5\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions\n found\n </p>\n </div>\n </div>\n )}\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: tokens[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </div>\n </>\n );\n}\n\nreturn MainComponent(props, context);" } } } } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
3 Tgas
Tokens Burned:
0.00037 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
104 Tgas
Tokens Burned:
0.01041 
Called method: 'set' in contract: social.near
Arguments:
{ "data": { "nearblocks.near": { "widget": { "bos-components.components.FT.Transfers": { "": "/**\n * Component: FTTransfers\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Tranfers List.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {string} [id] - The token identifier passed as a string\n * @param {Object.<string, string>} [filters] - Key-value pairs for filtering transactions. (Optional)\n * Example: If provided, method=batch will filter the blocks with method=batch.\n * @param {function} [onFilterClear] - Function to clear a specific or all filters. (Optional)\n * Example: onFilterClear={handleClearFilter} where handleClearFilter is a function to clear the applied filters.\n\n */\n\n\n\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\nconst FaCheckCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z\"\n fill=\"#50C878\"\n />\n </svg>\n );\n};\nconst FaTimesCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"\n fill=\"#ff0000\"\n />\n </svg>\n );\n};\nconst FaHourglassStart = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 384 512\">\n <path\n d=\"M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM288 437v11H96V437c0-25.5 10.1-49.9 28.1-67.9L192 301.3l67.9 67.9c18 18 28.1 42.4 28.1 67.9z\"\n fill=\"#FFEB3B\"\n />\n </svg>\n );\n};\n\nconst getOptions = (status) => {\n switch (status) {\n case null:\n return {\n bg: 'bg-yellow-50',\n text: 'text-yellow-500',\n icon: FaHourglassStart,\n label: 'Pending',\n };\n case false:\n return {\n bg: 'bg-red-50',\n text: 'text-red-500',\n icon: FaTimesCircle,\n label: 'Failure',\n };\n\n default:\n return {\n bg: 'bg-emerald-50',\n text: 'text-emerald-500',\n icon: FaCheckCircle,\n label: 'Success',\n };\n }\n};\n\nconst TxnStatus = (props) => {\n const option = getOptions(props.status);\n const Icon = option.icon;\n\n return (\n <div className=\"w-full md:w-3/4 break-words\">\n <span\n className={`inline-flex items-center text-xs rounded py-1 ${\n option.bg\n } ${option.text} ${props.showLabel ? ' px-2' : ' px-1'}`}\n >\n <Icon />\n {props.showLabel && <span className=\"ml-2\">{option.label}</span>}\n </span>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Clock = (props) => (\n <svg\n viewBox=\"64 64 896 896\"\n focusable=\"false\"\n data-icon=\"clock-circle\"\n width=\"1em\"\n height=\"1em\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n <path d=\"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z\"></path>\n </svg>\n);/* END_INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/CloseCircle.jsx\" */\nconst CloseCircle = (props) => {\n const handleClick = () => {\n if (props.onClick) {\n props.onClick('All');\n }\n };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n className={props.className}\n onClick={handleClick}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm0-9.414l2.828-2.829 1.415 1.415L13.414 12l2.829 2.828-1.415 1.415L12 13.414l-2.828 2.829-1.415-1.415L10.586 12 7.757 9.172l1.415-1.415L12 10.586z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/CloseCircle.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\nconst FaLongArrowAltRight = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\">\n <path\n d=\"M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216\"\n fill=\"#ffffff\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, t, id, filters, onFilterClear }) {\n const [showAge, setShowAge] = useState(true);\n const [txnLoading, setTxnLoading] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [address, setAddress] = useState('');\n const config = getConfig(network);\n const errorMessage = 'No transactions found!';\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n setTxnLoading(true);\n asyncFetch(`${config?.backendUrl}fts/${id}/txns/count${queryParams}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count);\n setTxnLoading(false);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTxnsData(page, qs) {\n const queryParams = qs ? qs + '&' : '';\n setIsLoading(true);\n asyncFetch(\n `${config?.backendUrl}fts/${id}/txns?${queryParams}page=${page}&per_page=25`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then((data) => {\n const resp = data?.body?.txns;\n if (data.status === 200 && Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(data, () => fetchTxnsData(page, qs));\n }\n })\n .catch(() => {});\n }\n\n let urlString = '';\n if (filters && Object.keys(filters).length > 0) {\n urlString = Object.keys(filters)\n .map(\n (key) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(filters[key])}`,\n )\n .join('&');\n }\n\n fetchTotalTxns(urlString);\n fetchTxnsData(currentPage, urlString);\n }, [config?.backendUrl, currentPage, id, filters]);\n\n const onHandleMouseOver = (e, id) => {\n e.preventDefault();\n\n setAddress(id);\n };\n\n const columns = [\n {\n header: '',\n key: '',\n cell: (row) => (\n <>\n <TxnStatus status={row?.outcomes?.status} showLabel={false} />\n </>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-end',\n },\n {\n header: <span>{t ? t('hash') : 'HASH'}</span>,\n key: 'transaction_hash',\n cell: (row) => (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/txns/${row?.transaction_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.transaction_hash}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>BLOCK</span>,\n key: 'block.block_height',\n cell: (row) => (\n <>\n <a\n className=\"hover:no-underline\"\n href={`/blocks/${row?.included_in_block_hash}`}\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.block?.block_height\n ? localFormat(row?.block?.block_height)\n : row?.block?.block_height ?? ''}\n </a>\n </a>\n </>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>{t ? t('type') : 'TYPE'}</span>,\n key: 'cause',\n cell: (row) => (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"bg-blue-900/10 text-xs text-nearblue-600 rounded-xl px-2 py-1 max-w-[120px] inline-flex truncate\">\n <span className=\"block truncate\">{row?.cause}</span>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.cause}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>Affected</span>,\n key: 'affected_account_id',\n cell: (row) => (\n <>\n {row?.affected_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.affected_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.affected_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.affected_account_id)\n }\n >\n {row?.affected_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.affected_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: '',\n key: '',\n cell: (row) =>\n row?.involved_account_id === row?.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 inline-flex items-center justify-center bg-green-200 text-white text-sm font-semibold\">\n {t ? t('txnSelf') : 'Self'}\n </span>\n ) : Number(row?.delta_amount) > 0 ? (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white rotate-180\">\n <FaLongArrowAltRight />\n </div>\n ) : (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white\">\n <FaLongArrowAltRight />\n </div>\n ),\n tdClassName: 'text-center',\n },\n {\n header: <span>Involved</span>,\n key: 'involved_account_id',\n cell: (row) => (\n <span>\n {row?.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.involved_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.involved_account_id)\n }\n >\n {row?.involved_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.involved_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: <span>Quantity</span>,\n key: 'amount',\n cell: (row) => (\n <>\n {row?.delta_amount\n ? localFormat(\n tokenAmount(\n Big(row.delta_amount).abs().toString(),\n row?.ft?.decimals,\n true,\n ),\n )\n : ''}\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n {\n header: (\n <>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n onClick={toggleShowAge}\n className=\"text-left text-xs px-5 py-4 w-full flex items-center font-semibold uppercase tracking-wider text-green-500 focus:outline-none flex-row whitespace-nowrap\"\n >\n {showAge ? (\n <>\n {t ? t('token:fts.age') : 'AGE'}\n <Clock className=\"text-green-500 ml-2\" />\n </>\n ) : (\n <> {t ? t('token:fts.ageDT') : 'DATE TIME (UTC)'}</>\n )}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"top\"\n >\n {showAge\n ? 'Click to show Datetime Format'\n : 'Click to show Age Format'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </>\n ),\n key: 'block_timestamp',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {!showAge\n ? row?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(row?.block_timestamp),\n )\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {showAge\n ? row?.block_timestamp\n ? formatTimestampToString(nanoToMilli(row?.block_timestamp))\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n },\n ];\n\n return (\n <>\n {txnLoading ? (\n <div className=\"pl-3 max-w-sm py-5 h-[60px]\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions found\n </p>\n </div>\n <div className=\" flex items-center px-2 text-sm mb-4 text-nearblue-600 lg:ml-auto\">\n {filters && Object?.keys(filters)?.length > 0 && (\n <div className=\"flex items-center px-2 text-sm text-gray-500 lg:ml-auto\">\n Filtered By:\n <span className=\"flex items-center bg-gray-100 rounded-full px-3 py-1 ml-1 space-x-2\">\n {filters &&\n Object?.keys(filters)?.map((key) => (\n <span className=\"flex\" key={key}>\n {capitalizeFirstLetter(key)}:{' '}\n <span className=\"inline-block truncate max-w-[120px]\">\n <span className=\"font-semibold\">{filters[key]}</span>\n </span>\n </span>\n ))}\n <CloseCircle\n className=\"w-4 h-4 fill-current cursor-pointer\"\n onClick={onFilterClear}\n />\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: txns[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Info": { "": "/**\n * Component: FTInfo\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Information About Fungible Token On Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\n\nfunction MainComponent({ token, id, network }) {\n const [tokens, setTokens] = useState({} );\n const config = getConfig(network);\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n\n if (!token && token === undefined) {\n fetchFTData();\n }\n }, [config?.backendUrl, id, token]);\n\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n\n return (\n <div className=\"px-3 pt-2 pb-5 text-sm text-gray\">\n {tokens?.description && (\n <>\n <h3 className=\"text-nearblue-600 text-sm font-semibold py-2 underline\">\n Overview\n </h3>\n <p className=\"text-sm py-2 text-nearblue-600\">\n {tokens?.description}\n </p>\n </>\n )}\n <h3 className=\"text-nearblue-600 text-sm font-semibold py-2 underline\">\n Market\n </h3>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Volume (24H):</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.volume_24h !== null && tokens?.volume_24h !== undefined ? (\n `$${dollarNonCentFormat(tokens?.volume_24h)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Circulating MC:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.market_cap !== null && tokens?.market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens?.market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">On-chain MC:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.onchain_market_cap !== null &&\n tokens?.onchain_market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens?.onchain_market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 py-2 text-nearblue-600\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Circulating Supply:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.circulating_supply !== null &&\n tokens?.circulating_supply !== undefined ? (\n `${localFormat(tokens?.circulating_supply)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap lg:w-1/2 pt-6 text-gray-400 text-xs\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0\">Market Data Source:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {tokens?.coingecko_id && (\n <a\n className=\"text-green-500 mr-4\"\n href=\"https://www.coingecko.com/\"\n target=\"_blank\"\n rel=\"noreferrer nofollow noopener\"\n >\n CoinGecko\n </a>\n )}\n {tokens?.coinmarketcap_id && (\n <a\n className=\"text-green-500 mr-4\"\n href=\"https://coinmarketcap.com/\"\n target=\"_blank\"\n rel=\"noreferrer nofollow noopener\"\n >\n Coinmarketcap\n </a>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.List": { "": "/**\n * Component: FTList\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Top Tokens on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet.\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {number} [currentPage] - The current page number being displayed. (Optional)\n * Example: If provided, currentPage=3 will display the third page of blocks.\n * @param {function} [setPage] - A function used to set the current page. (Optional)\n * Example: setPage={handlePageChange} where handlePageChange is a function to update the page.\n */\n\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n\n/* INCLUDE COMPONENT: \"includes/icons/ArrowDown.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\nconst ArrowDown = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/ArrowDown.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/SortIcon.jsx\" */\nconst ArrowUp = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 10.828l-4.95 4.95-1.414-1.414L12 8l6.364 6.364-1.414 1.414z\" />\n </svg>\n );\n};\n\nconst SortIcon = (props) => {\n return (\n <ArrowUp\n className={`h-3 w-3 fill-current transition-transform mr-1 duration-700 ${\n props.order !== 'asc' ? 'transform rotate-180' : 'transform rotate-0'\n }`}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/SortIcon.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Question = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v2h-2v-2zm2-1.645V14h-2v-1.5a1 1 0 011-1 1.5 1.5 0 10-1.471-1.794l-1.962-.393A3.501 3.501 0 1113 13.355z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n\nconst initialSorting = {\n sort: 'onchain_market_cap',\n order: 'desc',\n};\nconst initialPagination = {\n per_page: 50,\n};\nfunction MainComponent({ t, network, currentPage, setPage }) {\n const [searchResults, setSearchResults] = useState([]);\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [tokens, setTokens] = useState({});\n\n const [sorting, setSorting] = useState(initialSorting);\n const errorMessage = t ? t('token:fts.top.empty') : 'No tokens found!';\n const config = getConfig(network);\n const ArrowUp = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={24}\n height={24}\n className=\"h-3 w-3 fill-current mr-1\"\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 10.828l-4.95 4.95-1.414-1.414L12 8l6.364 6.364-1.414 1.414z\" />\n </svg>\n );\n };\n\n useEffect(() => {\n function fetchTotalTokens(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(`${config?.backendUrl}fts/count${queryParams}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.tokens?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTokens(qs));\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTokens(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}fts?${queryParams}order=${sqs?.order}&sort=${sqs?.sort}&page=${page}&per_page=50`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.tokens;\n if (data.status === 200) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTokens(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n if (sorting) {\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n }\n }, [config?.backendUrl, currentPage, sorting]);\n\n const onOrder = (sortKey) => {\n setSorting((state) => ({\n ...state,\n sort: sortKey,\n order:\n state.sort === sortKey\n ? state.order === 'asc'\n ? 'desc'\n : 'asc'\n : 'desc',\n }));\n };\n const debouncedSearch = useMemo(() => {\n return debounce(500, (value) => {\n if (!value || value.trim() === '') {\n setSearchResults([]);\n return;\n }\n asyncFetch(`${config?.backendUrl}fts?search=${value}&per_page=5`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((data) => {\n const resp = data?.body?.tokens;\n setSearchResults(resp);\n })\n .catch(() => {});\n });\n }, [config?.backendUrl]);\n\n const onChange = (e) => {\n const value = e.target.value;\n debouncedSearch(value);\n };\n const columns = [\n {\n header: <span>#</span>,\n key: '',\n cell: (_row, index) => (\n <span>\n {serialNumber(index, currentPage, initialPagination.per_page)}\n </span>\n ),\n tdClassName:\n 'pl-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.token') : 'TOKEN'}</span>,\n key: 'name',\n cell: (row) => (\n <>\n <div className=\"flex items-center\">\n <TokenImage\n src={row?.icon}\n alt={row?.name}\n appUrl={config?.appUrl}\n className=\"w-5 h-5 mr-2\"\n />\n <a href={`/token/${row?.contract}`} className=\"hover:no-underline\">\n <a className=\" text-green-500 hover:no-underline\">\n <span className=\"truncate max-w-[200px] mr-1\">{row?.name}</span>\n <span className=\"text-nearblue-700 truncate max-w-[80px]\">\n {row?.symbol}\n </span>\n </a>\n </a>\n </div>\n </>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 w-80 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.price') : 'PRICE'}</span>,\n key: 'price',\n cell: (row) => (\n <span>\n {row?.price === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n ` $${localFormat(row?.price)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.change') : 'CHANGE'} (%)</span>,\n key: 'change_24',\n cell: (row) => (\n <span>\n {row?.change_24 === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : Number(row?.change_24) > 0 ? (\n <div className=\"text-neargreen flex flex-row items-center\">\n <ArrowUp />+{dollarFormat(row?.change_24)}%\n </div>\n ) : (\n <div className=\"text-red-500 flex flex-row items-center\">\n <ArrowDown className=\"h-3 w-3 fill-current mr-1\" />\n {row?.change_24 ? dollarFormat(row?.change_24) + '%' : ''}\n </div>\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>{t ? t('token:fts.top.volume') : 'VOLUME'} (24H)</span>,\n key: 'volume_24h',\n cell: (row) => (\n <span>\n {row?.volume_24h === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${dollarNonCentFormat(row?.volume_24h)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <span className=\"flex\">\n <span className=\"uppercase whitespace-nowrap\">Circulating MC</span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\" h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 \"\n align=\"start\"\n side=\"bottom\"\n >\n {\n 'Calculated by multiplying the number of tokens in circulating supply across all chains with the current market price per token.'\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n key: 'market_cap',\n cell: (row) => (\n <span>\n {row?.market_cap === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${dollarNonCentFormat(row?.market_cap)}`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n thClassName:\n 'px-6 py-2 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <span>\n {' '}\n <button\n type=\"button\"\n onClick={() => onOrder('onchain_market_cap')}\n className=\"w-full px-6 py-2 text-left text-xs font-semibold tracking-wider text-green-500 focus:outline-none flex flex-row\"\n >\n {sorting?.sort === 'onchain_market_cap' && (\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting?.order} />\n </div>\n )}\n <span className=\"uppercase whitespace-nowrap\">On-Chain MC</span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\" h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {\n \"Calculated by multiplying the token's Total Supply on Near with the current market price per token\"\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </button>\n </span>\n ),\n key: 'onchain_market_cap',\n cell: (row) => (\n <span>\n {row?.onchain_market_cap === null ? (\n <span className=\"text-xs\">N/A</span>\n ) : (\n `$${\n row?.onchain_market_cap\n ? dollarNonCentFormat(row?.onchain_market_cap)\n : row?.onchain_market_cap ?? ''\n }`\n )}\n </span>\n ),\n tdClassName:\n 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n },\n // {\n // header: (\n // <span>\n // <button\n // type=\"button\"\n // onClick={() => onOrder('holders')}\n // className=\"w-full px-6 py-2 text-left text-xs font-semibold uppercase tracking-wider text-green-500 focus:outline-none flex flex-row\"\n // >\n // {sorting?.sort === 'holders' && (\n // <div className=\"text-nearblue-600 font-semibold\">\n // <SortIcon order={sorting?.order} />\n // </div>\n // )}\n // Holders\n // </button>{' '}\n // </span>\n // ),\n // key: 'holders',\n // cell: (row: Token) => (\n // <span>{row?.holders ? localFormat(row?.holders) : ''}</span>\n // ),\n // tdClassName:\n // 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 align-top',\n // },\n ];\n\n return (\n <div className=\" bg-white border soft-shadow rounded-xl pb-1 \">\n <div className=\"flex flex-row items-center justify-between text-left text-sm text-nearblue-600 px-3 py-2\">\n {isLoading ? (\n <div className=\"max-w-lg w-full pl-3\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <p className=\"pl-3\">\n {t\n ? t('token:fts.top.listing', { count: totalCount })\n : `A total of ${totalCount} Token Contracts found`}\n </p>\n )}\n <div className={`flex w-full h-10 sm:w-80 mr-2`}>\n <div className=\"flex-grow\">\n <label htmlFor=\"token-search\" id=\"token-search\">\n <input\n name=\"search\"\n autoComplete=\"off\"\n placeholder=\"Search\"\n className=\"search ml-2 pl-8 token-search bg-white w-full h-full text-sm py-2 outline-none border rounded-xl\"\n onChange={onChange}\n />\n </label>\n {searchResults?.length > 0 && (\n <div className=\"z-50 relative\">\n <div className=\"text-xs rounded-b-md -mr-2 ml-2 -mt-1 bg-white py-2 shadow\">\n {searchResults.map((token) => (\n <div\n key={token?.contract}\n className=\"mx-2 px-2 py-2 hover:bg-gray-100 cursor-pointer hover:border-gray-500 truncate\"\n >\n <a\n href={`/token/${token?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"hover:no-underline flex items-center my-1 whitespace-nowrap \">\n <div className=\"flex-shrink-0 h-5 w-5 mr-2\">\n <TokenImage\n src={token?.icon}\n alt={token?.name}\n appUrl={config?.appUrl}\n className=\"w-5 h-5\"\n />\n </div>\n <p className=\"font-semibold text-sm truncate\">\n {token?.name}\n <span className=\"text-nearblue-700 ml-2\">\n {token?.symbol}\n </span>\n </p>\n </a>\n </a>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: tokens[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 50,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.TokenFilter": { "": "/**\n * Component: FTTokenFilter\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Filter on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {string} [tokenFilter] - The token filter identifier passed as a string\n */\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaAddressBook.jsx\" */\nconst FaAddressBook = () => {\n return (\n <svg\n stroke=\"currentColor\"\n fill=\"currentColor\"\n stroke-width=\"0\"\n viewBox=\"0 0 448 512\"\n color=\"#db9a04\"\n height=\"10\"\n width=\"10\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-228-32c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H118.4C106 384 96 375.4 96 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z\"\n fill=\"#db9a04\"\n ></path>\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaAddressBook.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction decodeArgs(args) {\n if (!args || typeof args === 'undefined') return {};\n\n return JSON.parse(Buffer.from(args, 'base64').toString());\n}\n\nfunction txnMethod(\n actions,\n t,\n) {\n const count = actions?.length || 0;\n\n if (!count) return t ? t('txns:unknownType') : 'Unknown';\n if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction';\n\n const action = actions[0];\n\n if (action.action === 'FUNCTION_CALL') {\n return action.method;\n }\n\n return action.action;\n}\n\nfunction gasPrice(yacto) {\n const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString();\n\n return `${localFormat(near)} Ⓝ / Tgas`;\n}\n\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction encodeArgs(args) {\n if (!args || typeof args === 'undefined') return '';\n\n return Buffer.from(JSON.stringify(args)).toString('base64');\n}\n\nfunction decodeArgs(args) {\n if (!args || typeof args === 'undefined') return {};\n\n return JSON.parse(Buffer.from(args, 'base64').toString());\n}\n\nfunction txnMethod(\n actions,\n t,\n) {\n const count = actions?.length || 0;\n\n if (!count) return t ? t('txns:unknownType') : 'Unknown';\n if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction';\n\n const action = actions[0];\n\n if (action.action === 'FUNCTION_CALL') {\n return action.method;\n }\n\n return action.action;\n}\n\nfunction gasPrice(yacto) {\n const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString();\n\n return `${localFormat(near)} Ⓝ / Tgas`;\n}\n\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction MainComponent({ network, id, tokenFilter }) {\n const [ft, setFT] = useState({} );\n const [inventoryLoading, setInventoryLoading] = useState(false);\n const [inventoryData, setInventoryData] = useState(\n {} ,\n );\n\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchInventoryData() {\n setInventoryLoading(true);\n asyncFetch(`${config?.backendUrl}account/${tokenFilter}/inventory`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const response = data?.body?.inventory;\n if (data.status === 200) {\n setInventoryData(response);\n setInventoryLoading(false);\n } else {\n handleRateLimit(data, fetchInventoryData, () =>\n setInventoryLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n fetchInventoryData();\n }, [config.backendUrl, tokenFilter]);\n\n useEffect(() => {\n function ftBalanceOf(contracts, account_id) {\n return asyncFetch(`${config?.rpcUrl}`, {\n method: 'POST',\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 'dontcare',\n method: 'query',\n params: {\n request_type: 'call_function',\n finality: 'final',\n account_id: contracts,\n method_name: 'ft_balance_of',\n args_base64: encodeArgs({ account_id }),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (res\n\n\n\n) => {\n return res;\n },\n )\n .then(\n (data\n\n\n\n) => {\n const resp = data?.body?.result;\n return decodeArgs(resp.result);\n },\n )\n .catch(() => {});\n }\n\n function loadBalances() {\n setInventoryLoading(true);\n const fts =\n inventoryData?.fts &&\n inventoryData?.fts.filter((f) => id == f.contract);\n\n if (!fts?.length) {\n if (fts?.length === 0) setInventoryLoading(false);\n return;\n }\n\n let total = Big(0);\n\n const tokens = [];\n\n const pricedTokens = [];\n\n Promise.all(\n fts.map((ft) => {\n return ftBalanceOf(ft.contract, tokenFilter).then((rslt) => {\n return { ...ft, amount: rslt };\n });\n }),\n ).then((results) => {\n results.forEach((rslt) => {\n const ftrslt = rslt;\n const amount = rslt?.amount;\n\n let sum = Big(0);\n\n let rpcAmount = Big(0);\n\n if (amount) {\n rpcAmount = ftrslt.ft_meta?.decimals\n ? Big(amount).div(Big(10).pow(ftrslt.ft_meta?.decimals))\n : 0;\n }\n\n if (ftrslt.ft_meta?.price) {\n sum = rpcAmount.mul(Big(ftrslt.ft_meta?.price));\n total = total.add(sum);\n\n return pricedTokens.push({\n ...ftrslt,\n amountUsd: sum.toString(),\n rpcAmount: rpcAmount.toString(),\n });\n }\n\n return tokens.push({\n ...ftrslt,\n amountUsd: sum.toString(),\n rpcAmount: rpcAmount.toString(),\n });\n });\n\n setFT({\n amount: total.toString(),\n tokens: [...pricedTokens, ...tokens],\n });\n\n setInventoryLoading(false);\n });\n }\n\n loadBalances();\n }, [inventoryData?.fts, id, tokenFilter, config?.rpcUrl]);\n\n const filterToken = ft?.tokens?.length\n ? ft?.tokens[0]\n : ({} );\n\n return (\n <>\n {tokenFilter && (\n <div className=\"py-2\">\n <div className=\"bg-white soft-shadow rounded-xl px-2 py-3\">\n <div className=\"grid md:grid-cols-3 grid-cols-1 divide-y md:divide-y-0 md:divide-x\">\n <div className=\"px-4 md:py-0 py-2\">\n <div className=\"flex items-center\">\n <FaAddressBook />\n <h5 className=\"text-xs my-1 font-bold ml-1 \">\n FILTERED BY TOKEN HOLDER\n </h5>\n </div>\n <h5 className=\"text-sm my-1 font-bold text-green-500 truncate md:max-w-[200px] lg:max-w-[310px] xl:max-w-full max-w-full inline-block\">\n <a\n href={`/address/${tokenFilter}`}\n className=\"hover:no-underline\"\n >\n <a className=\"hover:no-underline\">{tokenFilter}</a>\n </a>\n </h5>\n </div>\n <div className=\"px-4 md:py-0 py-2\">\n <p className=\"text-xs my-1 text-nearblue-600\">BALANCE</p>\n\n {inventoryLoading ? (\n <Skeleton className=\"w-40\" />\n ) : (\n <p className=\"text-sm my-1\">\n {Number(filterToken?.rpcAmount)\n ? localFormat(filterToken?.rpcAmount)\n : ''}\n </p>\n )}\n </div>\n <div className=\"px-4 md:py-0 py-2\">\n <p className=\"text-xs my-1 text-nearblue-600\">VALUE</p>\n\n {inventoryLoading ? (\n <Skeleton className=\"w-40\" />\n ) : (\n <p className=\"text-sm my-1 flex\">\n ${ft?.amount ? dollarFormat(ft?.amount) : ft?.amount ?? ''}\n <span>\n {filterToken?.ft_meta?.price && (\n <div className=\"text-gray-400 ml-2\">\n @{filterToken?.ft_meta?.price}\n </div>\n )}\n </span>\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Overview": { "": "/**\n * Component: FTOverview\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Overview on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {string} [id] - The token identifier passed as a string\n * @param {string} [tokenFilter] - The token filter identifier passed as a string\n * @param {Object.<string, string>} [filters] - Key-value pairs for filtering transactions. (Optional)\n * Example: If provided, method=batch will filter the blocks with method=batch.\n * @param {function} [onFilterClear] - Function to clear a specific or all filters. (Optional)\n * Example: onFilterClear={handleClearFilter} where handleClearFilter is a function to clear the applied filters.\n */\n\n\n\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Links.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\nconst Links = (props) => {\n const { meta } = props;\n const twitter = urlHostName(meta?.twitter);\n const facebook = urlHostName(meta?.facebook);\n const telegram = urlHostName(meta?.telegram);\n\n return (\n <div className=\"flex space-x-4\">\n {meta?.twitter && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !twitter\n ? `https://twitter.com/${meta.twitter}`\n : meta.twitter\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/twitter_icon.svg\"\n alt=\"Twitter\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Twitter\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.facebook && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !facebook\n ? `https://facebook.com/${meta.facebook}`\n : meta.facebook\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/facebook_icon.svg\"\n alt=\"Facebook\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Facebook\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.telegram && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={\n !telegram ? `https://t.me/${meta.telegram}` : meta.telegram\n }\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/telegram_icon.svg\"\n alt=\"Telegram\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n Telegram\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n {meta?.coingecko_id && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <a\n href={`https://www.coingecko.com/en/coins/${meta.coingecko_id}`}\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n className=\"flex\"\n >\n <img\n width=\"16\"\n height=\"16\"\n className=\"w-4 h-4\"\n src=\"/images/coingecko_icon.svg\"\n alt=\"coingecko\"\n />\n </a>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-white text-xs p-2\"\n sideOffset={8}\n place=\"bottom\"\n >\n CoinGecko\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Links.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Question = (props) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n {...props}\n >\n <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v2h-2v-2zm2-1.645V14h-2v-1.5a1 1 0 011-1 1.5 1.5 0 10-1.471-1.794l-1.962-.393A3.501 3.501 0 1113 13.355z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Question.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n\n\nfunction MainComponent({\n network,\n t,\n id,\n tokenFilter,\n filters,\n onFilterClear,\n}) {\n const tabs = [\n t ? t('token:fts.ft.transfers') : 'Transfers',\n t ? t('token:fts.ft.holders') : 'Holders',\n 'Info',\n 'FAQ',\n 'Comments',\n ];\n const [isLoading, setIsLoading] = useState(false);\n const [txnLoading, setTxnLoading] = useState(false);\n const [holderLoading, setHolderLoading] = useState(false);\n const [stats, setStats] = useState({} );\n const [token, setToken] = useState({} );\n const [transfers, setTransfers] = useState('');\n const [holders, setHolders] = useState('');\n const [pageTab, setPageTab] = useState('Transfers');\n const [showMarketCap, setShowMarketCap] = useState(false);\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchFTData() {\n setIsLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setToken(resp);\n setIsLoading(false);\n } else {\n handleRateLimit(data, fetchFTData, () => setIsLoading(false));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsCount() {\n setTxnLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}/txns/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTransfers(resp.count);\n setTxnLoading(false);\n } else {\n handleRateLimit(data, fetchTxnsCount, () => setTxnLoading(false));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchStatsData() {\n asyncFetch(`${config?.backendUrl}stats`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((res) => {\n const data = res.body;\n if (res.status === 200) {\n setStats(data.stats[0]);\n } else {\n handleRateLimit(data, fetchStatsData);\n }\n })\n .catch(() => {})\n .finally(() => {});\n }\n function fetchHoldersCount() {\n setHolderLoading(true);\n asyncFetch(`${config.backendUrl}fts/${id}/holders/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setHolders(resp.count);\n setHolderLoading(false);\n } else {\n handleRateLimit(data, fetchHoldersCount, () =>\n setHolderLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n fetchStatsData();\n fetchFTData();\n fetchTxnsCount();\n fetchHoldersCount();\n }, [config.backendUrl, id]);\n\n const onTab = (index) => {\n setPageTab(tabs[index]);\n onFilterClear && onFilterClear('');\n };\n\n const onToggle = () => setShowMarketCap((o) => !o);\n return (\n <>\n <div className=\"flex items-center justify-between flex-wrap pt-4\">\n {isLoading ? (\n <div className=\"w-80 max-w-xs px-3 py-5\">\n <Skeleton className=\"h-7\" />\n </div>\n ) : (\n <h1 className=\"break-all space-x-2 text-xl text-gray-700 leading-8 py-4 px-2\">\n <span className=\"inline-flex align-middle h-7 w-7\">\n <TokenImage\n src={token?.icon}\n alt={token?.name}\n className=\"w-7 h-7\"\n />\n </span>\n <span className=\"inline-flex align-middle \">Token: </span>\n <span className=\"inline-flex align-middle font-semibold\">\n {token?.name}\n </span>\n </h1>\n )}\n </div>\n <div>\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-2 md:mb-2\">\n <div className=\"w-full\">\n <div className=\"h-full bg-white soft-shadow rounded-xl overflow-hidden\">\n <h2 className=\"border-b p-3 text-nearblue-600 text-sm font-semibold\">\n Overview\n </h2>\n\n <div className=\"px-3 divide-y text-sm text-nearblue-600\">\n <div className=\"flex divide-x my-2\">\n <div className=\"flex-col flex-1 flex-wrap py-1\">\n <div className=\"w-full text-nearblue-700 text-xs uppercase mb-1 text-[80%]\">\n Price\n </div>\n {isLoading ? (\n <div className=\"w-20\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : token?.price !== null && token?.price !== undefined ? (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n ${dollarFormat(token?.price)}\n {stats?.near_price && (\n <div className=\"text-nearblue-700 mx-1 text-sm flex flex-row items-center\">\n @{' '}\n {localFormat(\n (\n Big(token?.price) / Big(stats?.near_price)\n ).toString(),\n )}{' '}\n Ⓝ\n </div>\n )}\n {token?.change_24 !== null &&\n token?.change_24 !== undefined ? (\n Number(token?.change_24) > 0 ? (\n <div className=\"text-neargreen text-sm flex flex-row items-center\">\n {' '}\n (+{dollarFormat(token?.change_24)}%)\n </div>\n ) : (\n <div className=\"text-red-500 text-sm flex flex-row items-center\">\n {' '}\n ({dollarFormat(token?.change_24)}%)\n </div>\n )\n ) : null}\n </div>\n ) : (\n 'N/A'\n )}\n </div>\n <div className=\"flex-col flex-1 flex-wrap py-1 px-3\">\n <div className=\"w-full text-nearblue-700 text-xs mb-1 flex text-[80%]\">\n <span className=\"uppercase\">\n {showMarketCap\n ? 'CIRCULATING SUPPLY MARKET CAP'\n : 'FULLY DILUTED MARKET CAP'}\n </span>\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <Question className=\"w-4 h-4 fill-current ml-1\" />\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {\n 'Calculated by multiplying the tokens Total Supply on Near with the current market price per token.'\n }\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n </div>\n {isLoading ? (\n <div className=\"w-20\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (token?.fully_diluted_market_cap !== null &&\n token?.fully_diluted_market_cap !== undefined) ||\n (token?.market_cap !== null &&\n token?.market_cap !== undefined) ? (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n {token?.fully_diluted_market_cap !== null &&\n token?.fully_diluted_market_cap !== undefined &&\n token?.market_cap !== null &&\n token?.market_cap !== undefined ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <p\n className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\"\n onClick={onToggle}\n >\n $\n {showMarketCap\n ? dollarNonCentFormat(token?.market_cap)\n : dollarNonCentFormat(\n token?.fully_diluted_market_cap,\n )}\n </p>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {showMarketCap\n ? 'Click to switch back'\n : 'Click to switch'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n <p className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\">\n $\n {dollarNonCentFormat(\n Number(token?.market_cap)\n ? token?.market_cap\n : token?.fully_diluted_market_cap,\n )}\n </p>\n )}\n </div>\n ) : (\n <div className=\"w-full break-words flex flex-wrap text-sm\">\n {token?.onchain_market_cap ? (\n <p className=\"px-1 py-1 text-xs cursor-pointer rounded bg-gray-100\">\n ${dollarNonCentFormat(token?.onchain_market_cap)}\n </p>\n ) : (\n 'N/A'\n )}\n </div>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Max Total Supply:\n </div>\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {token?.total_supply\n ? dollarNonCentFormat(token?.total_supply)\n : token?.total_supply ?? ''}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Transfers:\n </div>\n {txnLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {transfers ? localFormat(transfers) : transfers ?? ''}\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Holders:</div>\n {holderLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className=\"w-full md:w-3/4 break-words\">\n {holders ? localFormat(holders) : holders ?? ''}\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n <div className=\"w-full\">\n <div className=\"h-full bg-white soft-shadow rounded-xl overflow-hidden\">\n <h2 className=\"border-b p-3 text-nearblue-600 text-sm font-semibold\">\n Profile Summary\n </h2>\n <div className=\"px-3 divide-y text-sm text-nearblue-600\">\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Contract:</div>\n {isLoading ? (\n <div className=\"w-full md:w-3/4 break-words\">\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n </div>\n ) : (\n <div className=\"w-full text-green-500 md:w-3/4 break-words\">\n <a href={`/address/${token?.contract}`}>\n <a className=\"text-green-500\">{token?.contract}</a>\n </a>\n </div>\n )}\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">Decimals:</div>\n <div className=\"w-full md:w-3/4 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n token?.decimals\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Official Site:\n </div>\n <div className=\"w-full md:w-3/4 text-green-500 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <a\n href={`${token?.website}`}\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n >\n {token?.website}\n </a>\n )}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-between py-4\">\n <div className=\"w-full md:w-1/4 mb-2 md:mb-0 \">\n Social Profiles:\n </div>\n <div className=\"w-full md:w-3/4 break-words\">\n {isLoading ? (\n <div className=\"w-32\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <Links meta={token} />\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div className=\"py-6\"></div>\n {tokenFilter && (\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.TokenFilter`}\n props={{\n network: network,\n id: id,\n tokenFilter: tokenFilter,\n }}\n />\n )}\n <div className=\"block lg:flex lg:space-x-2 mb-4\">\n <div className=\"w-full\">\n <Tabs.Root defaultValue={pageTab}>\n <Tabs.List>\n {tabs &&\n tabs.map((tab, index) => (\n <Tabs.Trigger\n key={index}\n onClick={() => onTab(index)}\n className={`text-nearblue-600 text-sm font-medium overflow-hidden inline-block cursor-pointer p-2 mb-3 mr-2 focus:outline-none ${\n pageTab === tab\n ? 'rounded-lg bg-green-600 text-white'\n : 'hover:bg-neargray-800 bg-neargray-700 rounded-lg hover:text-nearblue-600'\n }`}\n value={tab}\n >\n <h2>{tab}</h2>\n </Tabs.Trigger>\n ))}\n </Tabs.List>\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n <Tabs.Content value={tabs[0]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Transfers`}\n props={{\n network: network,\n id: id,\n t: t,\n filters: filters,\n onFilterClear: onFilterClear,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content value={tabs[1]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Holders`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content clssName=\"border-t\" value={tabs[2]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.Info`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>\n <Tabs.Content value={tabs[3]}>\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.FT.FAQ`}\n props={{\n network: network,\n id: id,\n token: token,\n }}\n />\n }\n </Tabs.Content>{' '}\n <Tabs.Content value={tabs[4]}>\n <div className=\"py-3\">\n {\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.Comments.Feed`}\n props={{\n network: network,\n path: `nearblocks.io/ft/${id}`,\n limit: 10,\n }}\n />\n }\n </div>\n </Tabs.Content>\n </div>\n </Tabs.Root>\n </div>\n </div>\n </div>\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.Holders": { "": "/**\n * Component: FTHolders\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Fungible Token Holders List.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, id, token }) {\n const [isLoading, setIsLoading] = useState(false);\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n const [totalCount, setTotalCount] = useState(0);\n const [holder, setHolder] = useState(\n {},\n );\n const [tokens, setTokens] = useState({} );\n const config = getConfig(network);\n const errorMessage = 'No token holders found!';\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchTotalHolders() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders/count`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count);\n } else {\n handleRateLimit(data, fetchTotalHolders);\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchHoldersData(page) {\n setIsLoading(true);\n\n asyncFetch(\n `${config?.backendUrl}fts/${id}/holders?page=${currentPage}&per_page=25`,\n {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n )\n .then(\n (data) => {\n const resp = data?.body?.holders;\n if (data.status === 200 && Array.isArray(resp) && resp.length > 0) {\n setHolder((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchHoldersData(page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n if (!token && token === undefined) {\n fetchFTData();\n }\n fetchTotalHolders();\n fetchHoldersData(currentPage);\n }, [config?.backendUrl, currentPage, id, token]);\n\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n\n const columns = [\n {\n header: 'Rank',\n key: '',\n cell: (_row, index) => (\n <span>{serialNumber(index, currentPage, 25)}</span>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 w-[50px]',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider w-[50]',\n },\n {\n header: 'Address',\n key: 'account',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[200px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/address/${row.account}`}\n className=\"hover:no-undeline\"\n >\n <a className=\"text-green-500 font-medium hover:no-undeline\">\n {row.account}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row.account}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Quantity',\n key: '',\n cell: (row) => (\n <>\n {' '}\n {row.amount && tokens?.decimals\n ? tokenAmount(row.amount, tokens?.decimals, true)\n : ''}\n </>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Percentage',\n key: 'total_supply',\n cell: (row) => {\n const percentage = token?.total_supply\n ? tokenPercentage(token.total_supply, row.amount, token.decimals)\n : null;\n return (\n <>\n {percentage === null ? 'N/A' : `${percentage}%`}\n {percentage !== null && percentage <= 100 && percentage >= 0 && (\n <div className=\"h-0.5 mt-1 w-full bg-gray-100\">\n <div\n style={{ width: `${percentage}%` }}\n className=\"h-0.5 bg-green-500\"\n />\n </div>\n )}\n </>\n );\n },\n tdClassName:\n 'px-5 py-3 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: 'Value',\n key: 'tokens',\n cell: (row) => {\n return (\n <span>\n {row.amount && tokens?.decimals && tokens?.price\n ? '$' + price(row.amount, tokens?.decimals, tokens?.price)\n : ''}\n </span>\n );\n },\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'x-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider whitespace-nowrap',\n },\n ];\n\n return (\n <>\n {isLoading ? (\n <div className=\"pl-3 max-w-sm py-5 h-[60px]\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions found\n </p>\n </div>\n </div>\n )}\n <Widget\n src={`${config.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: holder[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.FAQ": { "": "/**\n * Component: FTFAQ\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: FAQ About Fungible Token On Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet\n * @param {string} [id] - The token identifier passed as a string\n * @param {Token} [token] - The Token type passed as object\n */\n\n\n\n\n\n\n\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\n\n\n\n\n\nfunction MainComponent({ network, id, token }) {\n const [account, setAccount] = useState({} );\n const [contract, setContract] = useState(\n {} ,\n );\n const [transfers, setTransfers] = useState('');\n const [holders, setHolders] = useState('');\n const [largestHolder, setLargestHolder] = useState(\n {} ,\n );\n const [tokens, setTokens] = useState({} );\n\n const name = tokens?.name;\n const tokenTicker = tokens?.symbol;\n const config = getConfig(network);\n useEffect(() => {\n function fetchFTData() {\n asyncFetch(`${config.backendUrl}fts/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.contracts?.[0];\n if (data.status === 200) {\n setTokens(resp);\n } else {\n handleRateLimit(data, fetchFTData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchAccountData() {\n asyncFetch(`${config?.backendUrl}account/${id}`)\n .then(\n (data\n\n\n\n\n) => {\n const accountResp = data?.body?.account?.[0];\n if (data.status === 200) {\n setAccount(accountResp);\n } else {\n handleRateLimit(data, fetchAccountData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchContractData() {\n asyncFetch(`${config?.backendUrl}account/${id}/contract/deployments`)\n .then(\n (data\n\n\n\n\n) => {\n const depResp = data?.body?.deployments?.[0];\n if (data.status === 200) {\n setContract(depResp);\n } else {\n handleRateLimit(data, fetchContractData);\n }\n },\n )\n .catch(() => {});\n }\n function fetchTotalTxns() {\n asyncFetch(`${config?.backendUrl}fts/${id}/txns/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTransfers(resp?.count);\n } else {\n handleRateLimit(data, fetchTotalTxns);\n }\n },\n )\n .catch(() => {});\n }\n function fetchHoldersdata() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setLargestHolder(resp);\n } else {\n handleRateLimit(data, fetchHoldersdata);\n }\n },\n )\n .catch(() => {});\n }\n function fetchHoldersCount() {\n asyncFetch(`${config?.backendUrl}fts/${id}/holders/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.holders?.[0];\n if (data.status === 200) {\n setHolders(resp?.count);\n } else {\n handleRateLimit(data, fetchHoldersCount);\n }\n },\n )\n .catch(() => {});\n }\n if (!token && token === undefined) {\n fetchFTData();\n }\n fetchAccountData();\n fetchContractData();\n fetchHoldersCount();\n fetchTotalTxns();\n fetchHoldersdata();\n }, [id, config?.backendUrl, token]);\n useEffect(() => {\n if (token) {\n setTokens(token);\n }\n }, [token]);\n return (\n <div itemScope itemType=\"http://schema.org/FAQPage\">\n <div className=\"px-3 pb-2 text-sm divide-y divide-gray-200 space-y-2\">\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n What is {name} price now?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div itemProp=\"text\" className=\"text-sm text-nearblue-600 py-2\">\n The live price of {name} is{' '}\n {tokens?.price !== null && tokens?.price !== undefined ? (\n `$${dollarFormat(tokens?.price)} (${tokenTicker} / USD)`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}{' '}\n today with a current circulating market cap of{' '}\n {tokens?.market_cap !== null &&\n tokens?.market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens.market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . The on-chain marketcap of {name} is{' '}\n {tokens.onchain_market_cap !== null &&\n tokens.onchain_market_cap !== undefined ? (\n `$${dollarNonCentFormat(tokens.onchain_market_cap)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . {name}&apos;s 24-hour trading volume is{' '}\n {tokens.volume_24h !== null && tokens.volume_24h !== undefined ? (\n `$${dollarNonCentFormat(tokens.volume_24h)}`\n ) : (\n <span className=\"text-xs\">N/A</span>\n )}\n . {tokenTicker} to USD price is updated in real-time. {name} is{' '}\n {tokens.change_24 !== null && tokens.change_24 !== undefined ? (\n Number(tokens.change_24) > 0 ? (\n dollarFormat(tokens.change_24) + '%'\n ) : (\n dollarFormat(tokens.change_24) + '%'\n )\n ) : (\n <span>N/A</span>\n )}{' '}\n in the last 24 hours.\n </div>\n </div>\n </div>\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n When was {name} created on Near Protocol?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div className=\"text-sm text-nearblue-600 py-2\" itemProp=\"text\">\n The{' '}\n <a href={`/address/${id}`}>\n <a className=\"underline\">{name}</a>\n </a>{' '}\n contract was created on Near Protocol at{' '}\n {account?.created?.transaction_hash\n ? convertToUTC(\n nanoToMilli(account?.created.block_timestamp),\n false,\n )\n : account?.code_hash\n ? 'Genesis'\n : 'N/A'}{' '}\n by{' '}\n {contract?.receipt_predecessor_account_id && (\n <a href={`/address/${contract.receipt_predecessor_account_id}`}>\n <a className=\"underline\">\n {shortenAddress(contract.receipt_predecessor_account_id)}\n </a>\n </a>\n )}{' '}\n through this{' '}\n {contract?.transaction_hash && (\n <a href={`/txns/${contract.transaction_hash}`}>\n <a className=\"underline\">transaction</a>\n </a>\n )}\n . Since the creation of {name}, there has been{' '}\n {transfers ? localFormat(transfers) : 0} on-chain transfers.\n </div>\n </div>\n </div>\n <div\n itemScope\n itemProp=\"mainEntity\"\n itemType=\"https://schema.org/Question\"\n >\n <h3\n className=\"text-nearblue-600 text-sm font-semibold pt-4 pb-2\"\n itemProp=\"name\"\n >\n How many {name} tokens are there?\n </h3>\n <div\n itemScope\n itemProp=\"acceptedAnswer\"\n itemType=\"https://schema.org/Answer\"\n >\n <div className=\"text-sm text-nearblue-600 py-2\" itemProp=\"text\">\n There are currently{' '}\n {tokens?.circulating_supply !== null ? (\n `${\n tokens?.circulating_supply\n ? localFormat(tokens?.circulating_supply)\n : 0\n }`\n ) : (\n <span>N/A</span>\n )}{' '}\n {tokenTicker} in circulation for a total supply of{' '}\n {tokens?.total_supply !== null &&\n tokens?.total_supply !== undefined &&\n `${dollarNonCentFormat(tokens?.total_supply)}`}\n {tokenTicker}. {tokenTicker}&apos;s supply is split between{' '}\n {holders ? localFormat(holders) : 0} different wallet addresses.{' '}\n {largestHolder?.account && (\n <span>\n The largest {tokenTicker} holder is currently{' '}\n {largestHolder?.account && (\n <a href={`/address/${largestHolder.account}`}>\n <a className=\"underline\">\n {shortenAddress(largestHolder.account)}\n </a>\n </a>\n )}\n , who currently holds{' '}\n {tokenAmount(largestHolder?.amount, tokens?.decimals, true)}{' '}\n {tokenTicker} of all {tokenTicker}.\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.FT.TransfersList": { "": "/**\n * Component: FTTransfersList\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Tokens transfers list on Near Protocol.\n * @interface Props\n * @param {string} [network] - The network data to show, either mainnet or testnet.\n * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package.\n * @param {number} [currentPage] - The current page number being displayed. (Optional)\n * Example: If provided, currentPage=3 will display the third page of blocks.\n * @param {function} [setPage] - A function used to set the current page. (Optional)\n * Example: setPage={handlePageChange} where handlePageChange is a function to update the page.\n */\n\n\n\n\n\n\n\n/* INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Skeleton = (props) => {\n return (\n <div\n className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`}\n ></div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Skeleton.jsx\" */\n/* INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\nconst FaCheckCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z\"\n fill=\"#50C878\"\n />\n </svg>\n );\n};\nconst FaTimesCircle = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\">\n <path\n d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"\n fill=\"#ff0000\"\n />\n </svg>\n );\n};\nconst FaHourglassStart = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 384 512\">\n <path\n d=\"M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM288 437v11H96V437c0-25.5 10.1-49.9 28.1-67.9L192 301.3l67.9 67.9c18 18 28.1 42.4 28.1 67.9z\"\n fill=\"#FFEB3B\"\n />\n </svg>\n );\n};\n\nconst getOptions = (status) => {\n switch (status) {\n case null:\n return {\n bg: 'bg-yellow-50',\n text: 'text-yellow-500',\n icon: FaHourglassStart,\n label: 'Pending',\n };\n case false:\n return {\n bg: 'bg-red-50',\n text: 'text-red-500',\n icon: FaTimesCircle,\n label: 'Failure',\n };\n\n default:\n return {\n bg: 'bg-emerald-50',\n text: 'text-emerald-500',\n icon: FaCheckCircle,\n label: 'Success',\n };\n }\n};\n\nconst TxnStatus = (props) => {\n const option = getOptions(props.status);\n const Icon = option.icon;\n\n return (\n <div className=\"w-full md:w-3/4 break-words\">\n <span\n className={`inline-flex items-center text-xs rounded py-1 ${\n option.bg\n } ${option.text} ${props.showLabel ? ' px-2' : ' px-1'}`}\n >\n <Icon />\n {props.showLabel && <span className=\"ml-2\">{option.label}</span>}\n </span>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Status.jsx\" */\n/* INCLUDE: \"includes/formats.jsx\" */\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\n\nfunction dollarNonCentFormat(number) {\n const bigNumber = new Big(number).toFixed(0);\n\n // Extract integer part and format with commas\n const integerPart = bigNumber.toString();\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n return formattedInteger;\n}\n\nfunction weight(number) {\n let sizeInBytes = new Big(number);\n\n if (sizeInBytes.lt(0)) {\n throw new Error('Invalid input. Please provide a non-negative number.');\n }\n\n const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n let suffixIndex = 0;\n\n while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) {\n sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes\n suffixIndex++;\n }\n\n const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex];\n\n return formattedSize;\n}\n\nfunction convertToUTC(timestamp, hour) {\n const date = new Date(timestamp);\n\n // Get UTC date components\n const utcYear = date.getUTCFullYear();\n const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based\n const utcDay = ('0' + date.getUTCDate()).slice(-2);\n const utcHours = ('0' + date.getUTCHours()).slice(-2);\n const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2);\n const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2);\n\n // Array of month abbreviations\n const monthAbbreviations = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n const monthIndex = Number(utcMonth) - 1;\n // Format the date as required (Jul-25-2022 16:25:37)\n let formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n utcHours +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds;\n\n if (hour) {\n // Convert hours to 12-hour format\n let hour12 = parseInt(utcHours);\n const ampm = hour12 >= 12 ? 'PM' : 'AM';\n hour12 = hour12 % 12 || 12;\n\n // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM)\n formattedDate =\n monthAbbreviations[monthIndex] +\n '-' +\n utcDay +\n '-' +\n utcYear +\n ' ' +\n hour12 +\n ':' +\n utcMinutes +\n ':' +\n utcSeconds +\n ' ' +\n ampm;\n }\n\n return formattedDate;\n}\n\nfunction getTimeAgoString(timestamp) {\n const currentUTC = Date.now();\n const date = new Date(timestamp);\n const seconds = Math.floor((currentUTC - date.getTime()) / 1000);\n\n const intervals = {\n year: seconds / (60 * 60 * 24 * 365),\n month: seconds / (60 * 60 * 24 * 30),\n week: seconds / (60 * 60 * 24 * 7),\n day: seconds / (60 * 60 * 24),\n hour: seconds / (60 * 60),\n minute: seconds / 60,\n };\n\n if (intervals.year >= 1) {\n return (\n Math.floor(intervals.year) +\n ' year' +\n (Math.floor(intervals.year) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.month >= 1) {\n return (\n Math.floor(intervals.month) +\n ' month' +\n (Math.floor(intervals.month) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.day >= 1) {\n return (\n Math.floor(intervals.day) +\n ' day' +\n (Math.floor(intervals.day) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.hour >= 1) {\n return (\n Math.floor(intervals.hour) +\n ' hour' +\n (Math.floor(intervals.hour) > 1 ? 's' : '') +\n ' ago'\n );\n } else if (intervals.minute >= 1) {\n return (\n Math.floor(intervals.minute) +\n ' minute' +\n (Math.floor(intervals.minute) > 1 ? 's' : '') +\n ' ago'\n );\n } else {\n return 'a few seconds ago';\n }\n}\n\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction formatTimestampToString(timestamp) {\n const date = new Date(timestamp);\n\n // Format the date to 'YYYY-MM-DD HH:mm:ss' format\n const formattedDate = date.toISOString().replace('T', ' ').split('.')[0];\n\n return formattedDate;\n}\n\nfunction convertToMetricPrefix(numberStr) {\n const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes\n\n let result = new Big(numberStr);\n let count = 0;\n\n while (result.abs().gte('1e3') && count < prefixes.length - 1) {\n result = result.div(1e3);\n count++;\n }\n\n // Check if the value is an integer or has more than two digits before the decimal point\n if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) {\n result = result.toFixed(2);\n } else {\n result = result.toFixed(0);\n }\n\n return result.toString() + ' ' + prefixes[count];\n}\n\nfunction formatNumber(value) {\n let bigValue = new Big(value);\n const suffixes = ['', 'K', 'M', 'B', 'T'];\n let suffixIndex = 0;\n\n while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) {\n bigValue = bigValue.div(1000);\n suffixIndex++;\n }\n\n const formattedValue = bigValue.toFixed(1).replace(/\\.0+$/, '');\n return `${formattedValue} ${suffixes[suffixIndex]}`;\n}\n\nfunction gasFee(gas, price) {\n const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true);\n\n return `${near}`;\n}\n\nfunction currency(number) {\n let absNumber = new Big(number).abs();\n\n const suffixes = ['', 'K', 'M', 'B', 'T', 'Q'];\n let suffixIndex = 0;\n\n while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) {\n absNumber = absNumber.div(1000); // Divide using big.js's div method\n suffixIndex++;\n }\n\n const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places\n\n return (\n (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex]\n );\n}\n\nfunction formatDate(dateString) {\n const inputDate = new Date(dateString);\n\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n const dayOfWeek = days[inputDate.getDay()];\n const month = months[inputDate.getMonth()];\n const day = inputDate.getDate();\n const year = inputDate.getFullYear();\n\n const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year;\n return formattedDate;\n}\n\nfunction formatCustomDate(inputDate) {\n var date = new Date(inputDate);\n\n // Array of month names\n var monthNames = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n\n // Get month and day\n var month = monthNames[date.getMonth()];\n var day = date.getDate();\n\n // Create formatted date string in \"MMM DD\" format\n var formattedDate = month + ' ' + (day < 10 ? '0' + day : day);\n\n return formattedDate;\n}\n\nfunction shortenHex(address) {\n return `${address && address.substr(0, 6)}...${address.substr(-4)}`;\n}\n\nfunction capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction shortenToken(token) {\n return truncateString(token, 14, '');\n}\n\nfunction shortenTokenSymbol(token) {\n return truncateString(token, 5, '');\n}\n\nfunction gasPercentage(gasUsed, gasAttached) {\n if (!gasAttached) return 'N/A';\n\n const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2);\n return `${formattedNumber}%`;\n}\n\nfunction serialNumber(index, page, perPage) {\n return index + 1 + (page - 1) * perPage;\n}\n\nfunction capitalizeWords(str) {\n const words = str.split('_');\n const capitalizedWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1),\n );\n const result = capitalizedWords.join(' ');\n return result;\n}\n\nfunction toSnakeCase(str) {\n return str\n .replace(/[A-Z]/g, (match) => '_' + match.toLowerCase())\n .replace(/^_/, '');\n}\n\nfunction capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\nfunction yoctoToNear(yocto, format) {\n const YOCTO_PER_NEAR = Big(10).pow(24).toString();\n\n const near = Big(yocto).div(YOCTO_PER_NEAR).toString();\n\n return format ? localFormat(near) : near;\n}\n/* END_INCLUDE: \"includes/formats.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/**\n * @interface Props\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n */\n\n\n\n\n\nconst Clock = (props) => (\n <svg\n viewBox=\"64 64 896 896\"\n focusable=\"false\"\n data-icon=\"clock-circle\"\n width=\"1em\"\n height=\"1em\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n <path d=\"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z\"></path>\n </svg>\n);/* END_INCLUDE COMPONENT: \"includes/icons/Clock.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\nconst FaLongArrowAltRight = () => {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\">\n <path\n d=\"M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216\"\n fill=\"#ffffff\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/FaLongArrowAltRight.jsx\" */\n/* INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/**\n * @interface Props\n * @param {string} [src] - The URL string pointing to the image source.\n * @param {string} [alt] - The alternate text description for the image.\n * @param {string} [className] - The CSS class name(s) for styling purposes.\n * @param {string} [appUrl] - The URL of the application.\n */\n\n\n\n\n\n\n\n\n\n\nconst TokenImage = ({\n appUrl,\n src,\n alt,\n className,\n onLoad,\n onSetSrc,\n}) => {\n const placeholder = `${appUrl}images/tokenplaceholder.svg`;\n\n const handleLoad = () => {\n if (onLoad) {\n onLoad();\n }\n };\n\n const handleError = () => {\n if (onSetSrc) {\n onSetSrc(placeholder);\n }\n if (onLoad) {\n onLoad();\n }\n };\n\n return (\n <img\n src={src || placeholder}\n alt={alt}\n className={className}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/TokenImage.jsx\" */\n/* INCLUDE: \"includes/libs.jsx\" */\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction nanoToMilli(nano) {\n return Big(nano).div(Big(10).pow(6)).round().toNumber();\n}\n\nfunction truncateString(str, maxLength, suffix) {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength) + suffix;\n}\n\nfunction getConfig(network) {\n switch (network) {\n case 'mainnet':\n return {\n ownerId: 'nearblocks.near',\n nodeUrl: 'https://rpc.mainnet.near.org',\n backendUrl: 'https://api3.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.mainnet.near.org',\n appUrl: 'https://nearblocks.io/',\n };\n case 'testnet':\n return {\n ownerId: 'nearblocks.testnet',\n nodeUrl: 'https://rpc.testnet.near.org',\n backendUrl: 'https://api3-testnet.nearblocks.io/v1/',\n rpcUrl: 'https://archival-rpc.testnet.near.org',\n appUrl: 'https://testnet.nearblocks.io/',\n };\n default:\n return {};\n }\n}\n\nfunction debounce(\n delay,\n func,\n) {\n let timer;\n let active = true;\n const debounced = (arg) => {\n if (active) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n active && func(arg);\n timer = undefined;\n }, delay);\n } else {\n func(arg);\n }\n };\n\n debounced.isPending = () => {\n return timer !== undefined;\n };\n\n debounced.cancel = () => {\n active = false;\n };\n\n debounced.flush = (arg) => func(arg);\n\n return debounced;\n}\n\nfunction timeAgo(unixTimestamp) {\n const currentTimestamp = Math.floor(Date.now() / 1000);\n const secondsAgo = currentTimestamp - unixTimestamp;\n\n if (secondsAgo < 5) {\n return 'Just now';\n } else if (secondsAgo < 60) {\n return `${secondsAgo} seconds ago`;\n } else if (secondsAgo < 3600) {\n const minutesAgo = Math.floor(secondsAgo / 60);\n return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`;\n } else if (secondsAgo < 86400) {\n const hoursAgo = Math.floor(secondsAgo / 3600);\n return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`;\n } else {\n const daysAgo = Math.floor(secondsAgo / 86400);\n return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`;\n }\n}\n\nfunction shortenAddress(address) {\n const string = String(address);\n\n if (string.length <= 20) return string;\n\n return `${string.substr(0, 10)}...${string.substr(-7)}`;\n}\n\nfunction urlHostName(url) {\n try {\n const domain = new URL(url);\n return domain?.hostname ?? null;\n } catch (e) {\n return null;\n }\n}\n\nfunction holderPercentage(supply, quantity) {\n return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100);\n}\n\nfunction isAction(type) {\n const actions = [\n 'DEPLOY_CONTRACT',\n 'TRANSFER',\n 'STAKE',\n 'ADD_KEY',\n 'DELETE_KEY',\n 'DELETE_ACCOUNT',\n ];\n\n return actions.includes(type.toUpperCase());\n}\n\nfunction isJson(string) {\n const str = string.replace(/\\\\/g, '');\n\n try {\n JSON.parse(str);\n return false;\n } catch (e) {\n return false;\n }\n}\n\nfunction uniqueId() {\n return Math.floor(Math.random() * 1000);\n}\nfunction handleRateLimit(\n data,\n reFetch,\n Loading,\n) {\n if (data.status === 429 || data.status === undefined) {\n const retryCount = 4;\n const delay = Math.pow(2, retryCount) * 1000;\n setTimeout(() => {\n reFetch();\n }, delay);\n } else {\n if (Loading) {\n Loading();\n }\n }\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction formatWithCommas(number) {\n return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n/* END_INCLUDE: \"includes/libs.jsx\" */\n/* INCLUDE: \"includes/near.jsx\" */\nfunction tokenAmount(amount, decimal, format) {\n if (amount === undefined || amount === null) return 'N/A';\n\n const near = Big(amount).div(Big(10).pow(decimal));\n\n const formattedValue = format\n ? near.toFixed(8).replace(/\\.?0+$/, '')\n : near.toFixed(Big(decimal, 10)).replace(/\\.?0+$/, '');\n\n return formattedValue;\n}\n\nfunction tokenPercentage(\n supply,\n amount,\n decimal,\n) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n const nearSupply = Big(supply);\n\n return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2);\n}\nfunction price(amount, decimal, price) {\n const nearAmount = Big(amount).div(Big(10).pow(decimal));\n return dollarFormat(nearAmount.mul(Big(price || 0)).toString());\n}\nfunction mapRpcActionToAction(action) {\n if (action === 'CreateAccount') {\n return {\n action_kind: 'CreateAccount',\n args: {},\n };\n }\n\n if (typeof action === 'object') {\n const kind = Object.keys(action)[0];\n\n return {\n action_kind: kind,\n args: action[kind],\n };\n }\n\n return null;\n}\n\nfunction valueFromObj(obj) {\n const keys = Object.keys(obj);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const value = obj[key];\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'object') {\n const nestedValue = valueFromObj(value );\n if (nestedValue) {\n return nestedValue;\n }\n }\n }\n\n return undefined;\n}\n\nfunction txnLogs(txn) {\n let txLogs = [];\n\n const outcomes = txn?.receipts_outcome || [];\n\n for (let i = 0; i < outcomes.length; i++) {\n const outcome = outcomes[i];\n let logs = outcome?.outcome?.logs || [];\n\n if (logs.length > 0) {\n const mappedLogs = logs.map((log) => ({\n contract: outcome?.outcome?.executor_id || '',\n logs: log,\n }));\n txLogs = [...txLogs, ...mappedLogs];\n }\n }\n return txLogs;\n}\n\nfunction txnActions(txn) {\n const txActions = [];\n const receipts = txn?.receipts || [];\n\n for (let i = 0; i < receipts.length; i++) {\n const receipt = receipts[i];\n const from = receipt?.predecessor_id;\n const to = receipt?.receiver_id;\n\n if (Array.isArray(receipt?.receipt)) {\n const actions = receipt.receipt;\n\n for (let j = 0; j < actions.length; j++) {\n const action = actions[j];\n\n txActions.push({ from, to, ...action });\n }\n } else {\n const actions = receipt?.receipt?.Action?.actions || [];\n\n for (let j = 0; j < actions.length; j++) {\n const action = mapRpcActionToAction(actions[j]);\n\n txActions.push({ from, to, ...action });\n }\n }\n }\n\n return txActions.filter(\n (action) =>\n action.action_kind !== 'FunctionCall' && action.from !== 'system',\n );\n}\n\nfunction txnErrorMessage(txn) {\n const kind = txn?.status?.Failure?.ActionError?.kind;\n\n if (typeof kind === 'string') return kind;\n if (typeof kind === 'object') {\n return valueFromObj(kind);\n }\n\n return null;\n}\n\nfunction formatLine(line, offset, format) {\n let result = `${offset.toString(16).padStart(8, '0')} `;\n\n const hexValues = line.match(/[0-9a-fA-F]{2}/g) || [];\n\n hexValues.forEach((byte, index) => {\n if (index > 0 && index % 4 === 0) {\n result += ' ';\n }\n result += byte.toUpperCase().padEnd(2, ' ') + ' ';\n });\n\n if (format === 'twos') {\n result = result.replace(/(.{4})/g, '$1 ');\n } else if (format === 'default') {\n result += ` ${String.fromCharCode(\n ...hexValues.map((b) => parseInt(b, 16)),\n )}`;\n }\n\n return result.trimEnd();\n}\n\nfunction collectNestedReceiptWithOutcomeOld(\n idOrHash,\n parsedMap,\n) {\n const parsedElement = parsedMap.get(idOrHash);\n if (!parsedElement) {\n return { id: idOrHash };\n }\n const { receiptIds, ...restOutcome } = parsedElement.outcome;\n return {\n ...parsedElement,\n outcome: {\n ...restOutcome,\n nestedReceipts: receiptIds.map((id) =>\n collectNestedReceiptWithOutcomeOld(id, parsedMap),\n ),\n },\n };\n}\n\nfunction parseReceipt(\n receipt,\n outcome,\n transaction,\n) {\n if (!receipt) {\n return {\n id: outcome.id,\n predecessorId: transaction.signer_id,\n receiverId: transaction.receiver_id,\n actions: transaction.actions.map(mapRpcActionToAction1),\n };\n }\n return {\n id: receipt.receipt_id,\n predecessorId: receipt.predecessor_id,\n receiverId: receipt.receiver_id,\n actions:\n 'Action' in receipt.receipt\n ? receipt.receipt.Action.actions.map(mapRpcActionToAction1)\n : [],\n };\n}\n\nfunction mapNonDelegateRpcActionToAction(\n rpcAction,\n) {\n if (rpcAction === 'CreateAccount') {\n return {\n kind: 'createAccount',\n args: {},\n };\n }\n if ('DeployContract' in rpcAction) {\n return {\n kind: 'deployContract',\n args: rpcAction.DeployContract,\n };\n }\n if ('FunctionCall' in rpcAction) {\n return {\n kind: 'functionCall',\n args: {\n methodName: rpcAction.FunctionCall.method_name,\n args: rpcAction.FunctionCall.args,\n deposit: rpcAction.FunctionCall.deposit,\n gas: rpcAction.FunctionCall.gas,\n },\n };\n }\n if ('Transfer' in rpcAction) {\n return {\n kind: 'transfer',\n args: rpcAction.Transfer,\n };\n }\n if ('Stake' in rpcAction) {\n return {\n kind: 'stake',\n args: {\n publicKey: rpcAction.Stake.public_key,\n stake: rpcAction.Stake.stake,\n },\n };\n }\n if ('AddKey' in rpcAction) {\n return {\n kind: 'addKey',\n args: {\n publicKey: rpcAction.AddKey.public_key,\n accessKey: {\n nonce: rpcAction.AddKey.access_key.nonce,\n permission:\n rpcAction.AddKey.access_key.permission === 'FullAccess'\n ? {\n type: 'fullAccess',\n }\n : {\n type: 'functionCall',\n contractId:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .receiver_id,\n methodNames:\n rpcAction.AddKey.access_key.permission.FunctionCall\n .method_names,\n },\n },\n },\n };\n }\n if ('DeleteKey' in rpcAction) {\n return {\n kind: 'deleteKey',\n args: {\n publicKey: rpcAction.DeleteKey.public_key,\n },\n };\n }\n return {\n kind: 'deleteAccount',\n args: {\n beneficiaryId: rpcAction.DeleteAccount.beneficiary_id,\n },\n };\n}\nfunction mapRpcInvalidAccessKeyError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n\n if (error === 'DepositWithFunctionCall') {\n return {\n type: 'depositWithFunctionCall',\n };\n }\n if (error === 'RequiresFullAccess') {\n return {\n type: 'requiresFullAccess',\n };\n }\n if ('AccessKeyNotFound' in error) {\n const { account_id, public_key } = error.AccessKeyNotFound;\n return {\n type: 'accessKeyNotFound',\n accountId: account_id,\n publicKey: public_key,\n };\n }\n if ('ReceiverMismatch' in error) {\n const { ak_receiver, tx_receiver } = error.ReceiverMismatch;\n return {\n type: 'receiverMismatch',\n akReceiver: ak_receiver,\n transactionReceiver: tx_receiver,\n };\n }\n if ('MethodNameMismatch' in error) {\n const { method_name } = error.MethodNameMismatch;\n return {\n type: 'methodNameMismatch',\n methodName: method_name,\n };\n }\n if ('NotEnoughAllowance' in error) {\n const { account_id, allowance, cost, public_key } =\n error.NotEnoughAllowance;\n return {\n type: 'notEnoughAllowance',\n accountId: account_id,\n allowance: allowance,\n cost: cost,\n publicKey: public_key,\n };\n }\n\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcCompilationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CodeDoesNotExist' in error) {\n return {\n type: 'codeDoesNotExist',\n accountId: error.CodeDoesNotExist.account_id,\n };\n }\n if ('PrepareError' in error) {\n return {\n type: 'prepareError',\n };\n }\n if ('WasmerCompileError' in error) {\n return {\n type: 'wasmerCompileError',\n msg: error.WasmerCompileError.msg,\n };\n }\n if ('UnsupportedCompiler' in error) {\n return {\n type: 'unsupportedCompiler',\n msg: error.UnsupportedCompiler.msg,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcFunctionCallError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('CompilationError' in error) {\n return {\n type: 'compilationError',\n error: mapRpcCompilationError(error.CompilationError),\n };\n }\n if ('LinkError' in error) {\n return {\n type: 'linkError',\n msg: error.LinkError.msg,\n };\n }\n if ('MethodResolveError' in error) {\n return {\n type: 'methodResolveError',\n };\n }\n if ('WasmTrap' in error) {\n return {\n type: 'wasmTrap',\n };\n }\n if ('WasmUnknownError' in error) {\n return {\n type: 'wasmUnknownError',\n };\n }\n if ('HostError' in error) {\n return {\n type: 'hostError',\n };\n }\n if ('_EVMError' in error) {\n return {\n type: 'evmError',\n };\n }\n if ('ExecutionError' in error) {\n return {\n type: 'executionError',\n error: error.ExecutionError,\n };\n }\n return UNKNOWN_ERROR;\n}\nfunction mapRpcNewReceiptValidationError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidPredecessorId' in error) {\n return {\n type: 'invalidPredecessorId',\n accountId: error.InvalidPredecessorId.account_id,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n accountId: error.InvalidReceiverId.account_id,\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n accountId: error.InvalidSignerId.account_id,\n };\n }\n if ('InvalidDataReceiverId' in error) {\n return {\n type: 'invalidDataReceiverId',\n accountId: error.InvalidDataReceiverId.account_id,\n };\n }\n if ('ReturnedValueLengthExceeded' in error) {\n return {\n type: 'returnedValueLengthExceeded',\n length: error.ReturnedValueLengthExceeded.length,\n limit: error.ReturnedValueLengthExceeded.limit,\n };\n }\n if ('NumberInputDataDependenciesExceeded' in error) {\n return {\n type: 'numberInputDataDependenciesExceeded',\n numberOfInputDataDependencies:\n error.NumberInputDataDependenciesExceeded\n .number_of_input_data_dependencies,\n limit: error.NumberInputDataDependenciesExceeded.limit,\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptActionError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n const { kind } = error;\n if (kind === 'DelegateActionExpired') {\n return {\n type: 'delegateActionExpired',\n };\n }\n if (kind === 'DelegateActionInvalidSignature') {\n return {\n type: 'delegateActionInvalidSignature',\n };\n }\n if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) {\n return {\n type: 'delegateActionSenderDoesNotMatchTxReceiver',\n receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id,\n senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id,\n };\n }\n if ('DelegateActionAccessKeyError' in kind) {\n return {\n type: 'delegateActionAccessKeyError',\n error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError),\n };\n }\n if ('DelegateActionInvalidNonce' in kind) {\n return {\n type: 'delegateActionInvalidNonce',\n akNonce: kind.DelegateActionInvalidNonce.ak_nonce,\n delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce,\n };\n }\n if ('DelegateActionNonceTooLarge' in kind) {\n return {\n type: 'delegateActionNonceTooLarge',\n delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce,\n upperBound: kind.DelegateActionNonceTooLarge.upper_bound,\n };\n }\n if ('AccountAlreadyExists' in kind) {\n return {\n type: 'accountAlreadyExists',\n accountId: kind.AccountAlreadyExists.account_id,\n };\n }\n if ('AccountDoesNotExist' in kind) {\n return {\n type: 'accountDoesNotExist',\n accountId: kind.AccountDoesNotExist.account_id,\n };\n }\n if ('CreateAccountOnlyByRegistrar' in kind) {\n return {\n type: 'createAccountOnlyByRegistrar',\n accountId: kind.CreateAccountOnlyByRegistrar.account_id,\n registrarAccountId:\n kind.CreateAccountOnlyByRegistrar.registrar_account_id,\n predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id,\n };\n }\n if ('CreateAccountNotAllowed' in kind) {\n return {\n type: 'createAccountNotAllowed',\n accountId: kind.CreateAccountNotAllowed.account_id,\n predecessorId: kind.CreateAccountNotAllowed.predecessor_id,\n };\n }\n if ('ActorNoPermission' in kind) {\n return {\n type: 'actorNoPermission',\n accountId: kind.ActorNoPermission.account_id,\n actorId: kind.ActorNoPermission.actor_id,\n };\n }\n if ('DeleteKeyDoesNotExist' in kind) {\n return {\n type: 'deleteKeyDoesNotExist',\n accountId: kind.DeleteKeyDoesNotExist.account_id,\n publicKey: kind.DeleteKeyDoesNotExist.public_key,\n };\n }\n if ('AddKeyAlreadyExists' in kind) {\n return {\n type: 'addKeyAlreadyExists',\n accountId: kind.AddKeyAlreadyExists.account_id,\n publicKey: kind.AddKeyAlreadyExists.public_key,\n };\n }\n if ('DeleteAccountStaking' in kind) {\n return {\n type: 'deleteAccountStaking',\n accountId: kind.DeleteAccountStaking.account_id,\n };\n }\n if ('LackBalanceForState' in kind) {\n return {\n type: 'lackBalanceForState',\n accountId: kind.LackBalanceForState.account_id,\n amount: kind.LackBalanceForState.amount,\n };\n }\n if ('TriesToUnstake' in kind) {\n return {\n type: 'triesToUnstake',\n accountId: kind.TriesToUnstake.account_id,\n };\n }\n if ('TriesToStake' in kind) {\n return {\n type: 'triesToStake',\n accountId: kind.TriesToStake.account_id,\n stake: kind.TriesToStake.stake,\n locked: kind.TriesToStake.locked,\n balance: kind.TriesToStake.balance,\n };\n }\n if ('InsufficientStake' in kind) {\n return {\n type: 'insufficientStake',\n accountId: kind.InsufficientStake.account_id,\n stake: kind.InsufficientStake.stake,\n minimumStake: kind.InsufficientStake.minimum_stake,\n };\n }\n if ('FunctionCallError' in kind) {\n return {\n type: 'functionCallError',\n error: mapRpcFunctionCallError(kind.FunctionCallError),\n };\n }\n if ('NewReceiptValidationError' in kind) {\n return {\n type: 'newReceiptValidationError',\n error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError),\n };\n }\n if ('OnlyImplicitAccountCreationAllowed' in kind) {\n return {\n type: 'onlyImplicitAccountCreationAllowed',\n accountId: kind.OnlyImplicitAccountCreationAllowed.account_id,\n };\n }\n if ('DeleteAccountWithLargeState' in kind) {\n return {\n type: 'deleteAccountWithLargeState',\n accountId: kind.DeleteAccountWithLargeState.account_id,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptInvalidTxError(error) {\n const UNKNOWN_ERROR = { type: 'unknown' };\n if ('InvalidAccessKeyError' in error) {\n return {\n type: 'invalidAccessKeyError',\n error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError),\n };\n }\n if ('InvalidSignerId' in error) {\n return {\n type: 'invalidSignerId',\n signerId: error.InvalidSignerId.signer_id,\n };\n }\n if ('SignerDoesNotExist' in error) {\n return {\n type: 'signerDoesNotExist',\n signerId: error.SignerDoesNotExist.signer_id,\n };\n }\n if ('InvalidNonce' in error) {\n return {\n type: 'invalidNonce',\n transactionNonce: error.InvalidNonce.tx_nonce,\n akNonce: error.InvalidNonce.ak_nonce,\n };\n }\n if ('NonceTooLarge' in error) {\n return {\n type: 'nonceTooLarge',\n transactionNonce: error.NonceTooLarge.tx_nonce,\n upperBound: error.NonceTooLarge.upper_bound,\n };\n }\n if ('InvalidReceiverId' in error) {\n return {\n type: 'invalidReceiverId',\n receiverId: error.InvalidReceiverId.receiver_id,\n };\n }\n if ('InvalidSignature' in error) {\n return {\n type: 'invalidSignature',\n };\n }\n if ('NotEnoughBalance' in error) {\n return {\n type: 'notEnoughBalance',\n signerId: error.NotEnoughBalance.signer_id,\n balance: error.NotEnoughBalance.balance,\n cost: error.NotEnoughBalance.cost,\n };\n }\n if ('LackBalanceForState' in error) {\n return {\n type: 'lackBalanceForState',\n signerId: error.LackBalanceForState.signer_id,\n amount: error.LackBalanceForState.amount,\n };\n }\n if ('CostOverflow' in error) {\n return {\n type: 'costOverflow',\n };\n }\n if ('InvalidChain' in error) {\n return {\n type: 'invalidChain',\n };\n }\n if ('Expired' in error) {\n return {\n type: 'expired',\n };\n }\n if ('ActionsValidation' in error) {\n return {\n type: 'actionsValidation',\n };\n }\n if ('TransactionSizeExceeded' in error) {\n return {\n type: 'transactionSizeExceeded',\n size: error.TransactionSizeExceeded.size,\n limit: error.TransactionSizeExceeded.limit,\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptError(error) {\n let UNKNOWN_ERROR = { type: 'unknown' };\n if ('ActionError' in error) {\n return {\n type: 'action',\n error: mapRpcReceiptActionError(error.ActionError),\n };\n }\n if ('InvalidTxError' in error) {\n return {\n type: 'transaction',\n error: mapRpcReceiptInvalidTxError(error.InvalidTxError),\n };\n }\n return UNKNOWN_ERROR;\n}\n\nfunction mapRpcReceiptStatus(status) {\n if ('SuccessValue' in status) {\n return { type: 'successValue', value: status.SuccessValue };\n }\n if ('SuccessReceiptId' in status) {\n return { type: 'successReceiptId', receiptId: status.SuccessReceiptId };\n }\n if ('Failure' in status) {\n return { type: 'failure', error: mapRpcReceiptError(status.Failure) };\n }\n return { type: 'unknown' };\n}\n\nfunction mapRpcActionToAction1(rpcAction) {\n if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) {\n return {\n kind: 'delegateAction',\n args: {\n actions: rpcAction.Delegate.delegate_action.actions.map(\n (subaction, index) => ({\n ...mapNonDelegateRpcActionToAction(subaction),\n delegateIndex: index,\n }),\n ),\n receiverId: rpcAction.Delegate.delegate_action.receiver_id,\n senderId: rpcAction.Delegate.delegate_action.sender_id,\n },\n };\n }\n return mapNonDelegateRpcActionToAction(rpcAction);\n}\n\nfunction parseOutcomeOld(outcome) {\n return {\n blockHash: outcome.block_hash,\n tokensBurnt: outcome.outcome.tokens_burnt,\n gasBurnt: outcome.outcome.gas_burnt,\n status: mapRpcReceiptStatus(outcome.outcome.status),\n logs: outcome.outcome.logs,\n receiptIds: outcome.outcome.receipt_ids,\n };\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\nfunction dollarFormat(number) {\n const bigNumber = new Big(number);\n\n // Format to two decimal places without thousands separator\n const formattedNumber = bigNumber.toFixed(2);\n\n // Add comma as a thousands separator\n const parts = formattedNumber.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\n const dollarFormattedNumber = `${parts.join('.')}`;\n\n return dollarFormattedNumber;\n}\nfunction localFormat(number) {\n const bigNumber = Big(number);\n const formattedNumber = bigNumber\n .toFixed(5)\n .replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); // Add commas before the decimal point\n return formattedNumber.replace(/\\.?0*$/, ''); // Remove trailing zeros and the dot\n}\n/* END_INCLUDE: \"includes/near.jsx\" */\n\n\nfunction MainComponent({ network, t, currentPage, setPage }) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [showAge, setShowAge] = useState(true);\n const errorMessage = t ? t('txns:noTxns') : 'No transactions found!';\n const [tokens, setTokens] = useState(\n {},\n );\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n useEffect(() => {\n function fetchTotalTokens() {\n asyncFetch(`${config?.backendUrl}fts/txns/count`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, fetchTotalTokens);\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n function fetchTokens(page) {\n setIsLoading(true);\n asyncFetch(`${config?.backendUrl}fts/txns?page=${page}&per_page=25`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.txns;\n if (data.status === 200) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTokens(page),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {})\n .finally(() => {});\n }\n\n fetchTotalTokens();\n fetchTokens(currentPage);\n }, [config?.backendUrl, currentPage]);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n const onHandleMouseOver = (e, id) => {\n e.preventDefault();\n\n setAddress(id);\n };\n\n const columns = [\n {\n header: <span></span>,\n key: '',\n cell: (row) => (\n <>\n <TxnStatus status={row?.outcomes?.status} showLabel={false} />\n </>\n ),\n tdClassName:\n 'pl-5 pr-2 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-end',\n },\n {\n header: <span>{t ? t('token:fts.hash') : 'HASH'}</span>,\n key: 'transaction_hash',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap\">\n <a\n href={`/txns/${row?.transaction_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.transaction_hash}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white p-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span> {t ? t('type') : 'TYPE'}</span>,\n key: 'actions',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"bg-blue-900/10 text-xs text-nearblue-600 rounded-xl px-2 py-1 max-w-[120px] inline-flex truncate\">\n <span className=\"block truncate\">{row?.cause}</span>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"bottom\"\n >\n {row?.cause}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>Affected</span>,\n key: 'affected_account_id',\n cell: (row) => (\n <span>\n {row?.affected_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.affected_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.affected_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.affected_account_id)\n }\n >\n {row?.affected_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.affected_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span></span>,\n key: '',\n cell: (row) => {\n return row?.involved_account_id === row?.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 inline-flex items-center justify-center bg-green-200 text-white text-sm font-semibold\">\n {t('txns:txnSelf')}\n </span>\n ) : Number(row?.delta_amount) > 0 ? (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white rotate-180\">\n <FaLongArrowAltRight />\n </div>\n ) : (\n <div className=\"w-5 h-5 p-1 bg-green-100 rounded-full text-center flex justify-center items-center mx-auto text-white\">\n <FaLongArrowAltRight />\n </div>\n );\n },\n tdClassName: 'text-center',\n },\n {\n header: <span>Involved</span>,\n key: 'involved_account_id',\n cell: (row) => (\n <span>\n {row?.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span\n className={`truncate max-w-[120px] inline-block align-bottom text-green-500 whitespace-nowrap ${\n row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-0.5 px-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-0.5 px-1'\n }`}\n >\n <a\n href={`/address/${row?.involved_account_id}`}\n className=\"hover:no-underline\"\n >\n <a\n className=\"text-green-500 hover:no-underline\"\n onMouseOver={(e) =>\n onHandleMouseOver(e, row?.involved_account_id)\n }\n >\n {row?.involved_account_id}\n </a>\n </a>\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.involved_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'system'\n )}\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span> Quantity</span>,\n key: 'block_height',\n cell: (row) => (\n <span>\n {row?.delta_amount\n ? localFormat(\n tokenAmount(\n Big(row.delta_amount).abs().toString(),\n row?.ft?.decimals,\n true,\n ),\n )\n : ''}\n </span>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <span>Token</span>,\n key: 'block_height',\n cell: (row) => {\n return (\n row?.ft && (\n <div className=\"flex flex-row items-center\">\n <span className=\"inline-flex mr-1\">\n <TokenImage\n src={row?.ft?.icon}\n alt={row?.ft?.name}\n className=\"w-4 h-4\"\n appUrl={config?.appUrl}\n />\n </span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-nearblue-600 max-w-[110px] inline-block truncate whitespace-nowrap\">\n <a\n href={`/token/${row?.ft?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.ft?.name}\n </a>\n </a>\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.ft?.name}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n {row?.ft?.symbol && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-gray-400 max-w-[80px] inline-block truncate whitespace-nowrap\">\n &nbsp; {row?.ft?.symbol}\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {row?.ft?.symbol}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n )}\n </div>\n )\n );\n },\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <div className=\"w-full inline-flex px-5 py-4\">\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n onClick={toggleShowAge}\n className=\"text-left text-xs w-full flex items-center font-semibold uppercase tracking-wider text-green-500 focus:outline-none whitespace-nowrap\"\n >\n {showAge\n ? t\n ? t('token:fts.age')\n : 'AGE'\n : t\n ? t('token:fts.ageDT')\n : 'DATE TIME (UTC)'}\n {showAge && <Clock className=\"text-green-500 ml-2\" />}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"center\"\n side=\"top\"\n >\n {showAge\n ? 'Click to show Datetime Format'\n : 'Click to show Age Format'}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </div>\n ),\n key: 'block_timestamp',\n cell: (row) => (\n <span>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {!showAge\n ? row?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(row?.block_timestamp),\n )\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Content\n className=\"h-auto max-w-xs bg-black bg-opacity-90 z-10 text-xs text-white px-3 py-2 break-words\"\n align=\"start\"\n side=\"bottom\"\n >\n {showAge\n ? row?.block_timestamp\n ? formatTimestampToString(nanoToMilli(row?.block_timestamp))\n : ''\n : row?.block_timestamp\n ? getTimeAgoString(nanoToMilli(row?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName: 'inline-flex whitespace-nowrap',\n },\n ];\n\n return (\n <>\n <div className=\"bg-white border soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"max-w-lg w-full pl-3 py-5\">\n <Skeleton className=\"h-4\" />\n </div>\n ) : (\n <div className={`flex flex-col lg:flex-row pt-4`}>\n <div className=\"flex flex-col\">\n <p className=\"leading-7 px-6 text-sm mb-4 text-nearblue-600\">\n A total of {localFormat(totalCount.toString())} transactions\n found\n </p>\n </div>\n </div>\n )}\n <Widget\n src={`${config?.ownerId}/widget/bos-components.components.Shared.Table`}\n props={{\n columns: columns,\n data: tokens[currentPage],\n isLoading: isLoading,\n isPagination: true,\n count: totalCount,\n page: currentPage,\n limit: 25,\n pageLimit: 200,\n setPage: setPage,\n Error: errorMessage,\n }}\n />\n </div>\n </>\n );\n}\n\nreturn MainComponent(props, context);" } } } } }
Result:
{ "block_height": "114606652" }
No logs
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.17941  to nearblocks.near
Empty result
No logs