Search
Search

Transaction: 3HaqBuP...PPSr

Receiver
Status
Succeeded
Transaction Fee
0.00616 
Deposit Value
0 
Gas Used
61 Tgas
Attached Gas
300 Tgas
Created
March 11, 2024 at 8:19:10am
Hash
3HaqBuPwNae89MKK2mTUQxSmcGcNkr2LfrhqUKcFPPSr

Actions

Called method: 'set' in contract: social.near
Arguments:
{ "data": { "nearblocks.near": { "widget": { "bos-components.components.Address.AccessKeyRow": { "": "/**\n * Component: AddressAccessKeyRow\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Address Access key Row on Near Protocol.\n * @interface\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 {AccountContractInfo} [accessKey] - Key-value pairs for Accesskey info\n * @param {boolean} [showWhen] - Controls whether to show the date and time in UTC format or as a time ago string.\n */\n\n\n\n\n\n\n\n\n\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/libs.jsx\" */\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 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\nfunction fiatValue(big, price) {\n const value = Big(big).mul(Big(price));\n const stringValue = value.toFixed(6); // Set the desired maximum fraction digits\n\n const [integerPart, fractionalPart] = stringValue.split('.');\n\n // Format integer part with commas\n const formattedIntegerPart = integerPart.replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n ',',\n );\n\n // Combine formatted integer and fractional parts\n const formattedNumber = fractionalPart\n ? `${formattedIntegerPart}.${fractionalPart}`\n : formattedIntegerPart;\n\n return formattedNumber;\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 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/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 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\nfunction MainComponent({ network, t, accessKey, showWhen }) {\n const [keyInfo, setKeyInfo] = useState({} );\n\n const config = getConfig(network);\n\n const createdTime = accessKey.created?.block_timestamp\n ? nanoToMilli(accessKey.created?.block_timestamp)\n : '';\n const deletedTime = accessKey.deleted?.block_timestamp\n ? nanoToMilli(accessKey.deleted?.block_timestamp)\n : '';\n\n const txn = createdTime > deletedTime ? accessKey.created : accessKey.deleted;\n\n const action =\n accessKey.deleted?.transaction_hash && createdTime <= deletedTime\n ? 'Deleted'\n : 'Created';\n\n function showMethod(method) {\n switch (method) {\n case 'CREATE_ACCOUNT':\n case 'CreateAccount':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('createAccount')}\n </div>\n );\n case 'DEPLOY_CONTRACT':\n case 'DeployContract':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('deployContract')}\n </div>\n );\n case 'TRANSFER':\n case 'Transfer':\n return (\n <div className=\"bg-emerald-50 px-1 py-1 flex justify-center items-center text-xs\">\n {t('transfer')}\n </div>\n );\n case 'STAKE':\n case 'Stake':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('stake')}\n </div>\n );\n case 'ADD_KEY':\n case 'AddKey':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n Acces Key Created\n </div>\n );\n case 'DELETE_KEY':\n case 'DeleteKey':\n return (\n <div className=\"bg-red-50 px-1 py-1 flex justify-center items-center text-xs\">\n Acces Key Deleted\n </div>\n );\n case 'DELETE_ACCOUNT':\n case 'DeleteAccount':\n return (\n <div className=\"bg-red-50 px-1 py-1 flex justify-center items-center text-xs\">\n {t('deleteAccount')}\n </div>\n );\n\n default:\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {capitalizeWords(method)}\n </div>\n );\n }\n }\n\n useEffect(() => {\n function tokenInfo(view_access_key, 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: 'view_access_key',\n finality: 'final',\n account_id: view_access_key,\n public_key: account_id,\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((data) => {\n const resp = data?.body?.result;\n if (data.status === 200) {\n setKeyInfo(resp);\n } else {\n handleRateLimit(data, () => tokenInfo(view_access_key, account_id));\n }\n })\n .catch(() => {});\n }\n\n if (accessKey.public_key && accessKey.permission_kind === 'FUNCTION_CALL') {\n tokenInfo(accessKey.account_id, accessKey.public_key);\n }\n }, [config?.rpcUrl, accessKey]);\n\n return (\n <>\n <tr key={accessKey.public_key} className=\"hover:bg-blue-900/5\">\n <td className=\"px-6 py-4 text-sm text-nearblue-600 \">\n {txn?.transaction_hash ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 font-medium whitespace-nowrap\">\n <a href={`/txns/${txn?.transaction_hash}`}>\n <a className=\"text-green-500\">\n {txn?.transaction_hash && txn?.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-white text-xs p-2 break-words\"\n sideOffset={5}\n >\n {txn?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'Genesis'\n )}\n </td>\n <td className=\"pl-6 pr-2 py-4 text-sm text-nearblue-600 \">\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom \">\n {accessKey.public_key}\n </span>\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 break-words\"\n sideOffset={5}\n >\n {accessKey.public_key}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-start\">\n {accessKey.permission_kind === 'FUNCTION_CALL' ? (\n <div className=\"bg-blue-900/10 rounded px-4 h-6 flex items-center justify-center text-center text-xs\">\n Limited\n </div>\n ) : (\n <div className=\"bg-blue-900/10 rounded px-4 h-6 flex items-center justify-center text-center text-xs\">\n Full\n </div>\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {keyInfo &&\n Object.keys(keyInfo).length !== 0 &&\n keyInfo?.permission?.FunctionCall?.receiver_id}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-start \">\n {keyInfo && keyInfo?.permission && (\n <div className=\"flex flex-col \">\n {keyInfo?.permission?.FunctionCall?.method_names.length > 0\n ? keyInfo?.permission?.FunctionCall?.method_names.map(\n (method) => {\n return <div key={method}>{showMethod(method)} </div>;\n },\n )\n : accessKey.permission_kind === 'FUNCTION_CALL'\n ? 'Any'\n : 'Full Access'}\n </div>\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {Object.keys(keyInfo).length !== 0 &&\n keyInfo?.permission?.FunctionCall?.allowance &&\n 'Ⓝ ' +\n yoctoToNear(\n keyInfo?.permission?.FunctionCall?.allowance || '',\n true,\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {action}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {txn?.block_timestamp ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {showWhen\n ? txn?.block_timestamp\n ? getTimeAgoString(nanoToMilli(txn?.block_timestamp))\n : ''\n : txn?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(txn?.block_timestamp),\n )\n : ''}\n </span>\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={5}\n >\n {!showWhen\n ? txn?.block_timestamp\n ? getTimeAgoString(nanoToMilli(txn?.block_timestamp))\n : ''\n : txn?.block_timestamp\n ? formatTimestampToString(nanoToMilli(txn?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'Genesis'\n )}\n </td>\n </tr>\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.NFTTransactions": { "": "/**\n * Component: AddressNFTTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: NFT Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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: \"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 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 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 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}\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}\n/* END_INCLUDE: \"includes/libs.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 COMPONENT: \"includes/Common/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.jsx\" */\n\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/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/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/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/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 COMPONENT: \"includes/icons/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.jsx\" */\n\nfunction MainComponent(props) {\n const { network, t, id, filters, handleFilter, onFilterClear } = props;\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [showAge, setShowAge] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [address, setAddress] = useState('');\n\n const [sorting, setSorting] = useState('desc');\n const errorMessage = t ? t('txns:noTxns') : ' No transactions found!';\n\n const config = getConfig(network);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/nft-txns/count?${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsData(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/nft-txns?${queryParams}order=${sqs}&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) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTxns({});\n }\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTxnsData(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n })\n .catch(() => {});\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 if (urlString && sorting) {\n fetchTotalTxns(urlString);\n fetchTxnsData(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTxns();\n fetchTxnsData('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n handleFilter(name, filterValue);\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\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: <>{t ? t('txns:hash') : 'TXN HASH'}</>,\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 whitespace-nowrap',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"event\"\n value={filters ? filters?.event : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'event')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('method')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'cause',\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 },\n {\n header: <>Affected</>,\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=\"start\"\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 <>\n {row.involved_account_id === row.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : Number(row?.delta_amount) < 0 ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n )}\n </>\n ),\n tdClassName: 'text-center',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n Involved\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"involved\"\n value={filters ? filters?.involved : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'involved')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"involved\"\n type=\"button\"\n onClick={() => onClear('involved')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'involved_account_id',\n cell: (row) => (\n <>\n {row.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\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 row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-1'\n }`}\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 </>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n },\n {\n header: <>Token ID</>,\n key: 'token_id',\n cell: (row) => (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <a\n href={`/nft-token/${row?.nft?.contract}/${row?.token_id}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.token_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?.token_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ),\n tdClassName:\n 'px-5 py-4 text-sm text-nearblue-600 max-w-[110px] inline-block truncate',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <>Token</>,\n key: 'block_height',\n cell: (row) => {\n return (\n row?.nft && (\n <div className=\"flex flex-row items-center\">\n <span className=\"inline-flex mr-1\">\n <TokenImage\n src={row?.nft?.icon}\n alt={row?.nft?.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={`/nft-token/${row?.nft?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.nft?.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?.nft?.name}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n {row?.nft?.symbol && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-nearblue-700 max-w-[80px] inline-block truncate whitespace-nowrap\">\n &nbsp; {row?.nft?.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?.nft?.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 ',\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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 pl-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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/nft-token/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\n </div>\n </div>\n )}\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 </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.TokenTransactions": { "": "/**\n * Component: AddressTokenTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Tokens Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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/* INCLUDE COMPONENT: \"includes/Common/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.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 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/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.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/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({\n network,\n t,\n id,\n filters,\n handleFilter,\n onFilterClear,\n}) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [showAge, setShowAge] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const errorMessage = t ? t('txns:noTxns') : 'No transactions found!';\n const [tokens, setTokens] = useState(\n {},\n );\n const [sorting, setSorting] = useState('desc');\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n function fetchTotalTokens(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/ft-txns/count?${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count | 0);\n } else {\n handleRateLimit(data, () => fetchTotalTokens(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTokens(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/ft-txns?${queryParams}order=${sqs}&page=${page}&per_page=25`,\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?.txns;\n if (data.status === 200) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTokens({});\n }\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 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 if (urlString && sorting) {\n fetchTotalTokens(urlString);\n fetchTokens(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n handleFilter(name, filterValue);\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\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: <>{t ? t('txns:hash') : 'TXN HASH'}</>,\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 whitespace-nowrap',\n },\n {\n header: (\n <>\n {' '}\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"event\"\n value={filters ? filters?.event : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'event')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('method')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n </>\n ),\n key: 'cause',\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 },\n {\n header: <>Affected</>,\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 whitespace-nowrap',\n },\n {\n header: '',\n key: '',\n cell: (row) => (\n <>\n {row.involved_account_id === row.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : Number(row?.delta_amount) < 0 ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n )}\n </>\n ),\n tdClassName: 'text-center',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n Involved\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"involved\"\n value={filters ? filters?.involved : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'involved')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"involved\"\n type=\"button\"\n onClick={() => onClear('involved')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\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 },\n {\n header: <>Quantity</>,\n key: 'block_height',\n cell: (row) => (\n <span>\n {Number(row?.delta_amount) > 0 ? (\n <div className=\"text-neargreen flex flex-row items-center\">\n {'+' +\n localFormat(\n tokenAmount(row?.delta_amount, row?.ft?.decimals, true),\n )}\n </div>\n ) : (\n <div className=\"text-red-500 flex flex-row items-center\">\n {row?.delta_amount\n ? localFormat(\n tokenAmount(row?.delta_amount, row?.ft?.decimals, true),\n )\n : ''}\n </div>\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 whitespace-nowrap',\n },\n {\n header: <>Token</>,\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-nearblue-700 max-w-[80px] inline-block truncate\">\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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 pl-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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/token/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\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\nreturn MainComponent(props, context);" }, "bos-components.components.Address.Transactions": { "": "/**\n * Component: AddressTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.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 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/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.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: \"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 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 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 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\nfunction fiatValue(big, price) {\n const value = Big(big).mul(Big(price));\n const stringValue = value.toFixed(6); // Set the desired maximum fraction digits\n\n const [integerPart, fractionalPart] = stringValue.split('.');\n\n // Format integer part with commas\n const formattedIntegerPart = integerPart.replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n ',',\n );\n\n // Combine formatted integer and fractional parts\n const formattedNumber = fractionalPart\n ? `${formattedIntegerPart}.${fractionalPart}`\n : formattedIntegerPart;\n\n return formattedNumber;\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 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 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 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\nfunction MainComponent({\n network,\n t,\n id,\n filters,\n handleFilter,\n onFilterClear,\n}) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [showAge, setShowAge] = useState(true);\n const [sorting, setSorting] = useState('desc');\n const [currentPage, setCurrentPage] = useState(1);\n const errorMessage = t ? t('txns:noTxns') : ' No transactions found!';\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/txns/count${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsData(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/txns?${queryParams}order=${sqs}&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) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTxns({});\n }\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTxnsData(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n })\n .catch(() => {});\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 if (urlString && sorting) {\n fetchTotalTxns(urlString);\n fetchTxnsData(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTxns();\n fetchTxnsData('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n // Do something with the value if needed\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n if (name === 'type') {\n if (isAction(filterValue)) {\n handleFilter('action', filterValue);\n } else {\n handleFilter('method', filterValue);\n }\n } else {\n handleFilter(name, filterValue);\n }\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\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('txns:hash') : 'TXN 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 whitespace-nowrap text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"type\"\n value={filters ? filters?.action || filters?.method : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'type')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('type')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\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\">\n {txnMethod(row.actions, t)}\n </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 {txnMethod(row.actions, t)}\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 header: <span>{t ? t('txns:depositValue') : 'DEPOSIT VALUE'}</span>,\n key: 'deposit',\n cell: (row) => (\n <span>\n {row.actions_agg?.deposit\n ? yoctoToNear(row.actions_agg?.deposit, true)\n : row.actions_agg?.deposit ?? ''}{' '}\n Ⓝ\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 whitespace-nowrap',\n },\n {\n header: <span>{t ? t('txns:txnFee') : 'TXN FEE'}</span>,\n key: 'transaction_fee',\n cell: (row) => (\n <span>\n {row.outcomes_agg?.transaction_fee\n ? yoctoToNear(row.outcomes_agg?.transaction_fee, true)\n : ''}{' '}\n Ⓝ\n </span>\n ),\n tdClassName: 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left whitespace-nowrap text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:from') : 'FROM'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"from\"\n value={filters ? filters?.from : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'from')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"from\"\n type=\"button\"\n onClick={() => onClear('from')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'predecessor_account_id',\n cell: (row) => (\n <span>\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?.predecessor_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.predecessor_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?.predecessor_account_id)\n }\n >\n {row.predecessor_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.predecessor_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n },\n {\n header: <span></span>,\n key: '',\n cell: (row) => {\n return row.predecessor_account_id === row.receiver_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : id === row.predecessor_account_id ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n );\n },\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:to') : 'To'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"to\"\n value={filters ? filters?.to : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'to')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"to\"\n type=\"button\"\n onClick={() => onClear('to')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'receiver_account_id',\n cell: (row) => (\n <span>\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?.receiver_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.receiver_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?.receiver_account_id)\n }\n >\n {row.receiver_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.receiver_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n },\n {\n header: <span>{t ? t('txns:blockHeight') : ' BLOCK HEIGHT'}</span>,\n key: 'block_height',\n cell: (row) => (\n <span>\n <a\n href={`/blocks/${row.included_in_block_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 hover:no-underline\">\n {row.block?.block_height\n ? localFormat(row.block?.block_height)\n : ''}\n </a>\n </a>\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 whitespace-nowrap',\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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-3 text-sm mb-4 text-nearblue-600\">\n A total of {totalCount ? localFormat(totalCount.toString()) : 0}{' '}\n 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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\n </div>\n </div>\n )}\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 </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.AccessKeys": { "": "/**\n * Component: AddressAccessKeys\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Table of Accesskey 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 account identifier passed as a string.\n */\n\n\n\n\n\n\n\n\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 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/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/Paginator.jsx\" */\nconst FaChevronLeft = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n className=\"bi bi-chevron-left\"\n viewBox=\"0 0 16 16\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"\n />\n </svg>\n );\n};\nconst FaChevronRight = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n className=\"bi bi-chevron-right\"\n viewBox=\"0 0 16 16\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"\n />\n </svg>\n );\n};\n\n\n\n\n\n\n\n\nconst Paginator = (props) => {\n let pages;\n if (props.count) {\n pages = Math.ceil(props.count / props.limit);\n } else {\n pages = 1;\n }\n pages = pages > props.pageLimit ? props.pageLimit : pages;\n const onPrev = () => {\n if (props.page <= 1) return null;\n\n const newPage = (props.page || 1) - 1;\n props.setPage(newPage);\n return;\n };\n const onNext = () => {\n if (props.page >= pages) return null;\n\n const newPage = (props.page || 1) + 1;\n props.setPage(newPage);\n return;\n };\n const onFirst = () => props.setPage(1);\n const onLast = () => props.setPage(pages);\n\n return (\n <div className=\"bg-white px-2 py-3 flex items-center justify-between border-t md:px-4\">\n <div className=\"flex-1 flex items-center justify-between\">\n <div></div>\n\n <div>\n <div\n className=\"relative z-0 inline-flex rounded-md\"\n aria-label=\"Pagination\"\n >\n <button\n type=\"button\"\n disabled={props.page <= 1 || pages === 1}\n onClick={onFirst}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium rounded-md ${\n props.page <= 1\n ? 'text-gray-500'\n : 'text-green-400 hover:bg-green-400 hover:text-white'\n } bg-gray-100`}\n >\n First\n </button>\n <button\n type=\"button\"\n disabled={props.page <= 1 || pages === 1}\n onClick={onPrev}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 font-medium ${\n props.page <= 1\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } rounded-md bg-gray-100`}\n >\n <FaChevronLeft />\n </button>\n <button\n type=\"button\"\n disabled\n className=\"relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium text-gray-500 rounded-md bg-gray-100\"\n >\n Page {props.page} of {pages}\n </button>\n <button\n type=\"button\"\n disabled={props.page >= pages || pages === 1}\n onClick={onNext}\n className={`relative inline-flex items-center ml-1 px-2 md:px-3 py-2 rounded-md font-medium ${\n props.page >= pages\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } bg-gray-100`}\n >\n <FaChevronRight />\n </button>\n <button\n type=\"button\"\n disabled={props.page >= pages || pages === 1}\n onClick={onLast}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium rounded-md ${\n props.page >= pages\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } bg-gray-100 `}\n >\n Last\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Paginator.jsx\" */\n\nfunction MainComponent({ network, t, id }) {\n const [isLoading, setIsLoading] = useState(false);\n const [showWhen, setShowWhen] = useState(true);\n const [sorting, setSorting] = useState('desc');\n const [count, setCount] = useState(0);\n const [keys, Setkeys] = useState([]);\n\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n\n const config = getConfig(network);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n const toggleShowWhen = () => setShowWhen((s) => !s);\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\n\n useEffect(() => {\n setIsLoading(true);\n function fetchAccountData() {\n asyncFetch(\n `${config?.backendUrl}account/${id}/keys?order=${sorting}&page=${currentPage}&per_page=25`,\n )\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.keys;\n if (data.status === 200) {\n Setkeys(resp);\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchAccountData(),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchCountData() {\n asyncFetch(`${config?.backendUrl}account/${id}/keys/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.keys?.[0]?.count || 0;\n if (data.status === 200) {\n setCount(resp);\n } else {\n handleRateLimit(data, fetchCountData);\n }\n },\n )\n .catch(() => {});\n }\n fetchAccountData();\n fetchCountData();\n }, [config?.backendUrl, id, currentPage, sorting]);\n\n return (\n <>\n <div className=\"overflow-x-auto \">\n <table className=\"min-w-full divide-y border-t\">\n <thead className=\"bg-gray-100\">\n <tr>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Txn Hash\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Public key\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Access\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Contract\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Method\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Allowance\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Action\n </th>\n <th scope=\"col\" className=\"text-left\">\n <div className=\"w-full inline-flex px-5 py-4\">\n <button\n type=\"button\"\n onClick={toggleShowWhen}\n className=\"text-left text-xs w-full font-semibold uppercase tracking-wider text-nearblue-600 focus:outline-none\"\n >\n {showWhen ? 'When' : 'Date Time (UTC)'}\n </button>\n <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\n </div>\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white divide-y divide-gray-200\">\n {isLoading &&\n [...Array(25)].map((_, i) => (\n <tr key={i} className=\"hover:bg-blue-900/5 h-[57px]\">\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-tiny \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n </tr>\n ))}\n {!isLoading && keys.length === 0 && (\n <tr className=\"h-[57px]\">\n <td\n colSpan={100}\n className=\"px-6 py-4 text-nearblue-700 text-xs\"\n >\n No access keys\n </td>\n </tr>\n )}\n {keys &&\n keys.map((key) => (\n <Widget\n key={key.account_id + key.public_key}\n src={`${config.ownerId}/widget/bos-components.components.Address.AccessKeyRow`}\n props={{\n network: network,\n t: t,\n accessKey: key,\n showWhen: showWhen,\n }}\n />\n ))}\n </tbody>\n </table>\n </div>\n <Paginator\n count={count}\n page={currentPage}\n limit={25}\n pageLimit={200}\n setPage={setPage}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" } } } } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
3 Tgas
Tokens Burned:
0.00031 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
58 Tgas
Tokens Burned:
0.00585 
Called method: 'set' in contract: social.near
Arguments:
{ "data": { "nearblocks.near": { "widget": { "bos-components.components.Address.AccessKeyRow": { "": "/**\n * Component: AddressAccessKeyRow\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Address Access key Row on Near Protocol.\n * @interface\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 {AccountContractInfo} [accessKey] - Key-value pairs for Accesskey info\n * @param {boolean} [showWhen] - Controls whether to show the date and time in UTC format or as a time ago string.\n */\n\n\n\n\n\n\n\n\n\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/libs.jsx\" */\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 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\nfunction fiatValue(big, price) {\n const value = Big(big).mul(Big(price));\n const stringValue = value.toFixed(6); // Set the desired maximum fraction digits\n\n const [integerPart, fractionalPart] = stringValue.split('.');\n\n // Format integer part with commas\n const formattedIntegerPart = integerPart.replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n ',',\n );\n\n // Combine formatted integer and fractional parts\n const formattedNumber = fractionalPart\n ? `${formattedIntegerPart}.${fractionalPart}`\n : formattedIntegerPart;\n\n return formattedNumber;\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 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/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 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\nfunction MainComponent({ network, t, accessKey, showWhen }) {\n const [keyInfo, setKeyInfo] = useState({} );\n\n const config = getConfig(network);\n\n const createdTime = accessKey.created?.block_timestamp\n ? nanoToMilli(accessKey.created?.block_timestamp)\n : '';\n const deletedTime = accessKey.deleted?.block_timestamp\n ? nanoToMilli(accessKey.deleted?.block_timestamp)\n : '';\n\n const txn = createdTime > deletedTime ? accessKey.created : accessKey.deleted;\n\n const action =\n accessKey.deleted?.transaction_hash && createdTime <= deletedTime\n ? 'Deleted'\n : 'Created';\n\n function showMethod(method) {\n switch (method) {\n case 'CREATE_ACCOUNT':\n case 'CreateAccount':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('createAccount')}\n </div>\n );\n case 'DEPLOY_CONTRACT':\n case 'DeployContract':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('deployContract')}\n </div>\n );\n case 'TRANSFER':\n case 'Transfer':\n return (\n <div className=\"bg-emerald-50 px-1 py-1 flex justify-center items-center text-xs\">\n {t('transfer')}\n </div>\n );\n case 'STAKE':\n case 'Stake':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {t('stake')}\n </div>\n );\n case 'ADD_KEY':\n case 'AddKey':\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n Acces Key Created\n </div>\n );\n case 'DELETE_KEY':\n case 'DeleteKey':\n return (\n <div className=\"bg-red-50 px-1 py-1 flex justify-center items-center text-xs\">\n Acces Key Deleted\n </div>\n );\n case 'DELETE_ACCOUNT':\n case 'DeleteAccount':\n return (\n <div className=\"bg-red-50 px-1 py-1 flex justify-center items-center text-xs\">\n {t('deleteAccount')}\n </div>\n );\n\n default:\n return (\n <div className=\"px-1 py-1 flex justify-center items-center text-xs\">\n {capitalizeWords(method)}\n </div>\n );\n }\n }\n\n useEffect(() => {\n function tokenInfo(view_access_key, 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: 'view_access_key',\n finality: 'final',\n account_id: view_access_key,\n public_key: account_id,\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then((data) => {\n const resp = data?.body?.result;\n if (data.status === 200) {\n setKeyInfo(resp);\n } else {\n handleRateLimit(data, () => tokenInfo(view_access_key, account_id));\n }\n })\n .catch(() => {});\n }\n\n if (accessKey.public_key && accessKey.permission_kind === 'FUNCTION_CALL') {\n tokenInfo(accessKey.account_id, accessKey.public_key);\n }\n }, [config?.rpcUrl, accessKey]);\n\n return (\n <>\n <tr key={accessKey.public_key} className=\"hover:bg-blue-900/5\">\n <td className=\"px-6 py-4 text-sm text-nearblue-600 \">\n {txn?.transaction_hash ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom text-green-500 font-medium whitespace-nowrap\">\n <a href={`/txns/${txn?.transaction_hash}`}>\n <a className=\"text-green-500\">\n {txn?.transaction_hash && txn?.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-white text-xs p-2 break-words\"\n sideOffset={5}\n >\n {txn?.transaction_hash}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'Genesis'\n )}\n </td>\n <td className=\"pl-6 pr-2 py-4 text-sm text-nearblue-600 \">\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span className=\"truncate max-w-[120px] inline-block align-bottom \">\n {accessKey.public_key}\n </span>\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 break-words\"\n sideOffset={5}\n >\n {accessKey.public_key}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-start\">\n {accessKey.permission_kind === 'FUNCTION_CALL' ? (\n <div className=\"bg-blue-900/10 rounded px-4 h-6 flex items-center justify-center text-center text-xs\">\n Limited\n </div>\n ) : (\n <div className=\"bg-blue-900/10 rounded px-4 h-6 flex items-center justify-center text-center text-xs\">\n Full\n </div>\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {keyInfo &&\n Object.keys(keyInfo).length !== 0 &&\n keyInfo?.permission?.FunctionCall?.receiver_id}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 flex justify-start \">\n {keyInfo && keyInfo?.permission && (\n <div className=\"flex flex-col \">\n {keyInfo?.permission?.FunctionCall?.method_names.length > 0\n ? keyInfo?.permission?.FunctionCall?.method_names.map(\n (method) => {\n return <div key={method}>{showMethod(method)} </div>;\n },\n )\n : accessKey.permission_kind === 'FUNCTION_CALL'\n ? 'Any'\n : 'Full Access'}\n </div>\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {Object.keys(keyInfo).length !== 0 &&\n keyInfo?.permission?.FunctionCall?.allowance &&\n 'Ⓝ ' +\n yoctoToNear(\n keyInfo?.permission?.FunctionCall?.allowance || '',\n true,\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {action}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n {txn?.block_timestamp ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n {showWhen\n ? txn?.block_timestamp\n ? getTimeAgoString(nanoToMilli(txn?.block_timestamp))\n : ''\n : txn?.block_timestamp\n ? formatTimestampToString(\n nanoToMilli(txn?.block_timestamp),\n )\n : ''}\n </span>\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={5}\n >\n {!showWhen\n ? txn?.block_timestamp\n ? getTimeAgoString(nanoToMilli(txn?.block_timestamp))\n : ''\n : txn?.block_timestamp\n ? formatTimestampToString(nanoToMilli(txn?.block_timestamp))\n : ''}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ) : (\n 'Genesis'\n )}\n </td>\n </tr>\n </>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.NFTTransactions": { "": "/**\n * Component: AddressNFTTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: NFT Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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: \"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 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 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 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}\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}\n/* END_INCLUDE: \"includes/libs.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 COMPONENT: \"includes/Common/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.jsx\" */\n\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/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/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/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/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 COMPONENT: \"includes/icons/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.jsx\" */\n\nfunction MainComponent(props) {\n const { network, t, id, filters, handleFilter, onFilterClear } = props;\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [showAge, setShowAge] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const [address, setAddress] = useState('');\n\n const [sorting, setSorting] = useState('desc');\n const errorMessage = t ? t('txns:noTxns') : ' No transactions found!';\n\n const config = getConfig(network);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/nft-txns/count?${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsData(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/nft-txns?${queryParams}order=${sqs}&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) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTxns({});\n }\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTxnsData(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n })\n .catch(() => {});\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 if (urlString && sorting) {\n fetchTotalTxns(urlString);\n fetchTxnsData(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTxns();\n fetchTxnsData('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n handleFilter(name, filterValue);\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\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: <>{t ? t('txns:hash') : 'TXN HASH'}</>,\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 whitespace-nowrap',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"event\"\n value={filters ? filters?.event : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'event')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('method')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'cause',\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 },\n {\n header: <>Affected</>,\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=\"start\"\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 <>\n {row.involved_account_id === row.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : Number(row?.delta_amount) < 0 ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n )}\n </>\n ),\n tdClassName: 'text-center',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n Involved\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"involved\"\n value={filters ? filters?.involved : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'involved')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"involved\"\n type=\"button\"\n onClick={() => onClear('involved')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'involved_account_id',\n cell: (row) => (\n <>\n {row.involved_account_id ? (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\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 row?.involved_account_id === address\n ? ' rounded-md bg-[#FFC10740] border-[#FFC10740] border border-dashed p-1 -m-[1px] cursor-pointer text-[#033F40]'\n : 'text-green-500 p-1'\n }`}\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 </>\n ),\n tdClassName:\n 'px-5 py-4 whitespace-nowrap text-sm text-nearblue-600 font-medium',\n },\n {\n header: <>Token ID</>,\n key: 'token_id',\n cell: (row) => (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <span>\n <a\n href={`/nft-token/${row?.nft?.contract}/${row?.token_id}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.token_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?.token_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n ),\n tdClassName:\n 'px-5 py-4 text-sm text-nearblue-600 max-w-[110px] inline-block truncate',\n thClassName:\n 'px-5 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: <>Token</>,\n key: 'block_height',\n cell: (row) => {\n return (\n row?.nft && (\n <div className=\"flex flex-row items-center\">\n <span className=\"inline-flex mr-1\">\n <TokenImage\n src={row?.nft?.icon}\n alt={row?.nft?.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={`/nft-token/${row?.nft?.contract}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 font-medium hover:no-underline\">\n {row?.nft?.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?.nft?.name}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n {row?.nft?.symbol && (\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <div className=\"text-sm text-nearblue-700 max-w-[80px] inline-block truncate whitespace-nowrap\">\n &nbsp; {row?.nft?.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?.nft?.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 ',\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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 pl-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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/nft-token/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\n </div>\n </div>\n )}\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 </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.TokenTransactions": { "": "/**\n * Component: AddressTokenTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Tokens Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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/* INCLUDE COMPONENT: \"includes/Common/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.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 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/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.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/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({\n network,\n t,\n id,\n filters,\n handleFilter,\n onFilterClear,\n}) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [showAge, setShowAge] = useState(true);\n const [currentPage, setCurrentPage] = useState(1);\n const errorMessage = t ? t('txns:noTxns') : 'No transactions found!';\n const [tokens, setTokens] = useState(\n {},\n );\n const [sorting, setSorting] = useState('desc');\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n function fetchTotalTokens(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/ft-txns/count?${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count | 0);\n } else {\n handleRateLimit(data, () => fetchTotalTokens(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTokens(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/ft-txns?${queryParams}order=${sqs}&page=${page}&per_page=25`,\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?.txns;\n if (data.status === 200) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTokens((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTokens({});\n }\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 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 if (urlString && sorting) {\n fetchTotalTokens(urlString);\n fetchTokens(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTokens();\n fetchTokens('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n handleFilter(name, filterValue);\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\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: <>{t ? t('txns:hash') : 'TXN HASH'}</>,\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 whitespace-nowrap',\n },\n {\n header: (\n <>\n {' '}\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"event\"\n value={filters ? filters?.event : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'event')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('method')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n </>\n ),\n key: 'cause',\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 },\n {\n header: <>Affected</>,\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 whitespace-nowrap',\n },\n {\n header: '',\n key: '',\n cell: (row) => (\n <>\n {row.involved_account_id === row.affected_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : Number(row?.delta_amount) < 0 ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n )}\n </>\n ),\n tdClassName: 'text-center',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n Involved\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"involved\"\n value={filters ? filters?.involved : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'involved')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"involved\"\n type=\"button\"\n onClick={() => onClear('involved')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\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 },\n {\n header: <>Quantity</>,\n key: 'block_height',\n cell: (row) => (\n <span>\n {Number(row?.delta_amount) > 0 ? (\n <div className=\"text-neargreen flex flex-row items-center\">\n {'+' +\n localFormat(\n tokenAmount(row?.delta_amount, row?.ft?.decimals, true),\n )}\n </div>\n ) : (\n <div className=\"text-red-500 flex flex-row items-center\">\n {row?.delta_amount\n ? localFormat(\n tokenAmount(row?.delta_amount, row?.ft?.decimals, true),\n )\n : ''}\n </div>\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 whitespace-nowrap',\n },\n {\n header: <>Token</>,\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-nearblue-700 max-w-[80px] inline-block truncate\">\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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 pl-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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/token/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\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\nreturn MainComponent(props, context);" }, "bos-components.components.Address.Transactions": { "": "/**\n * Component: AddressTransactions\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Transactions of address 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 account 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} [handleFilter] - Function to handle filter changes. (Optional)\n * Example: handleFilter={handlePageFilter} where handlePageFilter is a function to filter the page.\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/Filter.jsx\" */\nconst Filter = (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=\"M14 14v6l-4 2v-8L4 5V3h16v2l-6 9zM6.404 5L12 13.394 17.596 5H6.404z\" />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Filter.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 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/Download.jsx\" */\nconst Download = () => {\n return (\n <svg\n width=\"11\"\n height=\"12\"\n viewBox=\"0 0 11 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M10.5418 12V2H6.87516V3H9.62516V11H1.37516V3H4.12516V2H0.458496V12H10.5418ZM5.04183 5.5H3.2085L5.50016 8.5L7.79183 5.5H5.9585V0H5.04183V5.5Z\"\n fill=\"#4b5563\"\n />\n </svg>\n );\n};/* END_INCLUDE COMPONENT: \"includes/icons/Download.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: \"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 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 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 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\nfunction fiatValue(big, price) {\n const value = Big(big).mul(Big(price));\n const stringValue = value.toFixed(6); // Set the desired maximum fraction digits\n\n const [integerPart, fractionalPart] = stringValue.split('.');\n\n // Format integer part with commas\n const formattedIntegerPart = integerPart.replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n ',',\n );\n\n // Combine formatted integer and fractional parts\n const formattedNumber = fractionalPart\n ? `${formattedIntegerPart}.${fractionalPart}`\n : formattedIntegerPart;\n\n return formattedNumber;\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 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 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 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\nfunction MainComponent({\n network,\n t,\n id,\n filters,\n handleFilter,\n onFilterClear,\n}) {\n const [isLoading, setIsLoading] = useState(false);\n const [totalCount, setTotalCount] = useState(0);\n const [txns, setTxns] = useState({});\n const [showAge, setShowAge] = useState(true);\n const [sorting, setSorting] = useState('desc');\n const [currentPage, setCurrentPage] = useState(1);\n const errorMessage = t ? t('txns:noTxns') : ' No transactions found!';\n const [address, setAddress] = useState('');\n\n const config = getConfig(network);\n\n const toggleShowAge = () => setShowAge((s) => !s);\n\n useEffect(() => {\n function fetchTotalTxns(qs) {\n const queryParams = qs ? '?' + qs : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/txns/count${queryParams}`,\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?.txns?.[0];\n if (data.status === 200) {\n setTotalCount(resp?.count ?? 0);\n } else {\n handleRateLimit(data, () => fetchTotalTxns(qs));\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchTxnsData(qs, sqs, page) {\n setIsLoading(true);\n const queryParams = qs ? qs + '&' : '';\n asyncFetch(\n `${config?.backendUrl}account/${id}/txns?${queryParams}order=${sqs}&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) {\n if (Array.isArray(resp) && resp.length > 0) {\n setTxns((prevData) => ({ ...prevData, [page]: resp || [] }));\n } else if (resp.length === 0) {\n setTxns({});\n }\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchTxnsData(qs, sorting, page),\n () => setIsLoading(false),\n );\n }\n })\n .catch(() => {});\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 if (urlString && sorting) {\n fetchTotalTxns(urlString);\n fetchTxnsData(urlString, sorting, currentPage);\n } else if (sorting && (!filters || Object.keys(filters).length === 0)) {\n fetchTotalTxns();\n fetchTxnsData('', sorting, currentPage);\n }\n }, [config?.backendUrl, id, currentPage, filters, sorting]);\n\n let filterValue;\n const onInputChange = (event) => {\n filterValue = event.target.value;\n // Do something with the value if needed\n };\n\n const onFilter = (\n e,\n name,\n ) => {\n e.preventDefault();\n\n if (filterValue !== null && filterValue !== undefined) {\n if (name === 'type') {\n if (isAction(filterValue)) {\n handleFilter('action', filterValue);\n } else {\n handleFilter('method', filterValue);\n }\n } else {\n handleFilter(name, filterValue);\n }\n }\n };\n\n const onClear = (name) => {\n if (onFilterClear && filters) {\n onFilterClear(name);\n }\n };\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\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('txns:hash') : 'TXN 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 whitespace-nowrap text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:type') : 'METHOD'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <div className=\"flex flex-col\">\n <input\n name=\"type\"\n value={filters ? filters?.action || filters?.method : ''}\n onChange={onInputChange}\n placeholder=\"Search by method\"\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'type')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"type\"\n type=\"button\"\n onClick={() => onClear('type')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\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\">\n {txnMethod(row.actions, t)}\n </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 {txnMethod(row.actions, t)}\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 header: <span>{t ? t('txns:depositValue') : 'DEPOSIT VALUE'}</span>,\n key: 'deposit',\n cell: (row) => (\n <span>\n {row.actions_agg?.deposit\n ? yoctoToNear(row.actions_agg?.deposit, true)\n : row.actions_agg?.deposit ?? ''}{' '}\n Ⓝ\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 whitespace-nowrap',\n },\n {\n header: <span>{t ? t('txns:txnFee') : 'TXN FEE'}</span>,\n key: 'transaction_fee',\n cell: (row) => (\n <span>\n {row.outcomes_agg?.transaction_fee\n ? yoctoToNear(row.outcomes_agg?.transaction_fee, true)\n : ''}{' '}\n Ⓝ\n </span>\n ),\n tdClassName: 'px-6 py-4 whitespace-nowrap text-sm text-nearblue-600',\n thClassName:\n 'px-5 py-4 text-left whitespace-nowrap text-xs font-semibold text-nearblue-600 uppercase tracking-wider',\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:from') : 'FROM'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"from\"\n value={filters ? filters?.from : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'from')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"from\"\n type=\"button\"\n onClick={() => onClear('from')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'predecessor_account_id',\n cell: (row) => (\n <span>\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?.predecessor_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.predecessor_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?.predecessor_account_id)\n }\n >\n {row.predecessor_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.predecessor_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n },\n {\n header: <span></span>,\n key: '',\n cell: (row) => {\n return row.predecessor_account_id === row.receiver_account_id ? (\n <span className=\"uppercase rounded w-10 py-2 h-6 flex items-center justify-center bg-green-200 text-white text-xs font-semibold\">\n {t ? t('txns:txnSelf') : 'SELF'}\n </span>\n ) : id === row.predecessor_account_id ? (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-yellow-100 text-yellow-700 text-xs font-semibold\">\n {t ? t('txns:txnOut') : 'OUT'}\n </span>\n ) : (\n <span className=\"uppercase rounded w-10 h-6 flex items-center justify-center bg-neargreen text-white text-xs font-semibold\">\n {t ? t('txns:txnIn') : 'IN'}\n </span>\n );\n },\n },\n {\n header: (\n <Popover.Root>\n <Popover.Trigger\n asChild\n className=\"flex items-center px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider focus:outline-none\"\n >\n <button className=\"IconButton\" aria-label=\"Update dimensions\">\n {t ? t('txns:to') : 'To'}\n <Filter className=\"h-4 w-4 fill-current ml-2\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"z-50 bg-white shadow-lg border rounded-b-lg p-2\"\n sideOffset={5}\n >\n <input\n name=\"to\"\n value={filters ? filters?.to : ''}\n onChange={onInputChange}\n placeholder={\n t ? t('txns:filter.placeholder') : 'Search by address e.g. Ⓝ..'\n }\n className=\"border rounded h-8 mb-2 px-2 text-nearblue-600 text-xs\"\n />\n <div className=\"flex\">\n <button\n type=\"submit\"\n onClick={(e) => onFilter(e, 'to')}\n className=\"flex items-center justify-center flex-1 rounded bg-green-500 h-7 text-white text-xs mr-2\"\n >\n <Filter className=\"h-3 w-3 fill-current mr-2\" />{' '}\n {t ? t('txns:filter.filter') : 'Filter'}\n </button>\n <button\n name=\"to\"\n type=\"button\"\n onClick={() => onClear('to')}\n className=\"flex-1 rounded bg-gray-300 text-xs h-7\"\n >\n {t ? t('txns:filter.clear') : 'Clear'}\n </button>\n </div>\n </Popover.Content>\n </Popover.Root>\n ),\n key: 'receiver_account_id',\n cell: (row) => (\n <span>\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?.receiver_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.receiver_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?.receiver_account_id)\n }\n >\n {row.receiver_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.receiver_account_id}\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </span>\n ),\n tdClassName: 'px-5 py-4 text-sm text-nearblue-600 font-medium',\n },\n {\n header: <span>{t ? t('txns:blockHeight') : ' BLOCK HEIGHT'}</span>,\n key: 'block_height',\n cell: (row) => (\n <span>\n <a\n href={`/blocks/${row.included_in_block_hash}`}\n className=\"hover:no-underline\"\n >\n <a className=\"text-green-500 hover:no-underline\">\n {row.block?.block_height\n ? localFormat(row.block?.block_height)\n : ''}\n </a>\n </a>\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 whitespace-nowrap',\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('txns:age')\n : 'AGE'\n : t\n ? t('txns: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 <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\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: 'whitespace-nowrap',\n },\n ];\n\n return (\n <div className=\"bg-white soft-shadow rounded-xl pb-1\">\n {isLoading ? (\n <div className=\"pl-6 max-w-lg w-full 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-3 text-sm mb-4 text-nearblue-600\">\n A total of {totalCount ? localFormat(totalCount.toString()) : 0}{' '}\n 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={onClear}\n />\n </span>\n </div>\n )}\n <span className=\"text-xs text-nearblue-600\">\n <a\n href={`/exportdata?address=${id}`}\n className=\"hover:no-underline\"\n target=\"_blank\"\n >\n <a\n target=\"_blank\"\n className=\"cursor-pointer mx-1 flex items-center text-nearblue-600 font-medium py-2 border border-neargray-700 px-4 rounded-md bg-white hover:bg-neargray-800 hover:no-underline\"\n >\n <p>CSV Export </p>\n <span className=\"ml-2\">\n <Download />\n </span>\n </a>\n </a>\n </span>\n </div>\n </div>\n )}\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 </div>\n );\n}\n\nreturn MainComponent(props, context);" }, "bos-components.components.Address.AccessKeys": { "": "/**\n * Component: AddressAccessKeys\n * Author: Nearblocks Pte Ltd\n * License: Business Source License 1.1\n * Description: Table of Accesskey 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 account identifier passed as a string.\n */\n\n\n\n\n\n\n\n\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 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/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/Paginator.jsx\" */\nconst FaChevronLeft = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n className=\"bi bi-chevron-left\"\n viewBox=\"0 0 16 16\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"\n />\n </svg>\n );\n};\nconst FaChevronRight = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n className=\"bi bi-chevron-right\"\n viewBox=\"0 0 16 16\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"\n />\n </svg>\n );\n};\n\n\n\n\n\n\n\n\nconst Paginator = (props) => {\n let pages;\n if (props.count) {\n pages = Math.ceil(props.count / props.limit);\n } else {\n pages = 1;\n }\n pages = pages > props.pageLimit ? props.pageLimit : pages;\n const onPrev = () => {\n if (props.page <= 1) return null;\n\n const newPage = (props.page || 1) - 1;\n props.setPage(newPage);\n return;\n };\n const onNext = () => {\n if (props.page >= pages) return null;\n\n const newPage = (props.page || 1) + 1;\n props.setPage(newPage);\n return;\n };\n const onFirst = () => props.setPage(1);\n const onLast = () => props.setPage(pages);\n\n return (\n <div className=\"bg-white px-2 py-3 flex items-center justify-between border-t md:px-4\">\n <div className=\"flex-1 flex items-center justify-between\">\n <div></div>\n\n <div>\n <div\n className=\"relative z-0 inline-flex rounded-md\"\n aria-label=\"Pagination\"\n >\n <button\n type=\"button\"\n disabled={props.page <= 1 || pages === 1}\n onClick={onFirst}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium rounded-md ${\n props.page <= 1\n ? 'text-gray-500'\n : 'text-green-400 hover:bg-green-400 hover:text-white'\n } bg-gray-100`}\n >\n First\n </button>\n <button\n type=\"button\"\n disabled={props.page <= 1 || pages === 1}\n onClick={onPrev}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 font-medium ${\n props.page <= 1\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } rounded-md bg-gray-100`}\n >\n <FaChevronLeft />\n </button>\n <button\n type=\"button\"\n disabled\n className=\"relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium text-gray-500 rounded-md bg-gray-100\"\n >\n Page {props.page} of {pages}\n </button>\n <button\n type=\"button\"\n disabled={props.page >= pages || pages === 1}\n onClick={onNext}\n className={`relative inline-flex items-center ml-1 px-2 md:px-3 py-2 rounded-md font-medium ${\n props.page >= pages\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } bg-gray-100`}\n >\n <FaChevronRight />\n </button>\n <button\n type=\"button\"\n disabled={props.page >= pages || pages === 1}\n onClick={onLast}\n className={`relative inline-flex items-center px-2 ml-1 md:px-3 py-2 text-xs font-medium rounded-md ${\n props.page >= pages\n ? 'text-gray-500'\n : 'text-green-400 hover:text-white hover:bg-green-400'\n } bg-gray-100 `}\n >\n Last\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n};/* END_INCLUDE COMPONENT: \"includes/Common/Paginator.jsx\" */\n\nfunction MainComponent({ network, t, id }) {\n const [isLoading, setIsLoading] = useState(false);\n const [showWhen, setShowWhen] = useState(true);\n const [sorting, setSorting] = useState('desc');\n const [count, setCount] = useState(0);\n const [keys, Setkeys] = useState([]);\n\n const initialPage = 1;\n const [currentPage, setCurrentPage] = useState(initialPage);\n\n const config = getConfig(network);\n\n const setPage = (pageNumber) => {\n setCurrentPage(pageNumber);\n };\n\n useEffect(() => {\n setCurrentPage(currentPage);\n }, [currentPage]);\n\n const toggleShowWhen = () => setShowWhen((s) => !s);\n\n const onOrder = () => {\n setSorting((state) => (state === 'asc' ? 'desc' : 'asc'));\n };\n\n useEffect(() => {\n setIsLoading(true);\n function fetchAccountData() {\n asyncFetch(\n `${config?.backendUrl}account/${id}/keys?order=${sorting}&page=${currentPage}&per_page=25`,\n )\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.keys;\n if (data.status === 200) {\n Setkeys(resp);\n setIsLoading(false);\n } else {\n handleRateLimit(\n data,\n () => fetchAccountData(),\n () => setIsLoading(false),\n );\n }\n },\n )\n .catch(() => {});\n }\n\n function fetchCountData() {\n asyncFetch(`${config?.backendUrl}account/${id}/keys/count`)\n .then(\n (data\n\n\n\n\n) => {\n const resp = data?.body?.keys?.[0]?.count || 0;\n if (data.status === 200) {\n setCount(resp);\n } else {\n handleRateLimit(data, fetchCountData);\n }\n },\n )\n .catch(() => {});\n }\n fetchAccountData();\n fetchCountData();\n }, [config?.backendUrl, id, currentPage, sorting]);\n\n return (\n <>\n <div className=\"overflow-x-auto \">\n <table className=\"min-w-full divide-y border-t\">\n <thead className=\"bg-gray-100\">\n <tr>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Txn Hash\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Public key\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Access\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Contract\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Method\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Allowance\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-4 text-left text-xs font-semibold text-nearblue-600 uppercase tracking-wider\"\n >\n Action\n </th>\n <th scope=\"col\" className=\"text-left\">\n <div className=\"w-full inline-flex px-5 py-4\">\n <button\n type=\"button\"\n onClick={toggleShowWhen}\n className=\"text-left text-xs w-full font-semibold uppercase tracking-wider text-nearblue-600 focus:outline-none\"\n >\n {showWhen ? 'When' : 'Date Time (UTC)'}\n </button>\n <button type=\"button\" onClick={onOrder} className=\"px-2\">\n <div className=\"text-nearblue-600 font-semibold\">\n <SortIcon order={sorting} />\n </div>\n </button>\n </div>\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white divide-y divide-gray-200\">\n {isLoading &&\n [...Array(25)].map((_, i) => (\n <tr key={i} className=\"hover:bg-blue-900/5 h-[57px]\">\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-tiny \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-nearblue-600 \">\n <Skeleton />\n </td>\n </tr>\n ))}\n {!isLoading && keys.length === 0 && (\n <tr className=\"h-[57px]\">\n <td\n colSpan={100}\n className=\"px-6 py-4 text-nearblue-700 text-xs\"\n >\n No access keys\n </td>\n </tr>\n )}\n {keys &&\n keys.map((key) => (\n <Widget\n key={key.account_id + key.public_key}\n src={`${config.ownerId}/widget/bos-components.components.Address.AccessKeyRow`}\n props={{\n network: network,\n t: t,\n accessKey: key,\n showWhen: showWhen,\n }}\n />\n ))}\n </tbody>\n </table>\n </div>\n <Paginator\n count={count}\n page={currentPage}\n limit={25}\n pageLimit={200}\n setPage={setPage}\n />\n </>\n );\n}\n\nreturn MainComponent(props, context);" } } } } }
Result:
{ "block_height": "114508439" }
No logs
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.18361  to nearblocks.near
Empty result
No logs