diff --git a/assets/icons.json b/assets/icons.json index 8812e206..4ea1806e 100644 --- a/assets/icons.json +++ b/assets/icons.json @@ -197,8 +197,13 @@ "l2beat": "M3.50521 3.54966C6.19251 1.25356 9.65297 1.67202 11.9929 3.71691C14.3301 1.67124 17.7537 1.28246 20.4709 3.54089C23.4445 6.01238 23.8016 10.2274 21.5118 13.1739C20.7167 14.197 19.2374 15.6826 17.7545 17.0967C16.255 18.5267 14.6963 19.9356 13.7042 20.8209L13.6822 20.8405C13.5197 20.9856 13.3571 21.1307 13.2072 21.2444C13.0387 21.3721 12.8318 21.5036 12.5679 21.5828C12.1958 21.6944 11.7907 21.6944 11.4186 21.5828C11.1547 21.5036 10.9478 21.3721 10.7793 21.2444C10.6294 21.1307 10.4669 20.9857 10.3043 20.8405L10.2823 20.8209C9.29019 19.9356 7.73154 18.5267 6.23203 17.0967C4.74915 15.6826 3.26977 14.197 2.47471 13.1739C0.176093 10.216 0.598423 6.03328 3.50521 3.54966ZM11.9488 8.18372C11.8209 7.80002 11.4744 7.53114 11.071 7.50247C10.6675 7.4738 10.2866 7.69098 10.1057 8.05274L8.88209 10.4999H8.50012C7.94784 10.4999 7.50012 10.9476 7.50012 11.4999C7.50012 12.0522 7.94784 12.4999 8.50012 12.4999H9.50012C9.87889 12.4999 10.2251 12.2859 10.3945 11.9471L10.8149 11.1065L12.0514 14.8161C12.1793 15.1998 12.5258 15.4687 12.9292 15.4974C13.3327 15.5261 13.7136 15.3089 13.8945 14.9471L15.1181 12.4999H15.5001C16.0524 12.4999 16.5001 12.0522 16.5001 11.4999C16.5001 10.9476 16.0524 10.4999 15.5001 10.4999H14.5001C14.1213 10.4999 13.7751 10.7139 13.6057 11.0527L13.1853 11.8934L11.9488 8.18372Z", "blockscout": "M 10.078125 3.554688 C 10.078125 3.066406 9.6875 2.667969 9.207031 2.667969 L 7.148438 2.667969 C 6.667969 2.667969 6.277344 3.066406 6.277344 3.554688 L 6.277344 5.660156 C 6.277344 6.152344 5.890625 6.550781 5.410156 6.550781 L 3.476562 6.550781 C 2.996094 6.550781 2.609375 6.949219 2.609375 7.441406 L 2.609375 20.421875 C 2.609375 20.914062 2.996094 21.3125 3.476562 21.3125 L 5.539062 21.3125 C 6.019531 21.3125 6.410156 20.914062 6.410156 20.421875 L 6.410156 7.441406 C 6.410156 6.949219 6.796875 6.550781 7.277344 6.550781 L 9.207031 6.550781 C 9.6875 6.550781 10.078125 6.152344 10.078125 5.660156 Z M 17.679688 3.554688 C 17.679688 3.066406 17.289062 2.667969 16.808594 2.667969 L 14.746094 2.667969 C 14.265625 2.667969 13.878906 3.066406 13.878906 3.554688 L 13.878906 5.660156 C 13.878906 6.152344 14.265625 6.550781 14.746094 6.550781 L 16.679688 6.550781 C 17.160156 6.550781 17.546875 6.949219 17.546875 7.441406 L 17.546875 20.421875 C 17.546875 20.914062 17.9375 21.3125 18.417969 21.3125 L 20.476562 21.3125 C 20.957031 21.3125 21.347656 20.914062 21.347656 20.421875 L 21.347656 7.441406 C 21.347656 6.949219 20.957031 6.550781 20.476562 6.550781 L 18.546875 6.550781 C 18.066406 6.550781 17.679688 6.152344 17.679688 5.660156 Z M 13.878906 10.992188 C 13.878906 10.5 13.488281 10.101562 13.007812 10.101562 L 10.949219 10.101562 C 10.46875 10.101562 10.078125 10.5 10.078125 10.992188 L 10.078125 16.761719 C 10.078125 17.25 10.46875 17.648438 10.949219 17.648438 L 13.007812 17.648438 C 13.488281 17.648438 13.878906 17.25 13.878906 16.761719 Z M 13.878906 10.992188", "lama": "M16.361 10.26a.9.9 0 0 0-.558.47l-.072.148l.001.207c0 .193.004.217.059.353c.076.193.152.312.291.448c.24.238.51.3.872.205a.86.86 0 0 0 .517-.436a.75.75 0 0 0 .08-.498c-.064-.453-.33-.782-.724-.897a1.1 1.1 0 0 0-.466 0m-9.203.005c-.305.096-.533.32-.65.639a1.2 1.2 0 0 0-.06.52c.057.309.31.59.598.667c.362.095.632.033.872-.205c.14-.136.215-.255.291-.448c.055-.136.059-.16.059-.353l.001-.207l-.072-.148a.9.9 0 0 0-.565-.472a1 1 0 0 0-.474.007m4.184 2c-.131.071-.223.25-.195.383c.031.143.157.288.353.407c.105.063.112.072.117.136c.004.038-.01.146-.029.243c-.02.094-.036.194-.036.222c.002.074.07.195.143.253c.064.052.076.054.255.059c.164.005.198.001.264-.03c.169-.082.212-.234.15-.525c-.052-.243-.042-.28.087-.355c.137-.08.281-.219.324-.314a.365.365 0 0 0-.175-.48a.4.4 0 0 0-.181-.033c-.126 0-.207.03-.355.124l-.085.053l-.053-.032c-.219-.13-.259-.145-.391-.143a.4.4 0 0 0-.193.032m.39-2.195c-.373.036-.475.05-.654.086a4.5 4.5 0 0 0-.951.328c-.94.46-1.589 1.226-1.787 2.114c-.04.176-.045.234-.045.53c0 .294.005.357.043.524c.264 1.16 1.332 2.017 2.714 2.173c.3.033 1.596.033 1.896 0c1.11-.125 2.064-.727 2.493-1.571c.114-.226.169-.372.22-.602c.039-.167.044-.23.044-.523c0-.297-.005-.355-.045-.531c-.288-1.29-1.539-2.304-3.072-2.497a7 7 0 0 0-.855-.031zm.645.937a3.3 3.3 0 0 1 1.44.514c.223.148.537.458.671.662c.166.251.26.508.303.82c.02.143.01.251-.043.482c-.08.345-.332.705-.672.957a3 3 0 0 1-.689.348c-.382.122-.632.144-1.525.138c-.582-.006-.686-.01-.853-.042q-.856-.16-1.35-.68c-.264-.28-.385-.535-.45-.946c-.03-.192.025-.509.137-.776c.136-.326.488-.73.836-.963c.403-.269.934-.46 1.422-.512c.187-.02.586-.02.773-.002m-5.503-11a1.65 1.65 0 0 0-.683.298C5.617.74 5.173 1.666 4.985 2.819c-.07.436-.119 1.04-.119 1.503c0 .544.064 1.24.155 1.721c.02.107.031.202.023.208l-.187.152a5.3 5.3 0 0 0-.949 1.02a5.5 5.5 0 0 0-.94 2.339a6.6 6.6 0 0 0-.023 1.357c.091.78.325 1.438.727 2.04l.13.195l-.037.064c-.269.452-.498 1.105-.605 1.732c-.084.496-.095.629-.095 1.294c0 .67.009.803.088 1.266c.095.555.288 1.143.503 1.534c.071.128.243.393.264.407c.007.003-.014.067-.046.141a7.4 7.4 0 0 0-.548 1.873a5 5 0 0 0-.071.991c0 .56.031.832.148 1.279L3.42 24h1.478l-.05-.091c-.297-.552-.325-1.575-.068-2.597c.117-.472.25-.819.498-1.296l.148-.29v-.177c0-.165-.003-.184-.057-.293a.9.9 0 0 0-.194-.25a1.7 1.7 0 0 1-.385-.543c-.424-.92-.506-2.286-.208-3.451c.124-.486.329-.918.544-1.154a.8.8 0 0 0 .223-.531c0-.195-.07-.355-.224-.522a3.14 3.14 0 0 1-.817-1.729c-.14-.96.114-2.005.69-2.834c.563-.814 1.353-1.336 2.237-1.475c.199-.033.57-.028.776.01c.226.04.367.028.512-.041c.179-.085.268-.19.374-.431c.093-.215.165-.333.36-.576c.234-.29.46-.489.822-.729c.413-.27.884-.467 1.352-.561c.17-.035.25-.04.569-.04s.398.005.569.04a4.07 4.07 0 0 1 1.914.997c.117.109.398.457.488.602c.034.057.095.177.132.267c.105.241.195.346.374.43c.14.068.286.082.503.045c.343-.058.607-.053.943.016c1.144.23 2.14 1.173 2.581 2.437c.385 1.108.276 2.267-.296 3.153c-.097.15-.193.27-.333.419c-.301.322-.301.722-.001 1.053c.493.539.801 1.866.708 3.036c-.062.772-.26 1.463-.533 1.854a2 2 0 0 1-.224.258a.9.9 0 0 0-.194.25c-.054.109-.057.128-.057.293v.178l.148.29c.248.476.38.823.498 1.295c.253 1.008.231 2.01-.059 2.581a1 1 0 0 0-.044.098c0 .006.329.009.732.009h.73l.02-.074l.036-.134c.019-.076.057-.3.088-.516a9 9 0 0 0 0-1.258c-.11-.875-.295-1.57-.597-2.226c-.032-.074-.053-.138-.046-.141a1.4 1.4 0 0 0 .108-.152c.376-.569.607-1.284.724-2.228c.031-.26.031-1.378 0-1.628c-.083-.645-.182-1.082-.348-1.525a6 6 0 0 0-.329-.7l-.038-.064l.131-.194c.402-.604.636-1.262.727-2.04a6.6 6.6 0 0 0-.024-1.358a5.5 5.5 0 0 0-.939-2.339a5.3 5.3 0 0 0-.95-1.02l-.186-.152a.7.7 0 0 1 .023-.208c.208-1.087.201-2.443-.017-3.503c-.19-.924-.535-1.658-.98-2.082c-.354-.338-.716-.482-1.15-.455c-.996.059-1.8 1.205-2.116 3.01a7 7 0 0 0-.097.726c0 .036-.007.066-.015.066a1 1 0 0 1-.149-.078A4.86 4.86 0 0 0 12 3.03c-.832 0-1.687.243-2.456.698a1 1 0 0 1-.148.078c-.008 0-.015-.03-.015-.066a7 7 0 0 0-.097-.725C8.997 1.392 8.337.319 7.46.048a2 2 0 0 0-.585-.041Zm.293 1.402c.248.197.523.759.682 1.388c.03.113.06.244.069.292c.007.047.026.152.041.233c.067.365.098.76.102 1.24l.002.475l-.12.175l-.118.178h-.278c-.324 0-.646.041-.954.124l-.238.06c-.033.007-.038-.003-.057-.144a8.4 8.4 0 0 1 .016-2.323c.124-.788.413-1.501.696-1.711c.067-.05.079-.049.157.013m9.825-.012c.17.126.358.46.498.888c.28.854.36 2.028.212 3.145c-.019.14-.024.151-.057.144l-.238-.06a3.7 3.7 0 0 0-.954-.124h-.278l-.119-.178l-.119-.175l.002-.474c.004-.669.066-1.19.214-1.772c.157-.623.434-1.185.68-1.382c.078-.062.09-.063.159-.012", + "celestials": "M 8 24 C 7.660156 24 7.382812 23.730469 7.382812 23.398438 L 7.382812 22.199219 C 7.382812 21.867188 7.660156 21.601562 8 21.601562 L 12.308594 21.601562 L 12.308594 23.398438 C 12.308594 23.730469 12.03125 24 11.691406 24 Z M 12.308594 21.601562 L 12.308594 19.199219 L 8 19.199219 C 7.660156 19.199219 7.382812 18.929688 7.382812 18.601562 L 7.382812 16.800781 L 5.539062 16.800781 C 5.199219 16.800781 4.921875 16.53125 4.921875 16.199219 L 4.921875 14.398438 L 3.078125 14.398438 C 2.738281 14.398438 2.460938 14.132812 2.460938 13.800781 L 2.460938 12 L 0.617188 12 C 0.273438 12 0 11.730469 0 11.398438 L 0 7.800781 C 0 7.46875 0.273438 7.199219 0.617188 7.199219 L 2.460938 7.199219 L 2.460938 5.398438 C 2.460938 5.070312 2.738281 4.800781 3.078125 4.800781 L 4.921875 4.800781 L 4.921875 3 C 4.921875 2.667969 5.199219 2.398438 5.539062 2.398438 L 7.382812 2.398438 L 7.382812 0.601562 C 7.382812 0.269531 7.660156 0 8 0 L 11.691406 0 C 12.03125 0 12.308594 0.269531 12.308594 0.601562 L 12.308594 1.800781 C 12.308594 2.132812 12.03125 2.398438 11.691406 2.398438 L 7.382812 2.398438 L 7.382812 4.800781 L 11.691406 4.800781 C 12.03125 4.800781 12.308594 5.070312 12.308594 5.398438 L 12.308594 7.199219 L 14.152344 7.199219 C 14.492188 7.199219 14.769531 7.46875 14.769531 7.800781 L 14.769531 9.601562 L 16.617188 9.601562 C 16.957031 9.601562 17.230469 9.867188 17.230469 10.199219 L 17.230469 12 L 19.078125 12 C 19.417969 12 19.691406 12.269531 19.691406 12.601562 L 19.691406 16.199219 C 19.691406 16.53125 19.417969 16.800781 19.078125 16.800781 L 17.230469 16.800781 L 17.230469 12 L 15.382812 12 C 15.042969 12 14.769531 11.730469 14.769531 11.398438 L 14.769531 9.601562 L 12.921875 9.601562 C 12.582031 9.601562 12.308594 9.332031 12.308594 9 L 12.308594 7.199219 L 7.382812 7.199219 L 7.382812 4.800781 L 4.921875 4.800781 L 4.921875 7.199219 L 2.460938 7.199219 L 2.460938 12 L 4.308594 12 C 4.648438 12 4.921875 12.269531 4.921875 12.601562 L 4.921875 14.398438 L 6.769531 14.398438 C 7.109375 14.398438 7.382812 14.667969 7.382812 15 L 7.382812 16.800781 L 12.308594 16.800781 L 12.308594 19.199219 L 14.769531 19.199219 L 14.769531 21 C 14.769531 21.332031 14.492188 21.601562 14.152344 21.601562 Z M 12.308594 16.800781 L 12.308594 15 C 12.308594 14.667969 12.582031 14.398438 12.921875 14.398438 L 14.152344 14.398438 C 14.492188 14.398438 14.769531 14.667969 14.769531 15 L 14.769531 16.800781 Z M 17.230469 18.601562 C 17.230469 18.929688 16.957031 19.199219 16.617188 19.199219 L 14.769531 19.199219 L 14.769531 16.800781 L 17.230469 16.800781 Z M 4.921875 7.199219 L 7.382812 7.199219 L 7.382812 9 C 7.382812 9.332031 7.109375 9.601562 6.769531 9.601562 L 5.539062 9.601562 C 5.199219 9.601562 4.921875 9.332031 4.921875 9 Z M 11.078125 12.601562 C 11.078125 12.929688 10.800781 13.199219 10.460938 13.199219 L 9.230469 13.199219 C 8.890625 13.199219 8.617188 12.929688 8.617188 12.601562 L 8.617188 11.398438 C 8.617188 11.070312 8.890625 10.800781 9.230469 10.800781 L 10.460938 10.800781 C 10.800781 10.800781 11.078125 11.070312 11.078125 11.398438 Z M 11.078125 12.601562", "line-chart": "M3.5,18.5L9.5,12.5L13.5,16.5L22,6.92L20.59,5.5L13.5,13.5L9.5,9.5L2,17L3.5,18.5Z", "bar-chart": "M3,22V8H7V22H3M10,22V2H14V22H10M17,22V14H21V22H17Z", "gantt-chart": "M2,5H10V2H12V22H10V18H6V15H10V13H4V10H10V8H2V5M14,5H17V8H14V5M14,10H19V13H14V10M14,15H22V18H14V15Z", - "crown": "M5 16L3 5L8.5 10L12 4L15.5 10L21 5L19 16H5M19 19C19 19.6 18.6 20 18 20H6C5.4 20 5 19.6 5 19V18H19V19Z" + "crown": "M5 16L3 5L8.5 10L12 4L15.5 10L21 5L19 16H5M19 19C19 19.6 18.6 20 18 20H6C5.4 20 5 19.6 5 19V18H19V19Z", + "earth": "M17.9,17.39C17.64,16.59 16.89,16 16,16H15V13A1,1 0 0,0 14,12H8V10H10A1,1 0 0,0 11,9V7H13A2,2 0 0,0 15,5V4.59C17.93,5.77 20,8.64 20,12C20,14.08 19.2,15.97 17.9,17.39M11,19.93C7.05,19.44 4,16.08 4,12C4,11.38 4.08,10.78 4.21,10.21L9,15V16A2,2 0 0,0 11,18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z", + "city": "M15,23H13V21H15V23M19,21H17V23H19V21M15,17H13V19H15V17M7,21H5V23H7V21M7,17H5V19H7V17M19,17H17V19H19V17M15,13H13V15H15V13M19,13H17V15H19V13M21,9A2,2 0 0,1 23,11V23H21V11H11V23H9V15H3V23H1V15A2,2 0 0,1 3,13H9V11A2,2 0 0,1 11,9V7A2,2 0 0,1 13,5H15V1H17V5H19A2,2 0 0,1 21,7V9M19,9V7H13V9H19Z", + "drop": "M12 18C12 18.7 12.12 19.36 12.34 20C12.23 20 12.12 20 12 20C8.69 20 6 17.31 6 14C6 10 12 3.25 12 3.25S16.31 8.1 17.62 12C16.93 12.06 16.28 12.22 15.67 12.47C15 10.68 13.5 8.33 12 6.39C10 8.96 8 12.23 8 14C8 16.21 9.79 18 12 18M19 17V14H17V17H14V19H17V22H19V19H22V17H19Z", + "faucet": "M21 21H3C3 19.9 3.9 19 5 19H19C20.11 19 21 19.89 21 21M19 7C19 5.39 17.93 3 15 3S11 5.39 11 7V18H13V7C13 6.54 13.17 5 15 5S17 6.54 17 7H16.5V9H19.5V7H19M7 12C6.45 12 6 12.45 6 13V14H3V15H6V18H8V13C8 12.45 7.55 12 7 12M21 14H18V13C18 12.45 17.55 12 17 12S16 12.45 16 13V18H18V15H21V14Z" } diff --git a/assets/styles/base.scss b/assets/styles/base.scss index 8151e013..4c4a465a 100644 --- a/assets/styles/base.scss +++ b/assets/styles/base.scss @@ -78,6 +78,7 @@ $grayscale: ( // --supply: #65c7f8; --supply: #1ca7ed; --staking: #85f891; + --geo-map: #8B8C8D; } [theme="dimmed"] { @@ -139,6 +140,7 @@ $grayscale: ( --block-progress-fill-background: #33a853; --logo-name: var(--txt-primary); --bar-fill: rgb(243, 147, 45); + --geo-map: #8B8C8D; } [theme="light"] { @@ -200,6 +202,7 @@ $grayscale: ( --block-progress-fill-background: #33a853; --logo-name: var(--txt-primary); --bar-fill: rgb(243, 147, 45); + --geo-map: #8B8C8D; } @font-face { diff --git a/components/LeftSidebar.vue b/components/LeftSidebar.vue index cc34e8ce..b0f64344 100644 --- a/components/LeftSidebar.vue +++ b/components/LeftSidebar.vue @@ -10,7 +10,7 @@ import NavLink from "@/components/modules/navigation/NavLink.vue" /** Utils */ import { getNetworkName } from "@/services/utils/general" import { StatusMap } from "@/services/constants/node" -import { isMobile } from "@/services/utils" +import { isMainnet, isMobile } from "@/services/utils" /** Store */ import { useAppStore } from "~/store/app" @@ -52,16 +52,19 @@ const mainLinks = reactive([ name: "Active", path: "/validators?status=active&page=1", queryParam: {status: "active"}, + show: true, }, { name: "Jailed", path: "/validators?status=jailed&page=1", queryParam: {status: "jailed"}, + show: true, }, { name: "Inactive", path: "/validators?status=inactive&page=1", queryParam: {status: "inactive"}, + show: true, }, ], }, @@ -74,16 +77,25 @@ const mainLinks = reactive([ name: "General", path: "/stats?tab=general", queryParam: {tab: "general"}, + show: true, }, { name: "Blocks", path: "/stats?tab=blocks", queryParam: {tab: "blocks"}, + show: true, }, { name: "Rollups", path: "/stats?tab=rollups", queryParam: {tab: "rollups"}, + show: true, + }, + { + name: "Ecosystem", + path: "/stats?tab=ecosystem", + queryParam: {tab: "ecosystem"}, + show: isMainnet(), }, ], }, @@ -99,11 +111,13 @@ const modularLinks = reactive([ { name: "Cost Savings", path: "/calculators/savings", + show: true, }, { name: "Register rollup", path: "https://forms.gle/nimJyQJG4Lb4BTcG7", external: true, + show: true, }, ], }, @@ -115,6 +129,7 @@ const modularLinks = reactive([ { name: "Treemap View", path: "/namespaces/treemap", + show: true, }, ], }, @@ -127,6 +142,11 @@ const modularLinks = reactive([ const isToolsLinkCollapsed = ref(false) const toolsLinks = reactive([ + { + icon: "drop", + name: "Faucet", + path: "/faucet", + }, { icon: "blob", name: "Blobstream", @@ -164,6 +184,10 @@ const newLinks = reactive([ const handleNavigate = (url) => { window.location.replace(url) } + +const handleOnClose = () => { + appStore.showSidebar = false +} @@ -194,7 +218,7 @@ const handleNavigate = (url) => { - + @@ -209,7 +233,7 @@ const handleNavigate = (url) => { - + @@ -225,7 +249,7 @@ const handleNavigate = (url) => { - + @@ -351,9 +375,9 @@ const handleNavigate = (url) => { .group_title { border-radius: 5px; - cursor: default; + cursor: pointer; - padding: 4px 6px; + padding: 6px 6px; margin: 0 2px; transition: all 0.2s ease; diff --git a/components/cmd/CommandMenu.vue b/components/cmd/CommandMenu.vue index 52c19ed2..cf664c20 100644 --- a/components/cmd/CommandMenu.vue +++ b/components/cmd/CommandMenu.vue @@ -291,6 +291,15 @@ const rawNavigationActions = [ router.push("/calculators/savings") }, }, + { + type: "callback", + icon: "arrow-narrow-right", + title: "Go to Faucet", + runText: "Open Faucet", + callback: () => { + router.push("/faucet") + }, + }, { type: "callback", icon: "arrow-narrow-right", diff --git a/components/modals/SendModal.vue b/components/modals/SendModal.vue index 3440aa35..367f575c 100644 --- a/components/modals/SendModal.vue +++ b/components/modals/SendModal.vue @@ -10,7 +10,6 @@ import Button from "@/components/ui/Button.vue" /** API */ import { search } from "@/services/api/search" -import { fetchAddressByHash } from "@/services/api/address" /** Services */ import amp from "@/services/amp" diff --git a/components/modals/StakingModal.vue b/components/modals/StakingModal.vue index 29fc3ae9..b6cd3217 100644 --- a/components/modals/StakingModal.vue +++ b/components/modals/StakingModal.vue @@ -210,7 +210,7 @@ watch( } if (cacheStore.current.validator) { - address.value = cacheStore.current.validator.address + address.value = cacheStore.current.validator.address?.hash } nextTick(() => { diff --git a/components/modules/address/AddressOverview.vue b/components/modules/address/AddressOverview.vue index 7100b4f3..c2ee0a30 100644 --- a/components/modules/address/AddressOverview.vue +++ b/components/modules/address/AddressOverview.vue @@ -25,15 +25,16 @@ import { comma, splitAddress } from "@/services/utils" /** API */ import { - fetchTxsByAddressHash, - fetchMessagesByAddressHash, - fetchBlobsByAddressHash, fetchAddressDelegations, + fetchAddressGranters, + fetchAddressGrants, fetchAddressRedelegations, fetchAddressUndelegations, - fetchAddressGrants, - fetchAddressGranters, fetchAddressVestings, + fetchBlobsByAddressHash, + fetchCelestials, + fetchMessagesByAddressHash, + fetchTxsByAddressHash, } from "@/services/api/address" /** Store */ @@ -58,6 +59,7 @@ const isRefetching = ref(false) const transactions = ref([]) const messages = ref([]) const blobs = ref([]) +const celestials = ref([]) /** Tabs */ const tabs = ref([ @@ -388,9 +390,25 @@ const getBlobs = async () => { isRefetching.value = false } +const getCelestials = async () => { + isRefetching.value = true + + const { data } = await fetchCelestials({ + hash: props.address.hash, + }) + + if (data.value?.length) { + celestials.value = data.value + } + + isRefetching.value = false +} +await getCelestials() + /** Delegation */ const isActiveDelegator = props.address.balance.delegated > 0 || props.address.balance.unbonding > 0 const collapseBalances = ref(!isActiveDelegator) +const collapseCelestials = ref(false) const totalBalance = parseInt(props.address.balance.spendable) + parseInt(props.address.balance.delegated) + parseInt(props.address.balance.unbonding) const delegations = ref([]) @@ -693,7 +711,24 @@ const handleOpenQRModal = () => { - + + + + + + + + {{ $getDisplayName('addresses', '', address) }} + + + + {{ splitAddress(address.hash) }} + + + + + + Address @@ -711,7 +746,6 @@ const handleOpenQRModal = () => { :amount="{ value: totalBalance }" :styles="{ amount: { size: '13' }, currency: { size: '13', color: 'primary' } }" /> - { + + + Celestials + + + + + + + + + + + {{ c.name }} + + + + + Details @@ -1087,6 +1148,34 @@ const handleOpenQRModal = () => { max-width: 100%; } } + + .avatar_container { + position: relative; + width: 50px; + height: 50px; + overflow: hidden; + border-radius: 50%; + } + + .avatar_image { + width: 100%; + height: 100%; + object-fit: cover; + } +} + +.cel_image_container { + position: relative; + width: 16px; + height: 16px; + overflow: hidden; + border-radius: 50%; +} + +.cel_image { + width: 100%; + height: 100%; + object-fit: cover; } .txs_wrapper { @@ -1209,6 +1298,18 @@ const handleOpenQRModal = () => { } } +.link { + &:hover { + span { + color: var(--txt-primary); + } + + img { + filter: brightness(1.2) + } + } +} + @media (max-width: 800px) { .content { flex-direction: column; diff --git a/components/modules/navigation/NavLink.vue b/components/modules/navigation/NavLink.vue index cb911566..6d51d22a 100644 --- a/components/modules/navigation/NavLink.vue +++ b/components/modules/navigation/NavLink.vue @@ -69,7 +69,7 @@ const handleClick = () => { - + { - + diff --git a/components/modules/rollup/RollupCharts.vue b/components/modules/rollup/RollupCharts.vue index c025c53e..def91420 100644 --- a/components/modules/rollup/RollupCharts.vue +++ b/components/modules/rollup/RollupCharts.vue @@ -354,7 +354,6 @@ const buildBarChart = (chartEl, data, onEnter, onLeave, metric) => { const onPointermoved = (event) => { onEnter() - // const idx = bisect(data, x.invert(d3.pointer(event)[0])) const idx = bisect(data, x.invert(d3.pointer(event)[0] - barWidth / 2)) const elements = document.querySelectorAll(`[metric="${metric}"]`) diff --git a/components/modules/stats/BarChart.vue b/components/modules/stats/BarChart.vue index 289b41e2..64b70bc1 100644 --- a/components/modules/stats/BarChart.vue +++ b/components/modules/stats/BarChart.vue @@ -33,8 +33,7 @@ const tooltip = ref({ }) const buildChart = (chart, cData, pData, onEnter, onLeave) => { - const width = chart.getBoundingClientRect().width - const height = chart.getBoundingClientRect().height + const { width, height } = chart.getBoundingClientRect() const marginTop = 12 const marginRight = 12 const marginBottom = 24 diff --git a/components/modules/stats/BarplotChartCard.vue b/components/modules/stats/BarplotChartCard.vue new file mode 100644 index 00000000..7da2f42b --- /dev/null +++ b/components/modules/stats/BarplotChartCard.vue @@ -0,0 +1,290 @@ + + + + + + {{ `By ${series.title}` }} + + + + + + + Amount: + {{ tooltip.amount }} + + + + + + + + + + diff --git a/components/modules/stats/ChartCardPreview.vue b/components/modules/stats/ChartCardPreview.vue index 1d9ac999..70eb6957 100644 --- a/components/modules/stats/ChartCardPreview.vue +++ b/components/modules/stats/ChartCardPreview.vue @@ -7,7 +7,7 @@ import { DateTime } from "luxon" import DiffChip from "@/components/modules/stats/DiffChip.vue" /** Services */ -import { abbreviate, comma, formatBytes, tia } from "@/services/utils" +import { abbreviate, comma, formatBytes, tia, truncateDecimalPart } from "@/services/utils" /** API */ import { fetchSeries, fetchSeriesCumulative, fetchTVS } from "@/services/api/stats" @@ -36,6 +36,11 @@ const diff = computed(() => { }) const chartEl = ref() const chartElPrev = ref() +const tooltipEl = ref() +const tooltip = ref({ + data: [], + show: false, +}) const getSeries = async () => { let data = [] @@ -59,7 +64,7 @@ const getSeries = async () => { period: 'day', from: parseInt( baseTime.minus({ - months: 2, + days: 60, }).ts / 1_000) }) } else if (props.series.name === "tvs") { @@ -77,8 +82,13 @@ const getSeries = async () => { })).reverse() } - prevData.value = data.slice(0, props.period.value).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) - currentData.value = data.slice(props.period.value, data.length).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) + if (props.series.aggregate === 'cumulative') { + prevData.value = data.slice(0, 30).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) + currentData.value = data.slice(30, data.length).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) + } else { + prevData.value = data.slice(0, props.period.value).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) + currentData.value = data.slice(props.period.value, data.length).map((s) => ({ date: DateTime.fromISO(s.time).toJSDate(), value: parseFloat(s.value) })) + } if (props.series.name === 'block_time') { prevData.value = prevData.value @@ -98,8 +108,8 @@ const getSeries = async () => { } if (props.series.name === 'tvs') { - currentTotal.value = currentData.value[currentData.value.length - 1].value // Math.max(...currentData.value.map(d => d.value)) - prevTotal.value = prevData.value[prevData.value.length - 1].value // Math.max(...prevTotal.value.map(d => d.value)) + currentTotal.value = currentData.value[currentData.value.length - 1].value + prevTotal.value = prevData.value[prevData.value.length - 1].value } else if (props.series.aggregate !== 'cumulative') { currentTotal.value = currentData.value.reduce((sum, el) => { return sum + +el.value; @@ -118,12 +128,21 @@ const getSeries = async () => { currentTotal.value = currentTotal.value / currentData.value.length } + let pData = [] + prevData.value?.forEach((d, index) => { + pData.push({ + date: currentData.value[index]?.date, + realDate: d.date, + value: d.value, + }) + }) + prevData.value = pData + dataLoaded.value = true } const buildChart = (chart, data, color) => { - const width = chart.getBoundingClientRect().width - const height = chart.getBoundingClientRect().height + const { width, height } = chart.getBoundingClientRect() const marginTop = 8 const marginRight = 12 const marginBottom = 24 @@ -132,6 +151,33 @@ const buildChart = (chart, data, color) => { const MAX_VALUE = Math.max(Math.max(...prevData.value.map((s) => s.value)), Math.max(...currentData.value.map((s) => s.value))) const MIN_VALUE = Math.min(Math.min(...prevData.value.map((s) => s.value)), Math.min(...currentData.value.map((s) => s.value))) + function formatDate(date) { + if (props.period.timeframe === 'hour') { + return DateTime.fromJSDate(date).toFormat("LLL dd HH:mm") + } + + return DateTime.fromJSDate(date).toFormat("LLL dd") + } + + function formatValue(value) { + switch (props.series.units) { + case 'bytes': + return formatBytes(value) + case 'utia': + if (props.series.name === 'gas_price') { + return `${truncateDecimalPart(value, 4)} UTIA` + } + + return `${tia(value, 2)} TIA` + case 'seconds': + return `${truncateDecimalPart(value / 1_000, 3)}s` + case 'usd': + return `${abbreviate(value)} $` + default: + return comma(value) + } + } + /** Scale */ const x = d3.scaleUtc( d3.extent(data, (d) => d.date), @@ -153,7 +199,89 @@ const buildChart = (chart, data, color) => { .attr("preserveAspectRatio", "none") .attr("style", "max-width: 100%;") .style("-webkit-tap-highlight-color", "transparent") - // .on("touchstart", (event) => event.preventDefault()) + .on("pointerenter pointermove", onPointerMoved) + .on("pointerleave", onPointerleft) + .on("touchstart", (event) => event.preventDefault()) + + // This allows to find the closest X index of the mouse: + const bisect = d3.bisector(function(d) { return d.date; }).center + + const cFocus = svg + .append('g') + .append('circle') + .style("fill", "var(--brand)") + .attr('r', 4) + .style("opacity", 0) + .style("transition", "all 0.2s ease" ) + + const pFocus = svg + .append('g') + .append('circle') + .style("fill", "var(--txt-tertiary)") + .attr('r', 4) + .style("opacity", 0) + .style("transition", "all 0.2s ease" ) + + const focusLine = svg + .append('g') + .append('line') + .style("stroke-width", 2) + .style("stroke", "var(--op-15)") + .style("fill", "none") + .style("opacity", 0) + + function onPointerMoved(event) { + tooltip.value.show = true + + cFocus.style("opacity", 1) + focusLine.style("opacity", 1) + + // Recover coordinate we need + let idx = bisect(currentData.value, x.invert(d3.pointer(event)[0])) + let selectedCData = currentData.value[idx] + cFocus + .attr("cx", x(selectedCData.date)) + .attr("cy", y(selectedCData.value)) + focusLine + .attr("x1", x(selectedCData.date)) + .attr("y1", 0) + .attr("x2", x(selectedCData.date)) + .attr("y2", height) + + let tooltipWidth = tooltipEl.value?.wrapper ? tooltipEl.value?.wrapper?.getBoundingClientRect()?.width : 100 + let xPosition = x(selectedCData.date) + tooltip.value.x = (xPosition + tooltipWidth) > width + 5 ? xPosition - tooltipWidth - 15 : xPosition + 15 + tooltip.value.y = Math.min(y(selectedCData.value), height - 100) + + tooltip.value.data[0] = { + date: formatDate(selectedCData.date), + value: formatValue(selectedCData.value), + color: "var(--brand)", + } + tooltip.value.data.splice(1, 1) + if (prevData.value.length) { + let selectedPData = prevData.value[idx] + + pFocus + .attr("cx", x(selectedPData.date)) + .attr("cy", y(selectedPData.value)) + .style("opacity", 1) + + tooltip.value.data[1] = { + date: formatDate(selectedPData.realDate), + value: formatValue(selectedPData.value), + color: "var(--txt-tertiary)", + } + } + + } + + function onPointerleft() { + tooltip.value.show = false + cFocus.style("opacity", 0) + pFocus.style("opacity", 0) + focusLine.style("opacity", 0) + } /** Default Horizontal Lines */ svg.append("path") @@ -207,7 +335,7 @@ const buildChart = (chart, data, color) => { const drawChart = async () => { await getSeries() - buildChart(chartEl.value.wrapper, currentData.value, "var(--mint)") + buildChart(chartEl.value.wrapper, currentData.value, "var(--brand)") buildChart(chartElPrev.value.wrapper, prevData.value, "var(--txt-tertiary)") } @@ -221,7 +349,6 @@ watch( await drawChart() }, ) - @@ -276,15 +403,53 @@ watch( + + + + + + {{ d.value }} + + + + + {{ d.date }} + + + + + + + + + + + + - {{ DateTime.now().minus({ - months: 2, - }).toFormat("LLL dd") - }} + {{ DateTime.fromJSDate(currentData[0]?.date).toFormat("LLL dd") }} {{ DateTime.now().minus({ @@ -346,10 +511,41 @@ watch( bottom: 0; left: 0; right: 0; +} - /* border-top: 2px solid var(--op-5); +.tooltip_wrapper { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; - padding-top: 8px; */ + & .tooltip { + min-width: 100px; + pointer-events: none; + position: absolute; + z-index: 10; + + background: var(--card-background); + border-radius: 6px; + box-shadow: inset 0 0 0 1px var(--op-5), 0 14px 34px rgba(0, 0, 0, 15%), 0 4px 14px rgba(0, 0, 0, 5%); + + padding: 10px; + + transition: all 0.2s ease; + } + + & .legend { + height: 8px; + width: 8px; + border-radius: 50%; + } + + & .horizontal_divider { + width: 100%; + height: 1px; + background: var(--op-5); + } } @media (max-width: 1000px) { diff --git a/components/modules/stats/GeoMap.vue b/components/modules/stats/GeoMap.vue new file mode 100644 index 00000000..aa89cd55 --- /dev/null +++ b/components/modules/stats/GeoMap.vue @@ -0,0 +1,632 @@ + + + + + + + + + + + + + + + + + Somewhere in.. + + means that it was not possible to determine the exact location. + + + + + + + + + + + + + + + Loading map.. + + + + + diff --git a/components/modules/stats/InsightCard.vue b/components/modules/stats/InsightCard.vue index 1108a0b5..277e205e 100644 --- a/components/modules/stats/InsightCard.vue +++ b/components/modules/stats/InsightCard.vue @@ -10,7 +10,7 @@ import DiffChip from "@/components/modules/stats/DiffChip.vue" import { abbreviate, capitilize, comma, formatBytes, shareOfTotal, shareOfTotalString } from "@/services/utils" /** API */ -import { fetch24hDiffs, fetchSummary } from "@/services/api/stats" +import { fetchGeneralStats, fetchSummary } from "@/services/api/stats" const props = defineProps({ series: { @@ -67,7 +67,7 @@ const getSeries = async () => { }, ] } else { - data = await fetch24hDiffs({ name: props.series.name }) + data = await fetchGeneralStats({ name: props.series.name }) } switch (props.series.name) { diff --git a/components/modules/stats/LineChart.vue b/components/modules/stats/LineChart.vue index 68d43e68..381f2658 100644 --- a/components/modules/stats/LineChart.vue +++ b/components/modules/stats/LineChart.vue @@ -34,8 +34,7 @@ const tooltip = ref({ }) const buildChart = (chart, cData, pData, onEnter, onLeave) => { - const width = chart.getBoundingClientRect().width - const height = chart.getBoundingClientRect().height + const { width, height } = chart.getBoundingClientRect() const marginTop = 6 const marginRight = 12 const marginBottom = 24 @@ -44,7 +43,7 @@ const buildChart = (chart, cData, pData, onEnter, onLeave) => { const MIN_VALUE = d3.min([...cData.data?.map(s => s.value), ...pData.data?.map(s => s.value)]) const MAX_VALUE = d3.max([...cData.data?.map(s => s.value), ...pData.data?.map(s => s.value)]) - + /** Scales */ const x = d3.scaleUtc( d3.extent(cData.data, (d) => d.date), @@ -246,7 +245,7 @@ const buildChart = (chart, cData, pData, onEnter, onLeave) => { } const drawChart = () => { - currentData.value.color = "var(--mint)" + currentData.value.color = "var(--brand)" prevData.value.color = "var(--txt-tertiary)" buildChart( chartEl.value.wrapper, diff --git a/components/modules/stats/RollupsActivityGraph.vue b/components/modules/stats/RollupsActivityGraph.vue index ad4b5b72..edb5a248 100644 --- a/components/modules/stats/RollupsActivityGraph.vue +++ b/components/modules/stats/RollupsActivityGraph.vue @@ -19,9 +19,15 @@ const metrics = ref([ - + + + No activity + + There has been no rollup activity in the last 24 hours + + \ No newline at end of file diff --git a/components/modules/stats/tabs/EcosystemTab.vue b/components/modules/stats/tabs/EcosystemTab.vue new file mode 100644 index 00000000..fe0feba9 --- /dev/null +++ b/components/modules/stats/tabs/EcosystemTab.vue @@ -0,0 +1,146 @@ + + + + + + Light Node Distribution + + + + + + + + + + + \ No newline at end of file diff --git a/components/modules/stats/tabs/GeneralTab.vue b/components/modules/stats/tabs/GeneralTab.vue index a15ba6a7..6c5508bc 100644 --- a/components/modules/stats/tabs/GeneralTab.vue +++ b/components/modules/stats/tabs/GeneralTab.vue @@ -14,7 +14,7 @@ import InsightCard from "@/components/modules/stats/InsightCard.vue" import { getInsightsByGroup, getSeriesByGroupAndType, STATS_PERIODS } from "@/services/constants/stats.js" /** API */ -import { fetch24hDiffs } from "@/services/api/stats.js" +import { fetchGeneralStats } from "@/services/api/stats.js" /** Store */ import { useAppStore } from "@/store/app" @@ -62,7 +62,7 @@ const insights = computed(() => getInsightsByGroup('General')) const get24hDiffs = async () => { isLoading.value = true - const data = await fetch24hDiffs({ name: 'changes_24h' }) + const data = await fetchGeneralStats({ name: 'changes_24h' }) diffs24h.value = data isLoading.value = false diff --git a/components/modules/stats/tabs/RollupsTab.vue b/components/modules/stats/tabs/RollupsTab.vue index 5a8c99fa..705c59fb 100644 --- a/components/modules/stats/tabs/RollupsTab.vue +++ b/components/modules/stats/tabs/RollupsTab.vue @@ -17,7 +17,7 @@ import Popover from "@/components/ui/Popover.vue" import { getSeriesByGroupAndType } from "@/services/constants/stats.js" /** Services */ -import { capitilize, capitalizeAndReplaceUnderscore } from "@/services/utils" +import { capitilize, capitalizeAndReplaceUnderscore, isMainnet } from "@/services/utils" /** API */ import { fetchRollups, fetchRollupsDailyStats } from "@/services/api/rollup.js" diff --git a/components/shared/AdvBanner.vue b/components/shared/AdvBanner.vue index eea02784..fa816677 100644 --- a/components/shared/AdvBanner.vue +++ b/components/shared/AdvBanner.vue @@ -17,11 +17,15 @@ const props = defineProps({ }, }) +const router = useRouter() + const adv = ref({}) const isDisplayed = ref(true) const handleClick = () => { - if (adv.value.link) { + if (adv.value.internalLink) { + router.push(adv.value.internalLink) + } else if (adv.value.link) { window.open(adv.value.link, '_blank') } else if (adv.value.modal) { modalsStore.open(adv.value.modal) diff --git a/components/widgets/StakingWidget.vue b/components/widgets/StakingWidget.vue index 76857323..34439c49 100644 --- a/components/widgets/StakingWidget.vue +++ b/components/widgets/StakingWidget.vue @@ -20,12 +20,12 @@ const wrapperEl = ref(null) const wrapperWidth = ref(0) const barWidth = computed(() => Math.round(wrapperWidth.value - 32)) -const totalSupply = computed(() => lastHead.value.total_supply / 1_000_000) +const totalSupply = computed(() => lastHead.value?.total_supply / 1_000_000) const totalSupplyUSD = computed(() => totalSupply.value * currentPrice.value?.close) -const totalVotingPower = computed(() => lastHead.value.total_voting_power) +const totalVotingPower = computed(() => lastHead.value?.total_voting_power) const totalVotingPowerUSD = computed(() => totalVotingPower.value * currentPrice.value?.close) -const bondedShare = computed(() => shareOfTotal(lastHead?.value.total_voting_power * 1_000_000, lastHead?.value.total_supply, 2)) +const bondedShare = computed(() => shareOfTotal(lastHead.value?.total_voting_power * 1_000_000, lastHead.value?.total_supply, 2)) const isRefetching = ref(true) const totalValidators = ref(0) diff --git a/package.json b/package.json index 127f34db..c25ede42 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "codemirror": "^6.0.1", "crypto-js": "^4.2.0", "d3": "^7.8.5", + "d3-geo": "^3.1.1", "d3-hierarchy": "^3.1.2", "focus-trap": "7.5.2", "iconv-lite": "^0.6.3", diff --git a/pages/calculators/savings.vue b/pages/calculators/savings.vue index 6d5e7a92..3a776a37 100644 --- a/pages/calculators/savings.vue +++ b/pages/calculators/savings.vue @@ -304,414 +304,424 @@ useHead({ - - - - - - Cost Saving Calculator - - - - Rollup Estimation Cost - - Discover the potential cost benefits of building on Celestia, modular blockchain network. - - - + + + + + + + + + Cost Saving Calculator + - - - - - Rollup Stack - + + Rollup Estimation Cost + + Discover the potential cost benefits of building on Celestia, modular blockchain network. + + - Rollup underlying technology (SDK). - - - - - - - - - {{ stack.name }} - - - ${{ comma(getAvgCallDataCostByStack(stack.name)) }} - - Unavailable - + + + + + Rollup Stack + - - - {{ percentDiff(rollupStacks[selectedRollupStack].price, rollupStacks[idx].price).pos ? "-" : "+" - }}{{ percentDiff(rollupStacks[selectedRollupStack].price, rollupStacks[idx].price).val.toFixed(2) }}% - - - - - + Rollup underlying technology (SDK). + - - - - - Transaction Type - - + + + + - Type of transaction used to calculate the total size of posted data. - - - - - - - - - {{ stack.name }} - {{ stack.description }} + + {{ stack.name }} + + + ${{ comma(getAvgCallDataCostByStack(stack.name)) }} + + Unavailable + - - - - + + + {{ percentDiff(rollupStacks[selectedRollupStack].price, rollupStacks[idx].price).pos ? "-" : "+" + }}{{ percentDiff(rollupStacks[selectedRollupStack].price, rollupStacks[idx].price).val.toFixed(2) }}% + + + - - - - + + - Expected transactions + Transaction Type - Total number of posted transactions. + Type of transaction used to calculate the total size of posted data. - + + + + - - {{ comma(txs) }} - - - - - - + + {{ stack.name }} + {{ stack.description }} + + + + + + - + - - - - - - Using L2 the expected cost ~${{ comma(expectedCostL2, ",", 0) }}, with Celestia ~${{ comma(expectedCostCelestia, ",", 0) }} for - {{ abbreviate(txs) }} transactions - - - - - - - ${{ comma(savingsUsingCelestia, ",", 0) }} - - You'll save using Celestia - + + + + + + Expected transactions + + - - ${{ tiaPerMb.toFixed(5) }} - Price per Mb in Celestia - + Total number of posted transactions. + + + + + + {{ comma(txs) }} + + + + + + + + - - - - ~{{ payLessPercentCelestia.toFixed(2) }}% - - You'll pay % less + + + + + + Using L2 the expected cost ~${{ comma(expectedCostL2, ",", 0) }}, with Celestia ~${{ comma(expectedCostCelestia, ",", 0) }} for + {{ abbreviate(txs) }} transactions + + + + + + + ${{ comma(savingsUsingCelestia, ",", 0) }} + + You'll save using Celestia + + + + ${{ tiaPerMb.toFixed(5) }} + Price per Mb in Celestia + - - - ${{ comma(additionalSettlementCost, ",", 0) }} - - Settlement Cost + + + + ~{{ payLessPercentCelestia.toFixed(2) }}% + + You'll pay % less + + + + + ${{ comma(additionalSettlementCost, ",", 0) }} + + Settlement Cost + - - - + + - - This estimation assumes a constant $TIA price. It should only be used as an estimation and - reference to compare what-if scenarios. - + + This estimation assumes a constant $TIA price. It should only be used as an estimation and + reference to compare what-if scenarios. + + - - - - - - - Constants - - - - Reset - - - - - Variables used to calculate the savings of Celestia's usage. - - - - Editable variables - - - - Static - + + + + + + Constants + + + Reset - - - - - - - - TIA Price - - - - ${{ tiaPrice }} - - - + + + + Variables used to calculate the savings of Celestia's usage. + + + + Editable variables + - - - + + Static - + + + - - Average Gas - {{ comma(averageGas) }} - - + + + + + TIA Price + + + + ${{ tiaPrice }} + + + + + + + + + + - - - Price per gas + + Average Gas + {{ comma(averageGas) }} + + - - - {{ pricePerGas }} UTIA - - - - - - - - - + + + Price per gas + + + + {{ pricePerGas }} UTIA + + + + + + + + + + - - - - - - - Avg batch size - - - {{ formatBytes(batchSize) }} / block - - - - - - - - - + + + + + Avg batch size + + + + {{ formatBytes(batchSize) }} / block + + + + + + + + + + - - - - Avg num of shares - 215 + + + Avg num of shares + 215 + - - - - Use EIP-4844 + + + Use EIP-4844 + - - + --> + + + + + + + Build with Celenium API + - - - - - - Build with Celenium API + + Unlock the power of Celestia: Scalable, Secure and Modular Blockchain. + - - Unlock the power of Celestia: Scalable, Secure and Modular Blockchain. - + Get started -> - - Get started -> - - + + @@ -721,6 +731,10 @@ useHead({ padding: 20px 24px 60px 24px; } +.breadcrumbs { + margin-bottom: 16px; +} + .left { } diff --git a/pages/faucet.vue b/pages/faucet.vue new file mode 100644 index 00000000..1ef02ab2 --- /dev/null +++ b/pages/faucet.vue @@ -0,0 +1,656 @@ + + + + + + + + + + Celenium Faucet + + + + Faucet is only available for + Mocha + network. + + + + + + + + + + + + + {{ validation.title }} + + + + + + + + + Recieve 0.5 TIA + + + + + + + + + + + + + Faucet + + + + {{ tia(faucetBalance, 2) }} TIA + + + + + + {{ splitAddress(faucetAddress) }} + + + + + + + + + + + + {{ account?.hash + ? $getDisplayName("addresses", "", account) === splitAddress(account?.hash) + ? 'Address' + : $getDisplayName("addresses", "", account) + : 'Address' + }} + + + + {{ tia(account?.balance?.spendable || 0, 2) }} TIA + + + + + {{ account?.hash + ? splitAddress(account.hash) + : 'celestia ••• celestia' + }} + + + + + + + + + + + + + + + View Tx + + + + + + {{ executionResult.message }} + + + + + + + + Please do not forget to + + return + + the test tokens if you no longer need them so that they can be used by other developers and testers. + + + + + + Frequently asked questions + + + + handleOpenQuestion(1)" align="center" justify="between" gap="12" :class="$style.head"> + What is the Celestia Faucet? + + + + + + + The Celestia testnet faucet is a service that provides free testnet tokens for developers and users who want to interact with the Celestia blockchain without spending real assets. These tokens have no monetary value and are solely for testing purposes. + + + + handleOpenQuestion(2)" align="center" justify="between" gap="12" :class="$style.head"> + How can I request testnet tokens? + + + + + + + You can request testnet tokens by entering your Celestia testnet address, and clicking the "Received 0.5 TIA" button. Tokens will be sent to your wallet within a few moments. + + + + handleOpenQuestion(3)" align="center" justify="between" gap="12" :class="$style.head"> + What are the limitations on requesting tokens? + + + + + + + To ensure fair distribution and prevent abuse, the faucet has the following limitations: + • You can receive 0.5 TIA per request. + • You can request tokens only once per hour per IP address or wallet address. + • If you reach the limit, you will need to wait before requesting again. + + + + handleOpenQuestion(4)" align="center" justify="between" gap="12" :class="$style.head"> + What should I do if I don’t receive my tokens? + + + + + + + If you haven't received your tokens: + • Double-check that you entered the correct Celestia address. + • Ensure you are using the Mocha network. + • If the issue persists, contact support. + + + + handleOpenQuestion(5)" align="center" justify="between" gap="12" :class="$style.head"> + Can I use testnet tokens on the mainnet? + + + + + + + No, testnet tokens are only for testing on the Celestia Mocha network. They cannot be transferred or used on the Celestia mainnet. + + + + handleOpenQuestion(6)" align="center" justify="between" gap="12" :class="$style.head"> + What happens if I run out of testnet tokens? + + + + + + + If you run out of testnet tokens, you can request more from the faucet (subject to request limits). You may also check community channels for alternative ways to obtain test tokens. + + + + handleOpenQuestion(7)" align="center" justify="between" gap="12" :class="$style.head"> + How can I contribute to the Celestia testnet? + + + + + + + If you no longer need the testnet tokens, please return them to the faucet so that other developers and testers can use them. You can send them back to the + + faucet + + . + Your contribution helps keep the testnet accessible for everyone! + + + + + + + + + + diff --git a/pages/stats/index.vue b/pages/stats/index.vue index e37841ce..c65c4ca6 100644 --- a/pages/stats/index.vue +++ b/pages/stats/index.vue @@ -5,10 +5,11 @@ import Button from "@/components/ui/Button.vue" /** Stats Tabs */ import BlocksTab from "@/components/modules/stats/tabs/BlocksTab.vue" import GeneralTab from "@/components/modules/stats/tabs/GeneralTab.vue" +import EcosystemTab from "@/components/modules/stats/tabs/EcosystemTab.vue" import RollupsTab from "@/components/modules/stats/tabs/RollupsTab.vue" /** Services */ -import { capitilize } from "@/services/utils" +import { capitilize, isMainnet } from "@/services/utils" useHead({ title: "Statistics - Celestia Explorer", @@ -61,8 +62,25 @@ useHead({ const route = useRoute() const router = useRouter() -const tabs = ref(['general', 'blocks', 'rollups']) -const activeTab = ref(route.query.tab && tabs.value.includes(route.query.tab) ? route.query.tab : tabs.value[0]) +const tabs = ref([ + { + name: "general", + visible: true, + }, + { + name: "blocks", + visible: true, + }, + { + name: "rollups", + visible: true, + }, + { + name: "ecosystem", + visible: true, + }, +]) +const activeTab = ref(route.query.tab && tabs.value.filter(t => t.visible).map(t => t.name).includes(route.query.tab) ? route.query.tab : tabs.value[0].name) const updateRouteQuery = () => { router.replace({ @@ -117,8 +135,8 @@ watch( - - {{ capitilize(t) }} + + {{ capitilize(t.name) }} @@ -133,6 +151,7 @@ watch( + diff --git a/pages/validators.vue b/pages/validators.vue index 6cfe5bb5..69f94c63 100644 --- a/pages/validators.vue +++ b/pages/validators.vue @@ -280,7 +280,7 @@ onMounted(() => { - {{ v.moniker ? v.moniker : splitAddress(v.address) }} + {{ v.moniker ? v.moniker : splitAddress(v.address?.hash) }} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 166bbc19..8a22609d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ dependencies: d3: specifier: ^7.8.5 version: 7.9.0 + d3-geo: + specifier: ^3.1.1 + version: 3.1.1 d3-hierarchy: specifier: ^3.1.2 version: 3.1.2 @@ -81,7 +84,7 @@ dependencies: devDependencies: '@nuxt/devtools': specifier: latest - version: 2.1.3(vite@5.4.14)(vue@3.5.13) + version: 2.2.1(vite@5.4.14)(vue@3.5.13) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -93,7 +96,7 @@ devDependencies: version: 3.0.0-rc.52(vite@5.4.14)(vue@3.5.13) nuxt-simple-sitemap: specifier: ^4.2.0 - version: 4.4.1(@nuxt/devtools@2.1.3)(@vue/compiler-core@3.5.13)(h3@1.15.1)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0) + version: 4.4.1(@nuxt/devtools@2.2.1)(@vue/compiler-core@3.5.13)(h3@1.15.1)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0) sass: specifier: 1.66.1 version: 1.66.1 @@ -1981,8 +1984,8 @@ packages: - magicast - supports-color - /@nuxt/devtools-kit@2.1.3(magicast@0.3.5)(vite@5.4.14): - resolution: {integrity: sha512-OlLo8LZTp71Wi9q0ooE1bYeS5P7P1sU3JUb+zqJRX6/jMQa2QP06hc6TOz/5AIsEOq8YPQTum4oJ9gpHx53B0g==} + /@nuxt/devtools-kit@2.2.1(magicast@0.3.5)(vite@5.4.14): + resolution: {integrity: sha512-6txRZPOs+YmiuqjaqZy0rls0CjcmNaJPMITZsLS3hTfKAsKOEMslPjgr0jnf4fpFujmkxFZc10txYlG24JZCAA==} peerDependencies: vite: '>=6.0' dependencies: @@ -1995,7 +1998,7 @@ packages: - supports-color dev: true - /@nuxt/devtools-ui-kit@1.7.0(@nuxt/devtools@2.1.3)(@vue/compiler-core@3.5.13)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0): + /@nuxt/devtools-ui-kit@1.7.0(@nuxt/devtools@2.2.1)(@vue/compiler-core@3.5.13)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0): resolution: {integrity: sha512-pYjwCP3FHz/rrEoJpb8plMinnPHRh+fFc90O+MncMC0aIGydtu4SGwAE3fZsg//JXqkvlY+JyozxqtF9IRA7rA==} peerDependencies: '@nuxt/devtools': 1.7.0 @@ -2004,7 +2007,7 @@ packages: '@iconify-json/logos': 1.2.4 '@iconify-json/ri': 1.2.5 '@iconify-json/tabler': 1.2.16 - '@nuxt/devtools': 2.1.3(vite@5.4.14)(vue@3.5.13) + '@nuxt/devtools': 2.2.1(vite@5.4.14)(vue@3.5.13) '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@5.4.14) '@nuxt/kit': 3.15.4(magicast@0.3.5) '@unocss/core': 0.65.4 @@ -2062,8 +2065,8 @@ packages: semver: 7.7.1 dev: true - /@nuxt/devtools-wizard@2.1.3: - resolution: {integrity: sha512-J+EjL/4E2oLnNyw7Ar2qj/VDa9PeWIqNchZ6kQR+wAQTbWMHX/qbxEPz6Yuflj08ltIwouU6uocixTJQJjfmqQ==} + /@nuxt/devtools-wizard@2.2.1: + resolution: {integrity: sha512-tJGIwFxwIOsDdpefnSPhiVJEjBC5Kr88EORV6PRYVQRPZThiO8if5UM0qhhkwoDYJ5U21nZpyIzKuCQ6svo9vA==} hasBin: true dependencies: consola: 3.4.0 @@ -2128,14 +2131,14 @@ packages: - vue dev: true - /@nuxt/devtools@2.1.3(vite@5.4.14)(vue@3.5.13): - resolution: {integrity: sha512-LBOSFh1UEjyp0vz2e9BEW5TfrsiuSOm5AAllcl/FFs7fYU/v4sZDcqrE+GGiwTQF14n9/4dsHQ5zBbNGr1pJvA==} + /@nuxt/devtools@2.2.1(vite@5.4.14)(vue@3.5.13): + resolution: {integrity: sha512-JkFRYLWFoklBuf+Zv6GwS9HPOFMuN3nomApWCnsNg8H7XqlFNIvB+wetmm6+u+43bNApjqE0ne7Y//o0V6FSaA==} hasBin: true peerDependencies: vite: '>=6.0' dependencies: - '@nuxt/devtools-kit': 2.1.3(magicast@0.3.5)(vite@5.4.14) - '@nuxt/devtools-wizard': 2.1.3 + '@nuxt/devtools-kit': 2.2.1(magicast@0.3.5)(vite@5.4.14) + '@nuxt/devtools-wizard': 2.2.1 '@nuxt/kit': 3.15.4(magicast@0.3.5) '@vue/devtools-core': 7.7.2(vite@5.4.14)(vue@3.5.13) '@vue/devtools-kit': 7.7.2 @@ -2153,7 +2156,7 @@ packages: local-pkg: 1.1.1 magicast: 0.3.5 nypm: 0.6.0 - ohash: 2.0.10 + ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 1.0.0 pkg-types: 2.1.0 @@ -2164,7 +2167,7 @@ packages: tinyglobby: 0.2.12 vite: 5.4.14(sass@1.66.1) vite-plugin-inspect: 11.0.0(@nuxt/kit@3.15.4)(vite@5.4.14) - vite-plugin-vue-inspector: 5.3.1(vite@5.4.14) + vite-plugin-vue-tracer: 0.1.1(vite@5.4.14)(vue@3.5.13) which: 5.0.0 ws: 8.18.1 transitivePeerDependencies: @@ -2454,6 +2457,7 @@ packages: dependencies: is-glob: 4.0.3 micromatch: 4.0.8 + napi-wasm: 1.1.3 dev: true bundledDependencies: - napi-wasm @@ -3906,7 +3910,7 @@ packages: peerDependencies: vue: ^3.0.0 dependencies: - '@vue/devtools-kit': 7.6.8 + '@vue/devtools-kit': 7.7.2 '@vue/devtools-shared': 7.7.2 mitt: 3.0.1 nanoid: 5.1.2 @@ -5709,6 +5713,7 @@ packages: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} hasBin: true + requiresBuild: true dev: true /detect-libc@2.0.3: @@ -7580,6 +7585,10 @@ packages: hasBin: true dev: true + /napi-wasm@1.1.3: + resolution: {integrity: sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg==} + dev: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -7697,6 +7706,7 @@ packages: /node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + requiresBuild: true dev: true /node-fetch-native@1.6.6: @@ -7875,12 +7885,12 @@ packages: - vue dev: true - /nuxt-simple-sitemap@4.4.1(@nuxt/devtools@2.1.3)(@vue/compiler-core@3.5.13)(h3@1.15.1)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0): + /nuxt-simple-sitemap@4.4.1(@nuxt/devtools@2.2.1)(@vue/compiler-core@3.5.13)(h3@1.15.1)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0): resolution: {integrity: sha512-Srj0tNW2+qpOHpJJ2C2YXo9SYHux38vPTiAylFNHLmsw3dcVThiUm4w1acs8Vh116EegxQxzBIVtXMaFTKHZpw==} deprecated: Package has been migrated to @nuxtjs/sitemap. dependencies: '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@5.4.14) - '@nuxt/devtools-ui-kit': 1.7.0(@nuxt/devtools@2.1.3)(@vue/compiler-core@3.5.13)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0) + '@nuxt/devtools-ui-kit': 1.7.0(@nuxt/devtools@2.2.1)(@vue/compiler-core@3.5.13)(nuxt@3.12.4)(postcss@8.5.3)(qrcode@1.5.4)(typescript@5.8.2)(vite@5.4.14)(vue@3.5.13)(webpack@5.98.0) '@nuxt/kit': 3.15.4(magicast@0.3.5) chalk: 5.4.1 defu: 6.1.4 @@ -8171,6 +8181,10 @@ packages: /ohash@2.0.10: resolution: {integrity: sha512-jf9szh2McTXpXGqejbfHxy4wcs6CXc6MShfzLIdHuCrl2W3qG49qutlOMq1Bdmvpv3s/XJffTu4ElRBPtIOncQ==} + /ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + dev: true + /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -10580,7 +10594,7 @@ packages: ansis: 3.17.0 debug: 4.4.0(supports-color@9.4.0) error-stack-parser-es: 1.0.5 - ohash: 2.0.10 + ohash: 2.0.11 open: 10.1.0 perfect-debounce: 1.0.0 sirv: 3.0.1 @@ -10636,6 +10650,20 @@ packages: - supports-color dev: true + /vite-plugin-vue-tracer@0.1.1(vite@5.4.14)(vue@3.5.13): + resolution: {integrity: sha512-8BuReHmbSPd6iRQDQhlyK5+DexY1Hmb4K0GUVo9Te1Yaz8gyOZspBm9qdG1SvebdSIKw3WNlzpdstJ47TJ4bOw==} + peerDependencies: + vite: ^6.0.0 + vue: ^3.5.0 + dependencies: + estree-walker: 3.0.3 + magic-string: 0.30.17 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 5.4.14(sass@1.66.1) + vue: 3.5.13(typescript@5.8.2) + dev: true + /vite-plugin-wasm@3.4.1(vite@5.4.14): resolution: {integrity: sha512-ja3nSo2UCkVeitltJGkS3pfQHAanHv/DqGatdI39ja6McgABlpsZ5hVgl6wuR8Qx5etY3T5qgDQhOWzc5RReZA==} peerDependencies: diff --git a/services/api/address.js b/services/api/address.js index 0b1c57ae..3fc6d0bd 100644 --- a/services/api/address.js +++ b/services/api/address.js @@ -387,3 +387,18 @@ export const fetchVestingPeriods = ({ id, limit, offset }) => { console.error(error) } } + +export const fetchCelestials = ({ hash, limit, offset }) => { + try { + const url = new URL(`${useServerURL()}/address/${hash}/celestials`) + + if (limit) url.searchParams.append("limit", limit) + if (offset) url.searchParams.append("offset", offset) + + return useFetch(url.href, { + key: "address_celestials", + }) + } catch (error) { + console.error(error) + } +} diff --git a/services/api/faucet.js b/services/api/faucet.js new file mode 100644 index 00000000..4975a187 --- /dev/null +++ b/services/api/faucet.js @@ -0,0 +1,29 @@ +/** Services */ +import { faucetURL } from "@/services/config" + +export const faucetAddress = "celestia16etnwjxg6dsjuavjpr9tk822czfeylfm9f7x5g" + +export const fetchBalance = async () => { + try { + const data = await useFetch(`${faucetURL}/balance`) + return data + } catch (error) { + console.error(error) + } +} + +export const executeFaucet = async (address) => { + try { + + const data = await useFetch(`${faucetURL}/faucet`, { + method: "post", + body: { + address, + }, + }) + + return data + } catch (error) { + console.error(error) + } +} diff --git a/services/api/stats.js b/services/api/stats.js index db99538e..8e184c77 100644 --- a/services/api/stats.js +++ b/services/api/stats.js @@ -1,7 +1,7 @@ /** Services */ -import { tvlServiceURL, useServerURL } from "@/services/config" +import { nodeStatsURL, tvlServiceURL, useServerURL } from "@/services/config" -export const fetch24hDiffs = async ({ name }) => { +export const fetchGeneralStats = async ({ name }) => { try { const data = await $fetch(`${useServerURL()}/stats/${name}`) return data @@ -175,3 +175,17 @@ export const fetchSquareSize = async (from) => { console.error(error) } } + +export const fetchNodeStats = async ({ name, from, to }) => { + try { + const url = new URL(`${nodeStatsURL}/stats/${name}`) + + if (from) url.searchParams.append("from", from) + if (to) url.searchParams.append("to", to) + + const data = await $fetch(url.href) + return data + } catch (error) { + console.error(error) + } +} \ No newline at end of file diff --git a/services/config.js b/services/config.js index 34d066bc..b5aa41e2 100644 --- a/services/config.js +++ b/services/config.js @@ -37,7 +37,7 @@ export const useServerURL = () => { return Server.API.dev default: - return Server.API.dev + return Server.API.mainnet } } @@ -61,7 +61,7 @@ export const useSocketURL = () => { return Server.WSS.dev default: - return Server.WSS.dev + return Server.WSS.mainnet } } @@ -107,5 +107,7 @@ export const getStartChainDate = () => { } } -export const tvlServiceURL = "https://tvl.celenium.io/v1" export const blockscoutURL = "https://celestia-l2-router.k8s-dev.blockscout.com/api/v1/celestia/l2BatchMetadata" +export const nodeStatsURL = "https://node-stats.celenium.io/v1" +export const faucetURL = "https://api-faucet.celenium.io/v1" +export const tvlServiceURL = "https://tvl.celenium.io/v1" diff --git a/services/constants/advertising.js b/services/constants/advertising.js index ff9eaee1..ec2d44cc 100644 --- a/services/constants/advertising.js +++ b/services/constants/advertising.js @@ -9,13 +9,22 @@ const advertisements = [ weight: 0.4, }, { - name: 'celenium_survey', - link: 'https://t.co/4nBFExP2VR', - icon: 'validator', - header: 'Celenium survey', - body: 'Please take 5 minutes of your time and answer a few questions.', - footer: 'Take the survey', - weight: 0.3, + name: 'faucet', + internalLink: '/faucet', + icon: 'drop', + header: 'Celenium Faucet', + body: 'Free testnet TIA for the Celestia Mocha network!', + footer: 'Get Tokens', + weight: 0.2, + }, + { + name: 'celestials', + link: 'https://celestials.id/?utm_source=celenium_banner', + icon: 'celestials', + header: 'Celestials ID', + body: 'Celestia Modular usernames with unique, generative artworks', + footer: 'Pick your id', + weight: 0.2, }, { name: 'lumina', @@ -24,7 +33,7 @@ const advertisements = [ header: 'Your Own Node', body: 'Easily launch a node right in your browser or on your phone.', footer: 'Run Light Node', - weight: 0.3, + weight: 0.2, }, { name: 'celestia_update', @@ -33,7 +42,16 @@ const advertisements = [ header: 'Celestia Upgrade', body: 'Mainnet update scheduled for 28.01.2025.', footer: 'View Docs', - weight: 1.1, + weight: 0, + }, + { + name: 'celenium_survey', + link: 'https://t.co/4nBFExP2VR', + icon: 'validator', + header: 'Celenium survey', + body: 'Please take 5 minutes of your time and answer a few questions.', + footer: 'Take the survey', + weight: 0, }, ] diff --git a/services/constants/stats.js b/services/constants/stats.js index 0b0cf214..4a0f06d4 100644 --- a/services/constants/stats.js +++ b/services/constants/stats.js @@ -120,7 +120,19 @@ export const STATS_SERIES = [ }, ], }, -] + { + group: 'Ecosystem', + series: [ + { + name: 'nodetype', + title: 'node type', + }, + { + name: 'version', + title: 'version', + }, + ], + },] // TO DO: Replace forEach with for export function getSeriesByGroupAndType(group, type) { @@ -223,3 +235,316 @@ export const STATS_TIMEFRAMES = [ timeframe: 'month', }, ] + +const countryCodesMap = { + AF: 'AFG', + AL: 'ALB', + DZ: 'DZA', + AS: 'ASM', + AD: 'AND', + AO: 'AGO', + AI: 'AIA', + AQ: 'ATA', + AG: 'ATG', + AR: 'ARG', + AM: 'ARM', + AW: 'ABW', + AU: 'AUS', + AT: 'AUT', + AZ: 'AZE', + BS: 'BHS', + BH: 'BHR', + BD: 'BGD', + BB: 'BRB', + BY: 'BLR', + BE: 'BEL', + BZ: 'BLZ', + BJ: 'BEN', + BM: 'BMU', + BT: 'BTN', + BO: 'BOL', + BA: 'BIH', + BW: 'BWA', + BV: 'BVT', + BR: 'BRA', + IO: 'IOT', + BN: 'BRN', + BG: 'BGR', + BF: 'BFA', + BI: 'BDI', + KH: 'KHM', + CM: 'CMR', + CA: 'CAN', + CV: 'CPV', + KY: 'CYM', + CF: 'CAF', + TD: 'TCD', + CL: 'CHL', + CN: 'CHN', + CX: 'CXR', + CC: 'CCK', + CO: 'COL', + KM: 'COM', + CG: 'COG', + CD: 'COD', + CK: 'COK', + CR: 'CRI', + CI: 'CIV', + HR: 'HRV', + CU: 'CUB', + CY: 'CYP', + CZ: 'CZE', + DK: 'DNK', + DJ: 'DJI', + DM: 'DMA', + DO: 'DOM', + EC: 'ECU', + EG: 'EGY', + SV: 'SLV', + GQ: 'GNQ', + ER: 'ERI', + EE: 'EST', + ET: 'ETH', + FK: 'FLK', + FO: 'FRO', + FJ: 'FJI', + FI: 'FIN', + FR: 'FRA', + GF: 'GUF', + PF: 'PYF', + TF: 'ATF', + GA: 'GAB', + GM: 'GMB', + GE: 'GEO', + DE: 'DEU', + GH: 'GHA', + GI: 'GIB', + GR: 'GRC', + GL: 'GRL', + GD: 'GRD', + GP: 'GLP', + GU: 'GUM', + GT: 'GTM', + GN: 'GIN', + GW: 'GNB', + GY: 'GUY', + HT: 'HTI', + HM: 'HMD', + VA: 'VAT', + HN: 'HND', + HK: 'HKG', + HU: 'HUN', + IS: 'ISL', + IN: 'IND', + ID: 'IDN', + IR: 'IRN', + IQ: 'IRQ', + IE: 'IRL', + IL: 'ISR', + IT: 'ITA', + JM: 'JAM', + JP: 'JPN', + JO: 'JOR', + KZ: 'KAZ', + KE: 'KEN', + KI: 'KIR', + KP: 'PRK', + KR: 'KOR', + KW: 'KWT', + KG: 'KGZ', + LA: 'LAO', + LV: 'LVA', + LB: 'LBN', + LS: 'LSO', + LR: 'LBR', + LY: 'LBY', + LI: 'LIE', + LT: 'LTU', + LU: 'LUX', + MO: 'MAC', + MG: 'MDG', + MW: 'MWI', + MY: 'MYS', + MV: 'MDV', + ML: 'MLI', + MT: 'MLT', + MH: 'MHL', + MQ: 'MTQ', + MR: 'MRT', + MU: 'MUS', + YT: 'MYT', + MX: 'MEX', + FM: 'FSM', + MD: 'MDA', + MC: 'MCO', + MN: 'MNG', + MS: 'MSR', + MA: 'MAR', + MZ: 'MOZ', + MM: 'MMR', + NA: 'NAM', + NR: 'NRU', + NP: 'NPL', + NL: 'NLD', + NC: 'NCL', + NZ: 'NZL', + NI: 'NIC', + NE: 'NER', + NG: 'NGA', + NU: 'NIU', + NF: 'NFK', + MP: 'MNP', + MK: 'MKD', + NO: 'NOR', + OM: 'OMN', + PK: 'PAK', + PW: 'PLW', + PS: 'PSE', + PA: 'PAN', + PG: 'PNG', + PY: 'PRY', + PE: 'PER', + PH: 'PHL', + PN: 'PCN', + PL: 'POL', + PT: 'PRT', + PR: 'PRI', + QA: 'QAT', + RE: 'REU', + RO: 'ROU', + RU: 'RUS', + RW: 'RWA', + SH: 'SHN', + KN: 'KNA', + LC: 'LCA', + PM: 'SPM', + VC: 'VCT', + WS: 'WSM', + SM: 'SMR', + ST: 'STP', + SA: 'SAU', + SN: 'SEN', + SC: 'SYC', + SL: 'SLE', + SG: 'SGP', + SK: 'SVK', + SI: 'SVN', + SB: 'SLB', + SO: 'SOM', + ZA: 'ZAF', + GS: 'SGS', + ES: 'ESP', + LK: 'LKA', + SD: 'SDN', + SR: 'SUR', + SJ: 'SJM', + SZ: 'SWZ', + SE: 'SWE', + CH: 'CHE', + SY: 'SYR', + TW: 'TWN', + TJ: 'TJK', + TZ: 'TZA', + TH: 'THA', + TL: 'TLS', + TG: 'TGO', + TK: 'TKL', + TO: 'TON', + TT: 'TTO', + TN: 'TUN', + TR: 'TUR', + TM: 'TKM', + TC: 'TCA', + TV: 'TUV', + UG: 'UGA', + UA: 'UKR', + AE: 'ARE', + GB: 'GBR', + US: 'USA', + UM: 'UMI', + UY: 'URY', + UZ: 'UZB', + VU: 'VUT', + VE: 'VEN', + VN: 'VNM', + VG: 'VGB', + VI: 'VIR', + WF: 'WLF', + EH: 'ESH', + YE: 'YEM', + ZM: 'ZMB', + ZW: 'ZWE', + AX: 'ALA', + BQ: 'BES', + CW: 'CUW', + GG: 'GGY', + IM: 'IMN', + JE: 'JEY', + ME: 'MNE', + BL: 'BLM', + MF: 'MAF', + RS: 'SRB', + SX: 'SXM', + XK: 'XKK' +} +export const convertCountryCode = (alpha2) => countryCodesMap[alpha2.toUpperCase()] + +const countryCentroidMap = { + CAN: [-110, 60], + USA: [-100, 41], + FRA: [2.5, 47], + GBR: [-1.8, 53], + IDN: [114, -1], + // NOR: [12, 63], + NZL: [172.3, -42.5], +} +export const getCountryCentroid = (name) => countryCentroidMap[name] + +const cityCountryMap = { + sakaiminato: "JPN", + istanbul: "TUR", + imperia: "ITA", + ko_samui: "THA", + fatih: "TUR", + nicosia: "CYP", +} +export const getCountryByCity = (city) => cityCountryMap[city.toLowerCase().replace(" ", "_")] + +const loaderPathes = [ + { + name: "France", + path: "M283.4 19.83c-3.2 0-31.2 5.09-31.2 5.09c-1.3 41.61-30.4 78.48-90.3 84.88l-12.8-23.07l-25.1 2.48l11.3 60.09l-113.79-4.9l12.2 41.5C156.3 225.4 150.7 338.4 124 439.4c47 53 141.8 47.8 186 43.1c3.1-62.2 52.4-64.5 135.9-32.2c11.3-17.6 18.8-36 44.6-50.7l-46.6-139.5l-27.5 6.2c11-21.1 32.2-49.9 50.4-63.4l15.6-86.9c-88.6-6.3-146.4-46.36-199-96.17", + weight: 0.2, + }, + { + name: "Africa", + path: "m201.56 19.495l-87.79 9.131l-73.745 94.814v52.676l56.186 61.805l64.615-13.344l49.164 9.832l-10.535 37.926l33.711 61.103l-16.855 42.842l39.79 116.225l53.62-8.768l49.164-55.484l4.213-38.629l31.605-23.879l-6.322-69.531l83.594-106.994l-51.989 7.263l-79.363-138.359l-125.016-8.428z", + weight: 0.2, + }, + { + name: "Mongolia", + path: "m18.83 183.4l73.19-29.3L165.6 185c6.3-17 8.6-42.6 26.3-44.3c22.3-2.1 42.9 15.1 47.1 39.9l54-1.6l54.5 22.8l55-35.2l32.3 7.9s-20.3 32.6-9.7 42.4c9.1 8.5 35.5-10.9 35.5-10.9l32.6 22.1l-87.1 62.7c-6.7-4.7-16.4-13.5-27.1-5c-9.9 7.9-6 21.9 1 33.8c-32.9 31-71 43-109.8 51.7l-127.8-30l-92.59-70c9.92-34.7-14.36-61-30.98-87.9", + weight: 0.2, + }, + { + name: "Brazil", + path: "M292.8 41.71c16.1 58.89 125.3 78.19 197.9 116.19c1.6 35.2-14.4 72.6-56.7 102.3c2.9 70.2-41.8 110.2-114.3 132.4c-.3 33.2-12.7 64-47.3 90.3l-59-36.4l47.4-34.2c-1.8-25.6-9.6-52.3-55-67.3l-26.3-93.2c-54.5-10.4-51.9-31.3-56.3-50.9l-64.93 20.4c-49.154-31-51.902-75.4 6.26-83.4l6.99-72.78l51.18 9.12L133 37.03l49.6-7.9l20.7 37.33z", + weight: 0.2, + }, + { + name: "Australia", + path: "m380.37 28.839l-27.24 100.215l-64-48l17.405-34.46l-83.863 8.079l-13.541 42.38l-35.512-25.482l-67.16 85.62l-83.008 48.593l34.81 156.752l38.87 6.518l112-64l74.38 52.082l21.62-28.094l32 72.012L424 415.452l64.549-126.398l-6.014-64.703l-65.404-79.297l-36.762-116.215z", + weight: 0.2, + } +] +export function getRandomLoaderPath() { + const randomNum = Math.random() + + let cumWeight = 0 + for (let p of loaderPathes.filter(el => el.weight <= 1)) { + cumWeight += p.weight + if (randomNum <= cumWeight) { + return p.path + } + } +} \ No newline at end of file