From e2f019593c25a365797d29117745631ad9102cdd Mon Sep 17 00:00:00 2001 From: Satyajeet Kolhapure Date: Fri, 25 Oct 2024 16:09:54 +0100 Subject: [PATCH] fixed as per review feedback --- explorer/package.json | 2 + .../src/constants/columns/attestation.tsx | 18 ++- explorer/src/custom.css | 17 +++ explorer/src/main.tsx | 1 + .../components/AttestationCard/index.tsx | 113 +++++++++++++----- .../components/AttestationCard/interface.ts | 8 +- explorer/src/pages/Attestations/index.tsx | 2 +- explorer/src/pages/MyAttestations/index.tsx | 21 +--- .../components/RecentAttestations/index.tsx | 4 +- explorer/src/pages/Subject/index.tsx | 21 +--- explorer/src/utils/dateUtils.ts | 25 ++++ pnpm-lock.yaml | 51 ++++++++ 12 files changed, 205 insertions(+), 78 deletions(-) create mode 100644 explorer/src/custom.css diff --git a/explorer/package.json b/explorer/package.json index 22eef1d4..d59c15f6 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -27,6 +27,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@tanstack/react-table": "^8.10.7", "@verax-attestation-registry/verax-sdk": "2.1.1", + "@tippyjs/react": "^4.2.6", "@wagmi/core": "^1.4.7", "abitype": "^0.10.3", "class-variance-authority": "^0.7.0", @@ -45,6 +46,7 @@ "swr": "^2.2.4", "tailwind-merge": "^2.0.0", "tailwindcss-animate": "^1.0.7", + "tippy.js": "6", "usehooks-ts": "^2.9.1", "viem": "1.18.9", "vite-tsconfig-paths": "^4.2.1", diff --git a/explorer/src/constants/columns/attestation.tsx b/explorer/src/constants/columns/attestation.tsx index dbbff510..8fa39ead 100644 --- a/explorer/src/constants/columns/attestation.tsx +++ b/explorer/src/constants/columns/attestation.tsx @@ -12,8 +12,13 @@ import { Link } from "@/components/Link"; import { SortByDate } from "@/components/SortByDate"; import { ColumnsOptions } from "@/interfaces/components"; import { SWRCell } from "@/pages/Attestations/components/SWRCell"; -import { toAttestationById, toPortalById, toSchemaById } from "@/routes/constants"; -import { getBlockExplorerLink } from "@/utils"; +import { + CHAIN_ID_ROUTE, + toAttestationById, + toAttestationsBySubject, + toPortalById, + toSchemaById, +} from "@/routes/constants"; import { displayAmountWithComma } from "@/utils/amountUtils"; import { cropString } from "@/utils/stringUtils"; @@ -22,9 +27,14 @@ import { EMPTY_0X_STRING, EMPTY_STRING, ITEMS_PER_PAGE_DEFAULT } from "../index" interface ColumnsProps { sortByDate: boolean; chain: Chain; + network: string; } -export const columns = ({ sortByDate = true, chain }: Partial = {}): ColumnDef[] => [ +export const columns = ({ + sortByDate = true, + chain, + network, +}: Partial = {}): ColumnDef[] => [ { accessorKey: "id", header: () => ( @@ -82,7 +92,7 @@ export const columns = ({ sortByDate = true, chain }: Partial = {} return ( e.stopPropagation()} target="_blank" className="hover:underline" diff --git a/explorer/src/custom.css b/explorer/src/custom.css new file mode 100644 index 00000000..d1cb9810 --- /dev/null +++ b/explorer/src/custom.css @@ -0,0 +1,17 @@ +.tippy-box[data-theme~="light"] { + background-color: #0c0c11; + color: #fefefe; +} + +.tippy-box[data-theme~="dark"] { + background-color: #fefefe; + color: #0c0c11; +} + +.tippy-box[data-theme~="dark"] .tippy-arrow { + color: #fefefe; +} + +.tippy-box[data-theme~="light"] .tippy-arrow { + color: #0c0c11; +} diff --git a/explorer/src/main.tsx b/explorer/src/main.tsx index 3e377910..3fd3bd70 100644 --- a/explorer/src/main.tsx +++ b/explorer/src/main.tsx @@ -5,6 +5,7 @@ import { RouterProvider } from "react-router-dom"; import { router } from "./routes"; import "./index.css"; +import "./custom.css"; createRoot(document.getElementById("root")!).render( diff --git a/explorer/src/pages/Attestation/components/AttestationCard/index.tsx b/explorer/src/pages/Attestation/components/AttestationCard/index.tsx index 38f7ce2b..4f08842e 100644 --- a/explorer/src/pages/Attestation/components/AttestationCard/index.tsx +++ b/explorer/src/pages/Attestation/components/AttestationCard/index.tsx @@ -1,23 +1,25 @@ +import Tippy from "@tippyjs/react"; +import "tippy.js/dist/tippy.css"; import { ChevronRight } from "lucide-react"; import { generatePath, useLocation, useNavigate } from "react-router-dom"; import { useTernaryDarkMode } from "usehooks-ts"; import { Button } from "@/components/Buttons"; import { EButtonType } from "@/components/Buttons/enum"; +import { issuersData } from "@/pages/Home/data"; +import { IIssuer } from "@/pages/Home/interface"; import { useNetworkContext } from "@/providers/network-provider/context"; import { APP_ROUTES } from "@/routes/constants"; -import { parseDateTime } from "@/utils/dateUtils"; +import { timeElapsed } from "@/utils/dateUtils"; import { IAttestationCardProps } from "./interface"; export const AttestationCard: React.FC = ({ id, - logo, - logoDark, - name, - description, - issuerName, + schemaId, + portalId, issuanceDate, + expiryDate, }) => { const { network: { network }, @@ -25,6 +27,33 @@ export const AttestationCard: React.FC = ({ const navigate = useNavigate(); const location = useLocation(); const { isDarkMode } = useTernaryDarkMode(); + const isExpired = expiryDate ? new Date(expiryDate * 1000) < new Date() : false; + + const issuerData = issuersData.find((issuer) => + issuer.attestationDefinitions.some( + (definition) => + definition.schema.toLowerCase() === schemaId.toLowerCase() && + definition.portal.toLowerCase() === portalId.toLowerCase(), + ), + ) as IIssuer; + const attestationDefinitions = issuerData?.attestationDefinitions.find( + (definition) => definition.schema.toLowerCase() === schemaId.toLowerCase(), + ); + + if (!issuerData) { + console.log("Issuer not found for attestation", id, schemaId, portalId); + return null; + } + + const logo = attestationDefinitions?.logo ?? issuerData?.logo; + const logoDark = attestationDefinitions?.logoDark ?? issuerData?.logoDark; + const name = attestationDefinitions?.name ?? issuerData?.name; + const description = attestationDefinitions?.description ?? ""; + const issuerName = issuerData.name; + + const maxDescriptionLength = 200; + const isDescriptionLong = description.length > maxDescriptionLength; + const truncatedDescription = isDescriptionLong ? `${description.slice(0, maxDescriptionLength)}...` : description; const handleViewDetailsClick = (id: string) => { navigate(generatePath(APP_ROUTES.ATTESTATION_BY_ID, { chainId: network, id }), { @@ -40,33 +69,57 @@ export const AttestationCard: React.FC = ({ return (
-
-
- {displayLogo()} +
+
+
+ {displayLogo()} +
+
+
{name}
+
{issuerName}
+
- {name} + {description && description.trim() ? ( +
+ {isDescriptionLong ? ( + + {truncatedDescription} + + ) : ( + {description} + )} +
+ ) : null}
- {description && description.trim() ? ( -
{description}
- ) : null} -
- Issuer : - {issuerName} -
-
- Date : - {parseDateTime(issuanceDate.toString(), true).stringUTC} -
-
-
); diff --git a/explorer/src/pages/Attestation/components/AttestationCard/interface.ts b/explorer/src/pages/Attestation/components/AttestationCard/interface.ts index f1902b89..bbdf149c 100644 --- a/explorer/src/pages/Attestation/components/AttestationCard/interface.ts +++ b/explorer/src/pages/Attestation/components/AttestationCard/interface.ts @@ -1,9 +1,7 @@ export interface IAttestationCardProps { id: string; - logo: React.FC>; - logoDark?: React.FC>; - name: string; - description?: string; - issuerName: string; + schemaId: string; + portalId: string; issuanceDate: number; + expiryDate?: number; } diff --git a/explorer/src/pages/Attestations/index.tsx b/explorer/src/pages/Attestations/index.tsx index 3b0a3b2d..2f01f227 100644 --- a/explorer/src/pages/Attestations/index.tsx +++ b/explorer/src/pages/Attestations/index.tsx @@ -110,7 +110,7 @@ export const Attestations: React.FC = () => { const data = isLoading ? { columns: columnsSkeletonRef.current, list: skeletonAttestations(itemsPerPage) } - : { columns: columns({ chain: network.chain }), list: attestationsList || [] }; + : { columns: columns({ chain: network.chain, network: network.network }), list: attestationsList || [] }; const renderPagination = () => { if (attestationsCount) { diff --git a/explorer/src/pages/MyAttestations/index.tsx b/explorer/src/pages/MyAttestations/index.tsx index 356612b3..1f2e2a40 100644 --- a/explorer/src/pages/MyAttestations/index.tsx +++ b/explorer/src/pages/MyAttestations/index.tsx @@ -19,8 +19,6 @@ import { cropString } from "@/utils/stringUtils"; import { AttestationCard } from "../Attestation/components/AttestationCard"; import { TitleAndSwitcher } from "../Attestations/components/TitleAndSwitcher"; -import { issuersData } from "../Home/data"; -import { IIssuer } from "../Home/interface"; export const MyAttestations: React.FC = () => { const { @@ -94,27 +92,14 @@ export const MyAttestations: React.FC = () => {
{attestationsList.map((attestation) => { - const issuerData = issuersData.find((issuer) => - issuer.attestationDefinitions.some( - (definition) => - definition.schema === attestation.schema.id && definition.portal === attestation.portal.id, - ), - ) as IIssuer; - const attestationDefinitions = issuerData?.attestationDefinitions.find( - (definition) => definition.schema === attestation.schema.id, - ); - - if (!issuerData) return null; return ( ); })} diff --git a/explorer/src/pages/Schema/components/RecentAttestations/index.tsx b/explorer/src/pages/Schema/components/RecentAttestations/index.tsx index b7c1ee37..11b02ef3 100644 --- a/explorer/src/pages/Schema/components/RecentAttestations/index.tsx +++ b/explorer/src/pages/Schema/components/RecentAttestations/index.tsx @@ -12,7 +12,7 @@ import { APP_ROUTES } from "@/routes/constants"; export const RecentAttestations: React.FC<{ schemaId: string }> = ({ schemaId }) => { const { sdk, - network: { chain }, + network: { chain, network }, } = useNetworkContext(); const { data: attestations, isLoading } = useSWR( @@ -27,7 +27,7 @@ export const RecentAttestations: React.FC<{ schemaId: string }> = ({ schemaId }) const data = isLoading ? { columns: columnsSkeletonRef.current, list: skeletonAttestations(5) } : { - columns: columns({ sortByDate: false, chain }), + columns: columns({ sortByDate: false, chain, network }), list: attestations || [], }; diff --git a/explorer/src/pages/Subject/index.tsx b/explorer/src/pages/Subject/index.tsx index b8d14294..3518f06e 100644 --- a/explorer/src/pages/Subject/index.tsx +++ b/explorer/src/pages/Subject/index.tsx @@ -7,8 +7,6 @@ import { SWRKeys } from "@/interfaces/swr/enum"; import { useNetworkContext } from "@/providers/network-provider/context"; import { AttestationCard } from "../Attestation/components/AttestationCard"; -import { issuersData } from "../Home/data"; -import { IIssuer } from "../Home/interface"; export const Subject: React.FC = () => { const { subject } = useParams(); @@ -36,27 +34,14 @@ export const Subject: React.FC = () => {
{attestationsList && attestationsList.map((attestation) => { - const issuerData = issuersData.find((issuer) => - issuer.attestationDefinitions.some( - (definition) => - definition.schema === attestation.schema.id && definition.portal === attestation.portal.id, - ), - ) as IIssuer; - const attestationDefinitions = issuerData?.attestationDefinitions.find( - (definition) => definition.schema === attestation.schema.id, - ); - - if (!issuerData) return null; return ( ); })} diff --git a/explorer/src/utils/dateUtils.ts b/explorer/src/utils/dateUtils.ts index 68193966..ff92ee19 100644 --- a/explorer/src/utils/dateUtils.ts +++ b/explorer/src/utils/dateUtils.ts @@ -23,3 +23,28 @@ export const parseDateTime = (inputDate: string, isSeconds = false): ParseDateTi }, } as const; }; + +export const timeElapsed = (seconds: number): string => { + const now = new Date(); + const secondsElapsed = Math.floor(now.getTime() / 1000) - seconds; + + const minutes = Math.floor(secondsElapsed / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + const months = Math.floor(days / 30.44); + const years = Math.floor(days / 365.25); + + if (years > 0) { + return years === 1 ? "1 year ago" : `${years} years ago`; + } else if (months > 0) { + return months === 1 ? "1 month ago" : `${months} months ago`; + } else if (days > 0) { + return days === 1 ? "1 day ago" : `${days} days ago`; + } else if (hours > 0) { + return hours === 1 ? "1 hour ago" : `${hours} hours ago`; + } else if (minutes > 0) { + return minutes === 1 ? "1 minute ago" : `${minutes} minutes ago`; + } else { + return secondsElapsed === 1 ? "1 second ago" : `${secondsElapsed} seconds ago`; + } +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a1b9dd74..f88542c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -89,6 +89,9 @@ importers: '@tanstack/react-table': specifier: ^8.10.7 version: 8.17.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tippyjs/react': + specifier: ^4.2.6 + version: 4.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@verax-attestation-registry/verax-sdk': specifier: 2.1.1 version: 2.1.1(@graphql-mesh/types@0.98.4(@graphql-mesh/store@0.95.8)(@graphql-tools/utils@10.2.0(graphql@16.8.1))(graphql@16.8.1)(tslib@2.6.2))(@graphql-tools/utils@10.2.0(graphql@16.8.1))(@types/node@20.12.12)(@types/react@18.3.2)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.6.2)(typescript@5.2.2) @@ -146,6 +149,9 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.3.78)(@types/node@20.12.12)(typescript@5.2.2))) + tippy.js: + specifier: '6' + version: 6.3.7 usehooks-ts: specifier: ^2.9.1 version: 2.16.0(react@18.3.1) @@ -2335,10 +2341,12 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/config-array@0.5.0': resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -2346,9 +2354,11 @@ packages: '@humanwhocodes/object-schema@1.2.1': resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + deprecated: Use @eslint/object-schema instead '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@ipld/dag-cbor@7.0.3': resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==} @@ -3147,9 +3157,11 @@ packages: '@openzeppelin/defender-admin-client@1.54.2': resolution: {integrity: sha512-bKU+T/eY9P0rC7o+0av8BDb7/L2Ixgb9LVh+1gVVyg6ZDBT07DoU9VONOXJuL6rbOnlniZVo4xhm/7kNAuLIyw==} + deprecated: This package has been deprecated and will no longer be maintained, please use @openzeppelin/defender-sdk package instead. '@openzeppelin/defender-base-client@1.54.2': resolution: {integrity: sha512-0k2Md6WKKkLTbsygz4UYWojJAkgrNLrishmosUIBCjaiGcAXMopgnRgX6V4WjnWkyI8RVEqb9H6IZY+8BNk6Bw==} + deprecated: This package has been deprecated and will no longer be maintained, please use @openzeppelin/defender-sdk package instead. '@openzeppelin/defender-sdk-base-client@1.13.0': resolution: {integrity: sha512-XyCHF4Q//rInmJG6XM9x4JDiERJTCjmGX7FOmtbXYAKTTE5ygUvFU7gXJ5oxtbB2anPU3OJIPM25Shkd3+7dKw==} @@ -3452,6 +3464,9 @@ packages: resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} engines: {node: '>=12'} + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@prettier/sync@0.3.0': resolution: {integrity: sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw==} peerDependencies: @@ -4257,6 +4272,12 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@tippyjs/react@4.2.6': + resolution: {integrity: sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} @@ -4808,9 +4829,11 @@ packages: '@walletconnect/sign-client@2.10.2': resolution: {integrity: sha512-vviSLV3f92I0bReX+OLr1HmbH0uIzYEQQFd1MzIfDk9PkfFT/LLAHhUnDaIAMkIdippqDcJia+5QEtT4JihL3Q==} + deprecated: Reliability and performance greatly improved - please see https://github.com/WalletConnect/walletconnect-monorepo/releases '@walletconnect/sign-client@2.11.0': resolution: {integrity: sha512-H2ukscibBS+6WrzQWh+WyVBqO5z4F5et12JcwobdwgHnJSlqIoZxqnUYYWNCI5rUR5UKsKWaUyto4AE9N5dw4Q==} + deprecated: Reliability and performance greatly improved - please see https://github.com/WalletConnect/walletconnect-monorepo/releases '@walletconnect/time@1.0.2': resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} @@ -5224,10 +5247,12 @@ packages: are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} + deprecated: This package is no longer supported. are-we-there-yet@4.0.2: resolution: {integrity: sha512-ncSWAawFhKMJDTdoAeOV+jyW1VCMj5QIAwULIBV0SSR7B/RLPPEQiknKcg/RIIZlUQrxELpsxMiTUoAQ4sIUyg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -7187,6 +7212,7 @@ packages: ethereum-bloom-filters@1.1.0: resolution: {integrity: sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==} + deprecated: do not use this package use package versions above as this can miss some topics ethereum-cryptography@0.1.3: resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} @@ -7705,10 +7731,12 @@ packages: gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} + deprecated: This package is no longer supported. gauge@5.0.2: resolution: {integrity: sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. generate-function@2.3.1: resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} @@ -7815,13 +7843,16 @@ packages: glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported glob@9.3.5: resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} @@ -8212,6 +8243,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -9710,10 +9742,12 @@ packages: npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. npmlog@7.0.1: resolution: {integrity: sha512-uJ0YFk/mCQpLBt+bxN88AKd+gyqZvZDbtiNxk6Waqcj2aPRyfVx8ITawkyQynxUagInjdYT1+qj4NfA5KJJUxg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -10944,10 +10978,12 @@ packages: rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@5.0.5: @@ -11724,6 +11760,9 @@ packages: resolution: {integrity: sha512-0PU3c9PjMnltZaFo2sGYv/nnJsMjG0Cxx8X6FXHPPGjFyoo1SJDxvUXW1207rdiSxYizf31roo+GrkIByQeZoA==} engines: {node: '>=12'} + tippy.js@6.3.7: + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} @@ -17010,6 +17049,8 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@popperjs/core@2.11.8': {} + '@prettier/sync@0.3.0(prettier@3.2.5)': dependencies: prettier: 3.2.5 @@ -17913,6 +17954,12 @@ snapshots: '@babel/runtime': 7.24.5 '@testing-library/dom': 8.20.1 + '@tippyjs/react@4.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tippy.js: 6.3.7 + '@tokenizer/token@0.3.0': {} '@trysound/sax@0.2.0': {} @@ -28194,6 +28241,10 @@ snapshots: tiny-lru@11.2.6: {} + tippy.js@6.3.7: + dependencies: + '@popperjs/core': 2.11.8 + title-case@3.0.3: dependencies: tslib: 2.6.2