From 99a44b6fc1cc154a22bbf7b94e41c27f101f38ef Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Thu, 25 Jun 2026 07:50:28 +0530 Subject: [PATCH 01/10] feat: ga gtm integration (#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md --------- Co-authored-by: manishdex25 Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * refactor: update Polygon network label to include abbreviation (POL) - Changed the label for the Polygon network from 'Polygon' to 'Polygon (POL)' in multiple files, including NetworkModal, VerifySection, and chain-info. - Updated corresponding test cases to reflect the new label. - Adjusted chain configuration to use 'pol' instead of 'matic' for consistency. * fix: update Polygon network configuration - Changed the chain configuration from CHAIN_ID.pol to CHAIN_ID.matic for the Polygon network. - Added a comment indicating the need to revert to CHAIN_ID.pol once @trustvc/trustvc version 2.14.0 is published. * chore: update dependencies in package.json and package-lock.json - Bumped @trustvc/trustvc to version 2.14.1. - Updated @digitalbazaar/bbs-signatures to version 3.1.0 and its dependencies. - Updated @digitalbazaar/bls12-381-multikey to version 2.2.0 and its dependencies. - Updated @noble/curves and @noble/hashes to version 2.2.0. - Added new dependencies for cborg version 4.5.8 in multiple modules. - Removed outdated dependencies and cleaned up package-lock.json for better maintainability. * chore: update package-lock.json with new dependencies - Added new dependencies for @scure/base, @scure/bip32, @scure/bip39, and @sentry packages. - Updated existing dependencies for @noble/curves and @noble/hashes. - Enhanced package-lock.json for improved maintainability and consistency. * fix: update Polygon network configuration - Changed the chain configuration from CHAIN_ID.pol to CHAIN_ID.matic for the Polygon network. - Added a comment indicating the need to revert to CHAIN_ID.pol once @trustvc/trustvc version 2.14.0 is published. * feat: add end-to-end verification tests for Polygon Amoy documents - Introduced new test suite for verifying OpenAttestation v2 and W3C Verifiable Credential documents on the Polygon Amoy testnet (chainId 80002) and Polygon POL mainnet (chainId 137). - Created fixtures for minted documents and scenarios for tampered and not minted documents. - Implemented runtime modifications to generate test cases dynamically, ensuring comprehensive coverage of document integrity and status checks. * feat: enhance end-to-end tests for OpenAttestation v2 documents - Added a new function to assert the validity of OA documents when DNS TXT is not configured, expecting the issuer identity to be INVALID. - Updated test descriptions for clarity, reflecting the new validation logic for both Polygon Amoy and POL mainnet documents. - Replaced calls to the previous validation function with the new assertion function for improved accuracy in test outcomes. * refactor: streamline OA document validation tests - Removed the assertOaDocValid function, consolidating validation checks into assertAllValid for improved clarity and accuracy. - Updated test descriptions to reflect the new validation logic for both Polygon Amoy and POL mainnet documents, ensuring consistency across test cases. * Update e2e/tests/pol-amoy-verify.spec.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: run testcases * feat: enhance e2e tests for document verification - Added new RPC URLs for Polygon Amoy and POL mainnet to the e2e workflow configuration. - Updated the uploadDoc function in the test suite to handle both valid and invalid document states more effectively, improving the clarity of verification outcomes. - Refactored tests to assert verification failures using a dedicated function for better readability and maintainability. * chore: update e2e configuration and test timeouts - Changed the RPC URL for Polygon mainnet to a new endpoint for improved reliability. - Increased the per-test timeout in Playwright configuration to accommodate slower mainnet RPC calls. - Configured retries for mainnet tests to enhance test stability and reduce flakiness. * feat: add end-to-end verification tests for Polygon Amoy and POL mainnet documents - Introduced new test suites for verifying OpenAttestation v2 and W3C Verifiable Credential documents on the Polygon Amoy testnet and POL mainnet. - Created helper functions for writing tampered and not minted documents to facilitate testing. - Implemented comprehensive test cases to validate document integrity and status across both networks, enhancing overall test coverage. * refactor: update chain configuration for Polygon network * refactor: simplify AvailableBlockChains type definition in chain-info.ts * refactor: simplify RPC URL retrieval in useVerify integration tests. --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * chore: add OpenAttestation v2 + W3C VC verification e2e suites (#71) Adds read-only verification e2e coverage (no MetaMask) for issuer identity, document status, and document integrity across OA v2 (DNS-TXT document store / token registry, DNS-DID, OCSP, revocation store) and W3C VCs (ecdsa-sd-2023, bbs-2023, BitstringStatusList, TransferableRecords), with happy + error cases. - Local Hardhat fixtures + setup scripts (separate document-store deployer; token-registry mints) and DNS/OCSP route mocks - Dedicated Playwright config + GitHub Actions workflow (kept separate from the existing transferable-record e2e suite) - App: skip network-select for OCSP/DID-signed docs, use embedded chainId, clean error classification, and surface W3C TransferableRecords reasons verbatim in the error card; renderer test ids - package.json e2e:verify script; trustvc ^2.14.1 Co-authored-by: Claude Opus 4.8 (1M context) * Feat/sync master develop (#72) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md --------- Co-authored-by: manishdex25 Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * Feature/sync develop main (#73) * fix: sync main (#43) * feat: accept return to issuer (#40) * feat: accept return to issuer * fix: lint issue * fix: tests additions * fix: return message and rests * fix: code rabbit * feat: enhance deployment workflow and update dependencies (#41) * feat: enhance deployment workflow and update dependencies - Added a new input option to the deployment workflow for selecting the branch (develop for draft preview, main for production). - Updated Node.js version in the workflow from 20 to 22. - Modified the deployment command to include a URL parameter for the Sanity Studio hostname. - Updated dependencies in package.json and package-lock.json for @sanity/vision and sanity to version 5.22.0, and other related packages to their latest versions. * Update .github/workflows/deploy-sanity-studio.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: update deployment command in workflow - Removed explicit setting of SANITY_AUTH_TOKEN in the deploy command, relying on the environment variable instead for improved security and clarity. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: simplify deployment workflow by removing environment options (#42) - Removed the explicit environment options from the deployment workflow configuration, streamlining the setup process. --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Feat/fix dev deployment (#45) * feat: accept return to issuer (#40) * feat: accept return to issuer * fix: lint issue * fix: tests additions * fix: return message and rests * fix: code rabbit * feat: enhance deployment workflow and update dependencies (#41) * feat: enhance deployment workflow and update dependencies - Added a new input option to the deployment workflow for selecting the branch (develop for draft preview, main for production). - Updated Node.js version in the workflow from 20 to 22. - Modified the deployment command to include a URL parameter for the Sanity Studio hostname. - Updated dependencies in package.json and package-lock.json for @sanity/vision and sanity to version 5.22.0, and other related packages to their latest versions. * Update .github/workflows/deploy-sanity-studio.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: update deployment command in workflow - Removed explicit setting of SANITY_AUTH_TOKEN in the deploy command, relying on the environment variable instead for improved security and clarity. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: simplify deployment workflow by removing environment options (#42) - Removed the explicit environment options from the deployment workflow configuration, streamlining the setup process. * updated version * chore: update CI workflow to include concurrency and branch specifications - Renamed CI job to "Lint and Test" for clarity. - Added concurrency settings to prevent overlapping runs. - Specified branches for push events to include both develop and main. --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: update .env.example and vite.config.js for new environment var… (#46) * chore: update .env.example and vite.config.js for new environment variables * chore: remove deployment workflow for TrustVC website * chore: update .env.example and vite.config.js to remove NET variable * fix: remove unused variables (#47) * chore: update .env.example and vite.config.js for new environment variables * chore: remove deployment workflow for TrustVC website * chore: update .env.example and vite.config.js to remove NET variable * refactor: update environment configuration * Update .github/workflows/deploy-prod.yml Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor: improve deployment workflow and environment configuration * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md --------- Co-authored-by: manishdex25 Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: Cursor * feature: GA and GTM integrated * chore: trigger reverification * fix: module-level constant evaluated at import time * feat: separate env for dev and production * feature: fix issues * fix: udpated anlytics testcase * fix: parsed doc * fix: update loadDocument function to include optional source parameter and clean up analytics tests * fix: update analytics tests to use constants and improve mock values - Replaced hardcoded chain ID in analytics tests with the constant CHAIN_ID.mainnet for consistency. - Updated type definition for fragment creation in analytics tests to use VerificationFragmentType for better type safety. * fix: refactor verification logic and improve error handling - Simplified error type handling by storing the result of getErrorTypeFromFragments in a variable. - Enhanced readability by separating the isExpired calculation into its own variable before setting state. - Streamlined the trackDocumentVerified function call to use the new errorType variable. * Feature/onchain result tracking (#76) * refactor: remove unused analytics events and related tracking functions - Deleted ASSET_ACTION_COMPLETED and ASSET_ACTION_FAILED events from analytics constants. - Removed corresponding tracking function trackAssetActionFailed and its test cases to streamline analytics logic. - Updated analytics tests to reflect the removal of these events and functions. * feat: enhance asset action tracking with completion and failure events - Added new analytics events for asset actions: ASSET_ACTION_COMPLETED and ASSET_ACTION_FAILED. - Implemented tracking functions trackAssetActionCompleted and trackAssetActionFailed to log successful and failed asset actions. - Updated AssetManagementApplication component to track on-chain outcomes for asset actions. - Enhanced analytics tests to cover new tracking functions and ensure correct event logging. --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --- .env.example | 20 +- .github/workflows/ci.yml | 4 + .github/workflows/deploy-dev.yml | 12 +- .github/workflows/deploy-prod.yml | 12 +- .github/workflows/e2e-verify.yml | 4 + .github/workflows/e2e.yml | 4 + index.html | 9 + package-lock.json | 16 +- package.json | 1 + src/App.tsx | 20 +- .../AssetManagementApplication/index.tsx | 82 ++- src/components/ConnectToMagicLink/index.tsx | 16 +- src/components/ConnectToMetamask/index.tsx | 16 +- .../common/GoogleTagManager/index.tsx | 46 ++ .../VerifySection/useVerify.analytics.test.ts | 465 +++++++++++++ .../home/VerifySection/useVerify.ts | 70 +- src/constants/analyticsEvents.ts | 30 + src/hooks/useContactForm.ts | 6 + src/utils/analytics.test.ts | 640 ++++++++++++++++++ src/utils/analytics.ts | 563 +++++++++++++++ 20 files changed, 1998 insertions(+), 38 deletions(-) create mode 100644 src/components/common/GoogleTagManager/index.tsx create mode 100644 src/components/home/VerifySection/useVerify.analytics.test.ts create mode 100644 src/constants/analyticsEvents.ts create mode 100644 src/utils/analytics.test.ts create mode 100644 src/utils/analytics.ts diff --git a/.env.example b/.env.example index eef3509..ad581b4 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,28 @@ VITE_SUPPORT_API_BASE_URL= +# Analytics (GA4 + GTM) — see docs/analytics-setup.md +# +# Local dev: leave both empty to disable tracking (recommended). +# To test against the dev stack locally, set VITE_GTM_CONTAINER_ID to your dev GTM container. +# +# Deployed builds use GitHub secrets that map to these same Vite vars at build time: +# trustvc.io → VITE_GTM_CONTAINER_ID_PRODUCTION / VITE_GA4_TAG_ID_PRODUCTION +# dev.trustvc.io → VITE_GTM_CONTAINER_ID_DEVELOPMENT / VITE_GA4_TAG_ID_DEVELOPMENT +# +# GTM-only is recommended: set VITE_GTM_CONTAINER_ID, leave VITE_GA4_TAG_ID empty. +# Setting both to the same GA4 property double-counts events. +VITE_GTM_CONTAINER_ID= +VITE_GA4_TAG_ID= + # reCAPTCHA: site key (frontend). # Must match API secret key server-side. # In production, this must be set; do not allow verification bypass when missing. VITE_RECAPTCHA_SITE_KEY= -# Optional: platform/environment for Jira (e.g. dev, staging, prod). Default: dev -VITE_PLATFORM=dev +# Platform label sent on every analytics event (environment dimension). +# Deployed builds: set automatically by deploy-prod.yml (production) / deploy-dev.yml (dev). +# Local dev only — use local (default when unset): +VITE_PLATFORM=local VITE_MAGIC_API_KEY= VITE_NETWORK_TYPE=mainnet diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec8988a..853dc5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,3 +42,7 @@ jobs: env: VITE_RPC_URL_1: ${{ secrets.VITE_RPC_URL_1 }} VITE_RPC_URL_101010: ${{ secrets.VITE_RPC_URL_101010 }} + # Analytics disabled in CI — matches local .env.example defaults + VITE_GTM_CONTAINER_ID: '' + VITE_GA4_TAG_ID: '' + VITE_PLATFORM: local diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 08aeb58..578328d 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -39,6 +39,9 @@ jobs: AWS_REGION: ap-southeast-1 S3_BUCKET: ${{ secrets.S3_BUCKET_DEV }} ENV_FILE: ${{ secrets.TRUSTVC_WEB_ENV_DEVELOPMENT }} + VITE_GTM_CONTAINER_ID: ${{ secrets.VITE_GTM_CONTAINER_ID_DEVELOPMENT }} + VITE_GA4_TAG_ID: ${{ secrets.VITE_GA4_TAG_ID_DEVELOPMENT }} + VITE_PLATFORM: dev steps: - name: Checkout code @@ -54,7 +57,14 @@ jobs: cache-dependency-path: package-lock.json - name: Create .env for build - run: printf '%s' "$ENV_FILE" > .env + run: | + printf '%s\n' "$ENV_FILE" \ + | grep -v '^VITE_GTM_CONTAINER_ID=' \ + | grep -v '^VITE_GA4_TAG_ID=' \ + | grep -v '^VITE_PLATFORM=' > .env + echo "VITE_GTM_CONTAINER_ID=${VITE_GTM_CONTAINER_ID}" >> .env + echo "VITE_GA4_TAG_ID=${VITE_GA4_TAG_ID}" >> .env + echo "VITE_PLATFORM=${VITE_PLATFORM}" >> .env - name: Install dependencies run: npm ci diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 658d687..39c05e1 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -18,6 +18,9 @@ jobs: S3_BUCKET: ${{ secrets.S3_BUCKET_PROD }} CF_DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID_PROD }} ENV_FILE: ${{ secrets.TRUSTVC_WEB_ENV_PRODUCTION }} + VITE_GTM_CONTAINER_ID: ${{ secrets.VITE_GTM_CONTAINER_ID_PRODUCTION }} + VITE_GA4_TAG_ID: ${{ secrets.VITE_GA4_TAG_ID_PRODUCTION }} + VITE_PLATFORM: production steps: - name: Checkout code @@ -33,7 +36,14 @@ jobs: cache-dependency-path: package-lock.json - name: Create .env for build - run: printf '%s\n' "$ENV_FILE" > .env + run: | + printf '%s\n' "$ENV_FILE" \ + | grep -v '^VITE_GTM_CONTAINER_ID=' \ + | grep -v '^VITE_GA4_TAG_ID=' \ + | grep -v '^VITE_PLATFORM=' > .env + echo "VITE_GTM_CONTAINER_ID=${VITE_GTM_CONTAINER_ID}" >> .env + echo "VITE_GA4_TAG_ID=${VITE_GA4_TAG_ID}" >> .env + echo "VITE_PLATFORM=${VITE_PLATFORM}" >> .env - name: Install dependencies run: npm ci diff --git a/.github/workflows/e2e-verify.yml b/.github/workflows/e2e-verify.yml index 33c2083..b52e9e3 100644 --- a/.github/workflows/e2e-verify.yml +++ b/.github/workflows/e2e-verify.yml @@ -50,6 +50,10 @@ jobs: VITE_APP_NETWORK: local VITE_NETWORK_TYPE: testnet VITE_RPC_URL_1337: http://127.0.0.1:8545 + # Analytics disabled in E2E — no events sent to GA4/GTM during test runs + VITE_GTM_CONTAINER_ID: '' + VITE_GA4_TAG_ID: '' + VITE_PLATFORM: local - name: Wait for dev server run: npx wait-on http://localhost:5173 --timeout 180000 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a6ea1cc..64bf0ca 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -48,6 +48,10 @@ jobs: VITE_RPC_URL_1337: http://127.0.0.1:8545 VITE_RPC_URL_80002: https://rpc-amoy.polygon.technology/ VITE_RPC_URL_137: https://rpc.ankr.com/polygon + # Analytics disabled in E2E — no events sent to GA4/GTM during test runs + VITE_GTM_CONTAINER_ID: '' + VITE_GA4_TAG_ID: '' + VITE_PLATFORM: local - name: Wait for dev server run: npx wait-on http://localhost:5173 --timeout 180000 diff --git a/index.html b/index.html index df0c1f1..239b828 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,15 @@ TrustVC + +
diff --git a/package-lock.json b/package-lock.json index 0bfa5ac..03aa25c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-feather": "^2.0.10", + "react-ga4": "^3.0.1", "react-router-dom": "^7.12.0", "react-tooltip": "^5.30.0", "swiper": "^12.0.3" @@ -7512,15 +7513,6 @@ "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" }, - "node_modules/@trustvc/w3c-issuer/node_modules/web-did-resolver": { - "version": "2.0.32", - "resolved": "https://registry.npmjs.org/web-did-resolver/-/web-did-resolver-2.0.32.tgz", - "integrity": "sha512-L91/ApTmDjgzS0UDstTKn3kN/1hlQBnVcUN8K29e3xhVBpPktHYC6uvVAQ8ohbIg9D6wrrbaBQvfRArDxgJG2g==", - "dependencies": { - "cross-fetch": "^4.1.0", - "did-resolver": "^4.1.0" - } - }, "node_modules/@trustvc/w3c-issuer/node_modules/web-did-resolver": { "version": "2.0.32", "resolved": "https://registry.npmjs.org/web-did-resolver/-/web-did-resolver-2.0.32.tgz", @@ -18195,6 +18187,12 @@ "react": ">=16.8.6" } }, + "node_modules/react-ga4": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-3.0.1.tgz", + "integrity": "sha512-GyCc01bSheWXjzGDyHsXMOqk/SP5Cf/JrcJTg4hcpKx4eeSwaJKpJUc+ipF4ffLTZkmabmf3ZGBv4OKHTXNXyA==", + "license": "MIT" + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 3e0c84f..a93f67d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-feather": "^2.0.10", + "react-ga4": "^3.0.1", "react-router-dom": "^7.12.0", "react-tooltip": "^5.30.0", "swiper": "^12.0.3" diff --git a/src/App.tsx b/src/App.tsx index 57c27e6..9f24ff7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,12 @@ import { useState, useEffect } from 'react' import { matchPath, useLocation } from 'react-router-dom' import Navbar from './components/common/Navbar' import AppRouter from './routes' +import { GoogleTagManager } from './components/common/GoogleTagManager' + +const GTM_CONTAINER_ID = import.meta.env.VITE_GTM_CONTAINER_ID as + | string + | undefined +const GA4_TAG_ID = import.meta.env.VITE_GA4_TAG_ID as string | undefined type BackgroundRouteRule = { paths: string[] @@ -74,10 +80,16 @@ function App() { const appShellClassName = `app-shell ${backgroundClassName}` return ( -
- - -
+ <> + +
+ + +
+ ) } diff --git a/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx b/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx index f5a6e33..adf7d23 100644 --- a/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx +++ b/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx @@ -3,6 +3,7 @@ import React, { FunctionComponent, useCallback, useEffect, + useRef, useState, } from 'react' import { useProviderContext } from '../../common/contexts/providerContext' @@ -13,6 +14,11 @@ import { AssetManagementActions } from '../AssetManagementActions' import { AssetManagementForm } from '../AssetManagementForm' import { Tag } from '../../common/Tag' import { useTokenRegistryVersion } from '../../../hooks/useTokenRegistryVersion' +import { + trackAssetActionInitiated, + trackAssetActionCompleted, + trackAssetActionFailed, +} from '../../../utils/analytics' import { TokenRegistryVersions } from '../../../constants' interface AssetManagementIsTransferableDocumentProps { @@ -140,10 +146,84 @@ export const AssetManagementApplication: FunctionComponent< (assetManagementActions: AssetManagementActions) => { resetProviders() setAssetManagementAction(assetManagementActions) + if (assetManagementActions !== AssetManagementActions.None) { + trackAssetActionInitiated( + assetManagementActions, + chainId, + tokenRegistryVersion ?? undefined + ) + } }, - [setAssetManagementAction, resetProviders] + [setAssetManagementAction, resetProviders, chainId, tokenRegistryVersion] ) + // Track on-chain outcome for the active asset action. + // outcomeRef prevents double-firing; resets to null when the state cycles back + // through UNINITIALIZED (which resetProviders() triggers on each new attempt). + const outcomeRef = useRef(null) + useEffect(() => { + if (assetManagementAction === AssetManagementActions.None) return + const txState = (() => { + switch (assetManagementAction) { + case AssetManagementActions.NominateBeneficiary: + return nominateState + case AssetManagementActions.TransferHolder: + return changeHolderState + case AssetManagementActions.EndorseBeneficiary: + case AssetManagementActions.TransferOwner: + return endorseBeneficiaryState + case AssetManagementActions.TransferOwnerHolder: + return transferOwnerHoldersState + case AssetManagementActions.ReturnToIssuer: + return returnToIssuerState + case AssetManagementActions.AcceptReturnToIssuer: + return destroyTokenState + case AssetManagementActions.RejectReturnToIssuer: + return restoreTokenState + case AssetManagementActions.RejectTransferOwner: + return rejectTransferOwnerState + case AssetManagementActions.RejectTransferHolder: + return rejectTransferHolderState + case AssetManagementActions.RejectTransferOwnerHolder: + return rejectTransferOwnerHolderState + default: + return undefined + } + })() + if (!txState) return + if (txState === 'UNINITIALIZED' || txState === 'INITIALIZED') { + outcomeRef.current = null + return + } + if (txState !== 'CONFIRMED' && txState !== 'ERROR') return + const key = `${assetManagementAction}:${txState}` + if (outcomeRef.current === key) return + outcomeRef.current = key + if (txState === 'CONFIRMED') { + trackAssetActionCompleted(assetManagementAction, chainId) + } else { + trackAssetActionFailed( + assetManagementAction, + errorMessage ?? 'TRANSACTION_ERROR', + chainId + ) + } + }, [ + assetManagementAction, + chainId, + errorMessage, + nominateState, + changeHolderState, + endorseBeneficiaryState, + transferOwnerHoldersState, + returnToIssuerState, + destroyTokenState, + restoreTokenState, + rejectTransferOwnerState, + rejectTransferHolderState, + rejectTransferOwnerHolderState, + ]) + // Initialize the token information context with tokenId, tokenRegistryAddress and chainId useEffect(() => { if (tokenId && tokenRegistryAddress) { diff --git a/src/components/ConnectToMagicLink/index.tsx b/src/components/ConnectToMagicLink/index.tsx index cb7c965..2305375 100644 --- a/src/components/ConnectToMagicLink/index.tsx +++ b/src/components/ConnectToMagicLink/index.tsx @@ -1,5 +1,10 @@ import React, { useState } from 'react' import { toErrorMessage } from '../../utils/helper' +import { + trackWalletConnected, + trackWalletConnectFailed, + trackWalletDisconnected, +} from '../../utils/analytics' import { getMagicLinkIconSrc } from '../../utils/magicWallet' import { Button, ButtonSize } from '../common/Button' import Connected from '../ConnectToBlockchain/Connected' @@ -19,10 +24,13 @@ export const ConnectToMagicLinkModelComponent = ({ }: ConnectToMagicLinkModelProps) => { const { providerType, account, disconnectWallet } = useProviderContext() - const handleDisconnect = () => { - void disconnectWallet().catch(() => { + const handleDisconnect = async () => { + try { + await disconnectWallet() + trackWalletDisconnected('magic_link') + } catch { // Optional: surface a toast/error state - }) + } } return ( @@ -106,7 +114,9 @@ const ConnectToMagicLink: React.FC = () => { setIsConnecting(true) try { await upgradeToMagicSigner() + trackWalletConnected('magic_link') } catch (error: unknown) { + trackWalletConnectFailed('magic_link', getWalletErrorMessage(error)) setErrorMessage(getWalletErrorMessage(error)) } finally { setIsConnecting(false) diff --git a/src/components/ConnectToMetamask/index.tsx b/src/components/ConnectToMetamask/index.tsx index cd9fe2d..6c39c79 100644 --- a/src/components/ConnectToMetamask/index.tsx +++ b/src/components/ConnectToMetamask/index.tsx @@ -4,6 +4,11 @@ import Connected from '../ConnectToBlockchain/Connected' // import { NetworkContent } from '../NetworkSection/NetworkContent' // Warning icon - use inline SVG or import from public folder import { toErrorMessage } from '../../utils/helper' +import { + trackWalletConnected, + trackWalletConnectFailed, + trackWalletDisconnected, +} from '../../utils/analytics' import { SIGNER_TYPE, useProviderContext, @@ -24,8 +29,13 @@ export const ConnectToMetamaskModelComponent = ({ }: ConnectToMetamaskModelProps) => { const { providerType, account, disconnectWallet } = useProviderContext() - const handleDisconnect = () => { - disconnectWallet() + const handleDisconnect = async () => { + try { + await disconnectWallet() + trackWalletDisconnected('metamask') + } catch { + // Optional: surface a toast/error state + } } return (
@@ -121,7 +131,9 @@ const ConnectToMetamask: React.FC = ({ setErrorMessage('') try { await upgradeToMetaMaskSigner() + trackWalletConnected('metamask') } catch (error: unknown) { + trackWalletConnectFailed('metamask', getWalletErrorMessage(error)) console.error('Error in handleConnectWallet:', error) handleMetamaskError(error) } diff --git a/src/components/common/GoogleTagManager/index.tsx b/src/components/common/GoogleTagManager/index.tsx new file mode 100644 index 0000000..578a06b --- /dev/null +++ b/src/components/common/GoogleTagManager/index.tsx @@ -0,0 +1,46 @@ +import { useEffect } from 'react' +import { initGA4 } from '../../../utils/analytics' + +interface GoogleTagManagerProps { + /** GTM container ID — e.g. GTM-XXXXXXX */ + gtmContainerId?: string + /** GA4 measurement ID — e.g. G-XXXXXXXXXX */ + ga4TagId?: string +} + +/** + * Bootstraps analytics on mount: + * - Loads the GTM container script into (if gtmContainerId is set) + * - Initialises GA4 direct tracking via react-ga4 (if ga4TagId is set) + * + * Renders nothing. The GTM noscript fallback lives in index.html so it works + * before JavaScript runs. + */ +export const GoogleTagManager = ({ + gtmContainerId, + ga4TagId, +}: GoogleTagManagerProps) => { + useEffect(() => { + // GA4 direct tracking + if (ga4TagId) { + initGA4(ga4TagId) + } + + // GTM container + if (gtmContainerId && !document.getElementById('gtm-script')) { + window.dataLayer = window.dataLayer || [] + window.dataLayer.push({ + 'gtm.start': new Date().getTime(), + event: 'gtm.js', + }) + + const script = document.createElement('script') + script.id = 'gtm-script' + script.async = true + script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmContainerId}` + document.head.appendChild(script) + } + }, [gtmContainerId, ga4TagId]) + + return null +} diff --git a/src/components/home/VerifySection/useVerify.analytics.test.ts b/src/components/home/VerifySection/useVerify.analytics.test.ts new file mode 100644 index 0000000..b3a00f3 --- /dev/null +++ b/src/components/home/VerifySection/useVerify.analytics.test.ts @@ -0,0 +1,465 @@ +import React from 'react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { renderHook, act, waitFor } from '@testing-library/react' +import { useVerify } from './useVerify' +import { DocumentProvider } from '../../common/contexts/DocumentContext' + +// ─── Mock analytics ─────────────────────────────────────────────────────────── + +vi.mock('../../../utils/analytics', () => ({ + trackDocumentDropped: vi.fn(), + trackDocumentVerified: vi.fn(), + trackDocumentVerifyError: vi.fn(), + trackNetworkSelectionShown: vi.fn(), + trackNetworkSelected: vi.fn(), + trackNetworkSelectionCancelled: vi.fn(), + trackVerificationReset: vi.fn(), +})) + +// ─── Mock @trustvc/trustvc ──────────────────────────────────────────────────── + +Object.defineProperty(import.meta, 'env', { + value: { + VITE_RPC_URL_1: 'https://eth-mainnet.example.com', + VITE_RPC_URL_137: 'https://polygon.example.com', + }, + writable: true, + configurable: true, +}) + +if (!File.prototype.text) { + File.prototype.text = function () { + return new Promise(resolve => { + const reader = new FileReader() + reader.onload = () => resolve(reader.result as string) + reader.readAsText(this) + }) + } +} + +vi.mock('@trustvc/trustvc', async importOriginal => { + const actual = await importOriginal() + const mkChain = ( + id: string, + name: string, + rpcUrl: string, + explorerUrl: string + ) => ({ + id, + name, + label: name, + rpcUrl, + explorerUrl, + type: 'production' as const, + currency: 'ETH', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + }) + return { + ...actual, + verifyDocument: vi.fn(), + getChainId: vi.fn(), + isTransferableRecord: vi.fn().mockReturnValue(false), + isDocumentRevokable: vi.fn(), + SUPPORTED_CHAINS: { + '1': mkChain( + '1', + 'homestead', + 'https://eth-mainnet.example.com', + 'https://etherscan.io' + ), + '137': mkChain( + '137', + 'matic', + 'https://polygon.example.com', + 'https://polygonscan.com' + ), + '50': mkChain( + '50', + 'xdc', + 'https://xdc-rpc.com', + 'https://xdc-explorer.io' + ), + '101010': mkChain( + '101010', + 'stability', + 'https://stability-rpc.com', + 'https://stability-explorer.io' + ), + '1338': mkChain( + '1338', + 'astron', + 'https://astron-rpc.com', + 'https://astron-explorer.io' + ), + '11155111': mkChain( + '11155111', + 'sepolia', + 'https://sepolia-rpc.com', + 'https://sepolia-explorer.io' + ), + '80002': mkChain( + '80002', + 'amoy', + 'https://amoy-rpc.com', + 'https://amoy-explorer.io' + ), + '51': mkChain( + '51', + 'xdcapothem', + 'https://apothem-rpc.com', + 'https://apothem-explorer.io' + ), + '20180427': mkChain( + '20180427', + 'stabilitytestnet', + 'https://stability-test-rpc.com', + 'https://stability-test-explorer.io' + ), + '21002': mkChain( + '21002', + 'astrontestnet', + 'https://astron-test-rpc.com', + 'https://astron-test-explorer.io' + ), + }, + isWrappedV2Document: vi.fn().mockReturnValue(false), + isWrappedV3Document: vi.fn().mockReturnValue(false), + isRawV2Document: vi.fn().mockReturnValue(false), + isSignedWrappedV2Document: vi.fn().mockReturnValue(false), + isRawV3Document: vi.fn().mockReturnValue(false), + isSignedWrappedV3Document: vi.fn().mockReturnValue(false), + isTitleEscrowVersion: vi.fn().mockResolvedValue(false), + TitleEscrowInterface: { V4: 'V4', V5: 'V5' }, + getTokenRegistryAddress: vi.fn().mockReturnValue(undefined), + getTokenId: vi.fn().mockReturnValue(undefined), + getDocumentData: vi.fn().mockReturnValue({ id: 'test-key-id' }), + utils: {}, + v2: {}, + v3: {}, + vc: { + isSignedDocument: vi.fn().mockReturnValue(false), + isRawDocument: vi.fn().mockReturnValue(false), + isSignedDocumentV2_0: vi.fn().mockReturnValue(false), + }, + } +}) + +// ─── Import after mocks ─────────────────────────────────────────────────────── + +import * as analytics from '../../../utils/analytics' +import { + verifyDocument, + getChainId, + isTransferableRecord, + CHAIN_ID, +} from '@trustvc/trustvc' + +// ─── Helpers ────────────────────────────────────────────────────────────────── + +const wrapper = ({ children }: { children: React.ReactNode }) => + React.createElement(DocumentProvider, null, children) + +const makeFile = (content: object, name = 'doc.json') => + new File([JSON.stringify(content)], name, { type: 'application/json' }) + +const validFragments = [ + { + name: 'OpenAttestationHash', + type: 'DOCUMENT_INTEGRITY', + status: 'VALID', + data: {}, + }, + { + name: 'OpenAttestationDnsTxtIdentityProof', + type: 'ISSUER_IDENTITY', + status: 'VALID', + data: { identifier: 'example.com', location: 'example.com' }, + }, + { + name: 'OpenAttestationEthereumDocumentStoreStatus', + type: 'DOCUMENT_STATUS', + status: 'VALID', + data: {}, + }, +] + +const makeDragEvent = (file: File): React.DragEvent => + ({ + preventDefault: vi.fn(), + stopPropagation: vi.fn(), + type: 'drop', + dataTransfer: { files: [file] as unknown as FileList }, + }) as unknown as React.DragEvent + +const makeInputEvent = (file: File): React.ChangeEvent => + ({ + target: { files: [file] as unknown as FileList, value: '' }, + }) as unknown as React.ChangeEvent + +beforeEach(() => { + vi.clearAllMocks() + vi.mocked(getChainId).mockReturnValue(CHAIN_ID.mainnet) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(verifyDocument).mockResolvedValue(validFragments as any) +}) + +// ─── DOCUMENT_DROPPED source tracking ──────────────────────────────────────── + +describe('trackDocumentDropped', () => { + it('fires with source="drop" on handleDrop', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + const file = makeFile({ + version: 'https://schema.openattestation.com/2.0/schema.json', + }) + await act(async () => { + result.current.handleDrop(makeDragEvent(file)) + await new Promise(r => setTimeout(r, 0)) + }) + + expect(analytics.trackDocumentDropped).toHaveBeenCalledWith( + file.name, + 'drop' + ) + }) + + it('fires with source="file_picker" on handleFileInput', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + const file = makeFile({ data: 'test' }, 'upload.json') + await act(async () => { + result.current.handleFileInput(makeInputEvent(file)) + await new Promise(r => setTimeout(r, 0)) + }) + + expect(analytics.trackDocumentDropped).toHaveBeenCalledWith( + 'upload.json', + 'file_picker' + ) + }) + + it('fires with source="url" on loadDocument by default', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ data: {} }, '1', 'sample.json') + }) + + expect(analytics.trackDocumentDropped).toHaveBeenCalledWith( + 'sample.json', + 'url' + ) + }) + + it('fires with source="demo" when explicitly passed to loadDocument', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ data: {} }, '1', 'demo.json', 'demo') + }) + + expect(analytics.trackDocumentDropped).toHaveBeenCalledWith( + 'demo.json', + 'demo' + ) + }) +}) + +// ─── trackDocumentVerified ──────────────────────────────────────────────────── + +describe('trackDocumentVerified', () => { + it('fires after successful verification with extras', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + const doc = { data: 'valid' } + await act(async () => { + await result.current.loadDocument(doc, '1', 'verified.json') + }) + + await waitFor(() => { + expect(analytics.trackDocumentVerified).toHaveBeenCalled() + }) + + const [, , isValid, , , extras] = vi.mocked(analytics.trackDocumentVerified) + .mock.calls[0] + expect(isValid).toBe(true) + expect(extras).toHaveProperty('isExpired') + expect(extras).toHaveProperty('isTransferable') + expect(extras).toHaveProperty('tokenRegistryVersion') + expect(extras).toHaveProperty('chainId', '1') + }) + + it('fires with invalid result when fragments show error', async () => { + vi.mocked(verifyDocument).mockResolvedValue([ + { + name: 'OpenAttestationHash', + type: 'DOCUMENT_INTEGRITY', + status: 'INVALID', + data: {}, + }, + { + name: 'OpenAttestationDnsTxtIdentityProof', + type: 'ISSUER_IDENTITY', + status: 'VALID', + data: {}, + }, + { + name: 'OpenAttestationEthereumDocumentStoreStatus', + type: 'DOCUMENT_STATUS', + status: 'VALID', + data: {}, + }, + ] as any) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({}, '1', 'invalid.json') + }) + + await waitFor(() => { + expect(analytics.trackDocumentVerified).toHaveBeenCalled() + }) + + const [, , isValid] = vi.mocked(analytics.trackDocumentVerified).mock + .calls[0] + expect(isValid).toBe(false) + }) +}) + +// ─── trackDocumentVerifyError ───────────────────────────────────────────────── + +describe('trackDocumentVerifyError', () => { + it('fires when file is not valid JSON', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + const badFile = new File(['not valid json {{{'], 'bad.json', { + type: 'application/json', + }) + await act(async () => { + result.current.handleFileInput(makeInputEvent(badFile)) + await new Promise(r => setTimeout(r, 50)) + }) + + await waitFor(() => { + expect(analytics.trackDocumentVerifyError).toHaveBeenCalled() + }) + }) + + it('fires when verifyDocument throws', async () => { + vi.mocked(verifyDocument).mockRejectedValue(new Error('Network failure')) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({}, '1', 'error.json') + }) + + await waitFor(() => { + expect(analytics.trackDocumentVerifyError).toHaveBeenCalled() + }) + }) +}) + +// ─── trackNetworkSelectionShown ─────────────────────────────────────────────── + +describe('trackNetworkSelectionShown', () => { + it('fires when document requires network selection', async () => { + vi.mocked(getChainId).mockReturnValue(null as any) + vi.mocked(isTransferableRecord).mockReturnValue(true) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + const file = makeFile({ + version: 'https://schema.openattestation.com/2.0/schema.json', + }) + await act(async () => { + result.current.handleFileInput(makeInputEvent(file)) + await new Promise(r => setTimeout(r, 0)) + }) + + await waitFor(() => { + expect(analytics.trackNetworkSelectionShown).toHaveBeenCalled() + }) + + expect(result.current.verifyStatus).toBe('network-select') + }) +}) + +// ─── trackNetworkSelected ───────────────────────────────────────────────────── + +describe('trackNetworkSelected', () => { + it('fires with the chosen chain when handleNetworkConfirm is called', async () => { + vi.mocked(getChainId).mockReturnValue(null as any) + vi.mocked(isTransferableRecord).mockReturnValue(true) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + const file = makeFile({ + version: 'https://schema.openattestation.com/2.0/schema.json', + }) + await act(async () => { + result.current.handleFileInput(makeInputEvent(file)) + await new Promise(r => setTimeout(r, 0)) + }) + + await waitFor(() => + expect(result.current.verifyStatus).toBe('network-select') + ) + + await act(async () => { + await result.current.handleNetworkConfirm('137') + }) + + expect(analytics.trackNetworkSelected).toHaveBeenCalledWith('137') + }) +}) + +// ─── trackNetworkSelectionCancelled ────────────────────────────────────────── + +describe('trackNetworkSelectionCancelled', () => { + it('fires when handleNetworkCancel is called', async () => { + vi.mocked(getChainId).mockReturnValue(null as any) + vi.mocked(isTransferableRecord).mockReturnValue(true) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + const file = makeFile({ + version: 'https://schema.openattestation.com/2.0/schema.json', + }) + await act(async () => { + result.current.handleFileInput(makeInputEvent(file)) + await new Promise(r => setTimeout(r, 0)) + }) + + await waitFor(() => + expect(result.current.verifyStatus).toBe('network-select') + ) + + act(() => { + result.current.handleNetworkCancel() + }) + + expect(analytics.trackNetworkSelectionCancelled).toHaveBeenCalled() + expect(result.current.verifyStatus).toBe('idle') + }) +}) + +// ─── trackVerificationReset ─────────────────────────────────────────────────── + +describe('trackVerificationReset', () => { + it('fires when handleReset is called', async () => { + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({}, '1', 'doc.json') + }) + + act(() => { + result.current.handleReset() + }) + + expect(analytics.trackVerificationReset).toHaveBeenCalled() + expect(result.current.verifyStatus).toBe('idle') + }) +}) diff --git a/src/components/home/VerifySection/useVerify.ts b/src/components/home/VerifySection/useVerify.ts index 39698a8..b5c92a0 100644 --- a/src/components/home/VerifySection/useVerify.ts +++ b/src/components/home/VerifySection/useVerify.ts @@ -22,6 +22,16 @@ import { import { getRpcUrl, getIsExpired } from '../../../utils/helper' import { useDocumentContext } from '../../common/contexts/DocumentContext' import { type VerifyErrorType, getErrorTypeFromError } from './verifyErrorUtils' +import { + trackDocumentDropped, + trackDocumentVerified, + trackDocumentVerifyError, + trackNetworkSelectionShown, + trackNetworkSelected, + trackNetworkSelectionCancelled, + trackVerificationReset, + type DocumentDroppedSource, +} from '../../../utils/analytics' export type VerifyStatus = | 'idle' @@ -78,7 +88,8 @@ export interface UseVerifyReturn { loadDocument: ( _doc: unknown, _chainId: string | null | undefined, - _name: string + _name: string, + _source?: DocumentDroppedSource ) => Promise } @@ -518,8 +529,9 @@ export const useVerify = (): UseVerifyReturn => { const hasAtLeastOneValid = groupStatuses.some(s => s === 'VALID') const hasNoInvalid = groupStatuses.every(s => s !== 'INVALID') const isValid = hasAtLeastOneValid && hasNoInvalid + const errorType = !isValid ? getErrorTypeFromFragments(results) : undefined if (!isValid) { - setErrorType(getErrorTypeFromFragments(results)) + setErrorType(errorType!) setErrorMessage(getErrorMessageFromFragments(results)) } @@ -538,7 +550,8 @@ export const useVerify = (): UseVerifyReturn => { setTokenRegistryAddress(registryAddress) setTokenRegistryAddressContext(registryAddress || null) - setIsExpired(getIsExpired(doc)) + const isExpired = getIsExpired(doc) + setIsExpired(isExpired) //add code to fetch TokenId , keyId from the document const _keyId = getDocumentData(doc as any)?.id @@ -579,6 +592,13 @@ export const useVerify = (): UseVerifyReturn => { setRawDocument(doc) setVerifiedChainId(chainId ?? '') setVerifyStatus(isValid ? 'valid' : 'invalid') + + trackDocumentVerified(doc, results, isValid, issuer, errorType, { + isExpired, + isTransferable: transferable, + tokenRegistryVersion: trVersion, + chainId: chainId ?? null, + }) } const clearVerificationMetadata = () => { @@ -598,7 +618,10 @@ export const useVerify = (): UseVerifyReturn => { setKeyIdContext(null) } - const processFile = async (file: File) => { + const processFile = async ( + file: File, + source: DocumentDroppedSource = 'file_picker' + ) => { const currentId = ++verificationIdRef.current setFileName(file.name) setVerifyStatus('verifying') @@ -606,26 +629,32 @@ export const useVerify = (): UseVerifyReturn => { setPendingDoc(null) clearVerificationMetadata() + trackDocumentDropped(file.name, source) + + let parsedDoc: any try { const text = await file.text() - const doc = JSON.parse(text) + parsedDoc = JSON.parse(text) // Prefer the document's own chain; fall back to its embedded network field // (getChainId ignores that for DNS-DID/DID docs, which can still use a // REVOCATION_STORE on that chain) before asking the user to pick one. - const chainId = getChainId(doc) ?? getEmbeddedChainId(doc) + const chainId = getChainId(parsedDoc) ?? getEmbeddedChainId(parsedDoc) - if (!chainId && requiresNetworkSelection(doc)) { + if (!chainId && requiresNetworkSelection(parsedDoc)) { // Needs blockchain verification but has no chain anywhere — ask the user - setPendingDoc(doc) + setPendingDoc(parsedDoc) setVerifyStatus('network-select') + trackNetworkSelectionShown(parsedDoc) return } - await runVerification(doc, chainId, currentId) + await runVerification(parsedDoc, chainId, currentId) } catch (err) { + const errType = getErrorTypeFromError(err) clearVerificationMetadata() - setErrorType(getErrorTypeFromError(err)) + setErrorType(errType) setVerifyStatus('error') + trackDocumentVerifyError(parsedDoc, errType) } } @@ -633,18 +662,23 @@ export const useVerify = (): UseVerifyReturn => { if (!pendingDoc) return const currentId = ++verificationIdRef.current setVerifyStatus('verifying') + const docRef = pendingDoc + trackNetworkSelected(chainId) try { await runVerification(pendingDoc, chainId, currentId) } catch (err) { + const errType = getErrorTypeFromError(err) clearVerificationMetadata() - setErrorType(getErrorTypeFromError(err)) + setErrorType(errType) setVerifyStatus('error') + trackDocumentVerifyError(docRef, errType) } finally { setPendingDoc(null) } } const handleNetworkCancel = () => { + trackNetworkSelectionCancelled() setVerifyStatus('idle') setFileName('') setPendingDoc(null) @@ -666,13 +700,13 @@ export const useVerify = (): UseVerifyReturn => { e.stopPropagation() setDragActive(false) if (e.dataTransfer.files && e.dataTransfer.files[0]) { - processFile(e.dataTransfer.files[0]) + processFile(e.dataTransfer.files[0], 'drop') } } const handleFileInput = (e: React.ChangeEvent) => { if (e.target.files && e.target.files[0]) { - processFile(e.target.files[0]) + processFile(e.target.files[0], 'file_picker') e.target.value = '' } } @@ -680,7 +714,8 @@ export const useVerify = (): UseVerifyReturn => { const loadDocument = async ( doc: unknown, chainId: string | null | undefined, - name: string + name: string, + source: DocumentDroppedSource = 'url' ) => { const currentId = ++verificationIdRef.current setFileName(name) @@ -689,16 +724,21 @@ export const useVerify = (): UseVerifyReturn => { setPendingDoc(null) clearVerificationMetadata() + trackDocumentDropped(name, source) + try { await runVerification(doc, chainId, currentId) } catch (err) { + const errType = getErrorTypeFromError(err) clearVerificationMetadata() - setErrorType(getErrorTypeFromError(err)) + setErrorType(errType) setVerifyStatus('error') + trackDocumentVerifyError(doc, errType) } } const handleReset = () => { + trackVerificationReset() setVerifyStatus('idle') setFragments([]) setFileName('') diff --git a/src/constants/analyticsEvents.ts b/src/constants/analyticsEvents.ts new file mode 100644 index 0000000..20dd954 --- /dev/null +++ b/src/constants/analyticsEvents.ts @@ -0,0 +1,30 @@ +export const ANALYTICS_EVENTS = { + /** Fired when a user drops or selects a document file for verification. */ + DOCUMENT_DROPPED: 'DOCUMENT_DROPPED', + /** Fired when document verification completes — valid or invalid. */ + DOCUMENT_VERIFICATION_COMPLETED: 'DOCUMENT_VERIFICATION_COMPLETED', + /** Fired when the network selection dialog appears (document has no embedded chain). */ + NETWORK_SELECTION_SHOWN: 'NETWORK_SELECTION_SHOWN', + /** Fired when the user confirms a network in the selection dialog. */ + NETWORK_SELECTED: 'NETWORK_SELECTED', + /** Fired when the user dismisses the network selection dialog without selecting. */ + NETWORK_SELECTION_CANCELLED: 'NETWORK_SELECTION_CANCELLED', + /** Fired when the user resets the verifier back to idle state. */ + VERIFICATION_RESET: 'VERIFICATION_RESET', + /** Fired when a wallet is successfully connected. */ + WALLET_CONNECTED: 'WALLET_CONNECTED', + /** Fired when a connected wallet is explicitly disconnected. */ + WALLET_DISCONNECTED: 'WALLET_DISCONNECTED', + /** Fired when a wallet connection attempt fails. */ + WALLET_CONNECT_FAILED: 'WALLET_CONNECT_FAILED', + /** Fired when the user initiates a transferable record management action. */ + ASSET_ACTION_INITIATED: 'ASSET_ACTION_INITIATED', + /** Fired when a transferable record management action is confirmed on-chain. */ + ASSET_ACTION_COMPLETED: 'ASSET_ACTION_COMPLETED', + /** Fired when a transferable record management action fails. */ + ASSET_ACTION_FAILED: 'ASSET_ACTION_FAILED', + /** Fired when a support form is successfully submitted. */ + SUPPORT_FORM_SUBMITTED: 'SUPPORT_FORM_SUBMITTED', + /** Fired when a support form submission fails. */ + SUPPORT_FORM_FAILED: 'SUPPORT_FORM_FAILED', +} as const diff --git a/src/hooks/useContactForm.ts b/src/hooks/useContactForm.ts index b04c514..15b6f88 100644 --- a/src/hooks/useContactForm.ts +++ b/src/hooks/useContactForm.ts @@ -1,4 +1,8 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { + trackSupportFormSubmitted, + trackSupportFormFailed, +} from '../utils/analytics' import { getPresignedUrls, uploadToPresignedUrl, @@ -457,6 +461,7 @@ export const useContactForm = (options: UseContactFormOptions) => { attachmentKeys, recaptchaToken, }) + trackSupportFormSubmitted(typeOfEnquiry || 'Unknown') setSubmitSuccess( "Request submitted successfully. We'll get back to you soon." ) @@ -470,6 +475,7 @@ export const useContactForm = (options: UseContactFormOptions) => { ?.message const msg = rawMessage && rawMessage !== 'Failed to fetch' ? rawMessage : fallback + trackSupportFormFailed(typeOfEnquiry || 'Unknown', msg) setSubmitError(msg) } finally { setIsSubmitting(false) diff --git a/src/utils/analytics.test.ts b/src/utils/analytics.test.ts new file mode 100644 index 0000000..06d619f --- /dev/null +++ b/src/utils/analytics.test.ts @@ -0,0 +1,640 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import ReactGA from 'react-ga4' + +// ─── Mocks ──────────────────────────────────────────────────────────────────── + +vi.mock('react-ga4', () => ({ + default: { + initialize: vi.fn(), + event: vi.fn(), + }, +})) + +vi.mock('@trustvc/trustvc', async () => { + return { + isWrappedV2Document: vi.fn(), + isWrappedV3Document: vi.fn(), + isRawV2Document: vi.fn(), + isRawV3Document: vi.fn(), + isSignedWrappedV2Document: vi.fn(), + isSignedWrappedV3Document: vi.fn(), + vc: { + isSignedDocument: vi.fn(), + isRawDocument: vi.fn(), + isSignedDocumentV2_0: vi.fn(), + }, + } +}) + +// ─── Imports ────────────────────────────────────────────────────────────────── +// GTM_CONFIGURED and ENVIRONMENT are computed at analytics.ts module load. +// .env.test sets VITE_GTM_CONTAINER_ID= and VITE_PLATFORM=test so Vitest +// injects the correct values before any module evaluates. + +import * as trustvc from '@trustvc/trustvc' +import type { VerificationFragmentType } from '../components/home/VerifySection/useVerify' +import { + getDocumentSchema, + getIssuerMethod, + getSigningAlgorithm, + pushGTMEvent, + initGA4, + buildDroppedEvent, + buildVerificationEvent, + trackDocumentDropped, + trackDocumentVerified, + trackDocumentVerifyError, + trackNetworkSelectionShown, + trackNetworkSelected, + trackNetworkSelectionCancelled, + trackVerificationReset, + trackWalletConnected, + trackWalletDisconnected, + trackWalletConnectFailed, + trackAssetActionInitiated, + trackAssetActionCompleted, + trackAssetActionFailed, + trackSupportFormSubmitted, + trackSupportFormFailed, +} from './analytics' + +// ─── Helpers ────────────────────────────────────────────────────────────────── + +const mockAllFalse = () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(false) + vi.mocked(trustvc.isWrappedV3Document).mockReturnValue(false) + vi.mocked(trustvc.isRawV2Document).mockReturnValue(false) + vi.mocked(trustvc.isRawV3Document).mockReturnValue(false) + vi.mocked(trustvc.isSignedWrappedV2Document).mockReturnValue(false) + vi.mocked(trustvc.isSignedWrappedV3Document).mockReturnValue(false) + vi.mocked(trustvc.vc.isSignedDocument).mockReturnValue(false) + vi.mocked(trustvc.vc.isRawDocument).mockReturnValue(false) + vi.mocked(trustvc.vc.isSignedDocumentV2_0).mockReturnValue(false) +} + +const makeFragment = ( + name: string, + type: VerificationFragmentType, + status: 'VALID' | 'INVALID' | 'SKIPPED' | 'ERROR' = 'VALID' +) => ({ name, type, status, data: {} }) + +// All verification-related fields that GTM carries between events +const VERIFICATION_RESET_FIELDS = [ + 'verification_result', + 'issuer_identity', + 'document_schema', + 'document_type', + 'issuer_method', + 'signing_algorithm', + 'error_code', + 'is_expired', + 'is_transferable', + 'token_registry_version', + 'chain_id', +] + +const DOCUMENT_RESET_FIELDS = [ + 'file_name', + 'source', + ...VERIFICATION_RESET_FIELDS, +] + +beforeEach(() => { + window.dataLayer = [] + mockAllFalse() + vi.clearAllMocks() +}) + +afterEach(() => { + vi.clearAllMocks() +}) + +// ─── getDocumentSchema ──────────────────────────────────────────────────────── + +describe('getDocumentSchema', () => { + it('returns OA v2 for wrapped v2 document', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('OA v2') + }) + + it('returns OA v2 for raw v2 document', () => { + vi.mocked(trustvc.isRawV2Document).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('OA v2') + }) + + it('returns OA v2 for signed wrapped v2 document', () => { + vi.mocked(trustvc.isSignedWrappedV2Document).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('OA v2') + }) + + it('returns OA v3 for wrapped v3 document', () => { + vi.mocked(trustvc.isWrappedV3Document).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('OA v3') + }) + + it('returns OA v3 for raw v3 document', () => { + vi.mocked(trustvc.isRawV3Document).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('OA v3') + }) + + it('returns W3C VC V2.0 for signed VC v2', () => { + vi.mocked(trustvc.vc.isSignedDocument).mockReturnValue(true) + vi.mocked(trustvc.vc.isSignedDocumentV2_0).mockReturnValue(true) + expect(getDocumentSchema({})).toBe('W3C VC V2.0') + }) + + it('returns W3C VC V1.1 for signed VC v1', () => { + vi.mocked(trustvc.vc.isSignedDocument).mockReturnValue(true) + vi.mocked(trustvc.vc.isSignedDocumentV2_0).mockReturnValue(false) + expect(getDocumentSchema({})).toBe('W3C VC V1.1') + }) + + it('returns W3C VC V1.1 for raw VC', () => { + vi.mocked(trustvc.vc.isRawDocument).mockReturnValue(true) + vi.mocked(trustvc.vc.isSignedDocumentV2_0).mockReturnValue(false) + expect(getDocumentSchema({})).toBe('W3C VC V1.1') + }) + + it('returns Unknown for unrecognised document', () => { + expect(getDocumentSchema({})).toBe('Unknown') + }) +}) + +// ─── getIssuerMethod ────────────────────────────────────────────────────────── + +describe('getIssuerMethod', () => { + it('returns DNS-TXT from DNS-TXT identity fragment', () => { + const frags = [ + makeFragment('OpenAttestationDnsTxtIdentityProof', 'ISSUER_IDENTITY'), + ] + expect(getIssuerMethod({}, frags)).toBe('DNS-TXT') + }) + + it('returns DNS-DID from DNS-DID identity fragment', () => { + const frags = [ + makeFragment('OpenAttestationDnsDidIdentityProof', 'ISSUER_IDENTITY'), + ] + expect(getIssuerMethod({}, frags)).toBe('DNS-DID') + }) + + it('returns DID:WEB from DID identity fragment', () => { + const frags = [ + makeFragment('OpenAttestationDidIdentityProof', 'ISSUER_IDENTITY'), + ] + expect(getIssuerMethod({}, frags)).toBe('DID:WEB') + }) + + it('ignores SKIPPED identity fragments', () => { + const frags = [ + makeFragment( + 'OpenAttestationDnsTxtIdentityProof', + 'ISSUER_IDENTITY', + 'SKIPPED' + ), + ] + expect(getIssuerMethod({}, frags)).toBe('Unknown') + }) + + it('returns DID:WEB for W3C VC with did: issuer', () => { + vi.mocked(trustvc.vc.isSignedDocument).mockReturnValue(true) + const doc = { issuer: 'did:web:example.com' } + expect(getIssuerMethod(doc, [])).toBe('DID:WEB') + }) + + it('returns Unknown when no fragments match', () => { + expect(getIssuerMethod({}, [])).toBe('Unknown') + }) +}) + +// ─── getSigningAlgorithm ────────────────────────────────────────────────────── + +describe('getSigningAlgorithm', () => { + it('returns merkleroot2018 for OA v2 documents', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + expect(getSigningAlgorithm({}, [])).toBe('merkleroot2018') + }) + + it('returns merkleroot2018 for OA v3 documents', () => { + vi.mocked(trustvc.isWrappedV3Document).mockReturnValue(true) + expect(getSigningAlgorithm({}, [])).toBe('merkleroot2018') + }) + + it('returns BBS2023 from BBS integrity fragment', () => { + const frags = [ + makeFragment('Bbs2023W3CSignatureIntegrity', 'DOCUMENT_INTEGRITY'), + ] + expect(getSigningAlgorithm({}, frags)).toBe('BBS2023') + }) + + it('returns ECDSA2023 from ECDSA integrity fragment', () => { + const frags = [ + makeFragment('EcdsaW3CSignatureIntegrity', 'DOCUMENT_INTEGRITY'), + ] + expect(getSigningAlgorithm({}, frags)).toBe('ECDSA2023') + }) + + it('ignores SKIPPED integrity fragments', () => { + const frags = [ + makeFragment( + 'Bbs2023W3CSignatureIntegrity', + 'DOCUMENT_INTEGRITY', + 'SKIPPED' + ), + ] + expect(getSigningAlgorithm({}, frags)).toBe('Unknown') + }) + + it('returns Unknown for unrecognised document with no fragments', () => { + expect(getSigningAlgorithm({}, [])).toBe('Unknown') + }) +}) + +// ─── pushGTMEvent ───────────────────────────────────────────────────────────── + +describe('pushGTMEvent', () => { + it('pushes event to window.dataLayer', () => { + pushGTMEvent({ event: 'TEST_EVENT', foo: 'bar' }) + expect(window.dataLayer).toHaveLength(1) + expect(window.dataLayer[0]).toEqual({ event: 'TEST_EVENT', foo: 'bar' }) + }) + + it('initialises dataLayer if absent', () => { + delete (window as any).dataLayer + pushGTMEvent({ event: 'INIT_TEST' }) + expect(window.dataLayer).toBeDefined() + expect(window.dataLayer[0].event).toBe('INIT_TEST') + }) + + it('does not throw when window is undefined (SSR-like)', () => { + const originalWindow = global.window + // @ts-expect-error simulating SSR + delete global.window + expect(() => pushGTMEvent({ event: 'SSR' })).not.toThrow() + global.window = originalWindow + }) +}) + +// ─── initGA4 ───────────────────────────────────────────────────────────────── + +describe('initGA4', () => { + it('calls ReactGA.initialize with the tag id', () => { + initGA4('G-TEST123') + expect(vi.mocked(ReactGA.initialize)).toHaveBeenCalledWith('G-TEST123') + }) + + it('is safe to call multiple times (idempotent)', () => { + expect(() => { + initGA4('G-TEST123') + initGA4('G-TEST123') + }).not.toThrow() + }) + + it('does nothing for empty tag id', () => { + initGA4('') + expect(vi.mocked(ReactGA.initialize)).not.toHaveBeenCalled() + }) +}) + +// ─── buildDroppedEvent ──────────────────────────────────────────────────────── + +describe('buildDroppedEvent', () => { + it('includes file_name and default source', () => { + const evt = buildDroppedEvent('test.json') + expect(evt.event).toBe('DOCUMENT_DROPPED') + expect(evt.file_name).toBe('test.json') + expect(evt.source).toBe('file_picker') + }) + + it('uses the provided source', () => { + expect(buildDroppedEvent('a.json', 'drop').source).toBe('drop') + expect(buildDroppedEvent('b.json', 'url').source).toBe('url') + expect(buildDroppedEvent('c.json', 'demo').source).toBe('demo') + }) + + it('includes environment', () => { + const evt = buildDroppedEvent('x.json', 'file_picker') + expect(evt.environment).toBeDefined() + }) + + it('explicitly resets all verification fields to undefined to clear GTM state', () => { + const evt = buildDroppedEvent('test.json') as Record + for (const field of VERIFICATION_RESET_FIELDS) { + expect(evt[field]).toBeUndefined() + // The key must be present (explicit undefined) so GTM clears stale values + expect(Object.prototype.hasOwnProperty.call(evt, field)).toBe(true) + } + }) +}) + +// ─── buildVerificationEvent ─────────────────────────────────────────────────── + +describe('buildVerificationEvent', () => { + it('builds a valid event payload', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + const frags = [ + makeFragment('OpenAttestationDnsTxtIdentityProof', 'ISSUER_IDENTITY'), + ] + const evt = buildVerificationEvent({}, frags, true, 'dns-name.com') + expect(evt.event).toBe('DOCUMENT_VERIFICATION_COMPLETED') + expect(evt.verification_result).toBe('valid') + expect(evt.document_schema).toBe('OA v2') + expect(evt.issuer_method).toBe('DNS-TXT') + expect(evt.issuer_identity).toBe('dns-name.com') + expect(evt.signing_algorithm).toBe('merkleroot2018') + expect(evt.error_code).toBeUndefined() + }) + + it('sets verification_result to invalid', () => { + const evt = buildVerificationEvent({}, [], false, 'id.com', 'HASH_ERROR') + expect(evt.verification_result).toBe('invalid') + expect(evt.error_code).toBe('HASH_ERROR') + }) + + it('includes extras when provided', () => { + const evt = buildVerificationEvent({}, [], true, 'id.com', undefined, { + isExpired: true, + isTransferable: false, + tokenRegistryVersion: 'V5', + chainId: '1', + }) + expect(evt.is_expired).toBe(true) + expect(evt.is_transferable).toBe(false) + expect(evt.token_registry_version).toBe('V5') + expect(evt.chain_id).toBe('1') + }) + + it('uses Unknown for empty issuer identity', () => { + const evt = buildVerificationEvent({}, [], true, '') + expect(evt.issuer_identity).toBe('Unknown') + }) +}) + +// ─── trackDocumentDropped ───────────────────────────────────────────────────── + +describe('trackDocumentDropped', () => { + it('pushes DOCUMENT_DROPPED to dataLayer with correct source', () => { + trackDocumentDropped('doc.json', 'drop') + expect(window.dataLayer).toHaveLength(1) + expect(window.dataLayer[0].event).toBe('DOCUMENT_DROPPED') + expect(window.dataLayer[0].file_name).toBe('doc.json') + expect(window.dataLayer[0].source).toBe('drop') + }) + + it('defaults source to file_picker', () => { + trackDocumentDropped('doc.json') + expect(window.dataLayer[0].source).toBe('file_picker') + }) + + it('resets all verification fields to undefined in the dataLayer push', () => { + trackDocumentDropped('doc.json', 'drop') + const evt = window.dataLayer[0] as Record + for (const field of VERIFICATION_RESET_FIELDS) { + expect(Object.prototype.hasOwnProperty.call(evt, field)).toBe(true) + expect(evt[field]).toBeUndefined() + } + }) + + it('never throws', () => { + expect(() => trackDocumentDropped(null as any)).not.toThrow() + }) +}) + +// ─── trackDocumentVerified ──────────────────────────────────────────────────── + +describe('trackDocumentVerified', () => { + it('pushes DOCUMENT_VERIFICATION_COMPLETED with valid result', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + const frags = [ + makeFragment('OpenAttestationDnsTxtIdentityProof', 'ISSUER_IDENTITY'), + ] + trackDocumentVerified({}, frags, true, 'issuer.com') + expect(window.dataLayer[0].event).toBe('DOCUMENT_VERIFICATION_COMPLETED') + expect(window.dataLayer[0].verification_result).toBe('valid') + }) + + it('passes extras to the event', () => { + trackDocumentVerified({}, [], true, 'id.com', undefined, { + isExpired: false, + isTransferable: true, + tokenRegistryVersion: 'V4', + chainId: '137', + }) + expect(window.dataLayer[0].is_transferable).toBe(true) + expect(window.dataLayer[0].chain_id).toBe('137') + expect(window.dataLayer[0].token_registry_version).toBe('V4') + }) + + it('never throws', () => { + expect(() => trackDocumentVerified(null as any, [], true, '')).not.toThrow() + }) +}) + +// ─── trackDocumentVerifyError ───────────────────────────────────────────────── + +describe('trackDocumentVerifyError', () => { + it('pushes invalid DOCUMENT_VERIFICATION_COMPLETED with error_code', () => { + trackDocumentVerifyError(undefined, 'PARSE_ERROR') + const evt = window.dataLayer[0] + expect(evt.event).toBe('DOCUMENT_VERIFICATION_COMPLETED') + expect(evt.verification_result).toBe('invalid') + expect(evt.error_code).toBe('PARSE_ERROR') + expect(evt.document_schema).toBe('Unknown') + }) + + it('detects schema when doc is provided', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + trackDocumentVerifyError({}, 'NETWORK_ERROR') + expect(window.dataLayer[0].document_schema).toBe('OA v2') + }) + + it('never throws', () => { + expect(() => trackDocumentVerifyError(null as any, 'ERR')).not.toThrow() + }) +}) + +// ─── trackNetworkSelectionShown ─────────────────────────────────────────────── + +describe('trackNetworkSelectionShown', () => { + it('pushes NETWORK_SELECTION_SHOWN with document_schema', () => { + vi.mocked(trustvc.isWrappedV2Document).mockReturnValue(true) + trackNetworkSelectionShown({}) + expect(window.dataLayer[0].event).toBe('NETWORK_SELECTION_SHOWN') + expect(window.dataLayer[0].document_schema).toBe('OA v2') + }) + + it('never throws', () => { + expect(() => trackNetworkSelectionShown(null as any)).not.toThrow() + }) +}) + +// ─── trackNetworkSelected ───────────────────────────────────────────────────── + +describe('trackNetworkSelected', () => { + it('pushes NETWORK_SELECTED with chain_id', () => { + trackNetworkSelected('137') + expect(window.dataLayer[0].event).toBe('NETWORK_SELECTED') + expect(window.dataLayer[0].chain_id).toBe('137') + }) + + it('never throws', () => { + expect(() => trackNetworkSelected('')).not.toThrow() + }) +}) + +// ─── trackNetworkSelectionCancelled ────────────────────────────────────────── + +describe('trackNetworkSelectionCancelled', () => { + it('pushes NETWORK_SELECTION_CANCELLED', () => { + trackNetworkSelectionCancelled() + expect(window.dataLayer[0].event).toBe('NETWORK_SELECTION_CANCELLED') + }) +}) + +// ─── trackVerificationReset ─────────────────────────────────────────────────── + +describe('trackVerificationReset', () => { + it('pushes VERIFICATION_RESET', () => { + trackVerificationReset() + expect(window.dataLayer[0].event).toBe('VERIFICATION_RESET') + }) +}) + +// ─── trackWalletConnected ───────────────────────────────────────────────────── + +describe('trackWalletConnected', () => { + it('pushes WALLET_CONNECTED with metamask wallet_type', () => { + trackWalletConnected('metamask') + expect(window.dataLayer[0].event).toBe('WALLET_CONNECTED') + expect(window.dataLayer[0].wallet_type).toBe('metamask') + }) + + it('pushes WALLET_CONNECTED with magic_link wallet_type', () => { + trackWalletConnected('magic_link') + expect(window.dataLayer[0].wallet_type).toBe('magic_link') + }) +}) + +// ─── trackWalletDisconnected ────────────────────────────────────────────────── + +describe('trackWalletDisconnected', () => { + it('pushes WALLET_DISCONNECTED with correct wallet_type', () => { + trackWalletDisconnected('metamask') + expect(window.dataLayer[0].event).toBe('WALLET_DISCONNECTED') + expect(window.dataLayer[0].wallet_type).toBe('metamask') + }) +}) + +// ─── trackWalletConnectFailed ───────────────────────────────────────────────── + +describe('trackWalletConnectFailed', () => { + it('pushes WALLET_CONNECT_FAILED with wallet_type and error_code', () => { + trackWalletConnectFailed('metamask', 'User Rejected Transaction') + const evt = window.dataLayer[0] + expect(evt.event).toBe('WALLET_CONNECT_FAILED') + expect(evt.wallet_type).toBe('metamask') + expect(evt.error_code).toBe('User Rejected Transaction') + }) +}) + +// ─── trackAssetActionInitiated ──────────────────────────────────────────────── + +describe('trackAssetActionInitiated', () => { + it('pushes ASSET_ACTION_INITIATED with action, chain_id, and version', () => { + trackAssetActionInitiated('TransferHolder', '137', 'V5') + const evt = window.dataLayer[0] + expect(evt.event).toBe('ASSET_ACTION_INITIATED') + expect(evt.action).toBe('TransferHolder') + expect(evt.chain_id).toBe('137') + expect(evt.token_registry_version).toBe('V5') + }) + + it('works without optional params', () => { + trackAssetActionInitiated('ReturnToIssuer') + expect(window.dataLayer[0].action).toBe('ReturnToIssuer') + expect(window.dataLayer[0].chain_id).toBeUndefined() + }) +}) + +// ─── trackAssetActionCompleted ─────────────────────────────────────────────── + +describe('trackAssetActionCompleted', () => { + it('pushes ASSET_ACTION_COMPLETED with action and chain_id', () => { + trackAssetActionCompleted('TransferHolder', '137') + const evt = window.dataLayer[0] + expect(evt.event).toBe('ASSET_ACTION_COMPLETED') + expect(evt.action).toBe('TransferHolder') + expect(evt.chain_id).toBe('137') + }) + + it('works without optional chainId', () => { + trackAssetActionCompleted('ReturnToIssuer') + expect(window.dataLayer[0].action).toBe('ReturnToIssuer') + expect(window.dataLayer[0].chain_id).toBeUndefined() + }) +}) + +// ─── trackAssetActionFailed ─────────────────────────────────────────────────── + +describe('trackAssetActionFailed', () => { + it('pushes ASSET_ACTION_FAILED with action, error_code, and chain_id', () => { + trackAssetActionFailed( + 'NominateBeneficiary', + 'User Rejected Transaction', + '1' + ) + const evt = window.dataLayer[0] + expect(evt.event).toBe('ASSET_ACTION_FAILED') + expect(evt.action).toBe('NominateBeneficiary') + expect(evt.error_code).toBe('User Rejected Transaction') + expect(evt.chain_id).toBe('1') + }) + + it('works without optional chainId', () => { + trackAssetActionFailed('ReturnToIssuer', 'TRANSACTION_ERROR') + expect(window.dataLayer[0].action).toBe('ReturnToIssuer') + expect(window.dataLayer[0].chain_id).toBeUndefined() + }) +}) + +// ─── trackSupportFormSubmitted ──────────────────────────────────────────────── + +describe('trackSupportFormSubmitted', () => { + it('pushes SUPPORT_FORM_SUBMITTED with enquiry_type', () => { + trackSupportFormSubmitted('TradeTrust') + expect(window.dataLayer[0].event).toBe('SUPPORT_FORM_SUBMITTED') + expect(window.dataLayer[0].enquiry_type).toBe('TradeTrust') + }) + + it('resets all document and verification fields to clear GTM state', () => { + trackSupportFormSubmitted('General_Enquiry') + const evt = window.dataLayer[0] as Record + for (const field of DOCUMENT_RESET_FIELDS) { + expect(Object.prototype.hasOwnProperty.call(evt, field)).toBe(true) + expect(evt[field]).toBeUndefined() + } + }) +}) + +// ─── trackSupportFormFailed ─────────────────────────────────────────────────── + +describe('trackSupportFormFailed', () => { + it('pushes SUPPORT_FORM_FAILED with enquiry_type and error_code', () => { + trackSupportFormFailed('General_Enquiry', 'Server Error') + const evt = window.dataLayer[0] + expect(evt.event).toBe('SUPPORT_FORM_FAILED') + expect(evt.enquiry_type).toBe('General_Enquiry') + expect(evt.error_code).toBe('Server Error') + }) + + it('resets document and file fields (excluding its own error_code) to clear GTM state', () => { + trackSupportFormFailed('General_Enquiry', 'Server Error') + const evt = window.dataLayer[0] as Record + const docFields = DOCUMENT_RESET_FIELDS.filter(f => f !== 'error_code') + for (const field of docFields) { + expect(Object.prototype.hasOwnProperty.call(evt, field)).toBe(true) + expect(evt[field]).toBeUndefined() + } + // error_code belongs to this event itself — must not be cleared + expect(evt.error_code).toBe('Server Error') + }) +}) diff --git a/src/utils/analytics.ts b/src/utils/analytics.ts new file mode 100644 index 0000000..47bb114 --- /dev/null +++ b/src/utils/analytics.ts @@ -0,0 +1,563 @@ +import ReactGA from 'react-ga4' +import { + isWrappedV2Document, + isWrappedV3Document, + isRawV2Document, + isRawV3Document, + isSignedWrappedV2Document, + isSignedWrappedV3Document, + vc, +} from '@trustvc/trustvc' +import type { VerificationFragment } from '../components/home/VerifySection/useVerify' +import { ANALYTICS_EVENTS } from '../constants/analyticsEvents' + +// ─── Types ─────────────────────────────────────────────────────────────────── + +export type DocumentSchema = + | 'OA v2' + | 'OA v3' + | 'W3C VC V1.1' + | 'W3C VC V2.0' + | 'Unknown' + +export type IssuerMethod = 'DNS-TXT' | 'DNS-DID' | 'DID:WEB' | 'Unknown' + +export type SigningAlgorithm = + | 'merkleroot2018' + | 'BBS2023' + | 'ECDSA2023' + | 'Unknown' + +export type VerificationResult = 'valid' | 'invalid' + +// ─── GTM dataLayer types ────────────────────────────────────────────────────── + +export interface GTMEvent { + event: string + [key: string]: unknown +} + +declare global { + interface Window { + dataLayer: GTMEvent[] + } +} + +export type DocumentDroppedSource = 'drop' | 'file_picker' | 'url' | 'demo' + +export type WalletType = 'metamask' | 'magic_link' + +export interface DocumentDroppedEvent extends GTMEvent { + event: typeof ANALYTICS_EVENTS.DOCUMENT_DROPPED + environment: string + file_name: string + source: DocumentDroppedSource +} + +export interface DocumentVerificationEvent extends GTMEvent { + event: typeof ANALYTICS_EVENTS.DOCUMENT_VERIFICATION_COMPLETED + environment: string + document_schema: DocumentSchema + document_type: DocumentSchema + issuer_method: IssuerMethod + issuer_identity: string + signing_algorithm: SigningAlgorithm + verification_result: VerificationResult + error_code: string | undefined + is_expired: boolean | undefined + is_transferable: boolean | undefined + token_registry_version: string | null | undefined + chain_id: string | null | undefined +} + +// ─── Fragment → label maps ──────────────────────────────────────────────────── + +/** + * Maps DOCUMENT_INTEGRITY fragment names to signing algorithm labels. + * Extend this map to support future signing suites without touching call sites. + * Sourced from @trustvc/trustvc verifier implementations. + */ +const SIGNING_ALGORITHM_FRAGMENT_MAP: Readonly< + Record +> = { + OpenAttestationHash: 'merkleroot2018', + Bbs2023W3CSignatureIntegrity: 'BBS2023', + EcdsaW3CSignatureIntegrity: 'ECDSA2023', +} + +/** Maps ISSUER_IDENTITY fragment names to issuer method labels. */ +const ISSUER_METHOD_FRAGMENT_MAP: Readonly> = { + OpenAttestationDnsTxtIdentityProof: 'DNS-TXT', + OpenAttestationDnsDidIdentityProof: 'DNS-DID', + OpenAttestationDidIdentityProof: 'DID:WEB', +} + +// ─── Detection helpers ──────────────────────────────────────────────────────── + +export const getDocumentSchema = (doc: unknown): DocumentSchema => { + const d = doc as any + if ( + isWrappedV2Document(d) || + isRawV2Document(d) || + isSignedWrappedV2Document(d) + ) + return 'OA v2' + if ( + isWrappedV3Document(d) || + isRawV3Document(d) || + isSignedWrappedV3Document(d) + ) + return 'OA v3' + if (vc.isSignedDocument(d) || vc.isRawDocument(d)) + return vc.isSignedDocumentV2_0(d) ? 'W3C VC V2.0' : 'W3C VC V1.1' + return 'Unknown' +} + +export const getIssuerMethod = ( + doc: unknown, + frags: VerificationFragment[] +): IssuerMethod => { + // OA: derive from the identity proof fragment that actually ran (not skipped) + const identityFrag = frags.find( + f => f.type === 'ISSUER_IDENTITY' && f.status !== 'SKIPPED' + ) + if (identityFrag) { + const method = ISSUER_METHOD_FRAGMENT_MAP[identityFrag.name] + if (method) return method + } + // W3C VC: infer from the issuer DID method + const d = doc as any + if (vc.isSignedDocument(d) || vc.isRawDocument(d)) { + const issuer = typeof d?.issuer === 'string' ? d.issuer : d?.issuer?.id + if (typeof issuer === 'string' && issuer.startsWith('did:')) + return 'DID:WEB' + } + return 'Unknown' +} + +export const getSigningAlgorithm = ( + doc: unknown, + frags: VerificationFragment[] +): SigningAlgorithm => { + // OA v2/v3 always use SHA3 Merkle proof — no need to inspect fragments + const d = doc as any + if ( + isWrappedV2Document(d) || + isSignedWrappedV2Document(d) || + isRawV2Document(d) + ) + return 'merkleroot2018' + if ( + isWrappedV3Document(d) || + isSignedWrappedV3Document(d) || + isRawV3Document(d) + ) + return 'merkleroot2018' + + // W3C VC: identify from the active DOCUMENT_INTEGRITY verifier fragment + const activeFragment = frags.find( + f => + f.type === 'DOCUMENT_INTEGRITY' && + f.status !== 'SKIPPED' && + f.name in SIGNING_ALGORITHM_FRAGMENT_MAP + ) + return activeFragment + ? SIGNING_ALGORITHM_FRAGMENT_MAP[activeFragment.name] + : 'Unknown' +} + +// ─── GTM ───────────────────────────────────────────────────────────────────── + +/** + * Pushes an event to window.dataLayer only — no external calls are made here. + * GTM (if loaded) reads from dataLayer and forwards events per its own config. + * Events pushed before GTM loads are queued and replayed when GTM initialises. + * Safe to call from any context: silently no-ops in SSR, never throws. + */ +export const pushGTMEvent = (eventData: GTMEvent): void => { + try { + if (typeof window === 'undefined') return + window.dataLayer = window.dataLayer ?? [] + window.dataLayer.push(eventData) + } catch { + // Analytics failures must never affect the application + } +} + +// ─── GA4 ───────────────────────────────────────────────────────────────────── + +// When GTM is configured it forwards events to GA4 via its own tags — sending +// directly to GA4 as well would double-count every event, including the +// automatic page_view fired by ReactGA.initialize. Only use the GA4 direct +// channel when GTM is absent. +const GTM_CONFIGURED = Boolean(import.meta.env.VITE_GTM_CONTAINER_ID) + +let ga4Initialized = false + +export const initGA4 = (tagId: string): void => { + if (!tagId || ga4Initialized || GTM_CONFIGURED) return + try { + ReactGA.initialize(tagId) + ga4Initialized = true + } catch { + // Analytics failures must never affect the application + } +} + +const pushGA4Event = ( + eventName: string, + params: Record +): void => { + if (!ga4Initialized) return + try { + ReactGA.event(eventName, params as any) + } catch { + // Analytics failures must never affect the application + } +} + +// ─── Internal: fire to both channels ───────────────────────────────────────── + +const trackEvent = (payload: GTMEvent): void => { + pushGTMEvent(payload) + if (!GTM_CONFIGURED) { + const { event: eventName, ...params } = payload + pushGA4Event(eventName, params) + } +} + +// ─── Environment ───────────────────────────────────────────────────────────── + +const ENVIRONMENT = + (import.meta.env.VITE_PLATFORM as string | undefined) ?? 'local' + +// ─── Event builders ─────────────────────────────────────────────────────────── + +export const buildDroppedEvent = ( + fileName: string, + source: DocumentDroppedSource = 'file_picker' +): DocumentDroppedEvent => ({ + event: ANALYTICS_EVENTS.DOCUMENT_DROPPED, + environment: ENVIRONMENT, + file_name: fileName, + source, + // Explicitly clear verification fields so GTM doesn't carry stale values + // from the previous document_verification_completed event into this one. + verification_result: undefined, + issuer_identity: undefined, + document_schema: undefined, + document_type: undefined, + issuer_method: undefined, + signing_algorithm: undefined, + error_code: undefined, + is_expired: undefined, + is_transferable: undefined, + token_registry_version: undefined, + chain_id: undefined, +}) + +export const buildVerificationEvent = ( + doc: unknown, + frags: VerificationFragment[], + isValid: boolean, + issuerIdentity: string, + errorCode?: string, + extras?: { + isExpired?: boolean + isTransferable?: boolean + tokenRegistryVersion?: string | null + chainId?: string | null + } +): DocumentVerificationEvent => { + const schema = getDocumentSchema(doc) + return { + event: ANALYTICS_EVENTS.DOCUMENT_VERIFICATION_COMPLETED, + environment: ENVIRONMENT, + document_schema: schema, + document_type: schema, + issuer_method: getIssuerMethod(doc, frags), + issuer_identity: issuerIdentity || 'Unknown', + signing_algorithm: getSigningAlgorithm(doc, frags), + verification_result: isValid ? 'valid' : 'invalid', + error_code: errorCode, + is_expired: extras?.isExpired, + is_transferable: extras?.isTransferable, + token_registry_version: extras?.tokenRegistryVersion, + chain_id: extras?.chainId, + } +} + +// ─── Public tracking API ────────────────────────────────────────────────────── + +/** + * Fired when a user drops or selects a file for verification. + * Captures drop intent — before parsing or verification begins. + */ +export const trackDocumentDropped = ( + fileName: string, + source: DocumentDroppedSource = 'file_picker' +): void => { + try { + trackEvent(buildDroppedEvent(fileName, source)) + } catch { + // Analytics failures must never affect the application + } +} + +/** + * Fired when verification completes (valid or invalid). + * Captures schema, issuer method, identity, signing algorithm, result, and error code. + */ +export const trackDocumentVerified = ( + doc: unknown, + frags: VerificationFragment[], + isValid: boolean, + issuerIdentity: string, + errorCode?: string, + extras?: { + isExpired?: boolean + isTransferable?: boolean + tokenRegistryVersion?: string | null + chainId?: string | null + } +): void => { + try { + trackEvent( + buildVerificationEvent( + doc, + frags, + isValid, + issuerIdentity, + errorCode, + extras + ) + ) + } catch { + // Analytics failures must never affect the application + } +} + +/** + * Fired when an exception is thrown before fragments are available + * (parse error, network error, etc.). `doc` may be undefined when the + * file could not be parsed as JSON. + */ +export const trackDocumentVerifyError = ( + doc: unknown | undefined, + errorCode: string +): void => { + try { + const schema = doc != null ? getDocumentSchema(doc) : 'Unknown' + const algo = doc != null ? getSigningAlgorithm(doc, []) : 'Unknown' + trackEvent({ + event: ANALYTICS_EVENTS.DOCUMENT_VERIFICATION_COMPLETED, + environment: ENVIRONMENT, + document_schema: schema, + document_type: schema, + issuer_method: 'Unknown', + issuer_identity: 'Unknown', + signing_algorithm: algo, + verification_result: 'invalid', + error_code: errorCode, + is_expired: undefined, + is_transferable: undefined, + token_registry_version: undefined, + chain_id: undefined, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackNetworkSelectionShown = (doc: unknown): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.NETWORK_SELECTION_SHOWN, + environment: ENVIRONMENT, + document_schema: getDocumentSchema(doc), + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackNetworkSelected = (chainId: string): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.NETWORK_SELECTED, + environment: ENVIRONMENT, + chain_id: chainId, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackNetworkSelectionCancelled = (): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.NETWORK_SELECTION_CANCELLED, + environment: ENVIRONMENT, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackVerificationReset = (): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.VERIFICATION_RESET, + environment: ENVIRONMENT, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackWalletConnected = (walletType: WalletType): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.WALLET_CONNECTED, + environment: ENVIRONMENT, + wallet_type: walletType, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackWalletDisconnected = (walletType: WalletType): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.WALLET_DISCONNECTED, + environment: ENVIRONMENT, + wallet_type: walletType, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackWalletConnectFailed = ( + walletType: WalletType, + errorCode: string +): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.WALLET_CONNECT_FAILED, + environment: ENVIRONMENT, + wallet_type: walletType, + error_code: errorCode, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackAssetActionInitiated = ( + action: string, + chainId?: string, + tokenRegistryVersion?: string +): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.ASSET_ACTION_INITIATED, + environment: ENVIRONMENT, + action, + chain_id: chainId, + token_registry_version: tokenRegistryVersion, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackAssetActionCompleted = ( + action: string, + chainId?: string +): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.ASSET_ACTION_COMPLETED, + environment: ENVIRONMENT, + action, + chain_id: chainId, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackAssetActionFailed = ( + action: string, + errorCode: string, + chainId?: string +): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.ASSET_ACTION_FAILED, + environment: ENVIRONMENT, + action, + error_code: errorCode, + chain_id: chainId, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackSupportFormSubmitted = (enquiryType: string): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.SUPPORT_FORM_SUBMITTED, + environment: ENVIRONMENT, + enquiry_type: enquiryType, + // Clear document fields that persist in GTM's dataLayer from prior events + file_name: undefined, + source: undefined, + verification_result: undefined, + issuer_identity: undefined, + document_schema: undefined, + document_type: undefined, + issuer_method: undefined, + signing_algorithm: undefined, + error_code: undefined, + is_expired: undefined, + is_transferable: undefined, + token_registry_version: undefined, + chain_id: undefined, + }) + } catch { + // Analytics failures must never affect the application + } +} + +export const trackSupportFormFailed = ( + enquiryType: string, + errorCode: string +): void => { + try { + trackEvent({ + event: ANALYTICS_EVENTS.SUPPORT_FORM_FAILED, + environment: ENVIRONMENT, + enquiry_type: enquiryType, + error_code: errorCode, + // Clear document fields that persist in GTM's dataLayer from prior events + file_name: undefined, + source: undefined, + verification_result: undefined, + issuer_identity: undefined, + document_schema: undefined, + document_type: undefined, + issuer_method: undefined, + signing_algorithm: undefined, + is_expired: undefined, + is_transferable: undefined, + token_registry_version: undefined, + chain_id: undefined, + }) + } catch { + // Analytics failures must never affect the application + } +} From baa28ac3b08811eb2334e5245c32012bb1b25304 Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Tue, 30 Jun 2026 08:39:20 +0530 Subject: [PATCH 02/10] fix: gtm issues (#80) * fix: gtm issues * fix: declarations for duplicate entities --- .../AssetManagementPanel/AssetManagementApplication/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx b/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx index adf7d23..6220503 100644 --- a/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx +++ b/src/components/AssetManagementPanel/AssetManagementApplication/index.tsx @@ -170,8 +170,9 @@ export const AssetManagementApplication: FunctionComponent< case AssetManagementActions.TransferHolder: return changeHolderState case AssetManagementActions.EndorseBeneficiary: - case AssetManagementActions.TransferOwner: return endorseBeneficiaryState + case AssetManagementActions.TransferOwner: + return transferOwnerHoldersState case AssetManagementActions.TransferOwnerHolder: return transferOwnerHoldersState case AssetManagementActions.ReturnToIssuer: From 30d0c7a43cf68e5afad20efb6857c8ca6401dec0 Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Tue, 30 Jun 2026 15:45:44 +0530 Subject: [PATCH 03/10] feat: integration of sentry (#79) * feature: integration of sentry * feature: update sentry env variable and configurations * fix: types issue with sentry test files * fix: coderabbit issues * Update src/lib/sentry/scrub.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Refactor Sentry integration to use scoped context - Updated Sentry mock in tests to utilize a scoped context instead of global methods, improving test isolation and accuracy. - Refactored `withScope` function to accept a scope parameter, allowing for better context management during error capturing. - Enhanced tests for `captureVerificationInvalid` to verify context attachment through the scoped approach. - Adjusted Sentry initialization to ensure proper context handling in production and testing environments. * Refactor component structure in main.tsx for improved readability - Rearranged the component hierarchy within the render method to enhance clarity and maintainability. - Ensured that the SentryErrorBoundary wraps the DocumentProvider, improving error handling for the entire application. * Enhance URL scrubbing in Sentry integration - Added functionality to strip hash fragments and `q` query parameters from URLs in both event requests and navigation breadcrumbs, improving data privacy. - Updated tests to verify that sensitive URL components are correctly removed, ensuring robust handling of potentially sensitive information. * Enhance error handling and URL scrubbing in Sentry integration - Updated tests to ensure that Sentry test errors are correctly blocked in production environments. - Improved URL scrubbing functionality to strip sensitive query parameters and hash fragments from URLs. - Added test cases to verify the removal of sensitive information from URLs and to report timeout aborts to Sentry, enhancing overall data privacy and error reporting. * Enhance data redaction in Sentry scrubbing functionality - Added a test case to ensure camelCase sensitive keys are redacted regardless of casing, improving data privacy. - Updated sensitive keys in the scrub module to be case-insensitive, ensuring consistent redaction of sensitive information. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .env.example | 22 + .github/workflows/deploy-dev.yml | 13 + .github/workflows/deploy-prod.yml | 13 + package-lock.json | 508 +++++++++++++++++- package.json | 2 + .../VerifySection/useVerify.analytics.test.ts | 10 + .../home/VerifySection/useVerify.test.ts | 18 + .../home/VerifySection/useVerify.ts | 63 ++- src/lib/sanity/news.ts | 6 + src/lib/sentry/SentryErrorBoundary.tsx | 29 + src/lib/sentry/capture.test.ts | 119 ++++ src/lib/sentry/capture.ts | 195 +++++++ src/lib/sentry/documentSchema.ts | 40 ++ src/lib/sentry/index.ts | 13 + src/lib/sentry/init.ts | 53 ++ src/lib/sentry/scrub.test.ts | 153 ++++++ src/lib/sentry/scrub.ts | 206 +++++++ src/main.tsx | 35 +- src/utils/fetchClient.test.ts | 71 +++ src/utils/fetchClient.ts | 95 +++- vite.config.js | 47 ++ 21 files changed, 1662 insertions(+), 49 deletions(-) create mode 100644 src/lib/sentry/SentryErrorBoundary.tsx create mode 100644 src/lib/sentry/capture.test.ts create mode 100644 src/lib/sentry/capture.ts create mode 100644 src/lib/sentry/documentSchema.ts create mode 100644 src/lib/sentry/index.ts create mode 100644 src/lib/sentry/init.ts create mode 100644 src/lib/sentry/scrub.test.ts create mode 100644 src/lib/sentry/scrub.ts diff --git a/.env.example b/.env.example index ad581b4..20c0cdc 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,27 @@ VITE_SUPPORT_API_BASE_URL= +# ----------------------------------------------------------------------------- +# Sentry — error monitoring (see docs/sentry-setup.md) +# One project, one DSN; VITE_SENTRY_ENVIRONMENT separates dev/prod in the dashboard. +# ----------------------------------------------------------------------------- + +# Runtime (browser) — required in every deployed environment +# Leave empty locally to disable Sentry. +# Example: https://@o.ingest.sentry.io/ +VITE_SENTRY_DSN= +# Environment label shown in Sentry: local | dev | production +VITE_SENTRY_ENVIRONMENT=local +# Set to the git SHA at build time (injected automatically by the deploy workflow). +VITE_SENTRY_RELEASE= + +# Build-time only — used by @sentry/vite-plugin to upload source maps. +# Not embedded in the browser bundle. Leave empty to skip source map upload locally. +# Example: / / +SENTRY_AUTH_TOKEN= +SENTRY_ORG= +SENTRY_PROJECT= + +# ----------------------------------------------------------------------------- # Analytics (GA4 + GTM) — see docs/analytics-setup.md # # Local dev: leave both empty to disable tracking (recommended). diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 578328d..c3b7b5c 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -39,6 +39,9 @@ jobs: AWS_REGION: ap-southeast-1 S3_BUCKET: ${{ secrets.S3_BUCKET_DEV }} ENV_FILE: ${{ secrets.TRUSTVC_WEB_ENV_DEVELOPMENT }} + VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} + VITE_SENTRY_ENVIRONMENT: dev + VITE_SENTRY_RELEASE: ${{ github.sha }} VITE_GTM_CONTAINER_ID: ${{ secrets.VITE_GTM_CONTAINER_ID_DEVELOPMENT }} VITE_GA4_TAG_ID: ${{ secrets.VITE_GA4_TAG_ID_DEVELOPMENT }} VITE_PLATFORM: dev @@ -59,18 +62,28 @@ jobs: - name: Create .env for build run: | printf '%s\n' "$ENV_FILE" \ + | grep -v '^VITE_SENTRY_DSN=' \ + | grep -v '^VITE_SENTRY_ENVIRONMENT=' \ + | grep -v '^VITE_SENTRY_RELEASE=' \ | grep -v '^VITE_GTM_CONTAINER_ID=' \ | grep -v '^VITE_GA4_TAG_ID=' \ | grep -v '^VITE_PLATFORM=' > .env echo "VITE_GTM_CONTAINER_ID=${VITE_GTM_CONTAINER_ID}" >> .env echo "VITE_GA4_TAG_ID=${VITE_GA4_TAG_ID}" >> .env echo "VITE_PLATFORM=${VITE_PLATFORM}" >> .env + echo "VITE_SENTRY_DSN=${VITE_SENTRY_DSN}" >> .env + echo "VITE_SENTRY_ENVIRONMENT=${VITE_SENTRY_ENVIRONMENT}" >> .env + echo "VITE_SENTRY_RELEASE=${VITE_SENTRY_RELEASE}" >> .env - name: Install dependencies run: npm ci - name: Build run: npm run build + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - name: Upload build artifact (Dev) uses: actions/upload-artifact@v4 diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 39c05e1..e675293 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -18,6 +18,9 @@ jobs: S3_BUCKET: ${{ secrets.S3_BUCKET_PROD }} CF_DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID_PROD }} ENV_FILE: ${{ secrets.TRUSTVC_WEB_ENV_PRODUCTION }} + VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} + VITE_SENTRY_ENVIRONMENT: production + VITE_SENTRY_RELEASE: ${{ github.sha }} VITE_GTM_CONTAINER_ID: ${{ secrets.VITE_GTM_CONTAINER_ID_PRODUCTION }} VITE_GA4_TAG_ID: ${{ secrets.VITE_GA4_TAG_ID_PRODUCTION }} VITE_PLATFORM: production @@ -38,12 +41,18 @@ jobs: - name: Create .env for build run: | printf '%s\n' "$ENV_FILE" \ + | grep -v '^VITE_SENTRY_DSN=' \ + | grep -v '^VITE_SENTRY_ENVIRONMENT=' \ + | grep -v '^VITE_SENTRY_RELEASE=' \ | grep -v '^VITE_GTM_CONTAINER_ID=' \ | grep -v '^VITE_GA4_TAG_ID=' \ | grep -v '^VITE_PLATFORM=' > .env echo "VITE_GTM_CONTAINER_ID=${VITE_GTM_CONTAINER_ID}" >> .env echo "VITE_GA4_TAG_ID=${VITE_GA4_TAG_ID}" >> .env echo "VITE_PLATFORM=${VITE_PLATFORM}" >> .env + echo "VITE_SENTRY_DSN=${VITE_SENTRY_DSN}" >> .env + echo "VITE_SENTRY_ENVIRONMENT=${VITE_SENTRY_ENVIRONMENT}" >> .env + echo "VITE_SENTRY_RELEASE=${VITE_SENTRY_RELEASE}" >> .env - name: Install dependencies run: npm ci @@ -53,6 +62,10 @@ jobs: - name: Build run: npm run build + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/package-lock.json b/package-lock.json index 03aa25c..b8f2485 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@sanity/client": "^7.20.0", "@sanity/image-url": "^2.1.1", + "@sentry/react": "^10.62.0", "@trustvc/decentralized-renderer-react-components": "^1.0.3", "@trustvc/trustvc": "^2.14.1", "@types/lodash": "^4.17.24", @@ -28,6 +29,7 @@ }, "devDependencies": { "@eslint/js": "^9.17.0", + "@sentry/vite-plugin": "^5.3.0", "@synthetixio/synpress": "4.0.5", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.1.0", @@ -5254,6 +5256,366 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@sentry/babel-plugin-component-annotate": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-5.3.0.tgz", + "integrity": "sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@sentry/browser": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.62.0.tgz", + "integrity": "sha512-uJi0yPssB3Nt/cZ8/S8opW42gaM59/6IyNtPFYD7C0ciudi/nIo5QMVpCYBBI3jnKFOIQLlsMT4pDlOLuxxNuQ==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.62.0", + "@sentry/core": "10.62.0", + "@sentry/feedback": "10.62.0", + "@sentry/replay": "10.62.0", + "@sentry/replay-canvas": "10.62.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser-utils": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.62.0.tgz", + "integrity": "sha512-mS9HVVuWIdye9o0xUGFmzNOBqktF4n5kugrF8NCOYYDrr5ZV8Cx7BlquHQn5UpCeViVhZtcDlEm4iOK7++Px7A==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.62.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser-utils/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/bundler-plugin-core": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-5.3.0.tgz", + "integrity": "sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.5", + "@sentry/babel-plugin-component-annotate": "5.3.0", + "@sentry/cli": "^2.58.5", + "dotenv": "^16.3.1", + "find-up": "^5.0.0", + "glob": "^13.0.6", + "magic-string": "~0.30.8" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/cli": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.6.tgz", + "integrity": "sha512-baBcNPLLfUi9WuL+Tpri9BFaAdvugZIKelC5X0tt0Zdy+K0K+PCVSrnNmwMWU/HyaF/SEv6b6UHnXIdqanBlcg==", + "dev": true, + "hasInstallScript": true, + "license": "FSL-1.1-MIT", + "dependencies": { + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.7", + "progress": "^2.0.3", + "proxy-from-env": "^1.1.0", + "which": "^2.0.2" + }, + "bin": { + "sentry-cli": "bin/sentry-cli" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "2.58.6", + "@sentry/cli-linux-arm": "2.58.6", + "@sentry/cli-linux-arm64": "2.58.6", + "@sentry/cli-linux-i686": "2.58.6", + "@sentry/cli-linux-x64": "2.58.6", + "@sentry/cli-win32-arm64": "2.58.6", + "@sentry/cli-win32-i686": "2.58.6", + "@sentry/cli-win32-x64": "2.58.6" + } + }, + "node_modules/@sentry/cli-darwin": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.58.6.tgz", + "integrity": "sha512-udAVvcyfNa0R+95GvPz/+43/N3TC0TYKdkQ7D7jhPSzbcMc7l2fxRNN5yB3UpCA5fWFnW4toeaqwDBhb/Wh3LA==", + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.58.6.tgz", + "integrity": "sha512-pD0LAt5PcUzAinBwvDqc66x9+2CabHEv486yP0gRjWO7SakbaxmfVq/EXd8VLq/Tzi39LAu422UYK1lpW3MILw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.58.6.tgz", + "integrity": "sha512-q8mEcNNmeXMy5i+jWT30TVpH7LcP4HD21CD5XRSPAd/a912HF6EpK0ybf/1USO14WOhoXbAGi9txwaWabSe33g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-i686": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.58.6.tgz", + "integrity": "sha512-q8vNJi1eOV/4vxAFWBsEwLHoSYapaZHIf4j76KJGJXFKTkEbsjCOOsKbwUIBTQQhRgV4DFWh3ryfsPS/que4Kg==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-x64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.58.6.tgz", + "integrity": "sha512-DZu956Mhi3ZRjTBe1WdbGV46ldVbA8d2rgp/fh51GsI25zjBHah4wZnPTSzpc+YqxU6pJpg579B/r3jrIK530Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "linux", + "freebsd", + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-arm64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.58.6.tgz", + "integrity": "sha512-nj0Ff/kmAB73EPDhR8B4O9r+NUHK5GkPCkGWC+kXVemqAJWL5jcJ5KdxG0l/S0z6RoEoltID8/43/B+TaMlT7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-i686": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.58.6.tgz", + "integrity": "sha512-WNZiDzPbgsEMQWq4avsQ391v/xWKJDIWWWo9GYl+N/w5qcYKkoDW7wQG7T9FasI6ENn68phChTOAPXXxbfAdOg==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-x64": { + "version": "2.58.6", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.58.6.tgz", + "integrity": "sha512-R35WJ17oF4D2eqI1DR2sQQqr0fjRTt5xoP16WrTu91XM2lndRMFsnjh+/GttbxapLCBNlrjzia99MJ0PZHZpgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "FSL-1.1-MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sentry/cli/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -5278,6 +5640,27 @@ "dev": true, "license": "0BSD" }, + "node_modules/@sentry/feedback": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.62.0.tgz", + "integrity": "sha512-d0BVjJVny6qpBgGJgWL0fbcoQHjtD3z3R8EK/KzTS3RO92JX5n3A536n5D/rh0gZFgcIwiUzBXegmyPOSQn9ng==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.62.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/feedback/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@sentry/hub": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", @@ -5387,6 +5770,97 @@ "dev": true, "license": "0BSD" }, + "node_modules/@sentry/react": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.62.0.tgz", + "integrity": "sha512-PChimVpY0wzs3H/hJqyl87/ITTHwIZWTSY68QoENZyLnp7DvLcFiZYub/gFws1pzDPhtIQXVLU72fbmUjT5PSg==", + "license": "MIT", + "dependencies": { + "@sentry/browser": "10.62.0", + "@sentry/core": "10.62.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, + "node_modules/@sentry/react/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.62.0.tgz", + "integrity": "sha512-rWp4hBhZOmdQhisxcKzAwTGiRk/LvWnNaElWe7nbRhjsM/usp2095yfjq4iJ47v9MtO7xxY6eUz++fLBycqXKg==", + "license": "MIT", + "dependencies": { + "@sentry/browser-utils": "10.62.0", + "@sentry/core": "10.62.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay-canvas": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.62.0.tgz", + "integrity": "sha512-CzPAxmpe5US/ABGA1TzpjFKOFZN5uqlzrRh/uM9/daVuzLVKIAQ0XRNxo/PPEXvlDm/PoMdI5L0qIODuIKnyyw==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.62.0", + "@sentry/replay": "10.62.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay-canvas/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/replay/node_modules/@sentry/core": { + "version": "10.62.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", + "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/rollup-plugin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sentry/rollup-plugin/-/rollup-plugin-5.3.0.tgz", + "integrity": "sha512-hgPGPYdQJ/G1cGYOxAb7d4z3V+/k/E5/P/5TFPEEBLuIbFFk+JG0CISUDJdzXJjO382Lb99PBJuXGbueBmO79w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/bundler-plugin-core": "5.3.0", + "magic-string": "~0.30.8" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "rollup": ">=3.2.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@sentry/tracing": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", @@ -5442,6 +5916,20 @@ "dev": true, "license": "0BSD" }, + "node_modules/@sentry/vite-plugin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-5.3.0.tgz", + "integrity": "sha512-qcoSzo4n2MulVQ70UUPLq6dTleb2a2HwL2wuwvAgWhPChrYTuk6A6mDg6aQb9fairPAwFPiU9PzOANpoDJcz1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/bundler-plugin-core": "5.3.0", + "@sentry/rollup-plugin": "5.3.0" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/@sinclair/typebox": { "version": "0.34.48", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", @@ -11255,6 +11743,19 @@ "url": "https://bevry.me/fund" } }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -16487,9 +16988,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } diff --git a/package.json b/package.json index a93f67d..fed0324 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "dependencies": { "@sanity/client": "^7.20.0", "@sanity/image-url": "^2.1.1", + "@sentry/react": "^10.62.0", "@trustvc/decentralized-renderer-react-components": "^1.0.3", "@trustvc/trustvc": "^2.14.1", "@types/lodash": "^4.17.24", @@ -50,6 +51,7 @@ }, "devDependencies": { "@eslint/js": "^9.17.0", + "@sentry/vite-plugin": "^5.3.0", "@synthetixio/synpress": "4.0.5", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.1.0", diff --git a/src/components/home/VerifySection/useVerify.analytics.test.ts b/src/components/home/VerifySection/useVerify.analytics.test.ts index b3a00f3..bb1e3f3 100644 --- a/src/components/home/VerifySection/useVerify.analytics.test.ts +++ b/src/components/home/VerifySection/useVerify.analytics.test.ts @@ -4,6 +4,16 @@ import { renderHook, act, waitFor } from '@testing-library/react' import { useVerify } from './useVerify' import { DocumentProvider } from '../../common/contexts/DocumentContext' +// ─── Mock sentry — prevents @sentry/react from patching global timers ──────── + +vi.mock('../../../lib/sentry', () => ({ + captureVerificationBreadcrumb: vi.fn(), + captureVerificationException: vi.fn(), + captureVerificationInvalid: vi.fn(), + isSentryEnabled: vi.fn(() => false), + initSentry: vi.fn(), +})) + // ─── Mock analytics ─────────────────────────────────────────────────────────── vi.mock('../../../utils/analytics', () => ({ diff --git a/src/components/home/VerifySection/useVerify.test.ts b/src/components/home/VerifySection/useVerify.test.ts index 3c846de..b85014d 100644 --- a/src/components/home/VerifySection/useVerify.test.ts +++ b/src/components/home/VerifySection/useVerify.test.ts @@ -12,6 +12,24 @@ import { DocumentProvider } from '../../common/contexts/DocumentContext' // ─── Mocks ──────────────────────────────────────────────────────────────────── +vi.mock('../../../lib/sentry', () => ({ + captureVerificationBreadcrumb: vi.fn(), + captureVerificationException: vi.fn(), + captureVerificationInvalid: vi.fn(), + isSentryEnabled: vi.fn(() => false), + initSentry: vi.fn(), +})) + +vi.mock('../../../utils/analytics', () => ({ + trackDocumentDropped: vi.fn(), + trackDocumentVerified: vi.fn(), + trackDocumentVerifyError: vi.fn(), + trackNetworkSelectionShown: vi.fn(), + trackNetworkSelected: vi.fn(), + trackNetworkSelectionCancelled: vi.fn(), + trackVerificationReset: vi.fn(), +})) + // Mock import.meta.env Object.defineProperty(import.meta, 'env', { value: { diff --git a/src/components/home/VerifySection/useVerify.ts b/src/components/home/VerifySection/useVerify.ts index b5c92a0..c6864c9 100644 --- a/src/components/home/VerifySection/useVerify.ts +++ b/src/components/home/VerifySection/useVerify.ts @@ -22,6 +22,11 @@ import { import { getRpcUrl, getIsExpired } from '../../../utils/helper' import { useDocumentContext } from '../../common/contexts/DocumentContext' import { type VerifyErrorType, getErrorTypeFromError } from './verifyErrorUtils' +import { + captureVerificationBreadcrumb, + captureVerificationException, + captureVerificationInvalid, +} from '../../../lib/sentry' import { trackDocumentDropped, trackDocumentVerified, @@ -507,7 +512,8 @@ export const useVerify = (): UseVerifyReturn => { const runVerification = async ( doc: unknown, chainId: string | null | undefined, - currentId: number + currentId: number, + verificationFileName?: string ) => { const isStale = () => currentId !== verificationIdRef.current @@ -531,8 +537,17 @@ export const useVerify = (): UseVerifyReturn => { const isValid = hasAtLeastOneValid && hasNoInvalid const errorType = !isValid ? getErrorTypeFromFragments(results) : undefined if (!isValid) { + const errorMessage = getErrorMessageFromFragments(results) setErrorType(errorType!) - setErrorMessage(getErrorMessageFromFragments(results)) + setErrorMessage(errorMessage) + captureVerificationInvalid({ + doc, + fileName: (verificationFileName ?? fileName) || undefined, + chainId, + errorType: errorType!, + errorMessage, + fragments: results, + }) } // Compute issuer name @@ -593,6 +608,15 @@ export const useVerify = (): UseVerifyReturn => { setVerifiedChainId(chainId ?? '') setVerifyStatus(isValid ? 'valid' : 'invalid') + captureVerificationBreadcrumb( + isValid + ? 'Verification completed (valid)' + : 'Verification completed (invalid)', + { + chainId: chainId ?? undefined, + fileName: (verificationFileName ?? fileName) || undefined, + } + ) trackDocumentVerified(doc, results, isValid, issuer, errorType, { isExpired, isTransferable: transferable, @@ -648,12 +672,21 @@ export const useVerify = (): UseVerifyReturn => { return } - await runVerification(parsedDoc, chainId, currentId) + captureVerificationBreadcrumb('Verification started', { + fileName: file.name, + source: 'file', + }) + await runVerification(parsedDoc, chainId, currentId, file.name) } catch (err) { + if (currentId !== verificationIdRef.current) return const errType = getErrorTypeFromError(err) clearVerificationMetadata() setErrorType(errType) setVerifyStatus('error') + captureVerificationException(err, { + stage: 'processFile', + fileName: file.name, + }) trackDocumentVerifyError(parsedDoc, errType) } } @@ -665,12 +698,22 @@ export const useVerify = (): UseVerifyReturn => { const docRef = pendingDoc trackNetworkSelected(chainId) try { - await runVerification(pendingDoc, chainId, currentId) + captureVerificationBreadcrumb('Verification started', { + fileName, + source: 'file', + }) + await runVerification(pendingDoc, chainId, currentId, fileName) } catch (err) { + if (currentId !== verificationIdRef.current) return const errType = getErrorTypeFromError(err) clearVerificationMetadata() setErrorType(errType) setVerifyStatus('error') + captureVerificationException(err, { + stage: 'handleNetworkConfirm', + fileName, + chainId, + }) trackDocumentVerifyError(docRef, errType) } finally { setPendingDoc(null) @@ -724,15 +767,25 @@ export const useVerify = (): UseVerifyReturn => { setPendingDoc(null) clearVerificationMetadata() + captureVerificationBreadcrumb('Verification started', { + fileName: name, + source: 'url', + }) trackDocumentDropped(name, source) try { - await runVerification(doc, chainId, currentId) + await runVerification(doc, chainId, currentId, name) } catch (err) { + if (currentId !== verificationIdRef.current) return const errType = getErrorTypeFromError(err) clearVerificationMetadata() setErrorType(errType) setVerifyStatus('error') + captureVerificationException(err, { + stage: 'loadDocument', + fileName: name, + chainId, + }) trackDocumentVerifyError(doc, errType) } } diff --git a/src/lib/sanity/news.ts b/src/lib/sanity/news.ts index 2beaedd..3d0a738 100644 --- a/src/lib/sanity/news.ts +++ b/src/lib/sanity/news.ts @@ -1,4 +1,5 @@ import type { NewsArticle } from '../../types/news' +import { captureSanityError } from '../sentry' import { isSanityConfigured, sanityClient } from './client' const NEWS_LIST_QUERY = `*[_type == "post"] | order(publishedAt desc){ @@ -75,6 +76,7 @@ export const fetchNewsArticles = async () => { return sortFeaturedFirst(normalized) } catch (err) { console.error('[Sanity] fetchNewsArticles failed', err) + captureSanityError(err, { operation: 'fetchNewsArticles' }) return [] } } @@ -88,6 +90,7 @@ export const fetchLatestFeaturedNewsArticle = async () => { return normalized.find(isFeaturedPost) ?? null } catch (err) { console.error('[Sanity] fetchLatestFeaturedNewsArticle failed', err) + captureSanityError(err, { operation: 'fetchLatestFeaturedNewsArticle' }) return null } } @@ -100,6 +103,7 @@ export const fetchNewsArticleCount = async () => { return typeof count === 'number' ? count : 0 } catch (err) { console.error('[Sanity] fetchNewsArticleCount failed', err) + captureSanityError(err, { operation: 'fetchNewsArticleCount' }) return 0 } } @@ -121,6 +125,7 @@ export const fetchNewsArticlesPage = async (offset: number, limit: number) => { return (data ?? []).map(normalizeFeatured) } catch (err) { console.error('[Sanity] fetchNewsArticlesPage failed', err) + captureSanityError(err, { operation: 'fetchNewsArticlesPage' }) return [] } } @@ -138,6 +143,7 @@ export const fetchNewsArticleBySlug = async (slug: string) => { return data ? normalizeFeatured(data) : null } catch (err) { console.error('[Sanity] fetchNewsArticleBySlug failed', err) + captureSanityError(err, { operation: 'fetchNewsArticleBySlug' }) return null } } diff --git a/src/lib/sentry/SentryErrorBoundary.tsx b/src/lib/sentry/SentryErrorBoundary.tsx new file mode 100644 index 0000000..ad7ebc9 --- /dev/null +++ b/src/lib/sentry/SentryErrorBoundary.tsx @@ -0,0 +1,29 @@ +import type { ReactNode } from 'react' +import { Sentry } from './init' + +type SentryErrorBoundaryProps = { + children: ReactNode +} + +export const SentryErrorBoundary = ({ children }: SentryErrorBoundaryProps) => ( + +

Something went wrong

+

+ An unexpected error occurred. Please refresh the page or try again + later. +

+
+ } + beforeCapture={scope => { + scope.setTag('error.source', 'app') + scope.setTag('error.boundary', 'root') + }} + > + {children} + +) diff --git a/src/lib/sentry/capture.test.ts b/src/lib/sentry/capture.test.ts new file mode 100644 index 0000000..0ac5a94 --- /dev/null +++ b/src/lib/sentry/capture.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest' + +const mockScope = vi.hoisted(() => ({ + setTag: vi.fn(), + setContext: vi.fn(), +})) + +vi.mock('@sentry/react', () => ({ + init: vi.fn(), + captureException: vi.fn(), + captureMessage: vi.fn(), + addBreadcrumb: vi.fn(), + withScope: vi.fn((fn: (scope: typeof mockScope) => void) => { + fn(mockScope) + }), + browserTracingIntegration: vi.fn(() => ({})), + ErrorBoundary: ({ children }: { children: unknown }) => children, +})) + +vi.mock('./init', () => ({ + isSentryEnabled: vi.fn(() => true), +})) + +import * as Sentry from '@sentry/react' +import { + captureSanityError, + captureVerificationException, + captureVerificationInvalid, + triggerSentryTestError, +} from './capture' + +describe('captureSanityError', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('captures exception with sanity-cms source tag', () => { + const error = new Error('Sanity timeout') + captureSanityError(error, { operation: 'fetchNewsArticles' }) + + expect(Sentry.captureException).toHaveBeenCalledWith(error) + expect(Sentry.withScope).toHaveBeenCalled() + }) +}) + +describe('captureVerificationException', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('sends file extension metadata instead of raw filename', () => { + captureVerificationException(new Error('parse failed'), { + stage: 'processFile', + fileName: 'private-doc.json', + }) + + expect(mockScope.setContext).toHaveBeenCalledWith('details', { + fileExtension: '.json', + }) + }) +}) + +describe('captureVerificationInvalid', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('captures warning message without document payload', () => { + captureVerificationInvalid({ + doc: { proofValue: 'should-not-be-sent' }, + fileName: 'test.json', + chainId: '1', + errorType: 'VERIFICATION_ERROR', + errorMessage: 'Hash mismatch', + fragments: [ + { + name: 'OpenAttestationHash', + status: 'INVALID', + type: 'DOCUMENT_INTEGRITY', + }, + ], + }) + + expect(Sentry.captureMessage).toHaveBeenCalledWith( + 'Document verification failed', + 'warning' + ) + expect(Sentry.captureException).not.toHaveBeenCalled() + }) + + it('attaches context via scope, not global Sentry.setContext', () => { + captureVerificationInvalid({ + doc: {}, + fileName: 'test.json', + chainId: '137', + errorType: 'VERIFICATION_ERROR', + fragments: [], + }) + + expect(mockScope.setContext).toHaveBeenCalledWith( + 'verification', + expect.objectContaining({ fileExtension: '.json', fragmentSummary: [] }) + ) + }) +}) + +describe('triggerSentryTestError', () => { + it('blocks test errors in production environment', () => { + vi.stubEnv('VITE_SENTRY_ENVIRONMENT', 'production') + vi.stubEnv('VITE_SENTRY_DSN', 'https://example@o0.ingest.sentry.io/0') + try { + expect(() => triggerSentryTestError()).toThrow( + 'Sentry test errors are disabled in production' + ) + } finally { + vi.unstubAllEnvs() + } + }) +}) diff --git a/src/lib/sentry/capture.ts b/src/lib/sentry/capture.ts new file mode 100644 index 0000000..64c5a21 --- /dev/null +++ b/src/lib/sentry/capture.ts @@ -0,0 +1,195 @@ +import * as Sentry from '@sentry/react' +import type { VerifyErrorType } from '../../components/home/VerifySection/verifyErrorUtils' +import type { VerificationFragment } from '../../components/home/VerifySection/useVerify' +import { getDocumentSchemaLabel } from './documentSchema' +import { isSentryEnabled } from './init' + +export type ErrorSource = + | 'verification' + | 'support-api' + | 'sanity-cms' + | 'wallet' + | 'app' + +export type VerificationStage = + | 'processFile' + | 'handleNetworkConfirm' + | 'loadDocument' + | 'runVerification' + +const safeFileMetadata = ( + fileName?: string +): Record | undefined => { + if (!fileName) return undefined + + const dotIndex = fileName.lastIndexOf('.') + if (dotIndex > 0 && dotIndex < fileName.length - 1) { + return { fileExtension: fileName.slice(dotIndex) } + } + + return { hasFileName: 'true' } +} + +interface SentryScope { + setTag(key: string, value: string): void + setContext(key: string, context: Record | null): void +} + +const withScope = ( + source: ErrorSource, + tags: Record, + fn: (scope: SentryScope) => void +): void => { + if (!isSentryEnabled()) return + + Sentry.withScope(scope => { + scope.setTag('error.source', source) + for (const [key, value] of Object.entries(tags)) { + if (value != null && value !== '') { + scope.setTag(key, value) + } + } + fn(scope) + }) +} + +export const addBreadcrumb = ( + message: string, + category: string, + data?: Record +): void => { + if (!isSentryEnabled()) return + + Sentry.addBreadcrumb({ + category, + message, + level: 'info', + data: data as Record | undefined, + }) +} + +export const captureAppException = ( + error: unknown, + context?: { + source?: ErrorSource + tags?: Record + extra?: Record + } +): void => { + withScope(context?.source ?? 'app', context?.tags ?? {}, scope => { + if (context?.extra) { + scope.setContext('details', context.extra) + } + Sentry.captureException(error) + }) +} + +export const captureVerificationBreadcrumb = ( + message: string, + data?: Record +): void => { + addBreadcrumb(message, 'verification', data) +} + +export const captureVerificationException = ( + error: unknown, + context: { + stage: VerificationStage + fileName?: string + chainId?: string | null + } +): void => { + captureAppException(error, { + source: 'verification', + tags: { + 'verification.stage': context.stage, + 'verification.chain_id': context.chainId ?? undefined, + }, + extra: safeFileMetadata(context.fileName), + }) +} + +export const captureVerificationInvalid = (context: { + doc: unknown + fileName?: string + chainId?: string | null + errorType?: VerifyErrorType + errorMessage?: string + fragments?: VerificationFragment[] +}): void => { + if (!isSentryEnabled()) return + + const schema = getDocumentSchemaLabel(context.doc) + + withScope( + 'verification', + { + 'verification.result': 'invalid', + 'verification.schema': schema, + 'verification.error_type': context.errorType, + 'verification.chain_id': context.chainId ?? undefined, + }, + scope => { + const fragmentSummary = (context.fragments ?? []).map(fragment => ({ + name: fragment.name, + status: fragment.status, + type: fragment.type, + })) + scope.setContext('verification', { + ...safeFileMetadata(context.fileName), + errorMessage: context.errorMessage, + fragmentSummary, + }) + Sentry.captureMessage('Document verification failed', 'warning') + } + ) +} + +export const captureSanityError = ( + error: unknown, + context: { operation: string } +): void => { + captureAppException(error, { + source: 'sanity-cms', + tags: { + 'sanity.operation': context.operation, + }, + }) +} + +export const captureFetchError = ( + error: unknown, + context: { + service: 'support-api' | 'app' + path: string + method?: string + status?: number + } +): void => { + captureAppException(error, { + source: context.service, + tags: { + 'http.path': context.path, + 'http.method': context.method ?? 'GET', + 'http.status': context.status?.toString(), + }, + }) +} + +/** Dev-only helper for end-to-end Sentry verification. */ +export const triggerSentryTestError = (): void => { + if (!isSentryEnabled()) { + throw new Error('Sentry is not enabled (missing VITE_SENTRY_DSN)') + } + + const environment = + (import.meta.env.VITE_SENTRY_ENVIRONMENT as string | undefined) ?? + (import.meta.env.VITE_PLATFORM as string | undefined) ?? + 'local' + + if (environment === 'production') { + throw new Error('Sentry test errors are disabled in production') + } + + throw new Error('TrustVC Sentry test error — safe to ignore') +} diff --git a/src/lib/sentry/documentSchema.ts b/src/lib/sentry/documentSchema.ts new file mode 100644 index 0000000..bf3b31f --- /dev/null +++ b/src/lib/sentry/documentSchema.ts @@ -0,0 +1,40 @@ +import { + isWrappedV2Document, + isWrappedV3Document, + isRawV2Document, + isRawV3Document, + isSignedWrappedV2Document, + isSignedWrappedV3Document, + vc, +} from '@trustvc/trustvc' + +export type DocumentSchemaLabel = + | 'OA v2' + | 'OA v3' + | 'W3C VC V1.1' + | 'W3C VC V2.0' + | 'Unknown' + +export const getDocumentSchemaLabel = (doc: unknown): DocumentSchemaLabel => { + const d = doc as Record + if ( + isWrappedV2Document(d) || + isRawV2Document(d) || + isSignedWrappedV2Document(d) + ) { + return 'OA v2' + } + if ( + isWrappedV3Document(d) || + isRawV3Document(d) || + isSignedWrappedV3Document(d) + ) { + return 'OA v3' + } + if (vc.isSignedDocument(d) || vc.isRawDocument(d)) { + return vc.isSignedDocumentV2_0(d) || vc.isRawDocumentV2_0(d) + ? 'W3C VC V2.0' + : 'W3C VC V1.1' + } + return 'Unknown' +} diff --git a/src/lib/sentry/index.ts b/src/lib/sentry/index.ts new file mode 100644 index 0000000..786808c --- /dev/null +++ b/src/lib/sentry/index.ts @@ -0,0 +1,13 @@ +export { initSentry, isSentryEnabled, Sentry } from './init' +export { + addBreadcrumb, + captureAppException, + captureFetchError, + captureSanityError, + captureVerificationBreadcrumb, + captureVerificationException, + captureVerificationInvalid, + triggerSentryTestError, +} from './capture' +export { scrubEvent, scrubObject, scrubValue } from './scrub' +export { SentryErrorBoundary } from './SentryErrorBoundary' diff --git a/src/lib/sentry/init.ts b/src/lib/sentry/init.ts new file mode 100644 index 0000000..696c78e --- /dev/null +++ b/src/lib/sentry/init.ts @@ -0,0 +1,53 @@ +import * as Sentry from '@sentry/react' +import type { Event, EventHint } from '@sentry/react' +import { scrubBreadcrumb, scrubEvent } from './scrub' + +const dsn = import.meta.env.VITE_SENTRY_DSN as string | undefined + +export const isSentryEnabled = (): boolean => Boolean(dsn) + +let initialized = false + +export const initSentry = (): void => { + if (initialized || !dsn) return + + const environment = + (import.meta.env.VITE_SENTRY_ENVIRONMENT as string | undefined) ?? + (import.meta.env.VITE_PLATFORM as string | undefined) ?? + 'local' + + const release = import.meta.env.VITE_SENTRY_RELEASE as string | undefined + + Sentry.init({ + dsn, + environment, + release, + enabled: true, + // Session replay disabled — the verify UI may display credential content. + replaysSessionSampleRate: 0, + replaysOnErrorSampleRate: 0, + beforeSend: (event, hint) => + scrubEvent(event as Event, hint as EventHint) as typeof event | null, + beforeBreadcrumb: scrubBreadcrumb, + ignoreErrors: [ + 'ResizeObserver loop limit exceeded', + 'ResizeObserver loop completed with undelivered notifications', + ], + }) + + initialized = true + + if (typeof window !== 'undefined' && environment !== 'production') { + ;(window as TrustVCSentryTestWindow).__trustvcSentryTest = () => { + import('./capture').then(({ triggerSentryTestError }) => { + triggerSentryTestError() + }) + } + } +} + +interface TrustVCSentryTestWindow extends Window { + __trustvcSentryTest?: () => void +} + +export { Sentry } diff --git a/src/lib/sentry/scrub.test.ts b/src/lib/sentry/scrub.test.ts new file mode 100644 index 0000000..9f7f86f --- /dev/null +++ b/src/lib/sentry/scrub.test.ts @@ -0,0 +1,153 @@ +import { describe, expect, it } from 'vitest' +import { scrubBreadcrumb, scrubEvent, scrubObject, scrubValue } from './scrub' + +describe('scrubValue', () => { + it('redacts sensitive keys in objects', () => { + const result = scrubObject({ + fileName: 'doc.json', + proofValue: 'long-sensitive-proof', + credential: { id: 'abc' }, + }) + + expect(result.fileName).toBe('doc.json') + expect(result.proofValue).toBe('[Redacted]') + expect(result.credential).toBe('[Redacted]') + }) + + it('redacts long credential-like strings', () => { + const payload = JSON.stringify({ + proofValue: 'x'.repeat(600), + merkleRoot: 'abc', + }) + + const result = scrubValue(payload) + expect(result).toMatch(/^\[Redacted string len=\d+\]$/) + }) + + it('preserves short non-sensitive strings', () => { + expect(scrubValue('DNS-TXT')).toBe('DNS-TXT') + }) + + it('strips hash, q, and sensitive query params from URLs', () => { + const url = + 'https://trustvc.io/verify?token=abc&apiKey=xyz&safe=keep#{"key":"secret"}' + const result = scrubValue(url) + expect(result).toBe('https://trustvc.io/verify?safe=keep') + }) +}) + +describe('scrubObject', () => { + it('redacts nested sensitive keys', () => { + const result = scrubObject({ + verification: { + issuer_identity: 'example.com', + proof: { value: 'secret' }, + }, + }) + + expect(result.verification).toEqual({ + issuer_identity: 'example.com', + proof: '[Redacted]', + }) + }) + + it('redacts auth-related keys', () => { + const result = scrubObject({ + Authorization: 'Bearer secret', + Cookie: 'session=abc', + apiKey: 'key-123', + }) + + expect(result.Authorization).toBe('[Redacted]') + expect(result.Cookie).toBe('[Redacted]') + expect(result.apiKey).toBe('[Redacted]') + }) + + it('redacts camelCase sensitive keys regardless of casing', () => { + const result = scrubObject({ + targetHash: 'abc123', + rawDocument: { data: 'x' }, + fileContent: 'raw bytes', + fileText: 'plain text', + }) + + expect(result.targetHash).toBe('[Redacted]') + expect(result.rawDocument).toBe('[Redacted]') + expect(result.fileContent).toBe('[Redacted]') + expect(result.fileText).toBe('[Redacted]') + }) +}) + +describe('scrubEvent', () => { + it('scrubs string message fields and request bodies', () => { + const payload = JSON.stringify({ + proofValue: 'x'.repeat(600), + }) + + const event = scrubEvent({ + message: payload, + logentry: { message: payload, formatted: payload } as { + message: string + formatted: string + }, + exception: { + values: [{ type: 'Error', value: payload }], + }, + request: { data: payload }, + }) + + expect(event?.message).toMatch(/^\[Redacted string len=\d+\]$/) + expect(event?.logentry?.message).toMatch(/^\[Redacted string len=\d+\]$/) + expect( + (event?.logentry as { formatted?: string } | undefined)?.formatted + ).toMatch(/^\[Redacted string len=\d+\]$/) + expect(event?.exception?.values?.[0]?.value).toMatch( + /^\[Redacted string len=\d+\]$/ + ) + expect(event?.request?.data).toMatch(/^\[Redacted string len=\d+\]$/) + }) + + it('strips hash and q param from request.url', () => { + const shareUrl = + 'https://trustvc.io/?q=%7B%22type%22%3A%22DOCUMENT%22%7D#{"key":"secret"}' + const event = scrubEvent({ request: { url: shareUrl } }) + + expect(event?.request?.url).not.toContain('#') + expect(event?.request?.url).not.toContain('?q=') + expect(event?.request?.url).toBe('https://trustvc.io/') + }) + + it('leaves request.url unchanged when no sensitive params present', () => { + const event = scrubEvent({ request: { url: 'https://trustvc.io/' } }) + expect(event?.request?.url).toBe('https://trustvc.io/') + }) +}) + +describe('scrubBreadcrumb', () => { + it('scrubs breadcrumb message and data', () => { + const payload = JSON.stringify({ proofValue: 'x'.repeat(600) }) + const breadcrumb = scrubBreadcrumb({ + message: payload, + data: { authorization: 'Bearer secret' }, + }) + + expect(breadcrumb?.message).toMatch(/^\[Redacted string len=\d+\]$/) + expect(breadcrumb?.data).toEqual({ authorization: '[Redacted]' }) + }) + + it('strips hash and q param from navigation breadcrumb from/to URLs', () => { + const sensitiveUrl = + 'https://trustvc.io/?q=%7B%22type%22%3A%22DOCUMENT%22%7D#{"key":"secret"}' + const breadcrumb = scrubBreadcrumb({ + type: 'navigation', + category: 'navigation', + data: { from: sensitiveUrl, to: 'https://trustvc.io/' }, + }) + + const from = breadcrumb?.data?.from as string + expect(from).not.toContain('#') + expect(from).not.toContain('?q=') + expect(from).toBe('https://trustvc.io/') + expect(breadcrumb?.data?.to).toBe('https://trustvc.io/') + }) +}) diff --git a/src/lib/sentry/scrub.ts b/src/lib/sentry/scrub.ts new file mode 100644 index 0000000..80e2ba6 --- /dev/null +++ b/src/lib/sentry/scrub.ts @@ -0,0 +1,206 @@ +import type { Breadcrumb, Event, EventHint } from '@sentry/react' + +const REDACTED = '[Redacted]' + +/** Keys that must never leave the browser in Sentry payloads. + * Only list keys NOT already caught by SENSITIVE_KEY_PATTERN below. */ +const SENSITIVE_KEYS = new Set([ + 'targethash', + 'document', + 'rawdocument', + 'doc', + 'email', + 'phone', + 'filecontent', + 'filetext', + 'body', +]) + +const SENSITIVE_KEY_PATTERN = + /proof|credential|merkle|signature|payload|attachment|private|secret|password|token|auth|cookie|apikey|api[._-]key|bearer/i + +const CREDENTIAL_JSON_PATTERN = + /"(?:proofValue|merkleRoot|targetHash|verifiableCredential|credentialSubject)"/i + +const MAX_STRING_LENGTH = 500 +const MAX_DEPTH = 8 + +const isSensitiveKey = (key: string): boolean => + SENSITIVE_KEYS.has(key.toLowerCase()) || SENSITIVE_KEY_PATTERN.test(key) + +const looksLikeCredentialPayload = (value: string): boolean => + value.length > MAX_STRING_LENGTH || CREDENTIAL_JSON_PATTERN.test(value) + +// Strip the hash fragment (decryption key), the `q` query param (document URI), +// and any param whose name is sensitive before the URL leaves the browser in Sentry payloads. +const scrubUrl = (value: string): string => { + try { + const parsed = new URL(value) + parsed.hash = '' + for (const key of [...parsed.searchParams.keys()]) { + if (key === 'q' || isSensitiveKey(key)) { + parsed.searchParams.delete(key) + } + } + return parsed.toString() + } catch { + return value + } +} + +const scrubString = (value: string): string => { + if (value.startsWith('https://') || value.startsWith('http://')) { + return scrubUrl(value) + } + if (looksLikeCredentialPayload(value)) { + return `[Redacted string len=${value.length}]` + } + return value +} + +export const scrubValue = (value: unknown, depth = 0): unknown => { + if (depth > MAX_DEPTH) return '[Truncated]' + + if ( + value == null || + typeof value === 'boolean' || + typeof value === 'number' + ) { + return value + } + + if (typeof value === 'string') { + return scrubString(value) + } + + if (Array.isArray(value)) { + return value.map(item => scrubValue(item, depth + 1)) + } + + if (typeof value === 'object') { + return scrubObject(value as Record, depth + 1) + } + + return value +} + +export const scrubObject = ( + obj: Record, + depth = 0 +): Record => { + const result: Record = {} + + for (const [key, val] of Object.entries(obj)) { + if (isSensitiveKey(key)) { + result[key] = REDACTED + continue + } + result[key] = scrubValue(val, depth + 1) + } + + return result +} + +export const scrubBreadcrumb = (breadcrumb: Breadcrumb): Breadcrumb | null => { + const scrubbed: Breadcrumb = { ...breadcrumb } + + if (typeof scrubbed.message === 'string') { + scrubbed.message = scrubString(scrubbed.message) + } + + if (scrubbed.data) { + scrubbed.data = scrubObject(scrubbed.data as Record) + } + + return scrubbed +} + +export const scrubEvent = (event: Event, _hint?: EventHint): Event | null => { + if (typeof event.message === 'string') { + event.message = scrubString(event.message) + } + + if (event.logentry) { + const logentry = { + ...event.logentry, + ...(typeof event.logentry.message === 'string' + ? { message: scrubString(event.logentry.message) } + : {}), + } as Event['logentry'] & { formatted?: string } + + if (typeof logentry.formatted === 'string') { + logentry.formatted = scrubString(logentry.formatted) + } + + event.logentry = logentry + } + + if (event.exception?.values) { + event.exception = { + ...event.exception, + values: event.exception.values.map(value => ({ + ...value, + value: + typeof value.value === 'string' + ? scrubString(value.value) + : value.value, + })), + } + } + + if (event.extra) { + event.extra = scrubObject(event.extra as Record) + } + + if (event.contexts) { + const contexts: Record = {} + for (const [key, ctx] of Object.entries(event.contexts)) { + contexts[key] = + ctx && typeof ctx === 'object' + ? scrubObject(ctx as Record) + : ctx + } + event.contexts = contexts as Event['contexts'] + } + + if (event.tags) { + event.tags = Object.fromEntries( + Object.entries(event.tags).map(([key, value]) => [ + key, + isSensitiveKey(key) + ? REDACTED + : typeof value === 'string' + ? scrubString(value) + : value, + ]) + ) as Event['tags'] + } + + if (event.breadcrumbs) { + event.breadcrumbs = event.breadcrumbs + .map(crumb => scrubBreadcrumb(crumb)) + .filter((crumb): crumb is Breadcrumb => crumb != null) + } + + if (event.request?.url && typeof event.request.url === 'string') { + event.request.url = scrubUrl(event.request.url) + } + + if (event.request?.headers && typeof event.request.headers === 'object') { + event.request.headers = scrubObject( + event.request.headers as Record + ) as Record + } + + if (event.request?.data) { + if (typeof event.request.data === 'string') { + event.request.data = scrubString(event.request.data) + } else if (typeof event.request.data === 'object') { + event.request.data = scrubObject( + event.request.data as Record + ) + } + } + + return event +} diff --git a/src/main.tsx b/src/main.tsx index a9bfe4f..d807318 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,6 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' -import App from './App' import { BrowserRouter } from 'react-router-dom' import { OverlayProvider } from './components/common/contexts/OverlayContext' import { ProviderContextProvider } from './components/common/contexts/providerContext' @@ -12,6 +11,10 @@ import { getSupportedChainInfo, } from './utils/chain-utils' import { DocumentProvider } from './components/common/contexts/DocumentContext' +import { initSentry, SentryErrorBoundary } from './lib/sentry' +import App from './App' + +initSentry() const rootElement = document.getElementById('root') @@ -23,19 +26,21 @@ const defaultChainId = getChainInfoFromNetworkName(NETWORK_NAME).id ReactDOM.createRoot(rootElement).render( - - - - - - - - - - - + + + + + + + + + + + + + ) diff --git a/src/utils/fetchClient.test.ts b/src/utils/fetchClient.test.ts index c0ddb56..5b8cd9e 100644 --- a/src/utils/fetchClient.test.ts +++ b/src/utils/fetchClient.test.ts @@ -1,6 +1,12 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { createFetchClient, FetchClientError } from './fetchClient' +vi.mock('../lib/sentry', () => ({ + captureFetchError: vi.fn(), +})) + +import { captureFetchError } from '../lib/sentry' + describe('fetchClient', () => { beforeEach(() => { vi.clearAllMocks() @@ -122,6 +128,71 @@ describe('fetchClient', () => { ) } }) + + it('does not report caller aborts to Sentry', async () => { + const abortError = new DOMException( + 'The user aborted a request.', + 'AbortError' + ) + vi.stubGlobal('fetch', vi.fn().mockRejectedValue(abortError)) + + const client = createFetchClient({ baseUrl: 'https://api.example.com' }) + const controller = new AbortController() + controller.abort() + + await expect( + client.request('/aborted', { signal: controller.signal }) + ).rejects.toThrow() + + expect(captureFetchError).not.toHaveBeenCalled() + }) + + it('reports timeout aborts to Sentry', async () => { + // Fire the timeout callback synchronously so timedOut=true before fetch rejects + vi.stubGlobal( + 'setTimeout', + vi.fn().mockImplementation((fn: () => void) => { + fn() + return 0 + }) + ) + vi.stubGlobal('clearTimeout', vi.fn()) + + const abortError = new DOMException( + 'The user aborted a request.', + 'AbortError' + ) + vi.stubGlobal('fetch', vi.fn().mockRejectedValue(abortError)) + + const client = createFetchClient({ baseUrl: 'https://api.example.com' }) + await expect(client.request('/slow')).rejects.toThrow() + + expect(captureFetchError).toHaveBeenCalledOnce() + }) + + it('removes caller abort listener after request completes', async () => { + const removeEventListener = vi.fn() + const signal = { + aborted: false, + addEventListener: vi.fn(), + removeEventListener, + } as unknown as AbortSignal + + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue({ + ok: true, + headers: new Headers({ 'content-type': 'application/json' }), + json: () => Promise.resolve({ success: true }), + }) + ) + + const client = createFetchClient({ baseUrl: 'https://api.example.com' }) + await client.request('/ok', { signal }) + + expect(signal.addEventListener).toHaveBeenCalled() + expect(removeEventListener).toHaveBeenCalled() + }) }) describe('FetchClientError', () => { diff --git a/src/utils/fetchClient.ts b/src/utils/fetchClient.ts index 9b5479e..ac7973e 100644 --- a/src/utils/fetchClient.ts +++ b/src/utils/fetchClient.ts @@ -1,6 +1,9 @@ +import { captureFetchError } from '../lib/sentry' + type FetchClientOptions = { baseUrl: string timeoutMs?: number + service?: 'support-api' | 'app' } interface ApiErrorBody { @@ -27,9 +30,15 @@ export class FetchClientError extends Error { } } +const isAbortError = (error: unknown): boolean => + error instanceof DOMException + ? error.name === 'AbortError' + : error instanceof Error && error.name === 'AbortError' + export const createFetchClient = ({ baseUrl, timeoutMs, + service = 'app', }: FetchClientOptions) => { const normalizedBaseUrl = baseUrl.replace(/\/$/, '') const defaultTimeoutMs = timeoutMs ?? 15000 @@ -37,42 +46,75 @@ export const createFetchClient = ({ const request = async (path: string, init?: RequestInit): Promise => { const controller = new AbortController() const timeoutMs = defaultTimeoutMs - const timeoutId = globalThis.setTimeout(() => controller.abort(), timeoutMs) + let timedOut = false + const timeoutId = globalThis.setTimeout(() => { + timedOut = true + controller.abort() + }, timeoutMs) const signal = init?.signal + const method = init?.method ?? 'GET' + let onCallerAbort: (() => void) | undefined if (signal) { if (signal.aborted) controller.abort() - signal.addEventListener('abort', () => controller.abort(), { once: true }) + onCallerAbort = () => controller.abort() + signal.addEventListener('abort', onCallerAbort, { once: true }) } - const response = await fetch(`${normalizedBaseUrl}${path}`, { - ...init, - signal: controller.signal, - }).finally(() => { - globalThis.clearTimeout(timeoutId) - }) + try { + const response = await fetch(`${normalizedBaseUrl}${path}`, { + ...init, + signal: controller.signal, + }) - const contentType = response.headers.get('content-type') || '' - let data: unknown = null - if (contentType.includes('application/json')) { - try { - data = await response.json() - } catch { - data = null + const contentType = response.headers.get('content-type') || '' + let data: unknown = null + if (contentType.includes('application/json')) { + try { + data = await response.json() + } catch { + data = null + } } - } - const errorBody = - typeof data === 'object' && data !== null ? (data as ApiErrorBody) : null - if (!response.ok || (errorBody && errorBody.success === false)) { - const message = - errorBody?.error?.message || - errorBody?.message || - `Request failed with status ${response.status}` - throw new FetchClientError({ status: response.status, message, data }) - } + const errorBody = + typeof data === 'object' && data !== null + ? (data as ApiErrorBody) + : null + if (!response.ok || (errorBody && errorBody.success === false)) { + const message = + errorBody?.error?.message || + errorBody?.message || + `Request failed with status ${response.status}` + const error = new FetchClientError({ + status: response.status, + message, + data, + }) + captureFetchError(error, { + service, + path, + method, + status: response.status, + }) + throw error + } - return data as T + return data as T + } catch (error) { + if (!(error instanceof FetchClientError)) { + const callerAborted = isAbortError(error) && !timedOut + if (!callerAborted) { + captureFetchError(error, { service, path, method }) + } + } + throw error + } finally { + globalThis.clearTimeout(timeoutId) + if (signal && onCallerAbort) { + signal.removeEventListener('abort', onCallerAbort) + } + } } return { request } @@ -81,4 +123,5 @@ export const createFetchClient = ({ export const fetchClientSupport = createFetchClient({ baseUrl: (import.meta.env?.VITE_SUPPORT_API_BASE_URL as string | undefined) || '', + service: 'support-api', }) diff --git a/vite.config.js b/vite.config.js index c2f9719..7dab8de 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,6 +1,7 @@ import { fileURLToPath, URL } from 'node:url' import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' +import { sentryVitePlugin } from '@sentry/vite-plugin' import path from 'path' import { nodePolyfills } from 'vite-plugin-node-polyfills' @@ -10,6 +11,38 @@ export default defineConfig(({ mode }) => { const isTest = mode === 'test' const env = loadEnv(mode, process.cwd(), '') + const sentryAuthToken = + env.SENTRY_AUTH_TOKEN ?? process.env.SENTRY_AUTH_TOKEN + const sentryOrg = env.SENTRY_ORG ?? process.env.SENTRY_ORG + const sentryProject = env.SENTRY_PROJECT ?? process.env.SENTRY_PROJECT + const sentryRelease = + env.VITE_SENTRY_RELEASE ?? process.env.VITE_SENTRY_RELEASE + + const sentryBuildVars = { + SENTRY_AUTH_TOKEN: sentryAuthToken, + SENTRY_ORG: sentryOrg, + SENTRY_PROJECT: sentryProject, + VITE_SENTRY_RELEASE: sentryRelease, + } + const sentryBuildValues = Object.values(sentryBuildVars) + const allSentryBuildVarsEmpty = sentryBuildValues.every( + value => value === undefined || value === '' + ) + const allSentryBuildVarsSet = sentryBuildValues.every( + value => value !== undefined && value !== '' + ) + + if (!isTest && !allSentryBuildVarsEmpty && !allSentryBuildVarsSet) { + const missing = Object.entries(sentryBuildVars) + .filter(([, value]) => value === undefined || value === '') + .map(([key]) => key) + throw new Error( + `Incomplete Sentry build configuration. Set all of SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT, and VITE_SENTRY_RELEASE, or leave them all empty to skip source map upload. Missing: ${missing.join(', ')}` + ) + } + + const enableSentrySourceMaps = !isTest && allSentryBuildVarsSet + return { define: { 'process.env': { @@ -20,6 +53,7 @@ export default defineConfig(({ mode }) => { ...(isTest ? {} : { 'process.version': JSON.stringify('v16.0.0') }) }, build: { + sourcemap: enableSentrySourceMaps ? 'hidden' : false, commonjsOptions: { // crypto-browserify → randomfill uses `exports.*`; without this, // some CJS can leak into ESM chunks and throw "exports is not defined". @@ -32,6 +66,19 @@ export default defineConfig(({ mode }) => { globals: { Buffer: true, global: true, process: true }, protocolImports: true, }), + ...(enableSentrySourceMaps + ? [ + sentryVitePlugin({ + org: sentryOrg, + project: sentryProject, + authToken: sentryAuthToken, + release: { name: sentryRelease }, + sourcemaps: { + filesToDeleteAfterUpload: ['./dist/**/*.map'], + }, + }), + ] + : []), ], resolve: { alias: { From c761e14e846dbc7427280386c2617d89f24b5722 Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Wed, 1 Jul 2026 08:27:10 +0530 Subject: [PATCH 04/10] feat: sentry integration build issue (#81) * feature: integration of sentry * feature: update sentry env variable and configurations * fix: types issue with sentry test files * fix: coderabbit issues * Update src/lib/sentry/scrub.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Refactor Sentry integration to use scoped context - Updated Sentry mock in tests to utilize a scoped context instead of global methods, improving test isolation and accuracy. - Refactored `withScope` function to accept a scope parameter, allowing for better context management during error capturing. - Enhanced tests for `captureVerificationInvalid` to verify context attachment through the scoped approach. - Adjusted Sentry initialization to ensure proper context handling in production and testing environments. * Refactor component structure in main.tsx for improved readability - Rearranged the component hierarchy within the render method to enhance clarity and maintainability. - Ensured that the SentryErrorBoundary wraps the DocumentProvider, improving error handling for the entire application. * Enhance URL scrubbing in Sentry integration - Added functionality to strip hash fragments and `q` query parameters from URLs in both event requests and navigation breadcrumbs, improving data privacy. - Updated tests to verify that sensitive URL components are correctly removed, ensuring robust handling of potentially sensitive information. * Enhance error handling and URL scrubbing in Sentry integration - Updated tests to ensure that Sentry test errors are correctly blocked in production environments. - Improved URL scrubbing functionality to strip sensitive query parameters and hash fragments from URLs. - Added test cases to verify the removal of sensitive information from URLs and to report timeout aborts to Sentry, enhancing overall data privacy and error reporting. * Enhance data redaction in Sentry scrubbing functionality - Added a test case to ensure camelCase sensitive keys are redacted regardless of casing, improving data privacy. - Updated sensitive keys in the scrub module to be case-insensitive, ensuring consistent redaction of sensitive information. * Update build scripts and Vite configuration for improved performance - Added NODE_OPTIONS to build scripts to increase memory allocation during build processes. - Enhanced Vite configuration with manual chunking for better optimization of vendor libraries, specifically for web3 and React dependencies. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- package.json | 6 +++--- vite.config.js | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index fed0324..45ee537 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "type": "module", "scripts": { "dev": "vite --mode development --open", - "build:dev": "vite build --mode development", - "build:prod": "vite build --mode production", - "build": "vite build --mode production", + "build:dev": "NODE_OPTIONS=--max-old-space-size=6144 vite build --mode development", + "build:prod": "NODE_OPTIONS=--max-old-space-size=6144 vite build --mode production", + "build": "NODE_OPTIONS=--max-old-space-size=6144 vite build --mode production", "preview": "npm run build && vite preview", "preview:dev": "npm run build:dev && vite preview --mode development", "preview:prod": "npm run build:prod && vite preview --mode production", diff --git a/vite.config.js b/vite.config.js index 7dab8de..372dc44 100644 --- a/vite.config.js +++ b/vite.config.js @@ -59,6 +59,22 @@ export default defineConfig(({ mode }) => { // some CJS can leak into ESM chunks and throw "exports is not defined". transformMixedEsModules: true, }, + rollupOptions: { + output: { + manualChunks(id) { + if ( + id.includes('/node_modules/ethers/') || + id.includes('/node_modules/@tradetrust-tt/') || + id.includes('/node_modules/@trustvc/') + ) return 'vendor-web3' + if ( + id.includes('/node_modules/react/') || + id.includes('/node_modules/react-dom/') || + id.includes('/node_modules/react-router') + ) return 'vendor-react' + }, + }, + }, }, plugins: [ react(), From 8bc9ca14586d45656d9ddbabb5e43e6c6a9f7ac0 Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Fri, 3 Jul 2026 10:45:15 +0530 Subject: [PATCH 05/10] fix: filename issue with s3 (#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ga gtm integration (#75) (#78) * feat: ga gtm integration (#75) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * f… * fix: filename string equality --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --- src/components/common/Recaptcha/Recaptcha.tsx | 9 ++++++++- src/hooks/useContactForm.ts | 12 ++---------- src/hooks/useRecaptcha.ts | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/common/Recaptcha/Recaptcha.tsx b/src/components/common/Recaptcha/Recaptcha.tsx index 69d0840..3f53cd3 100644 --- a/src/components/common/Recaptcha/Recaptcha.tsx +++ b/src/components/common/Recaptcha/Recaptcha.tsx @@ -8,7 +8,14 @@ declare global { * reCAPTCHA v2 global helper (loaded from https://www.google.com/recaptcha/api.js) */ ready: (cb: () => void) => void - render: (container: HTMLElement, params: { sitekey: string }) => number + render: ( + container: HTMLElement, + params: { + sitekey: string + callback?: (token: string) => void + 'expired-callback'?: () => void + } + ) => number getResponse: (widgetId?: number) => string reset: (widgetId?: number) => void } diff --git a/src/hooks/useContactForm.ts b/src/hooks/useContactForm.ts index 15b6f88..6fd4810 100644 --- a/src/hooks/useContactForm.ts +++ b/src/hooks/useContactForm.ts @@ -381,18 +381,10 @@ export const useContactForm = (options: UseContactFormOptions) => { size: a.file.size, })) const presigned = await getPresignedUrls(files) - const presignedByFilename = presigned.reduce< - Record - >((acc, current) => { - if (!acc[current.filename]) acc[current.filename] = [] - acc[current.filename].push(current) - return acc - }, {}) const uploadResults = await Promise.allSettled( - pendingItems.map(item => { - const candidateList = presignedByFilename[item.file.name] || [] - const p = candidateList.shift() + pendingItems.map((item, index) => { + const p = presigned[index] if (!p) { setAttachmentStatus(item.id, { status: 'error', diff --git a/src/hooks/useRecaptcha.ts b/src/hooks/useRecaptcha.ts index b31c8c2..9b0fb2c 100644 --- a/src/hooks/useRecaptcha.ts +++ b/src/hooks/useRecaptcha.ts @@ -5,22 +5,30 @@ const SCRIPT_ID = 'recaptcha-v2-script' type UseRecaptchaOptions = { siteKey: string | null | undefined onChange?: (token: string) => void + onExpire?: () => void } -export const useRecaptcha = ({ siteKey, onChange }: UseRecaptchaOptions) => { +export const useRecaptcha = ({ + siteKey, + onChange, + onExpire, +}: UseRecaptchaOptions) => { const containerRef = useRef(null) const widgetIdRef = useRef(null) const siteKeyRef = useRef(siteKey) const onChangeRef = useRef(onChange) + const onExpireRef = useRef(onExpire) siteKeyRef.current = siteKey onChangeRef.current = onChange + onExpireRef.current = onExpire useEffect(() => { if (!siteKeyRef.current) return const ensureRendered = () => { if (!containerRef.current || widgetIdRef.current !== null) return + if (!siteKeyRef.current) return const grecaptcha = globalThis.window?.grecaptcha if (!grecaptcha || typeof grecaptcha.render !== 'function') return @@ -29,7 +37,10 @@ export const useRecaptcha = ({ siteKey, onChange }: UseRecaptchaOptions) => { callback: (token: string) => { onChangeRef.current?.(token) }, - } as unknown as { sitekey: string }) + 'expired-callback': () => { + onExpireRef.current?.() + }, + }) } const loadScript = () => { From 85bec0daf869cb55d19cb404dbd443eac14a08a8 Mon Sep 17 00:00:00 2001 From: manishdex25 Date: Fri, 3 Jul 2026 11:25:22 +0530 Subject: [PATCH 06/10] fix: magic link css and capture sentry logs (#83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ga gtm integration (#75) (#78) * feat: ga gtm integration (#75) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * f… * fix: filename string equality * feat: sentry log addition of handled exception for contact form * fix: magic link icon css --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --- src/components/common/Recaptcha/Recaptcha.tsx | 4 +- src/hooks/useContactForm.ts | 40 ++++++++++++++++++- src/index.css | 5 +++ src/pages/Contact/index.tsx | 2 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/components/common/Recaptcha/Recaptcha.tsx b/src/components/common/Recaptcha/Recaptcha.tsx index 3f53cd3..fc2e05c 100644 --- a/src/components/common/Recaptcha/Recaptcha.tsx +++ b/src/components/common/Recaptcha/Recaptcha.tsx @@ -32,13 +32,15 @@ interface RecaptchaProps { siteKey: string className?: string onChange?: (token: string) => void + onExpire?: () => void } export const Recaptcha = forwardRef( - function Recaptcha({ siteKey, className, onChange }, ref) { + function Recaptcha({ siteKey, className, onChange, onExpire }, ref) { const { containerRef, getToken, reset } = useRecaptcha({ siteKey, onChange, + onExpire, }) useImperativeHandle( diff --git a/src/hooks/useContactForm.ts b/src/hooks/useContactForm.ts index 6fd4810..0951d1d 100644 --- a/src/hooks/useContactForm.ts +++ b/src/hooks/useContactForm.ts @@ -8,6 +8,8 @@ import { uploadToPresignedUrl, createServiceRequestWithKeys, } from '@/utils/upload' +import { captureAppException } from '@/lib/sentry' +import { FetchClientError } from '@/utils/fetchClient' import { MAX_TOTAL_UPLOAD_BYTES, MAX_FILES, @@ -116,6 +118,18 @@ export const useContactForm = (options: UseContactFormOptions) => { setRecaptchaCompleted(true) }, []) + const handleRecaptchaExpired = useCallback(() => { + setRecaptchaCompleted(false) + setFieldErrors(prev => ({ + ...prev, + recaptcha: 'reCAPTCHA verification expired. Please verify again.', + })) + captureAppException(new Error('reCAPTCHA verification expired'), { + source: 'app', + tags: { 'recaptcha.event': 'expired' }, + }) + }, []) + const addFiles = useCallback( (newFiles: File[]) => { const nonEmpty = newFiles.filter(file => file.size > 0) @@ -390,9 +404,19 @@ export const useContactForm = (options: UseContactFormOptions) => { status: 'error', error: 'No upload URL was returned for this file.', }) - return Promise.reject( - new Error('No upload URL was returned for this file.') + const error = new Error( + 'No upload URL was returned for this file.' ) + captureAppException(error, { + source: 'support-api', + tags: { 'upload.stage': 'presign_mismatch' }, + extra: { + pendingCount: pendingItems.length, + presignedCount: presigned.length, + missingIndex: index, + }, + }) + return Promise.reject(error) } setAttachmentStatus(item.id, { status: 'uploading', @@ -425,6 +449,10 @@ export const useContactForm = (options: UseContactFormOptions) => { error: err instanceof Error ? err.message : 'Upload failed', }) + captureAppException(err, { + source: 'support-api', + tags: { 'upload.stage': 'presigned_put' }, + }) return Promise.reject(err) }) }) @@ -468,6 +496,13 @@ export const useContactForm = (options: UseContactFormOptions) => { const msg = rawMessage && rawMessage !== 'Failed to fetch' ? rawMessage : fallback trackSupportFormFailed(typeOfEnquiry || 'Unknown', msg) + // FetchClientError failures are already captured with request context in fetchClient.ts + if (!(err instanceof FetchClientError)) { + captureAppException(err, { + source: 'support-api', + tags: { 'contact.stage': 'submit' }, + }) + } setSubmitError(msg) } finally { setIsSubmitting(false) @@ -512,6 +547,7 @@ export const useContactForm = (options: UseContactFormOptions) => { validateTypeOfEnquiry, validateDescription, clearRecaptchaError, + handleRecaptchaExpired, onSubmit, isFormValid, } diff --git a/src/index.css b/src/index.css index cb5f3d2..81c6845 100644 --- a/src/index.css +++ b/src/index.css @@ -4331,6 +4331,11 @@ p.small { height: 24px; } +.connect-magiclink-button-icon { + width: 24px; + height: 24px; +} + .connect-metamask-button-text { display: flex; flex-direction: row; diff --git a/src/pages/Contact/index.tsx b/src/pages/Contact/index.tsx index d318f00..88c40fa 100644 --- a/src/pages/Contact/index.tsx +++ b/src/pages/Contact/index.tsx @@ -44,6 +44,7 @@ const Contact = ({ isDarkMode }: ContactProps) => { handleDrop, handleFileInput, clearRecaptchaError, + handleRecaptchaExpired, onSubmit, } = useContactForm({ getRecaptchaToken: () => @@ -169,6 +170,7 @@ const Contact = ({ isDarkMode }: ContactProps) => { siteKey={RECAPTCHA_SITE_KEY} className="flex justify-center" onChange={clearRecaptchaError} + onExpire={handleRecaptchaExpired} /> {fieldErrors.recaptcha && ( Date: Fri, 3 Jul 2026 11:51:20 +0530 Subject: [PATCH 07/10] feat: ga gtm integration (#75) (#78) (#85) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ga gtm integration (#75) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx * Update src/index.css * Update src/index.css * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx * Update src/index.css * Update src/index.css * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- --------- * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx * Update src/index.css * Update src/index.css * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- * feat: qr document loader (#64) * f… Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor From 17fdb7bd8ae86f80f954c773dcd330285a78dff5 Mon Sep 17 00:00:00 2001 From: isaackps Date: Mon, 20 Jul 2026 15:47:54 +0800 Subject: [PATCH 08/10] Fix: update font urbanist (#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Develop (#84) * feat: ga gtm integration (#75) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader… * fix: update font to urbanist --------- Co-authored-by: manishdex25 Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --- public/fonts/GilroyBold/font.woff | Bin 32798 -> 0 bytes public/fonts/GilroyBold/font.woff2 | Bin 31016 -> 0 bytes public/fonts/GilroyExtraBold/font.woff | Bin 31686 -> 0 bytes public/fonts/GilroyExtraBold/font.woff2 | Bin 29700 -> 0 bytes public/fonts/GilroyLight/font.woff | Bin 31818 -> 0 bytes public/fonts/GilroyLight/font.woff2 | Bin 30100 -> 0 bytes public/fonts/GilroyMedium/font.woff | Bin 32550 -> 0 bytes public/fonts/GilroyMedium/font.woff2 | Bin 30780 -> 0 bytes public/fonts/Urbanist/OFL.txt | 93 +++++++++++++ .../Urbanist/Urbanist-Italic-Variable.woff2 | Bin 0 -> 40660 bytes public/fonts/Urbanist/Urbanist-Variable.woff2 | Bin 0 -> 37848 bytes .../about/CapabilityCard/CapabilityCard.tsx | 4 +- .../about/EcosystemCard/EcosystemCard.tsx | 2 +- .../AddressBookOverlay/AddressBookOverlay.tsx | 10 +- src/components/common/Button/Button.tsx | 4 +- src/components/common/FormAlert/FormAlert.tsx | 2 +- src/components/common/Icons/Icons.tsx | 2 +- src/components/common/Navbar/Navbar.tsx | 18 +-- src/components/common/PartnerCard/index.tsx | 2 +- src/components/common/Tag/Tag.tsx | 2 +- .../common/TextAreaField/TextAreaField.tsx | 2 +- src/components/common/TextField/TextField.tsx | 2 +- src/components/home/PartnersSection/index.tsx | 4 +- .../home/VerifySection/VerifyError.tsx | 6 +- src/index.css | 128 +++++++----------- src/pages/About/index.tsx | 4 +- src/pages/Partners/index.tsx | 2 +- src/pages/Settings/index.tsx | 24 ++-- tailwind.config.js | 2 +- 29 files changed, 190 insertions(+), 123 deletions(-) delete mode 100755 public/fonts/GilroyBold/font.woff delete mode 100755 public/fonts/GilroyBold/font.woff2 delete mode 100755 public/fonts/GilroyExtraBold/font.woff delete mode 100755 public/fonts/GilroyExtraBold/font.woff2 delete mode 100755 public/fonts/GilroyLight/font.woff delete mode 100755 public/fonts/GilroyLight/font.woff2 delete mode 100755 public/fonts/GilroyMedium/font.woff delete mode 100755 public/fonts/GilroyMedium/font.woff2 create mode 100644 public/fonts/Urbanist/OFL.txt create mode 100644 public/fonts/Urbanist/Urbanist-Italic-Variable.woff2 create mode 100644 public/fonts/Urbanist/Urbanist-Variable.woff2 diff --git a/public/fonts/GilroyBold/font.woff b/public/fonts/GilroyBold/font.woff deleted file mode 100755 index 9f27086793d5a23d25a449f3838c337cda2c52b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32798 zcmX6@18^oh*X_1j8(Z5pwzmD$?o-?5*0yciw#}_=yIZ$k-~Z2?lbL&RlbK{P$(`i7 z%8QA~D=W)`fc(J+fdlz2i@pEVARxYfzN>5ykRM?GS^pJbF)_k#8y5sb)(Zqg*OhYy zsZU%)R15?}F7>;a{y#$efczz{Ag}bTje>v>PJ)1_1nwfR`G_m22!VjuCW3%KAc24& z`0OHwL&z&JFoS?N7k>9s_@=%Uec-vFHPG%`djJ9XNeco39;);c;@Hd>XaoY{LHO;% z@=bPV=tU8;Z}D4G{}L$?aSFCfFDV2vlkAE4!vO(CvFXACYe#i2n#m ztpH*Jv^M_MWWMKu4*~+pOi!w=Y-j7}^gU;*Zy(fe5`MLUFuSd3Ye8zGjXdRa7`n!A zs#`_49d9WXm9u&>gc4Izhf)$tTuUH#2u5KW5{GqhASIDg>yK>t8*mI~n}w4#liD&k zl76jn`}FADeQEc1rn%pn9CdNnZn?Uu5YmtVDACya%COp28@LdsrzK*~>ErR3<&-e@ zlK|W_d!p#pg_Ja1h{3$Z`cZ_=xFT$R(FmJ*_sQ9-)UBl$f||>H^6%f!UGr6zw5@V8{&$Po}BTU#9qNf+snpfDfi;wqH^$o z$o>}mB}{m4-)tc^@Z!Do`FXJNJ@4pMVH_icz^FLja~;D7i{Kkp$ym5KS!r0Nr-+{n z$2aEoZ6u#sI6y3perB5kezCyxWh9GiiU)$rf~o(**BpLg5)XM1Aq^*e3n2?hHKA{$ z=-qFYw{Nui*2ZwO#Kg$UNKB1};(Wzq+qL)FvG@wAme=UH`nKIX;h^2hpCY55A}2eG z9~7IAiKml^4VN4ZV;GSelTJs-xZ&)R#y~kXVeWkDj*|0WAi@A7-J-5b{ zB?G^4`h^(_)D;SLPmlC%G)-G?n7q{ZGLxT_n*J;)ucwQ5oVsW;`M2R)dz`j@uL&3T z6qD`M-u>>2N!)7?+6VrXsH-2RtFPheXB8^cFxdZ9)^WohOv!rgz4YZ_l7?fF0Xg|u zV-R0VKKE5zJnlPxz>n3KNP+lp--PCq+`kP-#Xvu?r1EI0{izvlliZ#BW0Ou4QF?9x z@KBEyK$|H{+tinwU&Ou$_^A;NJnG+Oj_VO^>@lYMq_eEEd(}eUwbcmhG1l~*AbzK7 zc+)a@vW_!Po7t{M|5m)T)HTsp>I=~4l9OIEjb1fPZkj^>HNidEYD5@AY@=s^r{me$ z-LxiOepZ})eR+U&92_>4&i1_VpXh!Sd{Nx^TK_lEOou)# zFhLAT7Xj5MgJY&4l56}=VB%s^(@66O_S<2$KGcSemJZfxRWZVBV!U0$$faR&c8a(? z!`MxKLX(!o$#O33tLFk4>E`;Zr|Q@2$M)asuj+rVuFkVP6<_}X{s6zqAwE5^{Jyd& zZ?;jvKRxq%iN2~oJ-2#ueO19c(*FKpELD>`yBOTKpm#6RkYw#lop=|L=H(~jn46DJ z)QPnu0+_06-T_QCrLa94CY22=9HhF_#-*&0jgm8MlQV3S)3=FPwuzaxi5a$O>3T#} zeIg3IA~L-q5(6tQWHh3+$Kxl9G?Hb~iqfDpvSmh5riwI*Wi$%M6E&)3Qprqz8I7le zwIz~eNH-XzF-x_08|v>-OE3nFNsr0r-`JLAOiAa{jEU(fC^$Te(_|(m$8wTVQstx4(v#BpX_9n( z9)!kn;h@29U);eTs3+u;YPtg#pIhNpOS~XmC-Pb}EwsgiEC2v)8ygp(V00&1k1p?I zleW83a&Y!haNtEht#nsPTXtOP;{5iec206u&O9*%5eiylRcXm#yzDeT- z*N@~<+@19Suj4sSmvpk0+`uBk+M=5lG+|oNi50<@GA!t?ohDqQ32;pPHbqd{C+R=F z@{ZHU{FV|f)3o<4xCOj>1-y74r+8Ptt&{g#TLUj97qv%j7Aqevuyk-Cjg5Y%zue)T z(q*M`lQ88)fa`Lm@BVei;sCOO7v*`eBGL&T&wYn0-XdZ_P5Dg*Aff^VzjnjjhCqiL zhD?U&MHBWs$!g#L!!!$t?&F8!HA&}5Y~zOG_v1L@;^Qgf+f+Vvs;gyA)Er460*?V_MQ2?}Nh(@2kTl{n@)cKTNpOq>@nNb;Rq>S6V|AMPO_LTy zf6*&=Rg+Xhs<10byuMh} zM0P$9g}1bZ$u=L19!XBzD%1hQo)C|3_&pBzoa)}l2*`*{nrE>CSQ}Pn?*Os$u7BQk zK%&|afNe_}Xa^#1`L0erM0qIa8dX#Lyu7Y*gvUKLAruB)_Vuk*Ubrvh16=Xa zODI(H((&`r8bLV>Vo+|EQvwD_nFLsGjM|tYiNMtFG#pnb6&nOE_^&ox5vQ}>{uymP zn6Ja-S{QX_Ep_!dLM%NSqQLTzA^}*1tW}(?t)*17t)!&1wf~YSHsDWB-J`IXUyLun zJ$I5zuW%XxGu7MNRc*E|R?D!!aV9V@LGx2@;`hs9oaE`3eQP)w`q67Cw0cp`diz*w zIb{~y(#pzKJ#PyCO^*iS2apek9G>;W7>qC5Znmqb)tl?~Rf4nJ!NLtjxG`hzQmwFv zjKwb*p)}|Z?`_~(&rBHlyuQp2jXVv^JU&bDr^q19!#1m`UaSCg>kL&jE&60Ej#*My z1{{Nb*CCmvr*ZIbI-Z0h3eRTYzKhqJpg}9pnV}Y{C7|G-bE=3=c%{ zZeiJKko=>{B1vjvg?Y4Z?{7A1r&KO~xUuAio>;=D2rAwf%#%>kkxGtI6@q9k-F4n) zB%>^1#F~dGmj=PygEgQ&rM*`NAA{Owm|Us>i&}&lO*}>%Pcn^MR^FkgGGbO7UOUSA zhp329h-w6f;YGn0Nq3 zDJ~hp4#jWh!H_KgM*-;~{KKo6hQiCqMz+?AGvHw$yV6D>PoKFU;Q7zh&XDz^wr{bF zTNl=wXdF3!0QR!Te37%*I|4}js4T0rS1JW&R?T8Nf>f+1OtEa)tLBhS@f_Yy^ZO z#K%>xZJst9YQ)A8Wy^pGm1X6$Rx1ME7}VVJij+kz17~4_Lk)AzRH|+U#*rqD%YY=# zo_%5HW60*qH5)ZG0FZZY2U8a|kZ3VhcO-T1zv|=4zYGxcd|SLC`3nK>_W2KF%~#et zR2ziiG*dxMM@KECli$U{0bph2?9fFt=p?I7C8dYzCl^P1h1AmL%FVcnMAvUsOEbt+ zFfu3y&2poL-TOEdMkn4BaV#a0uU?FJy8XI4{Op-acU4r5II3ne1&Lz=ZK9(m0!ean|E@24gw^l~j@j z@1UVHX(oSEDAF9LYv!O^dq}%R`)MBBDsIF!KLk~|8q&9HLFO!z4-AVB^ox%K3KRq3 z3hdFmS^aT3Ao8(xH1L^s6A9Z~j!X>X?)bvluu?ZHyMIw%4Kt-dOrhZNQ+_q@*t-%ck8vbaDoVwqB{FG%EU&@bF)pRL`wBL)*AU#z01{86 ze@xSr!=JUKl4CSgl^ZIWDovIi7E-!4;erW?TBEyInG*#!kw;f2R_Kzb@~lA8-X6k-47sW*1Pnnu^;jS*|oVpBjz~7sqhitknu@VCS2f zp&786Za75;V##^IU156&JejXt*B;@@4Wx6zE?aFiRki1bm&?HX&{Be$fSvy-C8O`I zL=skvt|xY_YGEUl<$1FSeuhA;+5nS*%|<(!lz(t9HPw5oFRk|V=Z9tcz70~voIhkq zn@pf0HZx9l5l+F836Vg7z%*16$q*orIx*ZBM!8C00@*=vmiE_Q!XcQz4WzYDG(AcM zia-RyA*nzFYP2D!zr;goFbCBNl>lP-LiLDP3?XN!A+Eq^!XXdvJ5@?{;zcYfb}Hng z1<|~fav^c#JJFL=sX8UUZh_Jtc?`&R!e+2SpD?0fDB#4RSVASS1~H({!r|W3i+Fhp z)S^i+j|!9sr3wt-Q&qp5p>zboJpx||hk$|f#6!q|5F}2}R3~UDN#TYti=_fiS;A=H zs4!0OR43YkP)S5XRN&ab3aEfg!IO3&d-S{v341v||6k#-Qmmj<^dxBhvuaSA0P1Q& zCk(1?#oRcUA(cQeqM`3Cg`GDCGX(#uJwyRhXuBNE70v9I5F)Z>)U0}-3o)x)UTcZS zuEZ^#P)zKeA83^zB`6hs+3e3i{0g)gWlBJvTb__2%mXjr-G3HQ;ua-uOyU+M?^xnC zT`&!1C`4#+O*8E%WDj{Qa8@K>|Fgsx*nBq-fGf85B0=`=A4+;195&@WBL@>p( zB~Vl1X2?RY$mtQYD1m%}pO+hjxeR#+A&{obqh~8da4_*?=wO zt?y^4Zh*g3jf1jtK4xW$MXNR8J?&?RVA0EyT)VV znz4%EBS(S0S1Q>gj0vw&f2O`1lUmwHWSB}F?Rg&r!02y+LB;NcGJDdLX~YV{>iz{; zc#&=$iYNf@H{x`}{r;<+;09)RUa>tEnkd~K-(mLwy8{`T=wC-uN`H?TwhHlbigLq6 z^E1w~sk62wl5~!6}d114ImJX~Ltj6h5Q@|DCdOdsaVzG`BFi11ecT!prj7_}X-P+o$%!?CtcQ)&=4kL0ylD z@8)Oqhy1^uHJtU3mYmt{(vRg!*B1V*Pt~^&gwedL0g;d-1U=4;^PR=MBHYRT0qnbjy$NppKG3{J>`Kj8sjmf6j#$U^mqbj4% z+MHs8s!2(-#4_vC&eiqFzUJ2K5P4T|r*3FJctk5^n>UN+%`N)=eZw*4m~1Aei&a;r z^T<8P?XQQYhwqj5;#>L?0pFz;#Ix1S>Z#+%@yvAabO6_gtM0tJ?eTfm*U8>CS;54z z4!4WW!ei+*<+j0ghfky)4*%TDjBTi1{*7iV8Lr;z`;@9V=;OD@H@W;rT{9Vkw z{O!zB&LRKu7wVVsr`}7={q|nZgl~;+(--hd=`-cM=4JcdckfFnc5%o}f{^1g9hPI| z)At|BycnsDEJ+tl^%Y{-jt`kXk`r6f!{?}u?63KFnw6FUD)CtEOMJyX!D}Xe?o%CT zylRJEf#e%-r|>eOIW6J~cS>oQ`QK#LAdVDlc$T18fm}XwsE?3|K6=sn?Prw^*$ROZ% z!j}qid%desB4<`(TxOpi8{SWDzvB4`toqFTfgvj5=YIJ8c54Gisv(ocyV=%x$br}+ zW+DL@6nCs9UX%|eENNrUfmE#EroEA=8HP+ZDdd!Z$kx}BNtxjpu%RP(RpnsVPUhfW z;dQA1En&t;(m4lfy6BW(`{-zaZWWIlXf&%2bsUcgf`&ugy!NzyE5JVO0}ivSMj6L1{&%avVO9#6j4= z;O&6UcftDv`7!)Un8}MJI68757IvBL>R85Hl2!K!IYtg8IBcM{?;*cJ;!PfhUyGW( zhUMuPds(N~*E!BS)kd2WC4qfPYqBY6_)$y5?rkD^$pqWG@Tot|vJWzUgo({CcMKFiv`+%F^cIDBhqr>i#aYNiVr=KpZ3Z47*NY+@zeKR&G#al)~klF~w zfP(PXr zXbtBw6t{5}v#<}39z?qCAa9e8pT+lgR(7Xes2RR2bzM_WX}5$i#Z<6=^e&b8aC4 zZV+M39RgI`Dpk~-Q`*7Fs|yXtkGm|5YWA+gUV}yn&r*6x@Nr1EFps%HOKNCGEX@&4 z9@Sl3|p4KjI=%moP6QPwocUI&S?F;9)Q73;dHBR_~sRrmd zBfa;)NlD+dh|zL@Y*@-A+ zam|4M7)#x+H<9R4sZ5dkez{~~tW$(2CMAnhLZpwg+m%F` zRbxsr^1afVtoHk2XDX@myJjR!#e)$y<%V%vPWVHo$asIWG~#L1(foi$V!Lz;p#{_x z^wOZ=$#dn&&kth*8d%VEnvH{i;|7~kU0t48r^OwIxH0O`9418!=I)C#nE})5K$?u` ztDb6ZM{3Vev4FC`NN0=)rpknzdp|p1ZYm7Lk@G-VERhZ_?Qr_ls8imeKvu(aqXty( zI#Uj{HCU5CWjF9$bbhxDwJ`$-g&k_yx}HIgSJqj1q_q1?+S%{ahQmh_bkS>s$Dva= z9|go+HF*Vc>Jt5utQ7DNntqfz0vEqoY4mtu+M_$0J$|28Y@EOHGMyuLQvm2LOlA^J5dZ?pFCyVJOQ|`;oi6 zOs9qhc(xJL!FVEI;Gb{_o){O0$2A9AqGf`m;2aPSXhMa+^kF0G;$b4QGVn#nPo z*&AA9Iw<<=>T#47J2Dp&h~KY>ONb{wuJtvDRUdmC@>llp~iB8gE}Q4$Azl>Tzd zq{wOu{YwkYBY9kt9f2TzTRZbes2+wSqNi_1)9I0W)_ix^Vop+i`(i1(-oBt4an+DSNlJJz`5Muxq%4M=WBlZRG{)g?%XShquflVO zOlySXG;|5!Krr$Ci3QZOO?$-*VyD3@^%(S!D|`+9p;*R48IKnq^5faCwi4&ty{SwZ zr5Nl{5@sPcx804dEbe49>%R$oM%XN-$NlvVbSI&@qdAJ5CdEG>gmD|n^qpPWn_X90 zKRw!SngIn~t{L5q$VJtF0$ke-^G^FGd~6)t8ryXC!fAPNo=_D%8QBTHkr zLy00xu>uH+V)RMstD0`IK#@VXL-7~HmAl>RUbhD+^=`+sF}Y9E?R#*f?9U{cB`Cti4^I)?i=B2Ih8zxhKw{9LWTw&VCWLT zVXetx(twiOJ9@RJ($nW&aWM;ZqMb?M)yM0y@a;0QE#cIpi9kzA)?m3h9^>sp`I)Wy zh!9Zp6TayQ$dgdx%u;?5#l%8jef$I*^APybSy!Tk3Aof}@0rjOk-J*V^W7G|Um1Os z?AemetH{LTQbPX4sw<+xw>JT1nqz@oH6|uA@rd9g&DRUS&CP#8ArlKt8R4`yf9x_t zJ8xlTQlx1moZgL74OlUWb*=7E_jB}k$ifT*gDZh3KkEPFz z>?s|MyvMj;CeNV4o?H}aRv z!-q##7;N6ns{UBa^f<=6f5#`5IBRO&(=eP7;00RcG1_UYwruTM~n23&-u}UD)m0 zd@aer9X@Zj?IuacZshH_!i&5l%rugsU!Qd3rCIhtRi~{TQNZN&WlG~&4;RTupvzPU zD_t`o27yiGWqu&R!^&L90((D7Q=f>5mFq;lVK7QZeTWX3c7Q&>P#Ch$uxn<#8fM$5 zfBX`Q@Czd7A#^#wnbFb6Qst6vv*~WJGz{8Y7@j0_^XXy}j0zbUn(6}-H6}aFnlODg zQhv%+aHkwBW}85G-81Z1Oa;@3)u>119b`Xhh=M8cD=4ta02YvdGTEWM{9Y9M$5+o1 z@!x&kha}}vKVK*lo4*+x%VFv}r$OlSMUSey-!d0dGOxuQk2tj{MGCdd_U}C zm*7)uz)jWc71-?2`k>w)99**_ov@4iOBAj+v!l~7_!|tL?s<^(N00eIKc$Yug&#TCWYPFreDzz4ZZ5xWi^VyRR|Edl*{z0hC>w=Sx1N1^ z!>^}zc;Wm;%u1WGg*Tae)|+kox|Pu1OtA1&evqpZzB^(5XSlFQ3UEasv?LM>4+m8Y zIU4VQmvsK!m%WP=FP8x}-@H)ZenoY|9VUQsL4CY2FYa!(4$WFRG-K|VO(iAR1=qJXCSvbo}gGo`%Qi2Qa3d5g&@aPSZc`#pz0SE-TquCd)B&Yg> zDOK9~&m%PX2l{YDpxQu^%?~jE91fLC2i(vBv)8y#NX!utJ)N*N@HvErncAN|exD@H z&b#_E-Sm$bk_5?{%W{C&j?=a*x}+AKBoQB4M_SMBAD1!%Jv=-^zKB9PpwPw$rT|N1 zoA#>meHKD1B+*p|Twxs4?5M}VBbMNAooygn%6zFWg5d@O2rB5MlX5KLPa)c%5I!{g zV$9F`T4GoX;4DMG5xmM*wU&Ciu~P~Kwp6D1;&pXT)PkqSr#56(OM zKjd)-FMf_gB{WUh{3B%LgLt#{P~s84XbI+l5QKdi!xaoa7NE4cko-x9EaZWlr@$ai z3|YYOJ27IhNv}G0`n_Zd#=Qt(IBv%djv{+14lK5S1vLS79EO^6J2h3t-pTB0ZYNdz!wkS>KLYa0`>-A*(x z#cusPy0Sd_dlp$|8rR9O@l+2bl6(WGIM48^&~MVsxWDs1=$|3xe!@v(#+H8l4lY}7 zx7Et3Hd&smtn6P63x>+?9K&B>r{U%;v2$?KG{4jixTh@kRZ+SS$8&1+`2Y&bZ5HZ4 zbgQ3H(XB^D^oh2M1YGGdJF#?!@Q*M7^xFH}7DRU)GbyI3&}5^H_}3X|96_VZn{iK$ zwmM)wHBZ1iUWP5>uM{^MjU^%DMYuqwiq`>bE&c_xjU-HPe_gf0t44ulQ*%`7N?Ub{ zHN)BHKwRfe`#J+@dTrXO5+zxtp6%v-DsbstUGE2qSKvtvx`(Rb6Zor$|69w5;a zs#hd0!R~t;tmsap+)WY4Wyhyj`_-)QZxxf@;_c{8&g7R(g&*?MvrPi>{bh0koG0!3 zCEK}OOUg#RRsRk?rd}Oex072F)S7BD&A?asHglXQEm~a$8^bVL}K4fy5V@I zbrT|76=Iv4GXe{uWpvHh>LFMW!30YKHiZ?_YcbLW2*8LNh$gHV$&d8?JjLcgYws6G z@Q$GBX-;+6^_5wThRK-j>hXE`ctcLff~S#4pFO;sxwwkwEGuhsbT}c4BjGJzZtoRn zzw|SLgDXUj3}Irm9yQ+HF4%|Aabb#OrEynZrRSoxm239P@n0wefkH@}xU~+UnLedoG9j~K`?Ck*$X`7osfKq;1mhpda0{*}bQ~j(b49>kWPu?5CDl}r19z!z1Bu#JWG zrx(L3Oz87-q<6xtWfCU=WFgLrNq%xroG~(KPK!R9atJ^(V+xJBvEVz{7Z=3|F`o{% zBH<0|l{VlcX{{d50Nsycus=p_e7&Nl)a=;fr-xWm*wk^GC<9j7dkSsuK^}c(zv|?G zTivwNr^EWD>vm7wnvs`VkgZ4k7|R9Q$P(-)o5VykR^Fa9b4zXF1tg^@h;yd$~>5n`0B=b;Mdg& z_R+_`;>qr{*yll@2aIyIpf8b)u7yn^J-z9I?f@@kwEynf)8=&BBb*eJ++u(MoKkn0 zl~$CE-dHE@03pCDFwg?}l@n!lo!fa^_55Wn6`}-A45qM_MFBw$i}m**6KPDlX*O== z9j1>T7Ux6ZsGs`Oh_rot<9hZe<)7Au!AKZNu3Sn%F?Be8wa7v7!h)hb_}g~;GuoVB zE*|{nw-(cJIn@&mnQcDHCkl%_sTjGWxe`EUG{Z^WZvD$O^z9AbM`At60>gPXrzSwl zB$d#&*JH%3DY0H>abRrXsE1;ZB++`NF4M9-V`Mz~f~9h1o4uoPl(v!ID#WA@1CCWd zo0}Y=OAhxTVoa?+Fml{upopLiwS!>i?+xVPsgyfAz-b{)1Q#{Hs9Q9Vfm!G1EsR_7 z_0MbcqM%QFyfmtup2q@${#buSzT!xF@gG6~$TDsxM&}X^>+i#&5Q#9{B!SNeCX8sa ztU%nEZ}I%>w>L(5+T{<(CEJ-&abL4T@iX&$Lo*#`RceuY}hwoiG{Q{vf=y4%~V z3;Y7e@95CrxbJSEU5Slqzd)&YPy}a`xIS~&ao3e97DE4I2E-DkDCOMdY}x3!jBir+ z-x3~=kw|}b@ahpm>;__Y=6ePLE(kwJ4dQ^!^A-DzWg*Q?8)K{(AK0m^5PqmpHdQ&y zK*D+}2z6myKaxw+yQU2!6gdU^`l6p7T60)9ywr-PCOUVdeSv|X;NezpVU}MGJR6`G zL?r@SI*;NIl^pj+$uRt5?7tVgZjG+Oy23r?p?iM)S@;$M<`yMBLZ=IEN{a3!ec=K zKn$^HY-WOw^}@;f5hO5!Dn)E=JrDK(3Z5-34i$BQgama$o_+DcnlTknDJE0h>F}a{ z__tyNARZ(qhbM?Zf0;ZFZfEZ;-5FLA!EH|@cg@plot6zToCf#Y5DOlYdU$aKh7*&s zl&=1U1Mj@8&5On1bTYVtOhWR#s4o=6SUeyJ_h_KB*$nZg9TK^-YNX(d$2J7FSfBa) zkhBxN%)#sy7sL)6ke(Xo_1;WaX|K>e3>5wu`QzqK#5%c#^&>TKdQ6cIDdD zBJwnyv)|5Th9)WLv>l7oVXL$#IMG}xwrA%E^H;yzREoM9{kfI|lhbvkyuL11Gx#k9 zZ`>rcvpVGL!kD?2Ub;f4=})edWun6~xs1IM{VItaF{!JQ7E|(3PUyK+$(<{eaP7&! zrXNhkS12B#4aMYTFPO~kM3L9ddf`__cHqPFWV1UClQKEDRXEO+H%EV;DLYQdJ?>k# z_v|m0fv&LCD`geR{axNu2EQoaZdLn|RK^AW;c+H4t&FfJ{Q~+^06`d3JzkogrOcj% zM9f^WBql4DBD^;A*dXLdk_T;_5**Xp);sprj!(MGQy>b}QgSY-!E z$2`xOq-md=Ls52O^F;QmBK@Qvcs+@r>zQOuFX40lg%tNxHEG*;^-oC?y|urv{K&h1 zL<5;7X+hHEM{ zQ{qStmB$e~f-8xxKo7-jEF3dj`kY`bF20xRl-5D=X40KGx%4fE_?CmS;N9Ub9FdG^ zp@c=*XQm4Ud2iP_fqgYL>kS!}1SS7NRLgo(-ekU%kOaS*iieJ!j+4o$owXJGI{Dy{ zEc~;U@Y8{=XD;FsP3_Huc6`~UT@D}Z$(uPqY=>R+)t)@03GM`cU#(&(iX=*)K)K!1 z{Gsi2bT@15SLqzsn;!mSmEe^x3upp=Rrw&c48`&^fgiB=0|Xi7^0byE2IzN_O&3H5 zCz4Q2n%-fnDSXJ==XonqFEmP|g^40-XwJ%!b$26P$Q>`Z@(@fEig0JRv2rT%NwbhO z$*NfA$a5Xx_;KJn&Nw3N6Tz4D%yLZ`!GFIc)5EclYsArI66(MC>`%1h=9ju5$=sQ=D&D#^LAKKf92@)vxSnR>b)ZZe+^aX%H57V*4h z=)-9Vt1#3X+CAy!JO%2J$yQu2-G}OhoA#Nv!cVeQSB1p&NW&Hbhn0;{rA5he$I|Z` z%d32m4f9x{VK>0e;NR|r#YYrQ7@KfF>ij{fY=V;_lVdRjj=v2lxh}!55yeb4N>S7r zPZ6ysKW!=b?J&HF$K!4rg%bsW?S_tVD`#Ud`3Z!QYSYUoG@T?Y60y?19IMiDo8KB) zxSUL!=J|d(MAji;{+Yj3-c--?5Wi!8Qd=dS(hOXb90cBZ$Eeqr8-eMzQb$JfA~HO_ z!S~Ecy*h&z7(A@Opc<)FjsickU`}OccOHaF^fIuTk6u5IfrfSc3NrbfbcMEphaGBO z`-9?(%m!;jUR3gQ>vo3_lPg-8Ig`oBaH{$HkV31_U&He9V_~!KX$}uBv|xkV6sK0V z$3sJFIION6-HK=U3yMam#!6zq`{YXBMuTx1A5-690E4svT0g{kqC|q{$d@nkm%5k7=1Xu>^ zkRA;~uxUojxg2o0rLvzQ6URiiWk=y^EIXgQQAH_xvHG1-TtDJKot#$X6CodGV=CSX zNgWG@B(@QGk6Na!Nc}N9Arh7}=Wku>6zt^K7ksWMNb+PO z($=bcT_CL*2YoSsSz3wAQv zs~U`>ZH@*O%p7Cuk9wor5wHY#NtbxkpZ4xfw6~ujgl3McQHQWo+Vs1hS!mkn-_(zCw92u6)vSvVW zKDqn|nYRGDD%Z`bdUKJz&7s57{DQ)^NZl$5&z6HN^@UFCOBiP&+*Q9amSKU)*OW>X zmi~>f;3a~DH(k^br1c1N7L_p*O|nh)V4c1~UMlj-yw=FA#`?ZS?_4do)1?d(^X}Y| z23JpscD!I4#L(o!`&W`5d|;4@K5hSdY0aB?VV4TpHPe7l#&#L9tIi z*%o{!yrb;~e0`Fy(5VIrr$V{`20sg`ZZT5WF+#s=BrPR&SlF=$?6??C+Ax1KnGAo8 zyV>%fJ;Oq;HH2pR4REuW2jGB&XK-a?q4Arj^Y$jGfdfasDfDApcs*NlZuaAM9g*v~`%uuqKQen*oZaK6pl z$T8*1sT68HN*5Ph0_WsK5L|orymfTjG?VuaTv!9eCd_eH+`J7Ws}!HB>7)wvuNFl) zr`9xUADX?EHbPT;7Krw9Op|AB)V*ZLDoFzWwM(pBiANy?>gK*x$lZ8-)OG$}R`2Ow z?7m7LFDxEBu*z)Le2?82HI_7O?W6@7Evb3x$^5bHW}J?;`d;WGV86(#mg1n!!)8 zYexiohLMA-0}Vg*<+Xu;X}rDcTcjB9<_P!5VjO~>)(LVV3#}d zhj_!{nA6SyiUQ(exy|Y$Th{oKLF2TYxuV!H6WiTjvIM;;T5J3QU%P@yA`|{W%HcAfF2(w0`E1?qBxy}m z9mAJnr7#G5t4KUjHNQ-MrNB>2=063J&lHhV$Umw40>F)a3~UGY#Vh(iS`73$CU+9q z`au2R5MWt6&cp@9EMs_VOamk;GQ|FPnB^ZVwwjk3H-RQQw4Ew-qZS)aN(bi(o~`?# z3>rsP>j0I9QrJza6SWA=mxqelmpF>-PITulH#Sj#q7Nb-)R|Zw*h_Fit;=!)CLWUu zZ%pcB?d|#u!4NZuS{6UP6mgh;kBdhNF{C3(fP>oer*3Ka6K>F-1rv zmJBdPIMXYA9$67Z?Kk_6G=4I5+#Grgt||cqAQdA74VEb9Pb#)H5&tuubUE**6lS;L ztL`0oE`zvKZsIHf-moAjDPu7pnpB{(O_w^t4S`ZDFw zU{2>EX&Scc!wK&3-(?uH3l0$(lZ^k#HJ;)`G3SKL8-{4amaW-Tx1}&OmCX!PERB{a zt{Vd}EMru&3yxz%<3gdsl3}%vL$-JPw}ho1z3*gW>hl_Gq|-7dn8mFJrQka>Z^;Uev&XZtpo9bo=kdG?w(q0UDdv0C#upTx9H_N?AQ42Cp~qf zO_!cTGkHVOwsb@PnD~LcDUSHi7o6{1-nsvT{+nS8SqdG6{)q?9R&CsWu*9&O=5fpQ z;7ximbEao3OxE$g8dW>6sVz%1-rht*@GCFS7))tkYb^V&xlArDb9}b+1?(4I^{(r` zPd{W&$o9k9@{+ClYxm_%*{=WnJo7ZE-=Xe0ci(XY#jQ=>nrleR%8QH8dVL#nFI|5( z<96XxZCc)p$x+GM&lTzkH-ZV+|83$QI#9hh2dcXH<%K1N>U}#8H)zR&W5Ui=n>MY} z?^&>?Xm^qNMB#y%vD$(~bLY<2r*BAGleJbIvpIRk0WA;Nl3{^Rj}K!*mt(+)z_CFYN#%qmA}sL>MV0Hb!7E09Z~rEJ32o12Zg~b!Wb{(uJ8AV~! zaZEyJs?rMD6CI72I~X&$?EyK zBzDn~WuGoFjE?A+?4ffWRDLePu;i=HidShNoLf^|yhbmbW91Si6Hl7?OgBIdp^+(^ zD_XLoNN?)G7A+}WW1!5dz9=sKN`LP3o${x;r+3oFoi-GI`o)q(T3$*uK9Jh(7flS@ z7$U+Pk|NZK6uVal&`9G$Bg+@TqaB!@%kktf0|xdTguEjmGR2d<-kA5Ag!w}0Vk(7K ztK{!Gc~gMYFp{?I6p6=9OvcC`ukyr8s*a(>N9o*9T3nGXZJ}D_|BM&jvqdC&A&w%O zmWh5VM1tmGa%`Jf5{ZJ*meFHi0Tp!x`csB6@HZ75_XC~Vq>5LoPK+cziq5Px6w$~{;!T} z4U4K;!!R>zt(moQyyP}zTC))~vr_PKz@z3pF|R=0Q1HSXL=kU^sF_zx^Ok8T8D0oQ zfdPxuN*rQ_xJc;^uOl+yFXf( zrKe?}Ww<5E5^Kq_6j+W~YArV`4=jIMne{1asx`~H(7MFB)mmsRwH~w{wbohhTmNkf zw58czw=J@j+s@c-*nYG9WqU*jX-qnhSI96DP2xx@SwL2i4@m*>kb~q1sV2XYKS%?$ zP)47j&(hX(BpprT>2$h|=FyY%GQCCrppO`3!K@35VJU18Tgle@JP-?587pU%teVxb zi|i`9&F-=L%wYeqTkVbP&Fq2pVEbVE6nmTn)91jmWDjdfhUpr1Y&N?nQE;)X1 z+;;r#xbFaN`3#=L7xAS$hri7?^38nfbKEEU zbGNA>&vVb-y&liB!lb11^rWQ1X&zl@gZLn+gDY5S!`b1K(R&6egb|2#48+zCkwMVe z$~}jR_0g^!W5@+(YvSK|2rKbz=s@?cT;(kBE!%SbcqURIi>9 zQ9X3$!Q{~e{ax6qCx=$wRTdmP&P5!Dr@V_=%K<#dlu2Xfz+U`c>VJBPhBpJHFqMhX zuJBO>-(=~l?rA5tnzHE1%IO16aIK>xy-Utdx#xO#s{;J=CmKPawUfpnb*VO1Vskp2 zi*r}WB`kOW+Oa`l2O`OKx;JmZ%*^=<($nW`DPE*^9!o~;{vx&Bb*K8XpM{3^(FrNE z=d4%8pv8sHb-Jr6O{+V1q18`k<6hgRn>*2+2qdSll?xLU;RwY^7y}^~1{n|wZ6E+9 zsxZDNy^~pZ^0+pDrq20bzuT#WO7pR)g3^{=94yGh2-Qy!FIBzez_7j0;?A@i zG?*#~svs1lsMYfhFmmXhCqHIR4XkH>G`$N3{)kqzzS3P4^Jl*84p#l4ZDMBWnKSvN z2M^^Z4jPo17^^#3S zp(CRyS@ToVvT}>nPD_JNjCr8GG8)mfxo_ug4*=Dz#r$O{ObM>)w?l=sy~t1tL%@FR zeYtGe>NU&tAK=}ci$BQPJi8TGYcoHeR5m8BRnfmlB%R)wtj*3|lRcNCe|6_y{6%Ior>)ZRlCYRmOqOjix#( zEG!~QK(S$5Ol$|B3HdaLGDV~##*szT7OkEhCb(5lwLogNb zFs!{oE8a()FLHfTMhask-0gslcF?Sz7i~FQ*-C(kSDHsY}aiVBg z*Wc&t6Ln4@;QT*Bp_yx()M9*YA>JHuz_{H4r-BzI!Oa4RO)&|ZLQ;W*Nq7s>5DA1( zcoya!UHH=bT+EYr%Z801<(RB47ymnk5sQo!X1cAXr^|9rnd$b)<8(_@>9*FF zZh?wBUFo98xfa$18!3dks=*Y=1yRLKu3#)&A!x3LXsV{?qN!hshC1RM4^rXEG;Lp% z)K_q{oRLS}PE~zZ`*gH@afZtJavDFht<)fhR^;=sy1J#fPrrEot+JVJ@fPGR)W8jX z^`_g^TveRsvZ%E9K9N&*d^*RCBAj$9uaAA`axPU2InhYcCQMnjV7#s>=T&)!_d_ZPcOkDPee zkfD%OSDYdi%Aww4v!&K^jJ$kl4DY2oKjsR5s_7`>PH4%T=cVeR0?v7=jJac^*uXbP zT~xte*LeRiGh&l<@zHzPbLT9|o*_;}AL-L??6|=qSE5@Kb1J+~fhK(KoOY585lq4N zZYBk;A_8qAq%b=DZGo1WQH$=kx#$4oE-lHQotm0CCs}uD_y&3ic(9o_=Z>QG;34RN zX7v(E;ijhUG@HX*3iOHWiRxmSDR?f-mZsi%$Eg)=ardW+x^i7KL}+3MAFej{c4Vw{ zR_;xXaASq)8MuslxzZblR~R;)8J-sF4j1JUBO@or3T^P%nQFj~A_R16aMo}fYSj9; z`A}~y=_QPJwFDWjRfE!C=coxu=%orophngStV&eB3IJcSA;r7N5?P2r@yKAeQ* zK`O;Wg@hQjuoRUR6@M;4WXU-b|(`hdW1;j ztAv_AvCa34tBCbYPK+8oO=VyS7jA6Agbkk-c)c$+x-hD5*9+~1(Ltq@Sa(vP5B2MW z#8Kw2ecBIr0j-w=4jWRWHuRPrA{c0WzCoKRC<1g47nt)v!fR3Si9&^W=^DG3XympK z1UjpDt0M1v7yP6Y83`$=Nztl1ONj8Pkjy|~ChQb=6aqv5KFDTveI=@2kD4tGc?Y)7|N8oxQS$kfa+75Vjzp*#bdCWfUT-GK_K@7o0)m z&t*fK73R7RXuLFvc=nN!24SY^gc@EHlA%GQv)`R;dby?V9u631h| zb8o$R@4mbI|M!3Y|KC@MC=p4@FPsM@bk>%kOQq}Tcf93Ivgl23xaB6Wp)?_2bN3RnjIs_S})Q^vY_9oqomH{c`e|+b->wE$5wnMZau2|H7euxpLcu z=l9DEm!6L6Z@YBcdHwQU`(#KmGSi-irCs{$c|@`@%brK2LuT9am~_e5_T&JSj7zU*=zZ^ILD0$5`)W{ZrP@vi>FOU$b^uzsP!=^)X$m@QrVL%S|fDx{LK( z)_KpNKA$@&wlKh64n*2AnHX8m2(k3src zPyfGKYs;Y~{}N{oG#UA`e@20nZdopyWUFlBx|9szo&XaU$itbz>=U_bX5BPr0k1{p zESdkg1y3xxKObH8cf1l_wsXbi6%VYujmTE3K50JJ42xQS3;K^}gs(Su+hl>{f#>yd zvTTMe3}M8}w#5g{W?9;!0_NPe7g+D9rIkTjAPW> z@4dip1suEaxf@rD{9eS_A=WQqv@V>Dc*8i3;BFChfuBXMVh`851J|C$XT|$D>Jn@w zj&b9G<4^eW4xp4V-adZ1I2*&feu-~I+rmW|$Mqv#S>k$5_|Dnk^N4p;Qdnad=ZE}0 zU996M)?U*6W4=dpZ{A_Fb8#HT;j)J^j|04FuDH^P@8c8B_8`YRf*FqE$#M2^K=-2O zXva36hs>yYRp2~bn;rsvdzIi5I6KU`jG2@%$Ahe0>T{nRL-)6jt8w|gf;o&&JYV*A zWExs1AIH6*o>MK_k54hy(do`auigLas%te?mFtB4RGO|7z0sy?BlTk$DNoi*!}G4y zb#V$Ax(zEUPt?9{%?(nSY=j9%9-msne`?arV3Xt4I8HC0cPwBhCAo0t{OG6w(@qX_EqJ16J4OqQLe+)I--AaIU~1D23_8BI9y1ys=s2h z2ODBF@SOfF~hV9G5U~Q&F z9|QX}TTwD)Q`apv&}FOGeS9*P~VN-4#DbO%L66!pr0D`p2N3YXg`9U?qVM=m~mL^h-fb)FiidI z#ZwhN|7cBaRX?b0%X*nHGusw+NPf`wr}E0)v#cMtJ&rW>gcSy*T^+B+htp);)_hW~ z#x9db5O$n+@QPVo-CUn)@TtY=`I;)LH+cO*mFs<(jxydWS`3W&aZ(k3E^X^RYhx9Q z0qq~|Y8r2M4XH-1?5$Lt1?{3@ncKB9Ea>P=>ns=rFzR;cwTjj^X-@q)TNd5*wW+r@Hm4wCku$kd;(wtD2(UN~6?*@l=CO zoJC*Km|Xq*noA|kU9sKXE%bS=zc)~vdeqkFn6P!x#_naHaMVXwVd6gU#ISv$SVb-| zTr?Iil}-XNLvivPts3(L&L{6ZWj)CqzE|DlM+GA-EwXHL_c6Oi;remO1S6p(`vS{q z4`$-dUA%7c9i20b`FYK-)nL)^o{n>-p_Adjnu}G5O_ntqFn5(EyUa9POV#nMiDxTQWcC4%ZD;-x(K_nq zLq*FUMH^Qf@!OYeRIwb%douh!I6kF}t+f}6W+8g&by>ahIEpxLN#{RZ%%6aO!V62VD4cuK4wz^pI_U_ ztg&5n=PMAGRQ!yw-im%6=&3kOJ`L=!nZu70%dMl``i#9cmhGkG&eud(nQnfMIXHa} z>NsG<+gCiqx2$Ftbf4yUGHhj%w=fldT@`Y0WpX6Z!YkenCW}ol;xO{j!)#qLY|UA? zlUjaZig9-ZN37-mmK96YeP3T&1^ScG+8d$z452Y2nwl@Ur&(#hx7)-4CA(AZ+OzQq z;vZ*bmOA_Jin~SWGw#2Z#OXbzzpd@$En-FKY9xSUKe2KJ!; zMWjC(#Es4t0{pJoqN)jdhg`m^wzH=*gz6sA1RA&du--G?v*=~N+3leZtg%tq?%|i| zLtSrA-Tq+_%pUi7?KomgW=I9h@W&YQFn8&n;X9WqGu(nhub`|Yfn%4=cuLZa(gl>< z2k)VGa9#E@N{l^+yI-!8YJt!0GJai4#Om~EjVsLk1@9pG(0k}#=05NkN6~M7_hXDv z+QoD9oIk@%_90d&d5@w!S6zEUiJr&Jw^oej?`c<>qp4cn`Jn zacw*FzQiI?chtAH>h43ikymT)?~n7(=^EDTv;4&seaKU~>>MZM?K+FA?zI*8hQ{nX z6oWe-)qTa9-Bfqf?3Ega6dQJdn&RD{Zw;`qk$NHErHj@lRD%2Zfq1l1XY+1zyxJ_M z+&z@j&gH*=$L%q@CRk0Ls~x89k28~-SZDqoWgSyB@0)v%iq*g174+X)Tkn*sI;{xYj#nRKjqC5Bg9=XrG*NsT|N z$k}V7`=B@0a{NQ>E%W3%#Qr{7vG#7HaYjLG1US^Ke}jQ@C-bb3UyWl$+`^2!> zY4)*j2r@cov#64tVad;+{r48YS9Qgez?;;Dw>VWVRr__vgxb+>4-a!a!F=ve%?D|@ zw|!d6ecs%q&m!N5@EwjTN${OYUrsA(m%N-IuavjR$K(;&r!s1@x=P)y-mmUdpH%lt zR9)@4YKM1Fz0upJuJy*%_4xiYe?j>ZXfma)@+xR^2=^=M8t*XL99Gw%=yo@FN7RjY z<_X+;8moz+M3~CB<}80J0!w8*GZ@8L*i)R>K3{WM@uDvQU7TB zI?TSVMY$g3Mz7?z()~S+7J6<+>}a}GiLHYDwV^*(U5$};=$76nT9&Yi0#@K+_9e9! zPyR&D!gHO4m}}h1rGmZ>`YX8(pV!;9#_c*w=+DJn7yY@s`;={=^!ivMo2MN0S;)=> z62P}Gzg;g~n2BB;TBi1B%`I85Dd3BH4NnNE!T6}QH zW{i{Kow-x(lLoHtnfz^1W9#PKyH@XKXn#6yxsRX2=3R^RVXpO%qrMfpCU4WfWwSfC zPVxz^>h{I=K#!T~FAg~Pd8_hlF_Xhq( zz@HnrY7gJ?QbSVo8Atn#Dj^4#gR7I3YJjvBFZ?*F(5XK zl0?bc(v313WdTYaWi_7HJC}NA(FMa)i>Qr?W z&bP8$q%OnfYi+p-<+?z*$(CDed8aM6sh#SB_`KVePpEs;=kWOe?+vSOuzVZezNa1& z<$Xb~*t?nar&w=QFQLAd^(R?h%sR{ZEY@eUzJc|5tY5?WOU}1NIh%Ap>H>YP($2R~ zKfo(JymC>XK9Scqu+0Y@u(P_0S3bn^49_!cxteX(^2%a;S9bFH20gC)r>@mP1wBEY z`aI2gnR*%ZDn6Cxm6)y_u1ItorDVTuBk$tf9#8i$o9De|EY{1}hUkdh89P`*M`#Pm z5Xv@`%TcaG*IR$yc5p`3ZA=dvJ%>fT9*%o?yf7J2;CFK!2S63bj?QJSQ z4Lutycj74(*|6WRK;(0YsZdQM#UN86Y zUpieUZ$cMuRBuE~dab$<(eRV%Nkl@9bl{0acw&iMg3s-EdYe3t<0kk!SN>WKVJ0_A z83Vjkg;hlU9;3$OJu0CR@?O=Z+T?wzU3JOrs$2EQ`{4s;$p_WzG4hAi0d+t=qFm+5 zofsvno`9G72}XWOJ*^I@7u7N4Im&UIkP~+jj-E|Y-KXxuOz&4;!1}(Zh7m_lV*p3lnP$n99oPT7qZ@AGm%*290y zm%mj@;m_ZpR;Ufo$AEf;>{O?yQ{)5cG<6#0dxkngKBUf87hu*Gsf*JqhGKB-=% zE|*WKE7TQouewrQDWBFdhVQ-#bKC(rDs`{A7cr#*E*7Hhmfy&4<)HjdUXYiRLWB@f zQA7wym4XM$s2QqP&4do;sJYOP!nzK%kV2|K3SYvQUx6$l>fa!X7-aEHJgH@oq%2aD zMK5KsgtAzw=b{z>hl|u=#3Rdqt&M6E;*rhjbaf`8k_*)~#3Qd(uR%2OI`un@>IB!N zQG@R{;`_Of^ox0Y?Y>Qp)C*Q^p6hJIJ7RcbY2uMN=hAoO~+I#*o` zZC1-9`vh!9hgR>os@oAD6@h6RXAHC8!+O4oQ<=su!d7%4X;N=d6irvm%@VH zDX*4y%X?r+JLSW`*`4xHT>B^a7x_E+6pr@+9rpo!_sbXM1M+40hI~Z6CI2D+EZ@iR zS^1$nCI2cvm4bXlo|Te(4YL{GepU$4M;qpqhBZ3UDKmhmZp<&Fe~$y}?Z=Uj`Iu`2 zHo8cnoN-iE<7mfh*Gf!I!0h9)Q8wZFDOf{7w%`cKIXIG7#Ve5^oQorYwVjVKFMyr5 zVU?F))a~*r)R$wm?eYe!HY?ZS=pbu!%9~;TIkJJG9ztM*!x&NPBT9|Lnx4{NkFa#82sk844vCUOqU4Y$blDF3&LRqTREO#SN}yX@?*g~9 zgIl_Br3VZXRkOe_2{KHA43i+kL?OAaQn%|V(+!mA5M>(0DmrnV!x83hmxdtY8948T ze20jFC?z{Y$qrGnr$Vypajs=L1etC@n{yz?A<8jIISx^dG0HJcImRi+1m&2b98aSh z+bGA)z|Fg)S8m0z9ccP6&Od@<2GP_jAH%U-J}&p5z86OiFtr=!p9h{Ukq70QX!9_R zOJoGccG-iY7btrKSNoBhNQQK)7QL_1o>S}ehtOlp=kgfFp=c{YfHF5!>fNSLKA!!7dR*qHAHfgw(X%XtXW1)x#05W*<%~*Jz{@-( zmm)@ZTGr85%%Yt~=`m)}+K1Hd;Ip>tC_-k!7aapfc*>KsqyJg<8u(KsYqfup4tki3 z_EXa7EQFU{ssCpIjve9HQH~ws*l~{C#fO-*ssGLLrx0bFN_{H zlY7$So({5(BCjZN$qe#`B6BEmhC|K>kuyT%j4(MPLe9vLGos{-PI5+^Y!N40w3993 zWQZ8KAxCbAlN)kmg*aIuMw37qUv}r|aR&ek>;O4$OljG4zPm`mk>7=L05fNc}njAe% zj_3%{)8y!Bazsj)o+d}Ugz0H=L`{UKX(MXdh?*{udgy7A^fcYXS35mTFHx2y%2GsGN5ID@ z`j{NOOO75TM_-a7?!xpXIifF2^tBOpQF@LXeMXMnB1a5Hh`})ZM2<)d5s7W|6FK6s zjd)bVW0+ncM^q+=${wOJK~(mT{kw_H9%3^=Z1xbF31TxrY^I3K9%8eH*z6&*CyCGm zIlY@W&5+Z($>T|4HbDmOC4+YpzdhvcUb1#Ku^c9r!{oReIj$S{It{vfC$#%691b;# z+zUq(G3Wbmemf4usMMj3L)38;8vaM%;N#G46x#g^(DPYDpi%i8ju^DP8|PZzap?OS z=;xa_9O!%m=UU%U>N`n&r>O5R^!)=M?}s?j@)&gAM%_oL`wVs8PTgn7Fj*krSD4Q} z(fr-7`ccoP4z%O5Gy)(AH612QNYGQzvm!#zl(DM4I zi6k{KKuu(+i9TB1EJ}YZrN4mE@1pblvW_lC+)yT2GQuQwO!!Ni8O+#V%?w zM0*-w)YMNc4lrtp(zXVu(JXB%NxiP2h4sjJV47^%c!ZJn(m|hT4-3XTLGP8K4W(&A zIoeQ~Hq=2IO4EjNw4oersFOBiqM$VG#zaABT1)5LX-xb7sb zbHs9nSWXkaIpWmBJXxY3Oa15gKM^@H)9S?RB4`abl)XdQJCtaMvNZl7L}`U6r%+(^ zj?LOlE?!%i!@enzGgFRI8%buzG0G*yTsT4Lq$r&r3X{x* zLzGmQddri~2g&Ch)M1`{K8t+5f_y$mybh4hJIUvR)N`JEK1gln$>%-f^ImE`Pc-+D z&li)=2g&Cqf*&NGcaqNsiTHIyNOTh`+C(;rI$l-(J z@Ds`5#x@3syChj{B{_U9xotkV?NoBx>Hvo?Ah-1gID8H{yqz4rksRL54B{j*c{iDS zEt&iTGWkX_`AlZMtH|d|$>+<+=iTJ<<>d2jGWjNQ_%d2Xk{rH_HatKMpFs{^L=N9T z4xdL3KZP8gC5N|@!4I^l&aYu(EEV1Ez{_=w$b)7T(QY$qjrBvuQYqSDfaG zBV6$euGsL+46ZoF6?byQNv=4~6=%8P4z9SH=udIoajrW-Om}hhom_o8QET@47pMgo zZy~JHVefJF9hOIhS7;~C_fEIDU6<(;IwGnDs2GR%B3OqL8& zMV^-30W?j%2S(8?2JhCW(( zikuK98}#URDEb#&{8zf#4)ibO!u&UPIy$J?M3gp>rcF4s38TR*H5j)V)HY%E;&Zf# zFl{0eu!#&cn4s?3s5KMqcT!U^>ZOBvNm2_b%DgRL0UdnLq-PMa+@nWw*gDL6hS!=I zt-96-R~s__KO_GwlHT2`y@fJ6Kq2ZO%pIVp|1Rpg7)fg&LJfoij1r~>B9wi^juobj zB`DiCMv3URt-O=q|9%*w#G{;%o=+EXpy*4YoJ)+eh!G7T`VTXgNB|9K&LzgVggKWO z=aS}J(!_yda6ms1r)-kMfue*`{|8s0tdV%yz1MwAl~o)E@bCAzFCZ$JVkwf|tgOt6 ztjx+t%+wSUiAc#TUPRE#g#Z!X(DEgG3q?axv*ucBt~u5kYpgX#%~^9)WJavDW@YA_ zW3IV!F8kf@J=JV&{c%@+oX_vv^BnH;JLfsixd#wH5|8#thi~$ftX!lNEvpJ+e7K+{ zf_3oQRb0A+{ucV-YK+9Kn1~t3Ljl5Ais!KvN#LZZIU$U8J!xeKuETA}L>8VvA<9vQ zwRln2li^tzitBMZ#$ys@Vh)NB!7{sBqy0@nX8yw=WIvRX8$#8L%={2`&YYDMLR-$P znIUxNW?K7&+?*L9rn&F)p)amLDsDhJ9>SxTi(*t@Io4yF>*2=$48thgfqO9-vyhJk zsKg3vz;@RofGd%P8!;C5;bCOsNtEDOti%gway^0=h-+{Y?!^6=g4vjdg{ZA8 zk$^!Mj+=28CSWRZ@Dxf>je2avPS+z5DHvh%bT=NrG(3j+C_@caV-sF-J^ElULbwIv zkby^#i>I*&ORxr;(d>F8;VN830P8$=Brp*(%%Qd$L0wk)86G z?5SQ-SsnaVo|I?gIr)qHEoy>aCdmQvDw$Sevym`T-Xw36cgg$YL^(xf$s9RH&bM9D zv%>!%($xmXZE~FYZ1){t`{(~tqwRn3nk4(kL>Z8N>61a3Ap6Jdz_=Y0w^zq)-?$wT zxBcQaB`#C-+dRe22y^VWx75xNb@uz*U}udMyoNW?ig$4cAEOIBIDykRhYR##Z>+Z{ zwzj;ZT3sGK#Buj7f9v8mE`IG|kBi+d{?Y%Ki(M|BckyQz&$-y^;#n8ZxI3T5#n@`6 zKX!!!TugWE*)A5l_9how+*nS!v0MOsu^nlsYdHna`^7u!+UT9JTC{)EBlf1z>yYos zHrZ-=UMB`|C{sC%vzX1<%;96q<>Sob6P&}j%;%Gw$EP@7b7<#I@35WN=pC|i8NGHp zebIaW(kb(xwfHQ)8*RZ~`9<$X@2x*uqCKN~fW7-(U%P>(M1YxRQk|Vlfx6gbP{9 zGA`m`9%Uy#;ivqJUHshoHCVq|E@d5;aXD9TC0DVYt9guH@HoF@H@~7iL9bT#@NDjr z@q^u^5wGG$`~0e1%h$Dlt<4lWfsVAizgLfDoK)P8@2qDdY*wx9Cv(5uc{Kb?<24-4 z5%wwVvQMctCpmWR{s13oF4g{TGs-o5j?Z%~*Ks{J@C7z-BllfClE00g-VobQ$J!}A z!%m`kcFvF3se6N+nD^lT+R%>o(SgJEE_B*DJ#K5+voq=*c=n9b5MY=)xykNZYxQ!z z#Lbq$QmaSU%q^Bnoz*M2i(4(LWmd0b3tzPSmRtQ{nU6hI`p$KSShix&`PP5GAoO$EVeB3Y|q;DPxBI8 z$@VPlt@iqRv0ce#-5aJ~kl8j99XO(0w->+C$C12_qj)oK;TYb^+j%F)aRMJ;1}8F; zS<&yY)wWpQL$=9%YTd*gdRu8(Y>ZvEbH8V~)!Im4Pp8M;0uR2}-`n%Cx5A#$=azZ2 zZ=*8mWsr%qwQkSqkL;p(srBEovm7?t)7WY=-)OVE-DY$L+b&-Te_QXK-LpCR|B8*j z*NrWfaldHpv1=L|e+SL;lUI1!V_;@7V%o#N%D}XNGM8)3o;|j_=k69_nW+!T!$#UViBW_T%gr?A z1?IAVrL0jY#VJ`Ss-_IpQA0IX2X$3n4bgDDph+g#>@Wq6>qIzFPOOveOm^lvd2W=O z}$606N4lPq$X&mvZ^UXe+Y>}l*7`4jDz@LL zq*2>?u?`JrNHf~gkxq2uHtyse?qvu=c~I*#TkB1fR+|(aVI2jNce-(J#g^RZWedsH($}8Zy3mT3?rZ6jG&N*Il@DPxRuYigD)eXgztN_wsbI>RI8G~(6Dp?|#ab%GtE{3`f%7sd&9D5%?;Ph3PEkZLXE@6_ zIdT=QFiWurl~I)CMtMt)it^-Fz)~&Ea;>_hNQP>vmgPv6nyQJKS<1CiYqeB+b+NQd zw|PpnxoT^Z)zOlsjk49*lBbbca8gwn%t7wsTL$qx4{%tUwMpBxL)%P*DXqEsQ$;$X zbGo35`b)(+tMfXpd>z$Ke*;7NDL{DIV_;-pU;yH?*EIR#`E9;3Ff+dZiZEPWdcqGz z|4aP$lf{ksJdn%GzyuNn0C+zQ{s4H|V_;-pVBYlaCj$dZ@xR3XSuAc0KoMlXqy+$= zwFYDW004N}t(9MhlvNnUpL5Q{{+--*c4nM#M`w4{U8bqlad%yY9A+!DF2q8rrS>AV zTmwOj3SH1bqHYR;3YLsm5W0$Bql<0~!yAn-X)80KU@xLj2r9%Vr{DR$Z`^Gr885o{ z@tp6x@A?0{Gv;?q*<*4ygWE6JDOKz@$~ADB{!2<-*KV{KEvmTNlv|FSrT>&Nrc)Id zHJ#OOVUhMG^fLTGyI{x3-9s*z#X7DiTO_^;tjl}Qd3^xZhz8>dhAZd@8j<4No(L=9AJMpfx8%J$#T914rq-np+BGp(fgZY zwkp}MPKEim$mxpifKo{HA}rD_pjXjW$ePybZ#GVTyq2eNvop{!)1tWBL9B8E9%ij3 zxUZx0hO9BWRf_0_F>?-|)nPNlUs6}V+mQlm7Mqgf9j!X*;e5A%tH)eWemT@u(oHO3 z3(N2|_yE46{>=AF*pv7qswej~Z$t>tQzZKAsDF9n`J&=wnKIToLu2 zJE#qIp4<;%fxKG&$C4}4car%|L^ZI0Ulz0~tk>#dP?x6^kF6%YU$@&&neT$S1CKvW z%ko+eH|SMA_g8ZG$88VCnP1V({H}e0{-t)8QZe#D4&tGYtLFo+;%k>DuZ1{mJIeTT z>I=@m9xy+5yha}=*6`0dQ`eIM^Q zKx{~9ceYF z!}cq*GlY9h2Rg*N4r!w~q`bZ)H%%X7Z7bvVXan?^QH?;4DWXL@_%r@{8P8rtb1Hkx zu86bDUn8}I{=_G~epbU;?r;}p`h>p8$g7jQ`2_n8?>7l)XooCVntL>LL?c!P<9gP`dWMRDB3c$h9Zot%&#F63oFF z;?ogbu+b!VgXiD~#3J3N9(|7b*hlan-{;Y_FoR#F)&CDC5l8m`00000Pyhld004N} zeUME~0znXkzZNtQf1(>##LNM7G8jP0N&!{g;vt}+GFL=DH>igUkO6Hk;GAWM?xuDO0F#&H{n?zKpi#qBCw2A4;doABk^|A5| zS5k69)w`sMz?(C&Rid0I=lXW#Y^tBC&g|4Z= z?)+OlwP%jh%k-DQuZf2oNr~+Je$;`SW6rHVpY90RQ8aYxSa(gVrzbVlHv7!g^$e+ z!XOZY?|llwU1z#4S~9|OFy7U)VkITu zTCa_J)HH@}ccG0e1VT_+1@#-11t9{a0B-h((KT&7GW5=ecMt5<4J?yvtd@KtOaS~F zX7^~UzFjvcVNM~)%@ur6`7|mUK_1WhLs^{!U*%fH=eA`i|1M1r@mwW8MaEHOyPA(0 diff --git a/public/fonts/GilroyBold/font.woff2 b/public/fonts/GilroyBold/font.woff2 deleted file mode 100755 index fb9e3346e41324b388bb9afdd2420bec20771931..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31016 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 Xabzq0)chPFRYv|Yr87%!tM^WSP zGy1Ojgymrg;Spg9=HYH4X2D-<3WZVNO@LEBL<*%m$~eEvlT>gw`h~d*V#+%=Dk%7q zv5n6{|I~vPguCGUW?r9bsUq%YKf)e53p`Lk4-B{~;bt|sMu35v!pBg>meRT0*D#Vm zAy9QRm#*3pNZ@+=g}Ht)6=yaoD9j^{jn6{CR1exd0pC-^jZn{0DNKZHf|EE*!}}yN zCMR^I4(;DKfipP&@e1t0ZtM$m{6gN2MjEiH<@)v0&E4IdYy5nJ)&wY`=XZqyYN3z5?yed{aCce(XR~P_?e8ZxSqfy4$|O0+0B(U96WVKr*bxZoh?80oR0MMUA1Px z!l0JxvN#~&93KHMz;M{HMZ(NuIE8vi_%Uqy*;9HX?DH0I3(Ohx5PlKBY=(qo|A8GT z(gUGmwDgMv<}-u>Xx>a=-fJ*G3ZyuK0q3E=6B;lDQ(mC~{1wn!ObEFL1~8nu|J!fv zGthvBP>%_USis0(39b0+g6e@0sAZ*lg@S4uwij%%kpnGQl3#9}yZ%2NP{T8H7&GxB z`(PO?{mF%jrmBnj{;JU6pw;2agB2{mO++kU*36571XBrcYARCb;?V(p&U%nCZlE=0 zap3CMX|qEwN${>79D#cPE@0~0JFZj_3)ltNLuY|ID(H^O?n;=W2GXToU*fcV@-EecdaP>c|M_&wy?dRjXU`5=FvH zQyA;;5-vQ-5@x|B*y<@g5@4#gfZJd;?DG(Q5uj*>gk}F>4k^+D z0pdnWzesRwhA<#OgO7mcV7PHf@CoRmUflt9dB_5}Th3unO#_7`={JA2)~dCjyn z1M?%#__`GkPyWeQEB&rUwhXjP>up}q_jCsl!0yU#Q9m zR}APCg<9P;+#4utt`J6FDU`X%=(QT1bx6V7AIM+N&b(@pQRpQrKZ!|LqFt zUQM9YiMZmT1dDMay<)cAb^-srD2dn#jzu@m07h?;!k&z!Oygav4*zP27+i%ul!bz| z8p??n55L+SX#BPa+L^Zh!b9nDc2jhb+*o*|>GDJALizsAoibSS=&*l*Kfd=+Selv_ z@`a2e_)}k0amAs4LC#AwI6 zZODFO6UAJ#29vjTXoA*|%aKp-A(%FHP~iN)E*hL+iVmhUf^#3($yI_M+C`%?PSN3% zMs)5&JK67P9mdi=uxspC(cowG^)_13J$?(p+-}%G8G^NnocQyE_}2Os0>m(D*al`n z8{4@{f-YFHOA@mnfbHBV+$G2F6hutsIJ+hCbEhCLI&FiZ)nHHw)9%LuP?UV*N>FMM;r>#2S;qmj92{nVq>q( zBkA!Q!-I9fhr`PfIQk9n{>@aQIJbT|N4 zX?0;qV}Xoze0b5OBjq}vDy87SH?1$qPSB;SPm9Qv#U_>xYv}UKgp8H?x#1@VHz*K& z8Z`oz+<%6)V8^kl(^*b~@^DoQnfaNmqQmf8_G^?Z8F<=iM_eS``r~Tf}Y-3OsTZ<07-r@G*|kjz;SNE(kB>E?T*H^$}Zq zj|V<=sJR#n=U_k!7GUklegD@tSI!)4`NUSNgx4n|JkTS6^b*!S#5eT7sqcl%U2F zJh=SrBp!V{zz1DH0#_J+569Q?`Ck(ld)JW@3)ozLp@4Nj5QX>c>(H!GhM9cJw&K)- z(O}uDjs3;9-R)b;!TD2o6n2dB#}PVw|L=%5aq{kc`*!cs;~d`a>-dI`&*QLp+B%nk zg)lPDa>~`mJiPbaqkgc`p$a!>O;Opod>IY=l9KGBRXT7|6$%Fa%-X^Y@w&uM(pTik zVgXwQ(R9^@*o1KX!kCkTISS0ZjR9Q#p8R~>F$lPYbNGQn4Q*HSEw#yEhZW#^$Y7lJ z1!p~up5%a2vJ`*sOI+TbygXgb;+Z`>PCxd<4(#=>ZeRJWRuKzWC%ZW)@c2%}xQJ+U zjK@)09FNv8jGKm+HZ2a@6nMlI-{aw()Zbeh!RZMMXu%b%QRK@1I&`W1@a0cz#R9l- zLc%RQ0?02R=rIPJ<=~#hbM9P;uv~HB!~)m}wiHG~9B44^iUdM0c^dC^Ra%UiOE`KC z+Oit3<;4Pa)41eE0Y_mzj)MF$36|qif;vxdk3e@1a7R~=!4=%^p?e#+-$flK=CD0% zBE=an9W^)|r=td@;|$Qi44A=*IbG0lQ(DTRSTc1VKr6IDE3k5(1{&0$1~reSffZPR z6iaH*e-LQEQ31)e; z=Xfjcb3@93r))O`C)A)5PS=@mvYdYWLBp#b zsVi?vyP=s4r@*gx+FTAJ$DGz~To}K{y%G7YY02@Ze~_*{UR`$ZRhT6zm_-l&RJ-R< zG+2K0psE&h)629;Ng11*P9lHSH7X6?wG_+QO17A0`ey8QYDfO8At4@he+Fxdub1t4 z6$bqB7d5q@vlO%2D)Uxp8W_M~Kw$?j!WN@}y`sN@B|#G|_(M{&e8CYveWze(bn9NA zOhlgi&2{`p63+Ex_vt&O7tv1^b}MQrennvdXg~ul9VfS}Ymo7Y>Pc3g%ILnXgJLYD z!QtN(MJw=>d6L$Ul7(}1I3BG~#PPBS+u03PNarn$j99I-tzOzZPj5fdZ_Jq6et%rM z(A?IlM6_OryrzG1yYJ6GXZATLIEY(l!rGFms$(TJRpo0FN|l6+w6#fkcwm#1cC02t zsVOZ#R;8~wmYI~aHZwsHk>VN);8UMB7lYwByQtlNrR%_nY)g2L$9F26BeT#jUcI2* zwkRlP^-)W)uN%V#1><4Je|s3{KU(!GPTWz0VU%qFYka~%Bn;wmxJKYISgUK$oP!X& zkBRt(h<`z$4UFKR!q`Mm%VFAEc`VE(=!@2`Iq@VrTO##I*JNlx`gRFWh~aZeDtA=r zf9fb~u2hnX>Nj-gFM);=55Nv%1PxiUEh|Prfv+#D|E6I#nC!md{T*6amPCggSf$4? z(+sFb;kFAX@Bxf~;jj}jaSYg_n^LU4q08gyF8*SJxY}e^*rD6>X8&J2vr|Wwo^>WwrIi>G6qKsj-R( zRz_RqK(PzDunW5g`tYy~wh=WJD2w4?D{dv?O_;-s6s^#Tz#xZ1IP`cj48ah=K_0BY ziZCx;g!L@gC{y&|VEa8mO-E~%&f)fZ0{C#y1zkkE$+Fm6ii123!O-N%FoZ({2RX1p zE5f{(7bk)h`vA647K2oc<#8KqBk03J7j{7xbP@33#hdIItD#dK;}HH%;4zOHv?8h( z^Ws4RRs^4LBCI#=WUf?A=U_W*C+Ndr7iO+R;1E)mu${1UPQ1yUfq~)>3=w$3q2w1w z^-{e!(4ZB8$2<(-??hzZ8oxH0Q}p5>4&#Y>oP#)sC+NjtF_u6v78A>>T^z&_R>5Hm z#@RnpPz=RH>}J0(7YbfH7DEY^UbY5Z+)QydmQ_48%7Cw&Hy10`s54{AW0yh!D$0Ge$86U2!UgVH`}y@sQTtRdBFX zspU6@f0O~mI6BAop&mog2^3fgf#3jRU?KRz`>4Y?I4m+~W#p!c76mrhW%5Pqk`Kh| z-2?q5Ot|d#sHysJ`7tHrhZCt+^^dRL07saC?}8t$Rko;eXlzDVV^e8qeO*aLRCH!~ zoFcw4+BH(Q7v(38oc^}M7A<@7R&R^RNwP&}m`;*wvdWuvEj5+x9W}{8-^(EMk{8ia zPmj~%$PcFDu+Rf>N0Jrqi0D}!I;3yBV9bB76xDUeKg}cfDZEd;V;j!Z9IR_BR(9{* zy?3_^E;yZR%1qfFuNPk!%?kzfT@Hu2xZp4po;$-ZMNI;YvFy&yuJB?y+Xr>@ zxkrn4r98Jh;Aorfc<~Q)&6R7zkIH{tAP?haHci!!bzO!gk>4c$kfp??t&Lo%bG{Yv z-(>mcl$+VBbxCVK2@Q@vdOll5egT*Mu7$xW@T$D2B9OE#?gR(XDoTuNM6J5P_MlP1~O4Nd}6MTB&w z7{h3r&?+cz=k1eVBGb|Sg{Qn^9H(-BgIPV-g=PeJ&IjHn)yIz3pVHx?5?aNT9p0At z$;O;?C5aQAVNIccKFiOd!)0(d%Ypwn8tlF57Fmj67r>NjpF{Gw_L~GvFF+VC;!Fr< z>*}OGEt(|}f9l4tLE)eAg%bYM4Q~bo##IUbj<*2HxI)Q|`LiqZl%OsG$`*kQC%Q3z zwuplDDFFj;6k5Y5)B^=Q*nlt?o$&6fwi{QK{a^3; zdW$}e%iHzY&Rt62%9-&7{g~Ou&#zQ=effEQfeu#i`}6bn%j`U7Z8(JDIB>^I1u{^k zxPs5!wJTRvKj6rZfBt?2R`3P;^7Frx&!6c({!st0KY7_1C4c9>U3of@B^vLtck3jT zK;K*mHemv7mT)3gQRoH@c5`Ab+%FWyakv~G5Ky>R5bz2E2q>J06)uA493qI>>{6m2 zVgb7}M-tV^taG6tW*13lC=zh-g{xl%5uI6WgdpM{?7Xia;*ad|_mYU>Khg9xmy2QB zg2Gl0bV{j?f+Kq z?6DfguF~>%pKEf9sAytm;%u_nB;VvalS-3XlOIifF?nM0%;XPKJJWd6B-5RyUznDd z)|uWieQf%|6wP=uPcvV$MP|#)!p%0Am6@G4>o)t<>`$|Q%z1Mw^F;Fv=9|s8n;$f< zG_N;rGe2v7+x!pne=Y1Rk}R?q+gS!X%+9eKmdEb0r|cd3%)T>={om$g^RX4R6}JW1TH4}my=;SRqio}B zGi{4)+iZJn8MY&~JlieXecKD$8{2=j|7o6@)Rb0U3(`WhmRf|?Q*&y=wK3W(ZKbwZ z+oK)Qj%#PMZ0%p|vUXj&t=-oiYVWj9+IJ1O7uUEC_vfW}RUXD0@)o>3@5sAx2T$UC z`9MC3kLOePOg@h<=F9o&vi$w+j4Q{DQn{o&ckSHia`oHgboTA*bnfcsGKFl;n=2FS zK}xn`$5T7+Xlloj#nFbvvBWQAQ1be@9mn^Xomt)Pv9;^>-jy-jK+m?M_K~LvzfK?g z49i;(ZdwBwu5%ZXwIlATto;0(sJe9`qH3G^(Ui{H8{09U4u^o7=e8fs<|2W^pYHJ` zR1;njG%SzRir3{okwINiFsZl_{f8wE?{06=Y5S#7=B&^1;_BnBtM+r}`Zu}2Wfev0 z@4prQ+5YS88TiAzK5(NhWEo{0E3Sm>s<0Ss$Hk4OUYY z1l0@Wo=LLQYsh?!nFI>GP}WSM%MBd8FOnME)V&)-kgamE?)W7x4(=)OZ6PEE(K@II z6sAHxYM)y*s9lHf`sX7bPcuT%_nv~n(1Wbluz1V1Kuq%8yK&v_JsU^%>OE{!?>@uU z?lE*3st%d{KdGjUo^?5RA`|TuRuG8_Dj)}j<%CSQTBdnR3WZ=YK}u2P^9sT=MKK{+vi599*&$W?0U)H!pfnGa#vrip7uEgu>H zUU`E~#%6Tc5U}?riKP9jk@;iB%pEhFqeo7)R|#e+dXj9q^9`B4Zo{k%_6;0=L!f++ zm37xxN^9XF;@mXk(CI)ODo_l9G?KzgLjDA<%LYmm%&5$Tyaxt>KpK{(j`}_agFqmy zlBa}pH(+?yYCuXll+}=mxYn_GOS#Cj+FLVA@w+)uwQEO2)i-qvbg#j3)*6DGVp;bZ z47Ao{aseyg4Z#`|r{X^Z{+Z7qpTT_0CjumFV$Y7d{>>JUR=#)_GiqT ze%JucmL?=EOt!aCP)R`G*rZW#(2d3)%nGx=UYDFR4|!AcBbF>FLLhC#O3EZUlEE*BRO`bb(gu z4bWJl8A)@`1qylR)afgWd5bgMZkghN>-_!afl#c}ca#S1aVVJagNo@*u<(shN=PhB z(W@sHH66~jkqP^RtfwY&(a+ja5HV4SmGItLzKvhs;I+P*p#z@JD916p#}Iy*+YQ%* zI05k(3N+Hz2s*I{ zIJYZ^#kbfSkw7qozhNZ&jU$O}$I7d?7^(2BHx`1_ER}OuoPs%0jJKxOHEZEE8EKd8 zLn0aGfAGaA_&lzT5@lF*^f7gqRWNxY$C4Bs_!y(%G5L&^bSSGkh3pcY12o?2N&N zm9vNn!XhCWo&X4|O*QY4mO17M`XZ+N$JxnMJ zJ;C3-6#b#8I}a4xW-DB~mmIL4+&!edDQ@%8cRMb$dEI^?QBd&22=v6~#{hhK^Vy`S ze9t~Z+~JrAiv}niYhb(>r`ou)hALU7i+XUs3$JVH2RRHZi%onpxDNhIzok&Q^U$$D z2{ar^EaHolDKg>PbKbbiz~~fHY+E^I_^|O~28zqwPd8}PwOdP(rqB@kI2G{!&i{8;j3voCmGBPe&$d+9P z3p9R52&h@0=W=XgQ^v5h;A)D_k;nWPfADXjfYE;5yo&nC^7JWHUY0-6>K_Qh7P z2pYhgOpc`l!D0e~sUTRILVcWrEpZWn(iEx)JPM=07^6VK2nMZj1QC<3U4n9f0uy1; zI4)efcDh`BcR8K?`Z}FE`?*XZ@o-5vOvM=m4h)4*bciz?9T1A4;1Dp)TK=44kussk z2bqn9RXTwS>h9|cg{@#H><%V6`hp!L+R+aS}3*_P`r$xP`c z-DD;m%W_M4pKT~7C6;_3N1D1M^&VZwPoQP~e&U3pGx;)6a?TsDWKmeR>H?_?KINps zBU`FTJ`9l3N6~=JkD61VB_}*OddDX@=M7l6D5_g^f!Ke}t+VHq{T$vE(nI3s%R~AkR7c8Q^JNEB9R7A52XJh1WN0&J3(1LmEW-Yptr8NteE?Yb; zUnV;oQgU5vzV4E&<9d=CoT8Mp@JN>NSCZ{KmI}ueDOLmnKnVZcD8R7M1E&WF$BrKpV0JiuY=Gs_z$n1xC>$MN z2cR`9SSUjh&>9wOlp_Ub4GRt`kOuVl&MqpExwD5VWba&rYUILV)I9Qp(AkGVfZ7FX zH>}0YU$_qs;2FGuPw)eNLZRpX1L+}YKkbBb&y)gqFcC_yE^H1v!rpKw9DmPeo^i~% zr^&@|HQWq$!^7|tyZ}DD51&Tg09EunM70e9rxI`U!@Pr=R>y1SP7K0G%)sW@75nBX z6zu+}odwZ_J@Njajfea&{KRo*PMGTK+&N*jDbG#)VU-t3ozt)E%xs^2W6#z-FU`EV zQIE?Sk6LZk@*(S=j}CM+Zhw7`zmx+o6(y{R^|2|o#*Ww>`{H06iQ^#%sD2-{{6v$j zjzv8E6nJpfUpJOTZ{%;h5*`i&7}79h%78WYvy}=R*h|A+rqryenX>tN+%hV7SXYHU zedaXOVAWlvX+KYCcrz7$#hB&1&R7iB;C48e?N$fY0jA8k*qYxkXUHZO0@RB7XpUgU z+zeB=>8SuId$#~{woqh0Q-IBwM={-Ji#5iokECU;=m;k4N7XQ4l6$G2C}o`^9j_^a zVXQODLz#{E?v%61tjtVa)G=_n9RE1i?>O*^InSIU`Elfj0a8gzm$^2Lq?@qCSlsv`&Td|lh->%W@2^2z|ruvY2 zjf-EkX5b7eLyAXg*!ZZUAOT83H>)_kNIX|_N=4)OjiUkOsXp9h)rj1zt93Dl%+XLI zh#}-$F7Za-yB0QX;^BNSQ!`*l#fpyeA^6v!6qcIBxq)?)2t!8BGL;p^Oy+8Au!H;w z!^T~>bD5M=akQ#ej;%=2*WH8<@~HmKgq0x&%htlpl5W>amz!lwN_kM`1i6TaL(904 z-5|ebl~o%4&WHxyGvDgOSLeg*kg3cTKh|kbFJ_JDH7e$u4G}U-5{>0G37-U9Hkj!+ zQE$(XNHG`x-n3U6%TZKp^62_&4EY&nb1~;J;3<3shA#5AjOBO=)ixTodhpD6NSfF* z(_|XF7I<911vD&=ZVg&|hGKNgaD6n`9{ZxewXtDm z&9%z$L?R%W9^1_79|Apouf|lE=)7R4k8-7Gjq-{(I4-B93UjJc2QQ?I1m>Jl&YEP- zzx$vj<@n`ckbdbwE&8fCM^cTkIoYY;N>;Nzp{ue_w?j6S*-eP7i!LBfFl7I5n^Yx2 zTNKbA(J4dvRQx_5-Mlh6>6|NiXC$zX7Op_pDW>AR@YsZl6X8ZN!y8)%TyXX>eOB1Z zdm`4w`?R1MiXt{QwU!Y>+Pj(0AXC{Z(u$I#P92fKMBIR94GHq*oXy`Z87)u+6uFYm z5NM~C!G*Js({M>4)h%k9rcG6&$=%7$;;F?i6%cc4i|jDEc}s_!thMr!a3ZJpz9y8y zph)Lnj}5JKAHB34KT1Q>J&CSndQnOX2Zai814IeQc~U828=g{TIIfriAjOR+Md6UL zgnY{LE_v!iHO6YIbw`2SXJc7%$sPj@89jkX-40~)En+GF-Q4a$n3WhIy@k5%JZi;Lo-x{(^DGG*Q@ zUQ%;%`AAwFvXVWo>EgJ`Ba?g{9F5TAatr%k#H=9+vYzyh;)On`OCzE07VfM!8wT{46Gg_CR;! z<(*7Y@nbsDC+Z2V^SdOuZc2#r!dp#MHg7au$wTR{6HNKffYIspCkdKKAn^1M{h_<| zh6BUJ@#AtnSeO*i4MRymg#@)2Z(U|tPs(Q+J&JJqp^ZM*zJ|zW*9Z%WH${{nkXRhY* ze^Qw4kn?${U;I%1OK)JdMvIK3oNP`8tDB05D?WszNL1mxy(;UrrTYnlpI-E1LOhUv zy$l^OR|AXw2aIS8I&5oeP_osay~(`F3213_PGXLUwQ8D|BQ*%DkTe-`#ZH6#s?^B^ zWBX&3)ho$0GB$NY6@3YcVG+f?voIVK$1^Uuj~+gyY}?I1Df8JQa)rhat4*Q)x;QR9 za4f|osUs&G#z1!jfPgG0-HuZec|hJ_p<*yh@T7KWa^>D(`54owx5=1_@0vqxf|s)M zima7Rs-#gzVcWs2%RxziCz$mBbyR`+u2(9Y$eRsmHmV;wV_(w%6FnFAyg6Z&4yd=7 z--%u4Y9}y(?Fp|JVr88w6S=py{A$f^tSb6^$8Y3F1UTClEPN?)1JYY!q~wfhj{cW7 zsAX5ol;G>w%Sf6KDGxHq3^mA=qlxP`V%W}@MeTI#l56w61R1nXqgQTb%=BiSj&5wFRnWurLpPcj$$3fT81*yR$ge<~Wo_j2e6W*56@qs37F>tm zAf{ePmiF2pusdki&s3C`3;i%F^UathCzcow*(<#V^5&PL!83|@$~HMeP>00hnX;>g z=0M^kMWiNW=hfdio66yqHo}~#P&Yad4qOY>R#ZK&=#<9xvyjOg%~UM&dxlILdj5Uh zLaBzD=kxsLy%dBp1K$-p>l|Y+V|dKj$IQKDQv%z2|{t9yP~(h&?wI1};` zcCKMR8}$8ie$@l!umVnfqZ;!YQJo7!bN;!!nTz=oV}8bZ$HsJWl4WL_x@@Nw11~W; zxyJXVk4zx($9^6Av!2XPHjgwH`rDD=(=+_)Vrt%FOnuKoz^_3D{9Tfe-^ARj_7x)x zW~B6_xixr7sr52jCBmE;ZAf?thlIGGMK#BHXqj@VF}t7596FxQJkw?@>luqKb3*N< z=WH2Wr$Q2()pSO>4o%wia6CnWGSq`XB7;9nZ-LH}wQfvSjkf|ks{~q_YzJ6}_=XmZ zIYDlh=2@M-BWL&%5LIuSF&_nw5=R&XD0RyI*c$;WF{d1t>rcj6s*Y=7UJR7~EIZ{C ztx_7Ab%CZ-*~ETJnItQvJ83FUPgLzfsQet`BscMTcwVUJ*;qui=&ssmfVA1TD7k(# z_#X3_woMyuEriunOGgH9hCRbs9n)W%z8u|HOM%G=uX_072=A(t3v5xKMU5jOj7p$g-ca~R9g_TCg`(wVmFJN$i?R~+;X6_5vK?k6?!JN;uM+Yf@>Kt072_a ziuAXSo(|Leeu{)(zkI}i_PIbNotrvlD@9fhe^|Hen1FnHFrOb>G!W$6vLQ_yC`UoJ z9tq)>PF`I8p=GQPr3H64b2cuhlN7yDe;6vgB5gj?niMq% z9TUOvF6*Gtb0t;{Glte2gK^$gflE``7J|__&tTM*Z32F8-qGeV=_)tjBeqqF4Fjd) z=7QKfyEBV}nRKgW842b!?vkjO61fC#sF*BqE0<}?4?;dL;HjEP6IY)Nap~HXXi#7P z8F=vFCk2C1!nW8M7vg?=jKwlYww7b%dbw5ZmPh3UbjopI5pp~masn62NzCLF8u|6{ z+Rm(!TZ547^@$2{ngme zV@V9KOh4S6b2*X0NO;F5Q^~0`@&jXuK1%Xq1LvS|rl9~A5@CZz7tzTmMC?<$Jz8-; zP1VTBG$;C(Q%`!MC9-fJ#J6s1qqZO?)1rM-Jq4be+S!zaQ>+f{T&qo8ZA)~Z8%Iid zVq~l<)^%u;L{sCDVCWQ&tx~gUW3{c(Efu~e6Nx#+RL`+PNe5|!ga&050@Iyz(U%%=TD0qrQ$Th}d>iQ^aP!c%7K1QOJ zRvL+qTAj~@EiBa&Go4kd40!7E0JkmTDXz};UDhz24>|ZXC}vFHnS>MN>PQ=#Fd6vV zNcU^q@58|W?25q;J7gfDhm=Gni)<6Gp0{yi@d^_H>3anl$EVc#@+T~Vh zVf5?8vnE>8!?3y5;K$f5w-(*jT49$DUuRW3tvjv#)z2Y2CN&$JQ>lLvwj|KYrU3yL@=S&UxzV*p2KK zcDp(y>xAI}J8#87yU+0ccKJhBVwde-xjlCGCNDSh#?Ce|_TZiYrpEZk+rFwKBS-IG z3uh&GlzTnWfQe>laPr@aYmA?m94=-#60*vagT%&t8d`{ zb3GEuY`z_1q}K29n18BEGh`O?-sW7wfd5FUB!h{^P!l1e6Wma|Oa5?7eaHNiC5a+$@nt9+oOn zu`E-(5?G@oC9_ULHIxndU;ndFXLXiM2(P}-SNdAt=sSI{OS-K4sxmUhSSG}{O&Eqy zJ)%cIkLhuwCv^l%NA&`3y{uR8=rz4Ygx=C;MCy0_M~W&{Nv^StgPIt;Oko+Yf`^Ia zQU0fq{7Pe%vX#Re)l_5Vsi|7BLao)BwQ8%jtWyVdV7)r42OHE&z1gWk6|r0W)SrDC zsDT_%iAp$#!BVM8L1h|;bU+7iBV^JM@tolt=efW|u1Yep0F6q9i0LT?4p6cRR9l@dJ^#U%vte0^M1_*^P@Ils>BO4K~fYOzrOl7Hta@9nw z)JE;pULDm*J=I6W8lXWMtRcF9QSC-gh?qf@YTVQp`hw7*4G>mCIKtI%>R|k~{ZSp| zkN|FohYXSFs}g$n?ouUmJ#D0-6(fIzpNeedsHSSE zw(6*X8mp3n#pom%o!CoK!;blTHd*)W%O;8k0j)I#ZVd3TZL;?iNX*~9B$%C#iBaZvGL=_O&aMq$RGnJS=7c! z9qJHCUFzYYK8*>X39WF_n$Eb%BM*x%bRm>{@`<1;U2#)Dcf#mFA3PLNNH|6GBb@#W zC6Zx`#LFl~5d|@7qnW^DVo1PhL9N9VuHb3~J5N7s7q_^Ble^r-%{}hnH6pl*U_MW(UC1Y> zAvhrjE(n1Ta6=fh1<&H!F@<^fD5snv=Cc7G8`(%4NSny{*veLl*v@{6IKTlCILN~k z@hDGI$TPf*k5_nwLSE%nig=CJ@bNltQOMi8Pjx=v1B&>NPx12^-x1(@ej$Tj`IT1u z#$RM{jFWWX6#o-PC6zSd3>OG;k&86p5|;^bg)4O6DpzUGHEt5*7Pn~1ZSD}{E_ZQq zkNX6vq6()Fgh(=k%94eVEt|G-$bsZkC_#lO42L}O5LCFrX{rcC5LBchamgz$PDLpS zOVNrUs943)MsbQGMDdCzs01a@Og{MtQKAxQtt2JUNXbgZsT8HqMAei^P}NnP*77S2 zp90FHP+7{Ng|d}{Pc>A7eB~;aZmOx;6snHuP^7x5OH0*LeG1h;4e+U<8d0dmYK%`! z)PyuORWs7nT+Q*Rg<8-`E!7gQTB#j{YOnUhtAjdFsE+DLOLbBw3e{PisjfWb;ZqlN zAy)b7N|6dwK!Sn_Ql#$cPABzLPcqd@y{N9<>Wxo*)Q5Z(sxJW*sfZ#KtC&9Or~VXb zfCdxL5Dg(-B`TpvLp2nqN>xfj4cBn$s7z%PXoN=4T_ZJ;9vY=l^wMaJrmMzi4D~fu zW2vEW8b@tCqDP3(6MBM?_Y8v1NV0R~Dobl{W=5WsLC0+><&1=!jj98{1& z4kdd#GieQEX=JV~%!O@vU{VlFD)Z2oEX`Pwv>|v*?9nWY>Ac{|Wf+T{EpVGV2(%R# z2qi-+f#J$Tr9k`KK;VtM5rH@JW*FL}l+q3*L+m*?01(3p_kstA#b}=987Q9RStLBi zbI>7#O?(1(SjG#1Qn1b2kbH;lBPFJw!Lp7kkXBO&Jk@9*3zvZa3Ig;YKpz4q2oOL* zfB*^tCPfLYye$hgx;yqy<@}2_#{S%t&YMtD$FGCZF>!YYw$Fl zg~oGu4x*V~Z1E~yg~n@m4HmEC_2hdU-hgN?+3927g!w5)pm7w(kl;8@K;tA%BE>13 zf^KzZy0>b5{SN zd?zkjhYsu4AmNrAp>NrP=Ki`X?~LqF$o)!Q!7HGd-Do^`FerA*~B#Rx%cVWLB*hv2Tr_y2aQ^V{2rj1ky>W+ejYa zk)ZSJ>%Ff?D!)tabjb~(B2}tb|DqlfcOK(hGG5^IctOyw0Vv)wRpQN}5T*k@F>yr? zRjQ^usI2U?@|q}@Ii*TvocJ}~8a3#|8zCNkJ|)lfh{ zeFFqW+fh3RMg0ifi3l|#b*$bHsZ^v!Q&~At1Kw0rMUav8kYr>Hkxw=9=@I4k@O}mU z!aq>RmP;Z}#>C2H%9QwNlA0Q%p;_Yc;iaC1l$DN7dbbEpa7xzGoZfQ!a370WdBHN2(Onva~GM>1mBy(~0^ztxl^kqBUkwC+PHb zc2C(R!k$QR1N(Nh#_c8YTW7D@LW~pZrp&tfl$+*GIb%}kFm-xxS!#;gw&QR)%G8^U zV%dt?YU+|J`E7->A{tt7VA@qGrKN5nI-yRJY#W{n@^-}^{`}~*AajtCUxd^c_(^3`J z*YZ034&5ka1DaW|Z$C~+%)=D4u06zNv)LSRxb1$QEi8<8<&Bqi@e(dxwk3^fV&%44 zY3)%tZR${ynw8B8rQ+aI9Ar|f(kNavQ;kEsY9?OOq*G^C3U7GDh~t%;P_0EIoi5UN z_d{27OMocSc-2g-lBvNGu`MEr6^clasJ0wg>c~zqKll;?bTUv*1~a6_Uy@mPM9WZJ zMvKmYr6igSqT;4Pk_?_O9wdYWi-i4?GR!p|pj#|ZhU5;}rNA*wv;(JbrZ$ha4=KWk zVV^QW1a~|Qt3h9MTrClm&;}$-@2Lm=E-LneH;X&vL1L~M`~1qZC!pE>I^#Gk)vdvK z7*gr%J!%K4c7IsxbDjH8>vu5fb4+cTusNFJVPe}WZe0^H1+`h{#y$BkF16!)GDQ-L zK;$EwaXo>!K#1iX^=V8UMK~9mE8&uG1ooKGBN8G)BX#Pu)^`up7w&pk^H()HVp$jd zT|Fcapf>I3Mlr(}&n%X(ekN#xl3!-GFI37_yYkJ$h$M+j>d}!N44{lj%w;*7F8w7oUXsb8 zKF#SwPX;oA$;@K~o0mAIyMD858qk8y^kNVrnL;@$sgSZKw7nWRG^8bY^ky)lnEDbw z+m;g7B-n3OgGRKX3w;>EXr{4%)ohi795DaQa%oI!@+qW*F-&J6YuF}nPmTR%HEBW{ zy3&^i7|RS6v6k)f`Ju#is;VmQ8eQx7T5hdBzJ~^Nx>vG5l`w#2FJDzxc~( zl`gtIyL*h&2oW)ioi=RzbY~L3EVVSyOdFjP=rt^!HfG{T=U}Bqn`pYZ7Fl7Pis8;_ z)9TfC?)Q)<9PyGjyyp{N`C<6mv>B79Igk6tS(n|M-9N@<3*{9*Oqo7$#spVDjyf7? zp`AQIee_RB&aU&1|5YEFPG8=*xATnnZ?K5OOO(95B3^`Y3*lh1IJxE_Wi zzG3tA&DS%(*d+P#I*(qvX%8IDWM;F7RsRs{fd_evBfP>p8K{ix+_{p=+?Fxx1!gQ( zEAz$aZH5o{>D&uB{-OV?|D*q{|7HJm`ycx6`s@AG{&Ih@Ki|$iXetxg*-{4D#}B=? z)jO~Cl2#_ILiX&u(EL-!HMfx^;|!Df!(IQwn49MO=~8A4s9d+aTYM6ZSLQwOhL^e{ zw>Rc1Vw5-#xKz)fx(n533~N!`zqvsJG;sJVCHj3@C^8?>0GW5zPm+0!RAk<&`cJMk z&yW+gm*$lpCOozBP*=%3Rm!!B{cjbv3F~nFCLO_;gG8xR!&Rmc8mUnltuY#_apQ>j zcC78MG-ef1nyFcutvQ;jc`Da@Ezm;!pda;Lx?J38*_(HZ19`bFBNixaqv9mYD zyvHYZjNu};WO-0k7DZ*%8m{ZAp|Y~IewzlhjO8%Jyj014%du;;r8F*Iq}9V#G*w<6 zJ5vi!`a!=DdRkV#59!uoqc=M*%Bc_~p4-5)c1vgaq7reKXpPotoz`oEHfobLt3q4! zk_aA8>P0`i*dD6X1ccGA>g~egceRgSYa=YvU={G-5VOYg2fEeXTO~A5EzY^}O5-B` zrHi`t>p?sGcZ}t)YR0$LQMvrE!+wpfnm4HVH{!7t^IJUFj&fR8uqcfCDRpVi0v_in zp5qm{6r*IND_b>H|5+7o%~y8~(mwxVv_KUm*?esNv}`NH@>tPUjg1N__RP;owSm)T>%qt1R?{` zfuulcpk^RHFf=eC^Rqjqs><7+T8|bS;z^$21zuOE;+3i_<*JUFsJYso6!c9?G*%N; zVSMHz^NWS$v_h?DE6bmsCOg7TwlnOOb|<^HU1D!aU6gv+ALIA=Q~Z8&>gFd7O51eG zsIF|Lw?qxd^RTJSIBlw&_pjXh{NBs=4w=5Yf3>=Man$mOBb5zVapJubYfcP2k$xif z__gCFkNMPFkLY(jsdrAbYWIX*)JYxF z2|brIbrc@L^*!tNlR*}Bs7rmCJYmI0+LZ!&P)L7~L0O>9+beAy0im`8bxXLyCzc%8TTkk9y@ANZBuIHp&OQ?Ke@J)R|__aS<2HKz*ZN0jglL-~#&e9Z%VOBp{gmOmKBM2<6=lT6|SeR!XKd}{nA z)l@S9lWnq0j>#~Q#%rQYyh$*zCc=c9I1^=JxGW#%%D?)MHl#!cC&Ty7< zT;wzh|Ek9QOtNIlDF-|y#g;tEiV5SDkZ7(}?VPRXm#g=CZmt$;rIy{bR|mCI7X{T_ zIqIPd<*9QPTUiCF|4&ah)loCG<$^L9$uA7&M@H~7n(kxkM&_9;>W1RbxT)t zO*eE$cXeA=bzL`gPJigMPVIQEn=gN=5&1x5t7}-+f96EKfB2IgwR7AbcK?>0XMLR* zig`S!u=COTx4@oue^}L6JI{qlzr!Y1R~cgVVtxGDt;t}9(BAw+nmOaAv^QsouZie} zV7VU2iX!bDm|e6tACM>yMqxGSulm_KRiqj6=U`oHLv7QXG&73!X1{dm*c&8Tb#V#I zAv|W5kF+S2Y^>ahWu^!1Pi9pk&5T4GEAB$I6{isX(54L?2`GYptQGfE0^<|Ne z#b5aXJm6?4NPba=NR1Z_%0`;mFZnpOn8;OKeyA1_9B6NURf#+MvYAL!KFNN09q)nE zBa&k%*B91C@z`lh_fzX)rW6mVLvBucB>8~WC!=d{ExS(*aq$ah5HETckPqo-eTK3{ z>0EX)j&|b8TyLZ3dWshX{}S0(^bASUB8&12my<5_SvSe;tcTF0_Y&J(u-VkOoP4=R-syRqoH3`+y&0}gar6O|@{U#!_^R)9i8hqW%6_~8 zNr>dK(lNReM`oA}bKJ93=>$gZb@DZ&kL<<2TTl3#&p3=gUZv<~j_x4%`R5-+t*#-m zn8@Z&vkv)@NXLV|Y)<=mH;YhfgyeHG+reW5~VLo1~Px~h1b!z-S>}wne zpkHGy#vIA_9dD=G7SnBq(JkL$LMMTXPtF;b72@e7r1d~*j)w3r|$B>q-=h z&AqEvI2Y$eHO}4eWU|x3yRi&rM_rFKV0I8iwgbnqW}!3b)nWoEp;NZgTH85Ar@rZz zlqPgLX^b^fi)lS_D6O2%5T@yz?krkBAlvAoovWpf-kqzZo8G%E)31p2gg*IenFdT) zDw}qEmChll3I2xFWPS|RUyrAoD3?b-SIG3VD=^K{`_l?HpC(ZxM(?WHO7DY1m-Z5> zldBwu?>tDT%dCbOR!5UH(H+f(9Zjs=)avzwx`Rlk)2jdB6gm45>b-0oSFzEx#LoVl zaeSETQmg$m`D@Vb3OpT6r?~{BetBP+=;uYWi~FpZ{k$jY*L@hSY^N6Hqb(dd zTpNrQa|+?_eZ#_XPT?+%-n)faqxwYL*=XZ@Jo!vNjXURZFz;mZY}EH<3*N6|@mtuBE$qvIY+*AQrm=(F?8{yb$Fl5&#cgIGTiC_{ z>}CV|(n*Gn!mk>!gjp7nXk}pl0CqS4001EX001Ng zV+9FlZFG150Crpe00V{q00^k4Yc6YTVR&!=0D0s9000I6000I8Do_A!VQpmq0D0^H z00AWc00LSv>Rh&PZ*z120DBYw000vJ001EWxBxPE+GM;3TvSK*KRkDL@4dUTx?=Pq z?mD}mAcBGl*n2^-Ar`El^dh|~*o_)B(WtREY}i04A}aP0d+%MNF)>l2(dgXGEI$8p zclkX}^1dHr=giERGc)JRoO8Z=FLFquLLA4{?VFgKnU?1hI4L_bvS(UyjMCUdu7j*m zoHbfyjnS|Gw)t=Q?*zV)u|=ImjsB`z)F`CmS6qJ>jznZY5;7q-)Eu=&?NArg7X_nG zG#16943vYWqq%4yT8#=&Au2=r(GheWT|)QKGxQ63gJkrD6S%K9XRZ;~g!AUwab3AU zu0I#Tjpbsv30w|0nVZRd%PrwnaRpoAv)py=9`}@c$^FSO?msH6s*cK8 z)mYU`<*Vwb>aOae8mbCaMX3^1X{sF6Ow~84?^SD61*$?-v1+gCxazFxit487zUpVy zTh&L^7qv!>)%Dd4)Q!|`>ZWQhbt`o{byszudZ2okdWp9@|*dcd?~-5Kg$2eU*d1_5BQ(>SNuEvGhZ!e1ikQ; z&`@v{S_)l-K|+|2B;*V8g;m0Kp;Gu!xFx(0K8T#?BsLJuqO0g7wiY{xy~KfHs2DEB ziy30RI8*#aTqrIV*NI!iono1IP&_W47q5%=#TVim@sn7s6}5G>Mr{*qbFII&i?)w; zuy&+2Qk$gB)=t&V(Js`k)Na)7)Rt)vX@AsS(caMB*FMw!rhTuq>eM=euD-63u9>d2 zuCuPUZlG?sZmcdwm!!+oP1ViTeXCopTc<1373=ot4(oo@UD4gvJ<+|?z0rNt*)Wf5 z;dq#trz#h=KMs47ATP@E`5L_V!?Vd+4!~W4T92Pj-&YzQ-*s66~Kc(<%-6Qm$(nB56Lmlf5 z%}h*n8eu3*sR2?k@1<4xv``F*E8DQFvdP$%zt$eY1dk$ zLvo};aoImq#MYCw$J=Gb|6_ac|K&`8jVAggr$r|Z zA37k>F)YzBEa@KulI=@KwojA%kM>l1d#b%X^&joAsqtz5R8^Woa;BX<)6Smx5B4m3 zdsdAhvi{MN4eQJPhavnOhUl5|Pw6=h={b&d=O~7lXqPzgf9jt2e}lg?(WGtsF&%8kPV@(Z94o*MEBK#bS@N-P- z=U9ZFV|G8s?5%2KI_C3pti{i*`TcAYAvL#II1=oBc2PJsx_$xH*&`L*iVTXE!|pO`d=DvC0dE=8xwX%HiT zs9{qy3t=f4;s%g;b`__lWyfaZL?*{)#zK6}wA0D4Ftb8Lrl)77O|p}*De2jHS+Ut* z%*52h?7Tz>eh^TSfgvU*Iy)-|LRogA68d5iqa%}*Gu5hRn{Q(UdvQA6AT^l}t6V|!#LCdd4P*Kt7{0npzO zQT!e8#ow>JJ?Dtd>y?(CXWx!%ShMIbFIPW^;jU46u0tbZ(ozyLU56*8CZ*;2y7ov; zcD3_mxk8kV&CHFB@pYgq*Z-od|G}-h3Xa045%NHtQ4hdRqtObq5f!1+=$3+%xH?=H z?rUx?w~^byRdGK8^7#UIr;{pEwL?{=x~}?DC9CVGUDQp~&DE{d!RoPqSW?xK0j)e# zKUcp3Tw+y!(Wo`GG(^)z(*bbEH=3oIm71%7K3;3y^E|KT>+^1WCw?S9j*sP2`HB2A z{#$-Azm?y`AK*{&7x^3fUH%FGf`7~Z$^R{2p|&6iM!{Y17TO5ig%Dx1FjFWJ_6moD zlfrr7rtq`yyI5cBB=!{hig99+xK!LB7KpD;CH_Zi(t2oHYddOt zX@j(bw8ORIv{BkA+F9Bq+U?q6ZHacT_N4Z#_M-MGpohoW=h|Pie{27v6LcnB6F?7s zy0*HGx}LgFU4kwJu)}QK54zR59l8U$Q@TsK>wp^W>mCDY_@w)S)mV#bg-1J6}xv=R3z?>ib_n3irSr6VbM!rVmg-R`H->+V>SnwSc6WOA|}!XR}OD3 zE4Jvv#3n>9H6u~j5JVWFJZsAQI^j>i(oN5};`~iT#_e0T9=TYYJbH_nnjY{UMzuc4 zL=&scgf7g)jDL>)m}>beb#H!zF?~`>x6TpeKW3V5VZATDd}K@MHglNX698oSZ-La) zq?ddN-?98|>^l=h?+#PZLI<%0v8RoC>PxjRskcQ=WdVM~Y>-P`iC$!zY+4Vze(mzY z;)1-4)n;1%8h<0QS4l@xla|97XJI|)f*r$+6Z2-ok5AiJHqFeOd+4t`;GePGOhp@t zgSzb-#BUKcubVk>;`ABW>64c4nQn0(%n#psB;hC1+p`B>>LvD(xzfQxP-bwHuZcBk z_nhi!ofpq3esCc^e20ZLy3hX>!uZR~Xkt;U4QtEBvvBIi+R}77ih5CJIsw$&oY*3M zBjeh(%{*}2EJv^aTdK&sskSxs)qhQ@@<}(M??1Zg#*HIYmo6O%>)m^FSbvMbAG0Xx z!~AHxUOHG_e(+#Sd3bnCOn7*C%s~*^i*4*eH=ZC}*v4LTBVSHvfNkC;@{krhWCfd` zCePyytWfM7n>2iE%#QPBTE@KfRaJahSyB0Mul2N>v6Mv5nwz-M-0D>0Jl4&q zXF}^IwC+HnkHgf9VJb3DeK=;Fg(27wPvVG0FBZ+)ICr{nTFRXMi_J|$+Ii;by%&s! z;y0x)HR}gqy4mK$(^}RLK`%|l-Qj*vDty0TVZlZtZLVjY4EMkk!wvD&OUv<28h3&i z=rn1DaGj>Cow<7I5BUvggS+X6#+QxU)NuDFez1_*nqM?|@^_P`5XPNt{Y#W3fvNbj z!p>j$Z#Hb0ztJ>|FrI3qYlo^XnHLFtSt6fOkhiP^4xjjgkMu%4&A zggsQn(^Z0=iOfr1g!^IrR>A@kF%8teeRlMIrG+)P!zWCR%N=jh(;4))Lc%7n(>y)B zkkES~&1Uz&^1X?k?y!~|!ED!Z;m6XIr^@!tn|r`a&Em3%sKrsHA%xavvYt+mvGm97 zyT85ZaceDU#nwreW8_it{C;IT`@(8VDVY9kn=h>gEp=LmUty}v#rjz|6Qmc(>^|-t zo)Mj9*_SqcONc3Gd`4on$5K(6b_~+x;;U&4!-DV*5%H zK*ZSSjB&BXfd|q~mTXT2d^oCN%$TUCF=HyC4qNoUlBrT_ zEIp>nAG77W;T~oU*=E*|ZZ3qC6bm$zdeRnj3?0LuWT6&YrH0kg)84Yvd%`L@G53dT zV-%qRb*1j$5R5Z0?A$!HF&;;{+bSge$cTuMBP%10>5o-b9y=CMIa1FSP&S+xq=&~( z+}MD7pA5Zk0Yl02^!Lh--T%q>fv|>VRve9K{#`go-N|IE*Q_D*D*+tLS^kx17?C+~ z_@Xy>CDF5R){gnHDE(0ETP^e_JoOOtLCpQiG_3#Ir32Qpssmn_^@`5JO-Pvjr8sNe z*YoFmr-vP(htx!yF@339kwu?`4J+~5q8&wMJ@dBB(_c76{b@Hj&&6P3Ew*BCcE!~p zQABPu12e<;?adx+;#raY8+oO23U-0f>?W6{5o(a#MFU-6{mvS40<)p)A{$CC@(YRF zT%i5f5q>=s^ayWjP6I^4czK&M>r0nXaK|@E0CNhUPB#hd!4|N-Y$;E>3$LilE9Sx* zq<*8b;?gbpW%Rwg!k-vQVn&UMkI~cP!r%}OBJC$9iCkF>3fUuuq$P|Vn^kngOsl}D z9iBtRSo8v`_pmeUSNiEG)lhBVb!IZpWOJp6jBVwXgAc^L8?sW;AcX=K10L-RBj97e zYi8SW(#J%n_gvcWGocM;zdwJTHmBp{SuTd0i3yXVOnMd&4a)IhXPFjE10zP+rt>4R zlO_k*os#qHKPD6FcYWdfCCf3=_?WrV##r9bq14y5j``BACkZ_*F5gwSWRIz0+r&}e zxtWVVRiHNb<*7o`p}gLew9pr0Lk4Egs!#VPoeqnW$UZj4r zZeF3SjQVitAgk3SkQh#5nwC%Q5paRcM8>m9Uf;~KM>ijz+uh#5nKOU>br1fPnJw(N zrY-e;CLAuw0<~t1u^5z#`&*B@Yl;3a{d^w>jmeIMXtibKlu47OPs!5TDp^;#k_CWQ zaTWAbq+a^*5Y~KKV&*-LZ=u`@JzoJ=8~n#2o-SfdZS$x~q!Z{Oo-LwH-w^xF)Kgb! z(u@@wEc6NUZcp@|NGV~86P2CzV_Hk3n`I~7KpWDA`bcb`K`_-cf!4lr{ja~eUuU%~ zdbx5x)>}g)J*y??OUPjS=@TA}4J<&=pTu&dp7nb5*40+Yx7XjtaU>o*zFd?DyLg26(nEYH(LcEWN6Z@>Xepgf zTTc4_`6KGBm;StQ@6~TT?|ORn?B?Tpt1Bp)XP_ioB@NK0PTaU-M}hL2o0>9dVv0o{ zU3@C{J!br&*CS~Ilm1ll-r?)@0?m>K-Xtu`Hjrn{^mLBA?mlL9JUcNV)iO|jjj%A< z77~dt{Yhu)ZB0D_uBtAr3z`u1G++y+zOY1SVBV}Q{J29G=-->lFoK0aCeoIL={FOw zn)GlXga+0f_-kF$r{bCVlDhpO<#219cJq2+KCGtJLrBbgnd+fljF_9g^pKG@7L{mZqg|N| zv;=pf#}y_(Y?mXbt1Ut>>_~`+NKMew4^lhmzlC`{^^n0GRZ&;HI3g2bsk^?C*edn% zJa91XBAl(`%o!Yjo_Zdli;Q#)8~|3Vr#86tw4v)~J?ls#^emn30-abxz;2?RLyZvt z67Cy>idEb^4wZ0d0YXhUZUKkN5ceGd@PgJLZXt)7B2 zYK_o(g#0*es|p1mZaYH95kMl;264O8s4YS#)Z895YR7TqYSe*4KO(LYp)-ivk5DJX z9YE+T;tnFz6QOg6gDK9dxI-Me#35K`FOECHp(}`kxdIW|j=19->Vwc##GORw8poYN z=mz3WbEq%Jol&8Fh&zu^e}tAGbW_D$K#jz6gt{P< ziBL8|CWLAul!uTCp$LRD2-QKz6`{!psS!#*fI*QHLfsJxLuecVIEuO=q~p+hgwhZ) zAT$A?NeCrzC>NnbgeD>YtVoMc4gw5|A`yy5h)1e*2*n~57%K{)7^K=DpjrrRLudy= z1qhjust_RyLIkO{acCV&;Ly%SXgX3|Mk;RwYtMyq zwi0bcC2#`IfKlIbjW{nZf{Wr}xJ+&~SHx9vN5TA;xGUT>u*fgmd+q~ZZmepcYO3n0 z>Z=-|icw{$a#Y(?yH)#DXH@4@H&jnmuhnWbuhy#@sV!>pI6^ezfsE?jpi$jE1>Y@niravd>y_&AHt92uSB!xA+{7dihaZ&aftmn zUb>hs&JkCOTg6iGwJ3{Uv=|U~5A6VLxb_erYO1Z)>2&pV7M+`}g|3~hmo8a1RX1Jt zt!^El=t{uRRl4K4Te`OxVIAORKfud_@L(JPh&cyO$MXRtmjF&af-mBG_>-Q~i~4$c zH+>6zJAE&Gi2k7dOs)F0oNKw(YFVp&t=_eU)rzbYT`RrTv|1Z$71#Qs)}OWO)NWqe zr*_NQt!sCz-MjXn+9PY{)}B>+aqTs=_tid9`&{jtwV%}ft@i8MA8IoLZ!j2K3>Jfz zp{=32VVGgGVZ33YVXEP4!&<{8!!5%d!%Ks;PVG9TI;4)JPE?($I>+l=sdKB&^E%aa z{^P_ssh#ROIXk&HnVcFs`8dsY`qrt^>8R5+r+ZHCoW9g`s@t?~@492_j;s51-D`F4 z*1cc%VclQ9^7?B0SD9Ze_-bdpy7f%;-0FGO>sYUIy~Xt&)cd90=lVkZ4)wd$?@@n1 z{et?1^~>t-uYaokFOrkwDfvhpq)t)~X{a<>ijj^>C#AR2f1K+%dpmb`?&mzpIm3Cg z^9AQi4eB=tYcQ@sVuPdxDGhQO6g4P!Y3MTECDJ9yCB-GrWwOgkm(?z7T@Je3YKR)v zY1p`7i-rRle%G*|;ns$w4c{1DjV+8Ljcbg%O$JklX@qHB zmYKGjo;8vhxit!Ew4l+tMqdCJ_a+0$P%?%@kOY!SvPnLfLFST0WChtkwvu8}P7aWx zf}w_o(er&!d~iXpeM{ zogSw>ern1!ZPK()(-lpRHofZE!*jdmWzXl$a5JxF1Dh2#D{XeB+3#Mpy;^$>^~&~I z?seGfnRg@a5#H09>zYq%zO_aB7SmdsYVp3s7a#0n@oDW7;&a!>>RZ>>#nhZgH)P_5X={MdRH|eJMonGj`gT%5^2K;l4saEp?H`yAxR7j z07=USH^(=*)?}e{d zPXbErY5i^#p=ow@dD`FVLwHT~w?JDxm|Dsses~W+=c9rh8?M4yTN7D~Aj(XDi`jH* zAAbF&<=b`{H{g`zY3p;%YOoIiSM6U`X>1=_;_-AW^wg`KrjUgLaGvcI zP(bgpPHjtu*j_+Q)+kE+#?CHxS9Hi?Y=0`1dCri{6?eq+S{N~e%6W371RL%GAayxi z1zoGC39_m1qGiU1)uvCamAeP&d5zm83!vAH4VVg z)w85eaOn-%aMP7dbsA^y%C~-(id(ZVr83j{Z2`W{`r11ZnEEYVRkc919c;^{Xmfc+v4j^|lB@oWjt#=`iS>51s0~zj$StL%eV#DUKxaGKD)<L z&>u&@$QS}h>;Dc}W918phSpOp@ZNB#4}`lkY_VNy1+Da$b=Fc+z1Yq%$-3e;`O-?E zX@vE=V9eaA*Vt?Gtjh~9_5NalTAI~celMN8(!DZ#7{6y|-;KRYX~eV4??Qje@Sr;p z2T$<{r?2MTH09uTu|E&IWUeuvElm~?{md)Q4-^?I1}cdOBU*W%!=#lc;h4oA--E=x*W9B*Rb z%t!eKq~`n3@RHq&mlav;7tei>G$SS9n>Z5_mJ=$J?)hfMPK#kWUQ3_I&n3Xbs)Ymq zwo0H4KY!khSwjnZqEWsrgr@y-$asqZwz~iTNgI6T)aosV&38Ie@z229{E_oJAG|Qy z5G=n3iI@?amt~4K`0M$-z2wtL8q}q-5?@+;LXp5`ZvIRH;8xrMh_RG2-t_o8D7F4l~aI-eT z&fQ_NM$wQ+hXoUP2n+j$7?zP`t>3}nX{zv=th4NAXR%W0rCc{SI&~GMz9qzum=_Dl@e^YbSK%oOzy9I7 zwF^rNc3nEFJzi0K;epX1_P#YV0#_f^G$%jNNzODvpp&d2_X%rhTgh6=EAJD7+?kGd z?nUIz^6>A8ts&^wUfBuDyfa!Ff@vtY;cyIm@?bA)>sdX?&S2Flo`Agt8}uUi_>>h} zL;B-WavsE))q{be7eE3Xtx)M+n5IW7ylzHe+q;sinC{C1zWRU>d2cYOEuxX3x zX$rYraXAxgFG6twJ}hUC#3u$fCWq+-xf~oJid5(yCt%uav_d7dAgiK*klhzy+E!td zBdnbc;m8n$yyPs;W8Us0tT2qQO|-rT207m=4`44zs*+$6U=y2SIIB6T@;v=7hf&THYxY8#mk)%#H+{OEtCJ|`y~N-s6DXf{_0jx4=& zZeQuS@@-QyH&~WUTb7e$>>n8y3_hc~+*TefrGrgB6FSCuCW||acizOdaAocjVEg*g z;IqtoFmv^xuD(J#mMhPS?6Iw_2c|>lP*)5V2`wCeQ6x;^mIqq9L#+JX2GBy0)s(DQ@$GlZ&EfI6(QwkWQ)Vw; zyKY(4rR$beD_5>svE~+WX@=Q6@IzOm(c~3%_Z2F!Ap|R?Jq)Ks8tD%DQ(1ROr6h&L zZ6cRDx!XIBLD-aryW?f_{qNXeziz~kg;!v9<)rfz$I^Uffnl@4}gue?ur1Q_J(Mpy^iK7}`&bXN#=g@(yh7jQpC)Pd>{ zNuHNaL<76BTs|d1vg6EV3kRwLl@a5}rRpYc@v7ntyUYsLMlmfquMAJZOK}W+PZvqq zn06J|9VLdcE9VIaIRomGfnO(l^zJ*lM>GtMvqxN z(xf~F3L(9>4cs4Qi5qt=amOA$v*OUyW2QKKBmF|eK?}RUf+Xc}-?}yP=B$2$SxDB< zP1371{YeVlFE_{~X(I*TCNyzCCG)%_40cRzaA znkqqp2d;z;<=L>-(oph&y1R>pbdpZy;$`xI9kKiWkdJ}pbAe2A{+2(x&(4aiXrK99O<$3K0l*dM50AY6036`^Jv_jI#77#6> z?X79BqHVx13!s4@&+7t3&`5k_Fc5S#jBp>VP~BRPWzh;D1G^t|HluT>>sZ`O_8o~w z*xCa{+t_U!Y&)$~W`~pSY+hq=iTqiXGYO&eTSZSf#M8iJ9Dj-ub(ht{g6$UVc>HELkomnoGX)=Aovp|6jWaoH# z4wCzGA{$80DQz^FyN`T) z+bTa1+ay~@k?F?g^jcvCJhB9!+$6e3{5bVUSSMqr(P2%dnhp8*oa_(z!wGS6eEjSP z)9~oxOBR|7ie4l#*my^3*;lr7O}UxPyF?CPdB`;^8X#iEz}hQW*Sn-T#CmQEF2vR> zrRT2P)7}xchk$!A+O0Zh3;62$a<t2&3DVOy%LqhQzDGBacw(sWR$udR~K7uS(zSXm{+sYL)Ujst)_PUj2j zl*HbS?7ahzKF+Yva`1WO!sEj0N8gyb|MzVUfdAA365w$XtH(40n+02_xf6e4*V&>Q zrZ?9|btts3a^_9Tg$@~kqr6SMgNsh2yvNPXQq4eG-$di75A~x_Gz#)3KNfHKKct*Z z=40AuF<}c~=LOG+oNx72=IGAcn8@13S(?+eu-KAc1=f8h^zL-!in$I6)`HwIwhHP(qeEHF% zCFT1qwAL%wTZ6@9oH%yM#Nms~%xfjN@SGf|xn#2O8WwC3&VR}3zievW0I5Hie-h;J zw3k33?Wd6bD>MTz06wqMdPg~XquE!~$ifTFub8*5$ig$&R{(QH!#@fH4bL$9QtwwH z4KJj?NJks1U7V?S>^2oQnr-bxCT<)Fw2@wCagy9#q+;%|9!xYcaU>MEX2l2iTK%YR z6^29h=MSV1|6T6~WzoLYF#s|Dx84Lin;w}e(bjMOpeEXwiFaF$95W>;-m-d6;f|k+ zKkYqVTJV%P-Ec|mJ${<&2rUcfoZObRF*4ux41BhE0X0d%WA~jqe`3$E3kM^H3>_ai z$YKbQyVGUTuFY%rR2rXzoMmb=TV$K3_&oKQvrmp@l}Bv0Fbj2(wym3ynUy~?-Qsgy zd4RkOT;xsgf`#j6WM$?}&w!KQFMA!q?88;K(Lg&xpfC-V{;y6~%5Nl37IBr(d7_~Z zwCyTUo6VCA7TZi2n;Bys#J16#<*4+3v6Lz`al9V5-Ob{~H4`oi^PrtKT1XXQ+po@5DSUtJf9 zS5M2y%$XV&p1i4is)g0=#dj>fp}g;9x_RZv(TsgzTP+6JU!J#(P*?dB__*zC$Tkuq z7dfwn&!MoNNZV;?HA$7H9l^F1tV9@;nHmOu##N+E^Y7lG&5dw2(N6FNm*vOuybGAs zW6WNSSXkX^AAZvklPL1#g%D-E*0dlE#uvY;qjlO@WVV4?}O zc|U;)V`?B2gc@iZ0WiDyG)%n&gFVbHf-oCk4g7;{MyhL-w z^Z7+l!;Qm}q6X!g4YNopeFaO76KCdT&Pg;y#;!VKp&ghv8ziziFNRRf-jXHDcbl1a zl;Y7Bf|-BD%=hw#4mM}y7aDa6t6eiT*7Z8T zSNoYT(zb6%AG+@)$tP>^3YmXNSQ+TS#N@Sbz#SdC30(jwo^4(fwpnb#Ho%wiDf&w4 z4DPmZjmefcOg5{=WN(>F^F)fSUi#~={^gh^%a0rbU{e7ACIjr234?kV%@ZiP4}9Ir zm3JWluu4)?!p7o>7HR=6VG)W8_H3*$o!pa=wAMoF-Qw>@v_0Z(Vl5conEAsk;2YBx z9~>`2)w{_jO^MGKZZgEuIrp)9+tFPjU`$WGXziZDlctJ2xf2TD>cQ46!i0$lxlyL! z@r6ZGU|=u4OXagsA563b<^Q7o5FYuzSPP3m!DxG05Z2XJx(v`!7CuXqV>JtEA1}GO-P@a z5t(SopPx5B@0-*)E=R%4%RC9;zOyC>qGp^~I{xCt12>-zLsqd#h zA?<18^9Qr6FsHNEQfT;|^XCulIdQxyJ~%imeuTx)ZaFC17t%zQZmR_3GwB`vRvs;L zQbkeWK}e+=HMz+oCN=5B8VxKAuShb7#3lvzF|zu-L2d?c)A zFAN!=fzF;mSms6+Aa%nmpU%458UKY>bR}#$?fr9S@&QwIN5YEe>=g1BIpT)@goaLp zR%T+^X)ghf2nMgsMlxTy^arxjSzZcOUn)@U9sl&+(JQ|gX}xA|SuGX4MOfG}Hk~)fP2_G8twWnACeH?w?-D_4UKf1%UBcbn31i15CUom} zT6shzKBK-L`(JIP82vmLy%iY!(Q{0XgUx%{ZC(a8@8z(0zHs+v(yccPbOnQZSPb-< z47rdGjknu73xH2@)Z~#NM&=Fn?n=9Wy}fDU7Jo3`<>n0bN$L~6=gO6Xd#+uritpDi zEWWSBP+&LrpCbF#ZtfNDu$%zaKDcW~m11os++>RT6%>2#2s@Z;9uSi-Sh4q??P)LC z>rchr31O34Qv8m0VWLJ=I}t*&VE% zxX~GGJ&DeuGZbUfZeZ=Xv^QO7H}@9B+_Jl3ZW?E|_m)oNBcbIE3Dyw11bSR@$dHQ_ z8FG?ChI~+wAzxKwSVI&U@=`^Hd{vPl53P~$-Y!FqsF7hEsK~JD9Wtz=6&cnvyNvgW z46C0a!(K6M-=`L( z|3N5WuQW&TQ9^^M>(o#}XFK;+K44hYL&)8fm$w)3Gz?P1F!7~r1;~3v4wAuaosy2qRK+*GgInIgu0kGD@t=jMop?7p`ROkH^)CJ_tOFJ|Vf90v z)$b&=RES@d#ZCp;Q|VBc^bx)W@RWKPsWTI^r0MA9>;#KH z3mC_A#)q&JWnkq&0^|wYhXsT)FC%lNLLde7@aD%4`_0V!fDfBEA#S*7RQBdQmKQYO z0M!`{tmkbEdz&r26AI|;6U4wi-^K=33Rf01^E>M{iG;rN1iRW5YIFbM0!rS=`YEsS zxht>ou?h4Q;0O0-hm=+02V}K`IX4tN4G^{)TK>uFqeVw|RkB~s-8m**{Mi#IavR~$E zuHlF7y*11*DA3Lf-Fs`8VNjsLOgo;X6D2F6?$t;zTvjUbI@tR(P6A_vQ-|#;qA+8Z&N6MuMgHjp*p>fqYs* z{qb!CDd8_i&u_?pF0i_UN#2qsWCay}LrUx!DFM1tpvqJlGV1Vd0(<_KM z8=3LrnCA)R@8>UG@cn$qN5yeJq;AhWbPKzbG=DmT@?UEMuD=kee)UhcXWkbZP>&i;bm=0{u9kbO!8{XsJjOldD!^FJ3J(yprrOyL$Rb=f7 z-!`T`rcaMgemDfM*hLPOk4X>7B&Km`%G~b?VXSCo@UU5lf8dY%w$awd=_QxX)V+hS z>cR4Jr?fXS{2$@PGx-$O!5`pQa~eRKQ;!$SW2d-yIZs_*w1m;u2N3x*1S=ShN|GznS0f+^wi5jIRcLW^IJ zF>;z5BSCV-!;e7uW?pbQ?LU721wYXG$6M$Tc*t{$oIHy z-78CyJP?{7ANruFp&&M8LpybCE}o)w`PRZPR+nc>VHLxKq(B}psq1Td+e<;|r%Pd@ z!-OJ0MC13$pC#ri(qcDO?8XBnkDwzVt5g1{VjA>8LO+sc&d>~HF=oY|Xz?dyoYl`U zt|Ke%STnAxGR`)_7V!eZU|@j3U26t+wGVzoiy!g8k^TZ=$_II!az3$i`6&L=havN>PYW?UkIXH1y$0DYx?2r=2n!HSNDJ|H%@_nS1HDLMD z+H<>SJxZdgh{roiX_MC5UE(HYPj9-9aR+@P(pf{Tp->(ukCM^@vwyI+x=#QZwAK)p z!W&y=y^n->J`}@1tzqh3#h9)D@@jz-Uj<1@zST>9C%pn_R7%1^_@dB(8~U2A5wCK; zi~TIVOm`Spo#B&CT$ps#bQQmi`FX%)i)}qyB2iBTPtm3a_RW}BYG!wA&H3nqS?8`8 z=^6;E<04lS#98PaxjDZ#d`obUk$D2_*0H7#8D_}W9b>Sjx7cJ|~f z6TRV_mA!UHwq?iW&1<)qwr!Z0nK@}t!zaucK5Yj z3vr2sDUVp^(e&zh)cbE2B|d$#6B^}taKUa1kO5tT^!P9jsh7KL0{cp!L)aA-!CpYZ zr=e?|sk;Ecx`Jmd1QuT{wxX?hHk`SC5)23B^E-(0@&Fwt&e&2ocbnQxFYNpa|N{CoB*2LV}dNLEk51P}) zv=x{rOEPm5s2KO`>XxvD$fQnKIHptIM z0v>l>Pi%GV4M0QdCu@D#U4jhwID;RajS*=M&Eaj`sJGk=XqLkpZqR;K6&#jaOz#Nn zF1z=>DZNMU^6ZXCT^C}xGn}4ed4$z0u`vRj#3u2!fy`Zo+pEwN+CV&rkz=iT2?jA3 z+_WhLK_Eh)AXn}zcUInI^rwZA+>LqLx`|9#hO(UF%Hm)=9V3E>KjrOG)A#HiyUSCM z1Y>P5*1isq1?#ZRf?OH=1)W4E!FYikcWh2s2UFT$U5XqEcl$2A$17Wc!M4t}&i18% zRH{ff$eXPjtyp3s1RBF)c-s^xX$%i_R?Lbi{PGlNrA^KgSS0X3ok9<9xGcYsoh3R# zbT9%d8zIt28p+#oMW&QW-7bbIVxWyh@^Y>SZZX#xJUt}S9~k`d3<)flec-`2dP-fW z=Y9CcJmJiR$!1xWSPW~W{DlgOqwQG>ntJi*53BcE%EZaxqrM(wVq+j|m}v+d2xq1- z?GI?r#Eh&v6JtU{WAe9FSm+F9$Q3u{q^wLdwHp%HqQ#GaPxltD-M-lpR&X%+hUxcf zcWD!d!u4n%%d$+fwUd%2ZYkbfu(@bgL3ZMViCM`O!$)h=gOdN-od-7_TXnc0Gv56= zYDV1Dq=rla?3}zitFYX-d)wB%2ezk%tv6Hhfd3HD=15amNUH#b$E`?MpKR$B9^Ji@ zk-2>8Ox{P#~L#yPl}98*>G%^-ESRUuG_xQTX+iS=xj7yC=sR^X5#S zIm?`~GG$rDa&7dQl=a0%xRP?C>C%t*9I=$F#*3&VUAt6rZjXhjF7lISPRg5Lib&sG zQnGD#W$}i*$;&Mi+Rw!gDCuKjTG!Tg7o^d!(;y4q67o2 zJYVvbg(Kuk3yngQU>^uXH>E4Y)(h&rXk7tMJFvvTptSV*om?SsVC{cs#p+V;3k2M2 zUD_60NR(`}j*(af^I~n-ST>eIN$1dd?+@I(Vp+ay?y_m7IN|HL^XAO81c!EsZ)R%T zqv&*~W$u#si+?cE;o|beiAiKCA(K`^y z6(92klm^#w6nn)#!Y^s3m#h;I2HOo*)`CFMI9&OhD4$NXHx?@|iUDC8CRYV3#Kckz z%^k`Je2!FJc~iLj_tBhy2@(rn| z9=fCam5l*Kpb01kT|ke~EA*bzaR#nF*MPHd%{YIqBiDoL%Y|~|xP{zOZZ)@&E9NS> z^V}8gHusGCTcuH1RPL%aswmZD)hg8%Rk7-T>POWr)qT}(s=w7(U03a*ZmI639-&TD zf33cuzN>zuexZJ?;WcJWYfW2C56u8gsAjZgoF-nAsmasK(#+Sa(`?f0)a=uo)m+is z)jZPt%s1j2^FDlAz9ZkCAIXRD^Y|tFa(+F(nJ?v!^KW=62*OuF6Z`*i(MgCAQiLoa zUzjF*Eqp7K3+IHJ!d>Bk@I?4kcqdTND0+x3L_e{!7$^pdBgHT=L(CTQ#D(HIakIEf zED=wOm&9x0E%BcCQ2a%Fqg83OT8q|Q+g#g9+ezC~8*2amFXFU`+9}$Z+Bw?!+O^uv z+TGgy+QZt@+H=~=+8f$?+F$MehaS@LI;=D3zS5a>Ub+BXdtGN;kZzD}h%QVQZ~uSv z=INH`*60d!TXj2iyLDx{eYz^$N!=OU1>Ft%|BLZl_p9!W?oZvPro{dxlld0mn_;PN z!`kh8jCX?%cIXfs-YsEmTHz#fT=t~+C}a0iW8S|%b@)!jq>{MJ=B6K{O&ez9-XS09DE-0(L@{41~+JD zi<~C10wznn|6dbV160Lzg&lpn>)eAIOuN|dylR z_U*j4d+*+J?ma*6eD_Q4`rv~zisKD-P)Tanq ziQ(xoTcGe)j1pBc@#Q`5l-iZ(vU=V;)_l=@@?^>4TH72b^-8eT%kg|3C#<81MKVf& zl`Lqi9xov3zjYL_e8O3{O}gevRn<=v(mpIh>TALEbjb=-ym5hGwbUMdggo|noOxcN~5 z0OBYGKm_YEp}*|TON>=W+am0t(N9ogg!pkJ6|0L-teTFpqdRH%NvC-47-TxuEuF$vKwBj*B91&N(!1?d>n=LZ>CJmt>(LQ>Hp1JPBAvT(>oRZde->q+LYpc&q zNGQq8u}vep^>p$3ZXAJwt|`_NgGSi-{*bZ4LhbVTdp3PXUsJZBprCB`K@VR~xSWWZ z2MQ!*V5CB)gVmoVNHHC-U3=Rr+1{d;tzd}JDUv0IR0#Nq#Et$JHEQ65s=+V^PEFvO z=jbei8f~?ljn_8|)A9!!r1nNrP$tK`IyZY(Oe+ybLvEiH-{sa;{{Fh-+ErGl6PG7Vz1^LAP9^G4`ul(#%`8zon&Nf6L*9pXRMuSG3xOD?CHeSne4ViBsrh zSjXdmRZi1D!e$BO7RG&vVVH+`&te$GQQWf>MtPL?C52%e8z)y}#&vX~yW{#NpL9fX zcID29j#TAh3_mP42`5qwViz~B@I6y71IVkXRS|ndC;i}qnfR1DMbbMsHe0TdPURz( z_16hkFX4Z(~Z)`nMqGb1$(9!eg zQKf)G0v)Kuk2%iRlPR$9t2|L7aPWt-DTsn*&!)k)`H|6eh-2!8wJEziX!mP(v!l+B z<_M97#!`eGxs<#Y$cTGf0{e#~U(KvY@`eKCTFuf<5)`a&QJY5=VD-n6!l^)mN?94O zb;EDWK%?(eBfR05PUTq1p+{hcN1KErf;={C!M)}8Bo6u%BiJl+xLIJNmt@XgR$Sk{ z&O`Q0ZOWFA40;-K13=A5 zR82lbg22}!F<+y69EbS^j--6eRD2JL>j9teJy3w}L4jH*9;=ImiQyVpWdehAxGl0} zt~?{nve#;AtL%Dc7R}OABEdy53M7EBe5lVDKE}{EiseIn#wdCbEHZE^6=`rpR#9OS zPx5+U!$d6XWHa9{pl|uPnJ*+Ro5ySWEC$h89f~*Zs;k?vYaeLrHQ-OqLe^Y86=MDC z5?eR~ZMiCc%dwP}Ai)X$mkT2-#TW1m`VOq=w?EYn)s+?%m6qn)W`K?bRtruJyGtcG zJf;6f9&<-Lrj9wx0`<+BOJ08C2m_9aN6;d@z+-m0tSE8x{Lw_s3~b*suhI~^igK)( z{r&phx^nKNd_DV3RjmR{8mI~(AG?)Fif_WF)6?q*si_LeTwlLk^tWdrd*Yd^p~(?1{qVDw+YUMu1ak!8~3OJ?-s1Jz4EZNm*G* zN$puZHk*?7*r~O%Er_syJ+f|{scmn%;68C;{gPT6lsY#F_?;@OOh-k(fEz4c8Gq-M zfqTl?+p#q;eksioITS2nx9E(?=AXtXAS&IOPu^=8^T%JCgj4SXG!&vVgsI4FDNYB4 zXzT#=Z;+s&;=IVwfIKsy*Gd1TiUaxqcE7s5_MrfE;*gNP0IP%5x7||8XuPm}$Ch91 z@PHH1%3V*@L9sS;H~prQ1r|!9jg-Po>03R3JFWQ`&IwOAI6(t*o#obatOlcVYtyC_ zbsLb2-^z83W#=qMuYb92ej&*Z^gf1w;t2xnE-N}#2l_sbbNg!&jGc>@ZlC97XE6q> z9Rl_!!j+(WaIR=-hmw7VQl;EDb(&H*AgM*}l8M2-Ke)m>&^&jr2o zF>|L)Z8X=kBh*gwOgl!{yEeL~e7x$dePujdr%PSlG~7f^3Py%qIN)Von%hWZfd z>p$?m8?WO(MSUykqp0seeJ|?Ip?(PUDC);iKZW`kk-pN?JFAtpENJroqh*OEqrdmh zm>{K_R?}A6MSHL=rXjgTf{Bah@wUO-v(DA?uV2`QbFqahmOR+^?6QXnu~oO=Ok~yV zYqqUUGUBClIUSNQi`DYv zH9ueVn(DDo+m-rS!K&5YsYV(&Hu#EsI{-^eRZA3=eyM6jj-q@XuZ~wsRj*o>V?;hj zsuelwsx#>CO22Vam#I@)W7SbPCZvZebyBlxSV`(DygH}|`~%mS%ZT1+<8 zV*V2|)=6bnS5q^;cM=2?ryiw+Mmp>ImVCL+ZcSoObt5#&a^`C>_m3M5&!BhR`YO$1 zH?RF|NVYOn>+K_8W_Qo(8J$3O3S3n-R$PR=xkk2S#WV6*6niLZ?csY#&cA4`lmqF4 zkrXb_qXere<5SsES#cw-cs{c<%E&xR*?h{MLonCQrnRcsjp4o``1NRTz3kUMbIG$7 zN&m6xaBy~_)>|V;%@Xq)lLIqv#LUbzC!929FMk~kR5h_M&p4MZ~zi8~9 z;IEX%hXZ}O%B!_vKzNLL#u}~Og1bE<33Wy@x@SDejBF5Gta-iy^m&au7hvExe3xg& zF#b>RN7#CN*#NH6uQZC(ROuqb8mOXr;m1Ps3u+Porn8vnI_+;q!rQ zdElE-9T)ne`w?Ui>nYnB@uMe$0d;+(hE&5amAX+p-?k7fdLg?m`zwQ`grWf7$0)C5 z=A?a-!s5&3S*2ihWuK{oD9=CZ*6huX18Z?{7*(NJ)!DsZ{Ae?xd>;ht!eVNEs3vKd z%dnKAKJJu+jUASZPcC6iF6>vcsjGdglq&+cjv2WYLr?M4S#>wgXlswQz{T-847iQ) za?L{qm~m@tSd&f2_taRf#%bfTv=D2>36+0sxMRalB(LnzvI9O!#*YM^WKzTzaaS?K z{C-Z+%9gbsFV|b1wtU}nHpH5q$@J=?3_nL{Jwodkv}M%mHs*6va-Q4hGh2^fY^kw# zs}a=`7Wuprib~u%b}Se?mIFI>XCCV+?aVwA2(Pj}Bb;QF-t6MKAj9>VC5P|Uvbz)} z*FU>qGi9+WHd4I_p3!H&;^cao@?UDYSL9S-7%v6eRMdyA6U#qa{won$1P52!KV<8-7tjPuBf zkX4lY%tx+iox29_qiR0W>SQ#uX4jY4RN1xmxqf73GO?oCM==?i=kH%AWcKxgEmIqh zQl7TzXiDch=9rKe)6>Yn&eMe66$%)!^3HP8DY&ULJ>&fzMjG|ATD@A6l_<@@Cb4=? zYt2LnwOy+5pjFX%;jA+3Lc@B;p|eim&P6hZ_6BC{48`}+ro310vZYM?^mgRXwBs@< zM@|G$Smo`E;j>cs{!lv=&bD;EA7u2EP~2C>;hLR74;iN)=S=E5n^re5o4Ge}`^2nP zUktYcS(GP3&D6ZxdfzPAU2*GoF!lL>Jv?8Jt;R6ktT-*hHmpv?ONKYhUN7uL<#}#k zGh-5Chj$^gcODNi0YprVxsl0Iscwg3a@mX73%G!%4NoQi0 z(8JEMt9i<2B@@dSzJlibTv>m^8_RbbVnvN7_v&_0y>NCNjy#N>YkL5GY*ULlJ^g*A z5uWcOMFt~gr{k!*oROGZz7*sM!@hS`(Z0VQG-)heF|o>Vv*%O}zemAZ zipFnL^v+Aey!7sPsunLyzdsOOxy-PlcWrCYqI|na4mJCVl7t+?CUbFBUnwI&Brz)A zM!^8XnCUQf^G54zwTveWYpV-A>7*dz5ut)#80gXb0Wwg4S>|7Rs~A zP5X!q8lEP49-Yb}HPZwUTd*_k@4yB+Z@@14jQKHbLyR&K($Da;k{k)oMrYgFrfYee z`4vmqeGr`EfONl|1u)mo$rE@3%P$9WiY0O+9yiFAh)rq4}+o zp0D1|8#ViD;asp%dt=(X1JDrZwg(K-8RP;{y@N989_N_9?=#(QCUyj(;T$g{{o&x3 z5Dl4GXdl#@Du%4v2@QF-TBH)ZF)cOQVc>NulSHPK#MF6+S|MEd!m3j!!5TVL$=z!t*onXYvDfpI+PlIIX0#I4F0_UH!b$d@CLFoc-Q8I z_u!hap?{C!8V~ITzpf}Z__k7DGgSM19F&h_8M*WP4=J*JX-=3`3ki)rPzCEtkR9gc_J2yu1`eqGs41v-n)qYu%i=)3fD zZsToykZN=S|4i3<{?MbvV*yZ6e)sl z*NQBTV0F?nJ*+ghBC?`aG@1;M73`)?w&OEd#L={y<=c#vK1YqT{P`7qGEN#-7EQNL zI$f+X>ATIb7Qe9>ZMpkDio9h6pQ9$%UsU5Db*{E&tFt%6+ENPCQTs4L~qtY0!`q_W@ zTAdfEgjk_@Uq@%O^}9fvyeD}dS(Kq&!V*lcOLCay>SL-t zQAPW7)CW0uk|B;yjyd5h*uF`4ExaFJ+6AZS)=c z4EvlJm0kAk#u7PVACU4M|IX*>Vj0aEnn8Bq%#EnSymL3&cZV3{Ev&5aWPf=+9B#rS4LHgC_MS@q`fXXfC5$aP{dX{(1#H!_4*38sCY} zdBZT5g};cpL0Yf!V!DC;d<>iiLa>okV zE1&!2?mgniUZv~Bqj~g4G)}*jbN?v=e2^m?rN7`f$LXV-3lkUg3shLWxi+eS@f5@ zgD;X<@8(PBUf#?5={|lJUrL|l%lI;SfG_9E>2pfP;(-s!91n>cnIGT>Bx+>A$Wp1h z>EG$s^dIyZ{f6FP7T<4kOniTe)0~wEpo{15TwcHnd68&{WnJSfq>yfq!dGO>uZb+8 z{P!Y@xX9u$xl_p^1zDsai#d?R3dmxmnu{QEDK8U5t`LN-7Q}9qC}SIM=d&f&xS01y zWbtnP1Bol%%dg3(R(M?sHS+yB`Ti_FE8~dfWE{~PW#wudvz|(GwK;!-zhUN_z-*J4 zZ8v7S46|J>_p=^NwXCc)ALv&Rm6qnX*u#HHMD<@1o4rL<5x0_UJ9n@n`qirx4U2x) zibbuLxat(q@}TH-2cOTEh&K1}etwrcy+@v_c7(DLOQ)!pmeK;j{yJ%Gpi^YT0ooz0 zU1AMqh&5axIpaaPn)ZnW-AwNmTmGn6((QDY;Orjyq@4Q<{f*e|XXW^~pkqYP_Yi%V zK0#llN9k^QlKzSQnx2;9^YjCHfxbX5QJKC*KPH#HDYF?68%&GUX5?U*Q(n$>P?sR8 zTjpm=O1oIBw^xoNEs?oK#YUG=3^R_=dO6x`((8_x<-yXSfhhJAolNo4H$Z` zg%N%$BPxBwppiKJjwYo2mK;g?A30(YKcA3st8!SZ=qW4g5urRsg+pTCkQg{51`dgd zF5AVva}r-$oaeltM06|XJB3@?g3jOPo(B*8FAFia8*6BEgO9lB-6)PhWh zAk(z0qC?t_90~k7X-H(;CGBpJ?+{RshGd5z*&#^w43TWVw3SSUM5a5X&$%MUA;>We zISx%C$F`6h&x9QFkmEMN%|~RsKa*p>py@7Y-z~>NpsANWCC7gHG~F-t19B`DOnp(> zUlKg+rAO#7>GQZ8d+7-|_S2Xgy@Imu%9(!81h%r1GdLckCZkP;4^BWLFFTsmF+%{(Ckg^9HA>H=Xc;a2InSormHaDT7x;Bwk4 zEVzQ^!VmNcAFiVFg%elPdBPd%IJoR5`PSx6pb%P5eo>u9 zJ@8I@g~Q(?=ikfkm2s7i+7H`EgUz?{m3$=)2&W&S3*i4RZmArI3o zzLu}0EqsKJ&?df4Sa>tI+>y-jVLBUJ-X~oCHQFti5Tl_8Qqu6~X zKfzDX#rz~cNnQLM{toRBzJH45^FMNtmh#j5wA}lB{vj>rABi96gJ;<&o~1-5NnG$8 zos6iYU%bo+3Q`3S%&yo5pi3 zJkhq&;{77>#BJc7EVw5R)?x4pgG;)=9}MPTaE1lWu)!HNI3ohih=McPz!@=cMh7?} z0k%khE!x2r2{1$)+~9y465s|0tdIaJIADS#I3NWM$bkdW;D8J`pdB2Lg-tW8nPJT~ zthpO@+y>k2gr!=rREBkS!8&bNqzzll!WJ2pmw@Ftu(<^6%zbic9QTk-S9Nsz)>4KO*hcg12iRprXF~jZeS`2O!dIiq~K|~fvU}3kMjC0)r9w2?t2Dfy4~_ zgabTgLcT$J1qY~10+l^LWfG|D0sD6Yn?1m064>kkHj}_+64*=wn?1m053tz-W={d3 zNpN~MaM}h=?*@;jfY~G%d=41A8~E)3ch3Q9cLU22U^xPgbHH)kg0C}0mp6-cKO%<( zjY{q%M@(YQk4yVDIT%r?1s&VaaZEJ)SAv62i*{q8-M^vb6g}2TAzbwvZ0m;csKe-(tw$ zV$eqnnn=UDDoyN?GZ*j$Vzo*WNqE;7UnDtR0$NE!D=}y#2CYP)l?3v=7_^cUd3+eQ zJ|Fg7fCU#|wF_XW1=wf-*0~V&$FRJV(UY>g6tuD!T1mn3lCZoaEH44eOF|O^u)Gv3 zZvd93HIafQ2B3)?G?9emNNSXcozv=BB_fb}eZ zt;~n56ksJOSjhmQrbWZnW)-wS8rC>b+u$~m6rVeP)ffiHH zVi&Y%!=45ZHT6P^1BjZUu&n`TGzZ&CL9ZKNVM$n6Sg&zJO(#LGIp{TosHq3q-3aX_ z5jDl2;{jOSMnp}$TGOz<0-~nPh??dgYC08B(I}2Pp zz;y?3?EuSdz;YJ&b%0YH^W=bn9Q5zt{~EGruF;9!MNk^BAbSh4w;)j)vef>;hO}(R z$qudFGFiLM#cM0GureDfv#}-{YqGH>8|$z!UmJ6@Fh>Q&Hu|;r{s{6*MoyVPY#B$U zsItSDjFI33_B7KX&#ZX*C?p(%gk#9|EXnW|NgtKlspsArT5%jJj$_4ftT+ywC4jR8 z5SD@r3P9BWBvF7Q3c%9<@H7A<4SfV2u=<3V8SBw%X*JiH0m>M^oZ ztL;Y~oyMB`kU=kjjN_1T90=30NJ199KwAn~vxS&DicEP4v=K*k9D!UCW;aAhCjsf$ zAzj6h3-?1(HuP2ipAUl1+n~b&_%$m^=?AKN;vh31}*S$>)H{ zH^CAHz~O`7@J-Qn5QonLhiAayo5A4@ zGKf>b(QVhXskfV-sG zms5yiAT9;0<$7P@VRCUfw^ZHgC= zuUU|@&eS51v)<=Ug!Z`^vb7=G7-SoTY~zq^6jF^ro@yU(fngf8)(mW~4J+0eZ44{6 zuwn-*j$p+$R-DC(qgZhlR;>A^3oDLe#T{623M)=v#W}1vZ+3zd`qNl<0_#o!)16p- z2Ugz>)at$dKJJt8mWp*+czOa)j~hvDlV>Rzo+Gt-N(@g);3=&3?(u&i9sm=rH94rx zGIbuQGstF-t20H#hj}oe_N;j@ULGu$2fr-=vvq;lR)g8rnvAWMt3^W+Wk}RE`B|fn zTx+s1#YlOBA;m>`tb7et-UGQV1@q*=Ir$Lhbc1v9;GETvcM9@uhrE}9VU~bl@?e-Y zXdnmK^?_BEfK~F4;~KC^7o@oge9{HYw3}>9G08$O$viO0IxtBAOtJz@vK~yb5=^oH z95NRik^rig0nf|88;gMIUZ8q8@SFvn9pHHx@Vpp!UIsinCKptwc0&A+1T)Nsm8Zc8 z39!K&^$tb-W{cGSPpIrb{T5FB`prgkplrf2d-uvFvQ0LT3u!QH6Hdq`+F%nFY@!Vs zOhR`VXe}J=C!m)+^pb)W(vW#3WC3}+XHqk;4fm*#EcA}xn&!1;M)TJi#cFN+KQQ92 zjnwX5?JZOUykbKS5$piPf_G6*$w*2AQD`6%Vw4Cp5QXfcW~>NoED71FJ)o$1+lng^ zQ_Gn+Bp$*@AIKAu0SeoKsp}6qnL|gRA4#QW1H*Y#{dk&DBOX2F&VRvj|Hg23T(i3*CT){ zk%k*F7Wd&{WaCMc;90E13utmZf*6Qva1-vt{g{H;n1_X^!YVXihwG7mK^TskaTg|F zDsu1?N>Pn^Y{X92BM~VWVe@o19>6p_hWRK%4OU|lUUEJ9U@$_s1>=x`N05uBu?S1B z2Ak3BdL-d0T#GTd2M=O89>+6Sj9NU0E!c&Yf`V|3uSxEf`{e=owrrOj@?+U0d*q3t zqVh`L>EdwNLSL^uFE2**doocb%M_U^LvoZHQyi%%_m7q1WrmzAr^{@aC+EpRSt=tX zRRu-<8d)zJWRu)0-;k}cU4AG#Ww#|#;6EWx$+Pljc_C^5GAR4WfpUl(91ntU{}q`WGSEA!Y|QG=dLl*uxs+Ezj^Rfgm!IYy3^<7I}NET_wCnO9vF zDGAP#g|bveWQ|-d*T@ZWi)@lD)z#^D1oz3;jTXFyH_?iBaR?uy3q3f2(>R9<^kQ$Uw;gKU<6LzhpPRqCG*cR`>91?vwF@-K7z);z#@Z zs$I+1wScY76gz>Aw7kDpk7k@y+>h_9XCrJ@t?egszukE>{7mCD9L^E;DebaPsWvA$ zcJBTFA89Vt{%ZDL%taqIq`CkJzbu zgPoZ7;Q-puj`z`l!}cz8+B!XMYuU3i>K=IZjMETcm^-=2?ptg1a=ygPmcdf1N7&3Q zmP?)0E4YhWEvsc#uVf2fwEUJ^{aL=uM$2@C)vLIh+brjmRxfREc0y7+VxNK5?#smEbOiJ`g^fm z$!6UfreBcRHWM8go z$$e_w#2tEDX<2NHUAJ?;XSvndNMKK=$KC=DzS!T}^Rc(Wp3&!)d9-h%GU{cJiL|wD z&+3otqIs$H-?FnDHrvzKYBS$xv%KAAbO+lmUkQI(@1EVWIr{&Kjlb88EtYY=XzsCV z8XJEH&GVC2c-muNW-?<|U|?n7VCrIuU|?YIhR}?03`UGPKt2N}0}L>+Ga!Lb?{Gf` z2L^@TOw0=ZEf^j$?`GsvU|^UIl4JbBvoZ&+5OJ>0m88ZqHx1T+B%6*gcHlnH0A~7vVf(mQ7OeK zSt+Wf4AoIXHCG39RbLI!aJ`^OCfV#T1&-@PI8jcllkQA*<~n(9l$+$HxLIx+x4YZV z?e9+XjrJ9J@m`YW^8#L)m+57B+1>(gqd&nP@YnX|_@@R;AS@6Qhz%qKe1VKWhrocq zpsG7Bn358!%_Ea6a+%K}R$4 zyQWEQw43avx=q|{x2K!qPVkNLo%Z6qM6Z(PUDee122Fka6Rv40f1Rd*R+Fx1QeFP< z)BO5HN%-ZWOS>+uzLa}qb@8wr#W#K)T5@$B6WSUY8|o8E3B?zlDLhh`U)UakCxS_SL{ZlIFM%qy->IZg+j_AM4QNO+ z+S8FvbmKPeL>oi;IO_Wxf6dqwD&+{^4c$*1K<~^n}gO8cb9P64jtYbZ! z*~U)xbATWCk)YO?aIMubEz)l7(;n?NrHqW<7;Vun#xYe*n0_{ubkd+Xri!*|hNdf5 z%WP5%E|G*$nlhB55*4|LBr>Q*I@O7zDXnbhThNx4Dj=JF+(jSyaz7pToF{pd$9a|~ zc!uX}^2YHRZ!ne*nZi^);1w3KjKwTr6-#xPmF#5~yV=7b)>1$zp0fFUj0m14+UB)9 zFA>9w#Pcc@7)@o~BAGYwF`h(T$InDkc!z-XNmbsZCLd9YY1H6-o2^{x@(K0%lzPnM z7G}}N5+KXwtugaxVp-6}=B_o%X~$|hvw^N`q6-`8P98nkN)NWsn=iPX9rR*5Ieg6k z_Hj2~(VuS^$af4QpW%$4kcT zl;uWwOOA^2nO0~IaYm?Q{ zlBSKa)!CA#ky>z4RT<1d?&Dhq@jVZ4Sevy;+qFa6OoS<|x%yK@I-_&Cpo{uT#X76= zI<9;j)lYu|L;EQ}c-muNWME(b;+|g(i{trizA`W~zW|CbTwZ#@4@UoU{P&3^h4~7Q z%gn$85(NO6=?=&Mc-muNWME+4{qGY4153|8$Nvc|DGWdnWWb~a0HOK@a{vGUc-pO% zJ!lj`6vyApUPR9%C&`&yAS`|aT_lIc5pyD^L^;q%ND)5>f)G+@6vYoDjS3dgLc|0N zA{J^T7Ge>^LM#--!p6cNf(9f6krWmxK`lIgGdp{U8#NXdKmIfG-oBlE^PfBQMfU4E zBL9MS9PO2&ej)xmp0WN>(iN>k7h07_Zk` z$UR9esCO~GNZM;7cH{SWY2NiGnq;-rQR;V-53Kq6Amh1oO4B@=B{`3aQdp2tdi!3I zar6-wq~~#(W%Vx{V}JjE_uOhh*Q0SvPCHD)DJU(B+Q~V`-?N?iT_P$W0Te>YuVI35 z7M($p;H&!bjBX^qG0KxRb=K+zRZ9={5ZnF-y6yS=74Nb8-Vk4%q;^O(w5xG^7DKNf zJ|rp2EvLXca|_bUIclkjgV*JEs5kUz4!R%T_ROL;&B5HkPJGAxQ?F*>zNMo3tEF$N0V;)*evrfx83Y z{cj5IYkAV%%V&~Iv=Bc*{0a4@*pu;ipN*w#ZBy5*8_yKLqwhCo;X9L&&*))NJteoq zdMWgaWhFW1+*-HIEkypNH_1w`$A}qSiS|pu+W|e{bLtz~No)%J%y%{5QR9OQxf$!z z!1~vC6<>Sn$*UpGSa0C@ad)@aW5ow%Z+OA@)Oz@s2Q!JJ&ETfzcekoMzqh)r_x!@lGGU?3F5YfIaSlz0B9L&N-Sf&sRZ{>tWi>ji#K| zm~o}vA;$Y$y{`H7{&$|-FZa;{@mk>&_aw0YFI8SYXRw*P5y|ua;Nz>TI>Q+lU4<{d zqL~nV)c#Lo>5J)2o@WAiORmY|S^N9|>jUI1!vVhOA#3}cSNj>4q}}y5BJ#1AJz8q42JA1SE=JD9d+j*zT3{XfHt%B3 z{2uuF9sGEQK|yl{2^iBe2Bj8A)?)X&ZY9 zyO~d+c^J0w;3p8hH;DiM002+`0xAFic-n=K-!20|7{!01B^rN%Ymt2co2_U`dZi*R zBqH_idaK)3EGz9=yn#zk;KGH(`*;)&;Fu0Z2>CKQ=bSlnX1@=Z;gJ%iTmde%M%Y+3 z!eh*G?{JAa4-S_JcyV}~8(tlr@bpO*P3myP!&5AoJBOz|JSXK>Gz}QVK%x4N_I$pT_D zZ0eT!%Ee-uQc^iu^7Xh9j-^+1BeK=tkR6WM74kEdf64go{K)>%P_9fp1m9lSV_!;S zyZ=)Aa^{>^fAM)EWL?$JOkzzUv7WBfRLN~kFr=ncXO%To?avur+X|K7&-ER5g@5$$ z2HDA0+5i9mc-muNW&nf#TN#WPumAuo!U5_4c-n=J%?`pK5QOi23c_7z{fQnZy?F64 zuxt$p3yp9@Y659`Q0D>^q0T=<6r;z-#-J#^;qYv0vwuhK1I&UrXMZbOTxMJ z%=ReOa$ei~tEVBb{6W$m!t6v{exBBr$NB%v{;y*Wv3q|96QwMSXlx>vN^QUj>?T{x z%s2Y>?)+Yy`cIDK*yoJcZ3mPA180b!>?zw}-hV4Ku3kE6@`c;N)JgWwlWqPd=lfJhQc z$I`I{pZ-`HW}TZoKL2@|vu|168#@nlATPp4S2mX|0MsFkEXER{^bxm#9GJY@FF5*Z7JrR38EFmin!h8 zWg_~*Uf8VuU1pD@HON3ZqCGOu0n#3^&3ohn4#5V<0onj?S|GCcvN^antzz2Hx^9hqFutEjGR#y_~ zy6Un7*BLpgghC=MKLh{I!`lAWK6eIjh#C=;KYu_(3~5Ie3ac?*l$9^i z7gfGU<7N3GIkIWCbDH)0toH}-;ws@MC>mJ_7iFr-KeKB%kn(3aASom(q-QyJZl1YM zxTsSZ@%$(Ug%>MV&Z#M6r&Gx2Ri34HiVQ{r8W+iI(CR>uXZ(IJSWm~1R zPitM_QLPopAQW9#6iy;7!eWfXhq2l77I>c>t2}K~mgcJY8@pjqr@im#KEqH-89ecd zDv{-;iod?g)w-LK%LLKP;M>l%I=`L<7i)M82#k&lQhvP{G@5i@Ki<<37r z8AKGZc*{1O+V@Obv`3dt4GXnz)5PJ|afyF~$InLevoZf{qQA5JUi9n7uND?3R+{i} z;(Up?I!=XLk*E}d5P)!qir7eq)X0eJ$cy4AhpMQJ=IDs7=#OC-iq6~#FUD%Q$8w6rKkecrY6*ix>9c%NTX>Y&7k?TlvdML+D!-P zI9;S0bf2EmNBT|wIgrD1G)}}RI34HW0$hwMaaC@_ExA2+<$*k$$MbBS&r5j?Z{`Dh zoX_!PzR6GcEq~^Jq7p1oB)Y_rgpy2BN(RX;`J||nk;+m_8cGXkFWscC43W_?NoL9d zSuX2jtL%}(a!M}B4Y@DR-^v=K5j48S)1;b4Gixp_s3o+#R@1uLL|bbo9jFs@ zzOL5odRVXPJ$uKm!bd*3SJYj z;B=&cNv>#vU@3Sb6bchUxoQ$D1#c25uxb%31#g8yVL~WZtrQa}cuT~B(~+LGq@%Ql zh&08R5Xx0gD1_$swz2G!XZJ-BeHRZ9A#4pU9tT$)bi*k)C3MPEEgnxD&Ut+GJWX(} zrb@MD1jQMlGpw1F1!fW&vIMKnO6d69kWoo9md%YN9;NeLt@##fLEz|ubhtWhOFBxiRDmtxZ;@q*5+N%z zyCKO1q=i&aK`{=E3uA4#1=f`alFXVhz`_W&>PTQKnLj40CT_@)hw>Xy9*blW!jeHz zhDs}|I9VoyW||6B!Z}kt7rDp-IgW*ljT*zTkO`c?$-+rbv^0vAMoU>gupAO|`J9t( z+2W!sY;=U>1m40$&#?jv->yJZ?EqMdSq+G~GKr>WVYhA1#kS*(*>**(h7>BcUEzs} z@a2Mq?O5_8Vs;I32^`B?EuGpJ6|dc_3SU$tY%8o|uZEQFSm|ZCg)Uj|nen%DeNDDc z8EUdD`8KuvW=OC|Y>U`qjx|&!VawF9y^0gK3s-o`LHKqBb`>I!2@&%e5Ork|P0^B@ zY`d!=T;UeDQmEKIo*Q)A||8kW>ZMp8Q#LuY;vxI0;!4VJXE}-dT=BIjERSxkj>u)pRJvcnyOK z6B_xUe_30oVHraRc_Jn$k15R*OR=J1AbG;Eoda^hu_~v#G!be0vLY$cwxeAi3R^T( zv^&-mOF}WZb=YOdlZow|S`v<3z1*lnCK{qMu`VM~TC_b`v_r|Z%6_RmQJR56kuq7D z#rTLA?JCuhq$JW(R+2QMa+HQ$H&}(Gim|J`aSQdgOPSgx+BVwmT21TG=4+>G7i!mN zk7}=KZ)qPERxj*PIHYiR;ljd|g}V!n72YiTUtGPoTTvFTEZ$UnsrXazPknWL1AQxf zC%vps(HH7i=lVYSq53=e$NHE0cluxY|Aua?Vr*)7Mqn&9jxbI(&M;mu-Y~u~e)JGR z2q$$(J<^ekApsWxL-gFi%q&w(-dW@c>*XaxTPO2+)lzK>grEn=mS|#O4MN+A>TRJFRlI}=PrMJ=# z>3`WIHF@Yyi(4Ui{w&yhkQ&vEuWV!%Xj66@-z9B{73%Z zKn*5C149!-OG6t&2SX3TC_|(n&M?j}*Ra~K(U51@V>oWOV7O|yX}D{6X!v0GY50%* z&16=c)nY1hWKPVPHDeuFUpA19WocklZmVDf^?|39roD-RX!g8NrS<-DC~rhgFDDC!CBMe(W9j>D|(ru;1Z@=H+mps_G(+7hbujX&>Er3WFS&}}(GiBye&dE%+)emT z+h@R`#`9;u?wyP9&(q+ayX37Wl8b0Gp#@uG8w^B$Xo+ng5xk%&*g~|%RTp6mdMg6j zv>CVOh*=Lp4{N-H&LFn{cRok#OBP)PAK<<3+O>oGE?hY1*Q=Me-vCW%#n1w7*b*YR zy0@ZY@7~Y~fB(=>fB%Zmy&6}0Vp?ZNJ1RP3T2DwL6#_i0sp;ZAY`>4&(*=0wsYJnS zsaIIcNZ-)Bvt}qqXTEPADK9UqIAXlr?@*gAV}d=$nLmvndFwZC%`$CUKPx$9X3C^V z8a6^F!qrEh5>zPGKyNZ*(%f+g#hT?~V;$F;$KhagY|_TOysaCuv$sx< zk58I5R#Vi+Lr%H64)JW;<(iAeA4u> zW0N-InHAN8y&GEAPE%AjJcWP5DT3`O_*%!3Arqq~_BNrT1delGqzES7# zpe;oOlL*>Czab!>DU*~Q44i`*e>LLAR_JOh6CtzbN2QsYAFrQ;U5y-Ri$_pvkl^7A znj!-Uowz^4PIMSkB1E{*xKx;$Hh+e3dfdDLE6fcf=rrrZj&sKS5$TDm%zQ9|3~NmS z)qZ@`L?Co(~RK4(Fs|11`H)|;_6zK58+3J0@Kx*^eV({p0#n>>SPD7 zyPdc{uzXCqL-9{Cl*YFp%TiL7q)Zj~*Xb6oELtSmkkd5(HCeE2+rl){2!RA-^~(Nz z7tG6OUyLGg+mniS85OAY@=*li;0%j1!eSaGpf2hhqIITzx_SHUhwe8vi{`jRy%?%{=?nXp6Z{XWt8one zSQn~W1y?&RWp5bBlNg`P#t9CEI^Jcy{KtkQXgd=EGd)fH0>?&8(Do(^aE21;RBp+^ z{h2Y|X54pJz-b9;b$f`CS?M7(YwfBYLJA8R8xUq3v?t+MY1YbhIc6`$^_^`5*DKWn zm6Zn$SSo#dEEXT1O3ML_zZTQf7EFBzYailTqTFHVfEnlj8QFqE5rt9U1g_u%KIjCl zI7+kbs*2S(^wMj75m?y~8{Wq>ivS9a&=4KLIFmuNZk|@31&D6eN|lcZ3K}zJSI}X8 zc-OAOhl6&F;kXEJq)^oRM~+_G#(Etabywrytf%rj6^HLWHGUK5V8)^l2FbT6SG$Q6 z#;a};P@4jW)8vh$j2<_6Q@jv$M8OMEl znlkJelEfMaKmJmhojPaXyd@l5p~`(QK@;R<^$Il}!<6-Gb75YgnWM8cm7hBft)Q!( zWUrXeHH&c-i~jYr2>qX#43)s#Cil__7V-u9`hyG$3fMRSby4T)bODOqP*Pyg?t;?TMoH_Z}afsPQ%MMPJuSD5arZUJ;=jj?kf=jfA>e925GkBEhjl@=S>I z_8nh%&%Y9w()TZ32_!p zQLzS|LII~pg@6gxiHSZTi9J?1{1RX{_siL{-~s{qY-ADTj!@=FU1>K>`F##u}wFTKL zOH7qHlf5*qqCEv09F8_PoPa$A8yHTwqj2R#Oc~4Y$-gHCh>i!u{YM;<;E1X>bd;tG zNq0HVxCAX{U%v#+joe?|i`6>!7Rm_*3CZG)KpSWxA;DdQH*xCT)y?f@*UuUU^RL$> z>@}J-JW{m{I6t8WO2>P7MU3~+lutKrzkS>N_GZBkz^}WkpU;G_XpLvCpE_mAjH%6 zuhDGk7|D^4%FSK-EnmNW+4A-4m-X%1rGLLJ(cEhD$-dtlZ65qsPbE&yCp+(|y@aLe z6|Q{K)4d{bN?Mip!DlDyYJ$G3&-UugGk zPVK2UTTGS{JXY>Ql~rZc;vrkj$9A82Fqukau?nh)DykzY$d*b};)<40u@Z)xtC&c0 z8Ebv}=FPjdXZ0gtJ{9C!j>#%*IEwWF6~k8Do}5sn;gA;zad^BHOQo?mp+2S)sbi8= z`h#j}GPRJmd3rOehz_z!8uN#BLDigfceRmK?!VPp2Q4O~0ycrh0hL8Rp#4Be;2hvUhvx+yBwQj)2TBngCJkHx9RxglTP!_JL}K^MqC?tm^5DiK`VC6t+65SQ34SE1P20bLqAyCJ7Y@n|3#GvPoY(1ja1{x4vfZhWyK_7rd zppU>S&?ggJh<@}#Tw8R^fmXmGU@5Q)RNMfQv5Npbf!>fD0x$psGzTBVh8P$G2DFD1 z5C@7wV`vJ6p{QXKCO|hM7SIv;8=VM!p@Y#6C;@)x0|YIgonb;O9=i?15}+ltHkL}b zW3L6)1Ivskh&2!mUc+k%iy_tn&478t*kD1zKx2o4lw(^!FQ6@Kgf*}LRzMS2KEUoI z4iSn$9EpV?zzASGFowWT7zHC?FpP!aFb+m%4}-W25xmX*O`frsjCoj%ZP<@9xPfn! zf-+KbYDulBCyk~}6rv+^j4sg?x<(J_4Sk~@^j|n4u}CM1igKc^Xf1k)K4PudBKC?i z;+(i4o{Eo#VVDLRDU4_%i&4ZVV{|dP8U2hA#uQ_ralklhoHysfr5e3fhvJ|fxdx}f$4#Tfjxo4 zfpdGXE?f7km)2|Rll2>ALmEHU5^ zH^=+&QG54_i?@rWc*B$bRK6Uc6Im|P$?$b0gS5*kNK(gw6K9YHV9 z>+~kQO`o$w)`WFu4mWWkio7f{xh-Wsj z>fC*)8p(_Hp~I{omnEl2g&KXy@4c*3WJGX<|$?fHC zaJPHD*Tie)b?`cQ{k#F*9B-btz}x3t@zeO&kMdLe3jRcYiNDg{>c5HTNJ^wmWPW6m zM6#-^EgQ?$vXksC`^h14lpHUo%9(PFd=S`y3CafJgN4CAC;}y+B2WX@- zUWMsH6q3+{`NQhr)NpoqUT4&fmO4S_)1`GUy;Segr}QrqZ*rO9riy7~+M6C`pc!GN znmJ~PS!33jjb>YvAGILrV{~kE;pmFd1EYt=WbklHvSqua!cu2>X?@%Jj&-Ot#hPzD zX1!|t$@fiPAKx(FV&4nCcl?I?9r0`Q``I7-1N@`?5BXR6U-$nz;O&5(0r3HI0*V4^ z1AerVB-enHEE>VsYewFX15Ik;!ABe*$Ovv;z0wwvs}_U`t6_QCd% z_Go*8eWE?vKF_|?zRF%;-)i4!-(x>yKVd&)e`NpO{=5D8aADV~RKC}` zgzg!J{MTR28=cjd#{)_mDc<1hs7s?<%8JSo4p^pOKo_j$c zw1^Q}VKUMTcVQs3h-Lq^IS;$s8v~(5vvM1CA@+iD_K+?ZZVNvm?|^o?kC2_%A~t!_ zNCPj|!laUYMTd_YKZ9vSGfL)}c)2?~4%t(SR6m9OdX*Dfs97tSiWKQC2?V+>UR?p| zNK+_?r%*duLv}qv)`Q&+sT98;4~afx4`FFUeRqpW?a3*zQ&tio9mz^pwc>C{a355A z0$J&fRu~Kv<94YZ;5bnJKGC0=-XvYL2Ctf%HCYiA74{)TNk#2QXcXn~mI7|ED{o(}Y;0cihXmLpmLb zf`$5@-60*)>A1Eu1jp#Vbcb}&Rx3=#_4+^EAzchhzZ6f_UpYRG1)gN*(g8qsQ&C9} z3q`d`c71RLP!a7QJMSPbS)ojAtuXdLg))VYwk8zlHMjnitd2fJe;SD%2dxjmBK^%S z_XGV;8zeL}?q}}Phw}${j^lPW^tIH7KBj#BnEHsdHw>KLQ|0{MDBqxP%?-`55V)pp z3$ih8(lvQSL56#k+JdK0nS+1g8dVRR=v=u7nd#7zQ~%UkscqZ?_c+|~Gfob-c?PZ% zdrz1&$62V5r)4ZS2_L~l&ET1X7ez;6bsSQpLHFYQkyrvsFg>1)JN19ma{LCA5|}Ki z)jC|s@e+9&loH^B`k+W0PHV0JdCSz{fkb^}?l4lK_1uSlm*cV}?knG@ka)s3psd6v zB2jaMq4I>5Z^8RQz4Y5cKoEnD86OpJn!jR{;PTT-bM55-10b0agN@?=={KbhT zw#w9N<#%7xd&UFsgsj@yaHMOAVW><-%A*1{0^NY}L>H|-2u`P|VK5hFfLXuW11OI! zYOA)Pd#i8u0moaUDR_sCvd9s?5_sOp5X4+17rNcS9(vysZU{WZL^0Y1CND=OmZa{x)#w$P_DT{(Q zi`vn0vg>BqH6?dzwil;yF!$mQ`9likUX)f*w$*jQEG&(vTQ;jJrsb^9@?t{~lA*GE z{fc8|WjXAo@5Rq5dyvN_BoFd1P?y)Q%YeI>`TMr)K@sF(IJ*|p%?i!XHqbxn2XMW9 z=Yd+&<3S|93VkHi-8%O5FGl?ho~#Z>=ZegQQ_S3!+OuqZ=`9s3Ui{G_FQrNh^NfZn z;hc>>xC_;2sG{sxq~_MnYBW@dBq~y;Aa&+N5)Cux9YxK0IO2Xc5<@^KrVq8^aG2;m zXal8~rfG%2KnwL1Y5>khrC8jeG?o0heP!1ZCO<6e*&Idf7I%pV#Y&ml?fvR88H`E@ z)Uay<%mgJ@92V6o+0P;y*@G?Q!F#C>?IjPgum>4sC6~s=q8P)e>rru`3!CYyr9H8k zmT$oX_pYAUOb?@gY$<9lBs;bHjcg_{T~?ZDQ2+$F*Y(6^(OWBggsr|kv6;NIRprLq z8p<5Gt&JqvT08Z`W)WV2z0kDPFg1JrtE&%iq?ggH%*6tvX2Y%MtSsjUspk4#b5efBT;cTRxagk6@4N*Xp zGSTw`it;mD5pYx)l#t>gA(z&XJpppXnAzAz{|6pQjztP`FRPnJ_BT1?>AxgE4%CV{ zNpLx?8`e^TI28)?#-v8pwLBpI6xzjDNMhfp#95OvO_$i)f~n+v zS$3YfJgd>`@5|+PYRwN(D#YaRB^T${gT8`CS>ZFJjcju}$W}87oOFI^UvN@}xEc;) z_4|FnNz+A5FwkhdK^+WZQE}2aGO9y>-}|{6b(&)i3&qp&-IA--r8oG!$DMN)XU$9Z zQk+zmh9BwmeW6x_R3LAZ^Wh8RefnK1tQO0JLFGP__r)>kh0N{8O|5!>53PfowS{rsAc#96+Kw~K07mJHG78aS(vgc*w?tpen))ejj)Kzo)o_WXi?K_Hh zJ;cubzyA4o33~+0dBe?YShzY`xi#H09*7L7yJg|clBWUObq-4*xwMy zwwais*SLV2PKz^YSELBfuE_oMGcNcI(r}o5#s%C&siLLcgL z^(w6)PhMmA+#TwI-(Vu%cKbYo9i^WgH;IBpxL2N$vG61;fNe0DUeacD4$u$-KR$it z%1yUW;iijQkh{7IRkCT*D}WPjAzkOJ4d9g@g4QJ)fUnYyI!MWt=u@`oZRC_(iGAd{ zGKuraM$MC9DdTYsy2KQ1e1BLowl^v+nkB9V11;fXQ*$pxac|^z+y^5utsaw_MK}WF zG5L#}Tc3hV!7H17AaCOdbWx@FVJdzxqBknL>HJb3*iDl}Q#d5(-~J}51)nxEqj3W6 zP7;6HP`~K|yM-#69-%wO2X_CzxVp!4_4}f6t7wGl9_#;DEfXWu%FkoVr)5irGRE&r z@?t**2aY-%eKyscHSuQd(Q;{4)%m3ty|UnbeuMLznHxAleb$%%Pj?lp-T4%FgtVe$ z?Y@IXk{Q&+i#KmwW+n@bkct+5Ja3k9R7z^3N!d-ZxN)@f=#P9rc#6gYLcq7F?h%t? zGEBEV3_lgJ*j<%|14%5C-%m}aZdI9Ms_snw%j@q)hlgF8J3nV}npb+tt}FBEL0`nf z)IK|KhiQ&|6)&tjN&C8+f$9lf5>8ym3+*{b>I>clb|BbiY}_i1M*Cf#iFHnpqkQ7Q5uS7v#q-1e131~pvRPUG<+>tUq zRR0W!apK6hlXNm+^eVKO$0pDR#5oCM$gWnDpovK-QJCMXpm zT61i~3X%F>hv&F>%toZm+UN9-O1-&b3&-y_eaAie%N#$4J9g#XM(#}=yHfldQ-A95 zolNojsbdTEHoDt-ep6TT?@kk!%RW0(YQ8a219w%aT>f`yUFtyNz?4*fJ30oz6-L_EJjqIUd>tMNHJ`rK4her1F)OE5_8mUlz$e;!?#Ukr~`KiqpK8r zm%(j0PBCPjEMWy)T=+0hd(R8F6>J?j#U3zgy46Xhx?|^rY%u=e(3Za92(}L42PKU^ zVC1G0nu(NOILa}T%JGAo#@jLV2}dK%6;@W2XrcfvDv+x@m1WQEJs8Cyh*~3lC{y8& zTi$4mz98SeP5PTKI!nj1Pv%^+*YjP64eetCo z@d!d|#37D?(3;{+^(Ogooy~t>Xt0LUFK{FM5f{ncU~jZWJ*Xim)NZ2L3|oKU$bTYJ zk1Y7pXXtH56xzd$m>b2oFUe{V&r@iRZ^yHrnW>hE)33QqUpXA~Rm&3{9>kl}fl{Pg zj;2VK$|(6Rqg)|tW8(|T%JK^ioA~%CQ}KUmc(gKR(Y&E41~vVapLxWKIc;IO&~ulq z7+a0-sj++{^&#fxbDIBQpo9<^EyS;AVf{L5g64Y%N-7R{ua~=L!zlV3Iz@Smr{oG& zC@PUYC!I#=Gzy=Sj;KT<7_O%ZqCEH==Oo>ZqiNn&_ZF znR~1!DLN@5dJ-{>-QP#Bw>5%~uwo|Otmhu~?-%Qr_>RHe(dYT9?ne^XN|Y|v(CWoY z*wKiT8!bkRUNj}%+??mhtj>L3czS>OefspW-}KP2OB}=Nkh{y&cGOm<;Mc^^$@md= zt^b&Vr%oTwJ9efdX3*fVvHeVSpy+`OTK2B3d583S15c8VK`GYv*d@c~#L0VQNd+;x zOfvDQwl{6rtfb`SGtHpNr^f@`pi%8Bs4aW8ElZlUU}>VMQXA2^UT^rO89fR1d^5rDliy|ZmE-dJ%} zFNY7!Rn!aKy>ze$R>Uxw0%-CYMk)yFwER731tt3Ju*-NX+J?k;iZxI_Tq@k=*>=F5 zv3+UMoJC8gn8WDvN;!A)k~y>HES?xOb!Wk1lj?^^oeD0idhMU=S1#NuOFS64$5cfd z@%>&7hxq*hLk11n%g2ix+h#sq3?9J{YyF{Z=F`QJQf4)$e7WDO>5-caawrH$zHt@J zbTmb+ET*XEMV0ve45Ruqi0WgIL{95_IFTyDmwHLtWcZ?&M5!;hD(aOoilA?MyH zn8H!V+XN{ZwAODaXt#mk6hOlj3QB72Buyu++KHefgN7pj!xaSWu6_$mx8~X^a*9r; z88lbvmo}xSLdQyyG|W{_C+EZs)rU@r>z8b(EBJIgEoC%OSw45xs!8_P37d|Z=twT= zr_d*V4T5iB{@RWE406RWHDCM!hgQwVRmsFxq@QEh?){{ckwuPbMvhA6o&KC7)4LW9 zt(uXonvt!NdFzsXj){7uj4bL_$rAr))Lx z#Z~E6OuJI2otl%>h}uvaNR80^?SryghfMn7iZo?WeBw~MIsvP0F=x9`U1Lmq(M!tN zn&+vo7v;^JoNkgyI!t-;yo9-N_M!2foJA&m5h8Ux^kC#$JDNkPK^wFosfL=HYAT}( zdCfU>v-WRb^H~x*$q|vv=dsaZaw((lWvc&mt2X`ezBxVBq`K7c9eWF>lub?q$h1)S zY7YY2$y4TT%g))cJ;zjsFl9Q=;VVQ}(NZfqwEaM_4xjets16w|notvi{-copGZ&m_ zR{anG&&Hh(%Q47-cG|x5xd}6uC&o@PlYdz7!-DUouktHZ&gL9CYHYLyYQy3SPM8%+ z=342$+fUBvtq+|%d9a~2#0~V;CM=mTcdR{r!RB=HBv!>DT*pT(DjIhRi4To6@MXB< z*_^&D*Y4T6e1SQbRvn;zIw`M4qt>e%2ksUa>OfY+L~9DLTCZW>vJK*EZa zIs2{R>;oC*rUhw>cP_6(f#+Cvc!aOk1%4Djr+(zAu!OJH1%9-T9I#WDANffxJ|)+O zf%Diy5t`2_My4ZF#@j@;`dzsU*+hHKX zi&1wB%jZ?x$~ed4cG|>D1k+L(bx>D2d$#z>eH{(Sw~9V<1&wYTZNT0|I=nqE=QsP2 zjA>)zrp3j@nzWR@m((Po2)Bm%2$o>8hLZ~$6#9bNo@y!O%IB+jpZ?eRdpqp-_zr@f z_r26M%T&dM`-}oka9n=Gl5jwb)&|S#o=I2_m(^6BZUsn~A)l(|efnJI@Ug>wpOej0 z7vrQz($E}<67`j7GTo9A$1fT^Oeg;uf3!gG`#11MgP@mWrW!NpnKmpc@AT=CyyN9Z z;`{fHj2~{Q?KkFg3PzqnGp$4K80NoXKZ#M|BdsXMQ*uT}gT_}#Bdu`=HR$V!Dw<*p zoG_(-xK3X_>41*t_~ahGyfo$1zyk(#!WgYMWBT~-vs6|gPK#KguXH+Q)*&7C*&K!qkG4W|3Cx=qSt@<>Ag2n#zJj*85A(+<5_~?~% z|7O{R|LXXn$qQ=Y2pZ9FgaLaO=~z~7X1V?RuCWQx6URlyn6!bGN~&lqx@-6ZjV0Ku z+2lgDLK-za6D(!RH})lr88a!Nd!Iiz{GmKR@Vl=sw#+hBar!=^mM1vwK4K^rqqPuu z-7^UX;IcyG=~jS*Wcfxl?;iRGhvPmce^bRJu~319jkw<$6CQ+^#L6KW5rUXSvP+Sap z2L{Euptv|j493@EL`=}zx7b@R=p8lMJ0tKq=xwcgXLMm118lDc~a@B60ul;id=PEUQySQ$ruI2I4%SZNF8SZOO`bmR_F zw2dqaDH0+nf+Cg2R;pIUp7IhtfYP*Slp;|iA`q!eLyDvx5qE^HZ9{FT(RJ41I&;Vi zsJ8TvytuQ}P+mZ_rS~`3lN;4QdCCTLD8sr>nz~~|!NzdJ1VK3V?JHc#2?r5s3-=VZn&#^-#{0^lZXW`_I zqNY08AcsMQ&+|Xu9yZ9hEk(|oJaMRfNVG&mpdisXaw9wUEG z+QEt{_JUK;#)zI|yT{1?AtT#`o(S4#s5CjpykimLpC%m zHh-28pO_pw^d3`b9m>7Vzd5D+&kreZ1`465v<|zxMH;1$^OYq6$%zzMrFC!zYH-P6 zaEyZsZXNDIxGLc=N_iML#*vHMI=KtURY?v*rFC!zYL##l!UeYu_c*x1;4n&gB{>So zMFC-4Agn8NI*ECjw-%fqYRT&PKe|ZMtu*YZeF~oraw#grcWW8WVDMU|F2zvs-CF*b zq`687?lfknp{VWg16pLV_Qj&7&x3GZKuju)=Yd zFH4De#fyHk|5m)klW$gr78ZtGk}~qsic58x(p!s5+*?%S*;`cPnHd+CI5W;v6U81x zX$T;e>)vm`u4FDxpSLLi_S=5r{|YH-n_8zj%&jzB-ZX-2I_d95KT0rG|FGuA)j!lB zLy2BLJ!9_CtIRLI+5JI~{!_8=h9yo<8e{K2zToOY6GQG(q`dm4)vNV%MBb-C%Ehz; z`6ukf8FNSPG4a(+>G|l+$NcT&a`{v1>1OzCeo>+Jo)?V}WPe{(@%E^xlAq`=j%j!J zeDd`RAm!AF^W7OZM*IUbHI5Ilq5A1h!th>dW#=XIIzG3sd&s!3CMtUzd^d zfO7V8-1C3_t=5JsSbau@1Usx`UnTYOPCHH@Yo82NYkS}tA6@~KxB^rBdFMJ&R9 zqVU~PX*q-Srw&}f?J=4-hh!C2YEe&q2Y!|77j2wbnVZ0e9`8^!Gzwg48$lr^($F&b z?`%ui`(^Ky8sj9C=QS3doTMSiveqP1I02s0!V zuSo}8YZlHn&0ScOzQUr2VVJ2pN^+-VniKQ(-dm(2?mOzj>m7CZ?xl9KYES(sbHncZ ztZIPi=pVEDU5YAd)A^v;`UvfYzV(-}ZRV$6Ui+3sY%fkoJ{wG`uMI3DO8sGfo+VjUNPtOZeaPxvpi?7QV`G7|5Pi*iO z4%8gr@FALgd*xpn$W@Ruy5dL&6S1XGtu*Tq80OcqvhW1lKWRx~rpQvG9uOl&94smtoH|E6j0S&F81aV>h=Vg_A>1PMluRpV zm?{cjH3~RZknfbNB<>TcD&k=^;yFF_pX{ZQC<=tC!Wt``MG))6CsGij&&Z02Ja-s@ zF4kXm_ZRNB5BLmLn#gNzGbMeWc&So*3GTPZ{T8eE7IsW#2$qy|u}HjB4LeO{6f6nq zam(a>0r!h2#lFtayP$WVe^Z9taQq~vi$%W9Aq)CrfB3rTubE*tX8j~D#8a`Zd{Rdy zmS!!(S0`Ozl?;bb@RPO>hlHe}W$Nz-cOZ-c&xe*IOk3T%hWrlp%Fm&;zswA6*tn(g zu`_@|Xui7kQth&@bK&RsW_JVHcG?-5Q(Uk(;sCWg(%vzP!UB}-B3`_s&Kg$mdBg!~ zdBiq7huR`=eCYN&TbDg{qGjq+cLUl6C=2(Ao+?@KEd?S5Rg!}FzG(4C{T;1XgO)Om z)g;Dm7-7DpMepr=b(G$oS{;{Y6(SBFSW?_z zA+Hh3GLOu?bi;%-v`$TPR&31C;T5rLU+UI`ktT|y0BS`M76nVhEwMu#Jt5nXrXNh3 z&^X#`?LCbA$nWc6FRz_zJa|}l96pzQ&HVD~+wg;5@7q?LzNA8RmTTj-Z5uZ3*t(@; z#uj}>K|#q}GwuY>Em*s&K;N}x%i68x9UF@0%yAXZI$&j!!yke9&kjymzlxgB@=NJRP{|N!z=a__BG#tkn z4#Q?lr~h({ryJy;pO^xFtPO^ZqsF(NQ5>f!ucVIX#Ap)PUU21zxV%eyH4ZUIla_4V zzG{d0>haBWJM@{`8y6fmUxSq^m00CVQgwV8(+zdYiuUN87iEndY*vsn zS^EHznlCHj$H| lTyMf*`5+vS=NgFDoy6ZwQ-89(c$@9!5zL3Q@?60f-R;BotC1 zQ|@4t&rc<5kqj@VCTe~hfo3!@@=CCNEQ`L9f;?gOSyW2maFL4{@njS6oLuB$NaFCo z!<0KB+xIV(yb?8|DIx+*)Xd1sVJ(tHU(uHWha+OoXbx!d=eYIkhgcX;QF zl=T*9U$Uo;ZYLtlWa`+J+|#>shI=&m?-o`U)b(m+*Etqa(N`9`RJ?;&96JU zvtrlwO?uf%yg?SWq^MxkY_o#aK1;o3wCAKmN0UPTeh>vkHyp6~DsH~2fYn!VSyBo` zH4dwP^*Ydhw`KT_g!Ow(Ti33wY1lS5W1|JFZ?K;;d+qIEj*PZbtBms8b#wHb83oQs zrs(E0Z=U6D{_T=%)0`5Q)0w~Fl*>Zq{;bo!FQ>gU!|%aq1RhviGjE$-U$gn}X%l%H z)%9hS<*O~*muz3Yby>iX`L!ieO!HPQUb@VZUzxvpc6mVNn*8-{lY$)a=3@1{d`Z*m ztL0Cis<*DyU#io|?Y6v*?3h(sU%#XFpnJo-l5!n>SJ|a0W9o;Ssb!~5R_iaF z&{9{BBi{6-sF$?!vi@plwTvzzL~R~+bdZI*8XU@#o%~ohLkJ%LGuyLmW8*OsjjmR= z@lDk$3g<6eT%^z8N;ER-H5&Hz8M54fJ7~pf*3Ib zL0oA8q%&L0C*sABKeZbgb*CV*A&7zyb47!Vg3w)3kReRIB$Z}UG!hR?qj%gZ1wwi;3jaINUM-f;_)AK9u|ZV)g79Lg>y#HGu}sj80{3bs zA*nkKbPsnBlG@^;LyB%;*L8~8y5$ZE8t_AXCF!5PhABxqu*AJOUC3~Od%CBPw6MUv zQXnM#f^o|P6=DN-??@r3U4eV9lae&xh+uFz4ciL}0%O`!6e3gBUua2*oFWuM1*U8u4H{AEK z?+xF2U!kwWcieZ&ci;D}?=#=Oe%-<~&CH|BCYyNlqANs%d{~Hj2 z@_{OWMuAp=0f9+@Wr0}W{lMeEmw_L3rib(AUq~`VIZQ{=WWL|B5}!s<8$vnWeL?Y#{ibO;W(~8R+1Si5+nW8&;pS*_ygA97Z!R%c zn9rLV&0=$(dBQwvUNvu;_sp32f%&ceyyuu^F-us|s$hkzx>ll|9ro3-28XC1PRS*NYb)^+Q)6|+9HKDNHFzO{a`ez*RvrG8Li(n9}> zTSwU2w`|#f}?`YnE@x`H9f7nG^ z7U$&VEzX%WZ%tv*#x>g<%F$=e+px8GD&+1fQo)vA+8AqxFTCRV$9X6w-sXPD7`+3dg9^yC+YdVZ@Zq`BvDmqx9Xk#h+TM|N$3dsxd+*%ohY!yUZQXj%(2kD8 zcD$*ei5MBF#t9VO!m8pW)oh}5dhjv~Ko;;b`d!r+tA19 zjnp;e$d-cYA|nIqL)RgvA3i*D`tFGXxf3@zSowYS!N{cZk@*VnI{K+BPg62>V@m%$ z4u(qEFFi@WO%;PQff`U#8VylJbpa!|-H099d-=@a={-Vp2y6_z^LUSH`S2JyN8hL6x0pUVKeqBfE9^ z2ZyTg>GS8#m@$9Tt`Jq>^>6h<7J?ayMq>&!#bIEV4i{wR3c!Kxv9O{{!mwCE@y2m6 zNMZa!0izTy^4c*f!bB`GAVb#XPDqFUiQtAw<@at0N<efe|=HZ%M~!O-^9yB0?xYWZhj3xWxRzHbQdy;=M?l7QWsI?QvBaOR8oBES^}1-^AX7q?RXl+(;UnH_87~>CS4j>;!q;?vJY;}nlNEj)&z$* zmgAV<)vzf66EJ}v**;_J*sK|29Qh=gCg7HsqX6shzuy#4_3b~O(#GDnj{WMDqcCH5|h+7dZ8##4&V&~gGq1K3c+M$z|$xu!WMO!B2S||)DgjcrfZ!Ql0A1RGRuH)xjtyjfswsxxo}e` z@-(_ZfNGDYDUJpTGf->zxOJNo-}P$-mJJS3bOCFQQ`423|BsUP)977w%Kayv#v$Pl z{C>M4je3xVJ+>5 z(dID%XZ|%+tQP2hzZJz%T&q^(cjO1g>D}9ooGh9(WJ3s@Quh70)XUX^LG_=_SWu`9mvp`r-QV34o!72PnX{CjC= z#7=F8w_NGw*Hrdu@o~p~;h=(jfIurvzX&+RpaeR@IO@U>t|9#W*!t zol|oDveg@3atdLm*r`If3UuoDhCl{8V`m&4)Db(5PqnBsbtbo?leaIMECUlMi@`qi z63yHp3RIzRpaIT2uAW9q1;hqi%4pHAe|xa;BF5204%v$~Y}vAQLoqO_$>DRi`vFCT zG!qM7R=5Xe(w@8Oj*`Tp3f#!QIySW36|LiWCp{>?G$kB;HE1p zLqLfl{!RCb9~F(?uOR-0sD?9vdu`&koh*3tK3FOp>w1ThX98WMIK0S#trp`#A69@3ZE*6D+vheO-f<;(;>7Ge8wq7)YPo<1 zPgUGx{Px0BIM>F|KR@N?f}0lzu(9)B#`8+%Dids~!NILDPJo(Kw}zxoI#Br0=ni!s zHO9nmawia9ABSQxCgV_0X58JQfZkjM47+l`@eC-G0XN){FL0U!zU@sxoX`4OK;K1f z@qm3)fxE`ei08!iD{I!i_`=!{xD87LU?PVEtY)0q@y79$AxNNV#*mrIN4^#UTxWN{ z2qjYl+_)!g+yQnnz5>Sa*LEx)5+pYu9g|UiWJuc`fMIU{m%l6WfbL^F=m^R$u zXAabygS%##0%Kk8zH8bCWr%8ky;i{HXZ}$bHx1m|?BgVl^Nj+UkEQ*FGJ#=B4m1^i zB=HD?Pxa}8d~VnJHKu76Xh8c?`(E>FKlnxw!*|yoSI1w*AJhVZ{)P65f4>%J-?4i? ztq^h7l> zXKa`=5EEy`Rt?15MKd-KBerDOVq;5e*%BkZYQ`$#(5l!X=YmLcP2{5&POwmb-thStvpOcs3l(1B~Wvbi+Uls&CuhhPMV7;HUT%cHqybuoM3Y zbj?84j>dhv$wmkJV=0cr$v796;|6S)aQCk5`*zR~JP#9iE#886<3s4;Gx&1iEg+9p zA}FUUBNyNIlPUurtjKTk8OTR>lw&d$BDP6!!eWgV-69i9@l5{s!uLv=`t0r(wKt#9 zZ`h#wqwfuQs5GPO99rKhyQE@z#UqvHmFgr_-8O2X=6=xVHHaWmx~oUmxx88CB8pN} zV>BjWI_6?AVpxYQXaK=yF*tkrkkzW*Oq1EIaA1sf7LqlteS8NTjUai24Vwc*Sixq^ zntj-Of|eBi|{naIxkSojJOcb9`E1v}MQqQ1ur35UOkqDih;i;_7Zh z&a2{=wdw6-Z2EHr>`Sj!5tf`e<@WN0n_%CWzJ5G)7Pmd#U+Ah78lgma3s zSOl7E!sj5H0DITD0c-vw85J9|5n+O}gbgA$J&8u9;6+YG6ss(8KB^AUJz}?4+iDK- z)R@$n<=wG-ZjB~#5%Ev}FPvtD{w%g=GO?#+yHesb=r!)T=HBC|3Tc^8?2>Y8eo1;^(~%kO^Cce4H> zlHsy9F%~T+0K_^W2C@fY($xbhI6mde0!bBt9Zf=MNt^xNdGQr2xE;>)u@AWA+k1p^e01JDhN}$}73YY~m6Q&% zgUXUj7j&837*mAxQOI%zVO-Az7wAaCsTv4+lRMF-F!aGR>lVJ2^~p^W#2O3O=(9*> zFoZ^3n94EyA(#fI46Urh0S?`_bwbdY7c6ZQo+K(sHPL{kN5iE097wn@Rw+SJXcGBB+#*>h zBeOGOJ(Fa~3CzKCDGWT{D+l;JAj-^^Zy*i*)^F6;H8n#*gxLB5AUl4lhs1Fw(;)Q%#fswoy(}XY2dNOfGRM6@)ad_q0n36) z9V+x7??w=15E8r^k{Tkd5sXwhty+i!C6qKFD**L3HtPa!U9Rl{LxhIH2d3vJyKp;+ z_15jBS0p~>)5~cU8*7qVQDv|pw{JSZc_BzxW=3>0Q_k($1d6_XEPzi|hu_T792P?g zTqoEBvF}*{yzq!HXmzxBTJ+x-yX@Yes)Ba_8qyI5M-&)^pd6|Y9-X#?i~68nc2FAF zXaGbnK!5b-^jG?gS@lB>w7rYGD9cL@8$Qm$oG3;>mhq!YC*M~Ix)%8nbyuG(7;KQy z>SL_LSa{QlH%_{Q085Y>N5`Bj>0?p;Tb9=sa}#1DRzyxbRuYKm!MX9J_I@U3C6-a_ z+Xo(vf!U>9m(<2W_TGGUjd$P|!x`-JB2~cRNdnks_^ks$!W=>qfNCjei`bw>z^$t0 z;=*ZI=OhXxt#smA+ez*zYtW-ji8c4^($aw`N=Il+X$2aY&Av|ZDfCjs=1A&5MRiyi zRAIf$?W|A19>Vvh0iZ|J{6yE|k#1mYVWGS)k)?e4AWO>thQ+7&he!UX2i;173+YI_ zh2<5~sY3z4WpZ1+)Zd=vxCj7Iw_$7xZe`NRiDx_k?w%@)o?x%co`SqDL%)DEjNaF3 zfQKtKRNSy&B{kun&q6NW$2UBn1gXPL%rCNfgfn>D2$jFQi?xHJ5${rSF)l5HzvLbirli2a4TAM4X)(!7`JG)uU1!46$5-(lttN zcIvu-Knfe#;Y`3Om%}BVB8HWq9NQmbM%cy^1Tch47K7eLce@aA3^b?|cfxNPh!qNs zVg0A|PZn|A6FK8%&}^F`CPJ%oI?39xRZ8(iEcpN*=zKlcglM~@X=!EI6prggD&nLI zX9M!vWS3AhkQc^qNt=;BxYDL38{8kR@K21uZ2K+Il}-PMNA)~(G00`nX#uv$)~EksJx~8W!N4i z;og=GYF(?n2zHZDSnAoIjCm@zDp7?_IG_qMwP&%S3InZdqCX3FWTisJ^huk9^Ea+I z@xGWSy2R}u?>#*mMOrQJ*(vre-c_M+{Si2HRu+ywfyIkutm$d)!zelp>)Xn%E&CkV zs8JTU*5yz4aave;iN{lAS;G<7%D%tYSpf)yJ^+W&AGEq4@v^A}-2$1>+nO33C8$aQ zWu5qO{Xqt7=2A>wJ`Br`CPkVyZsbP=c*nlqLo|Ke3 zxuoplav@HA+L;l1rzdZdk5Q=*qeZXcm+Y=Ki3(zggh8!jYT3eQ*5sZ@Y4()9eLywy zpPcO;)UtAE*NhP-SX4Rwx*yG&(UDj)&J~RO=i|er=at^}iJ?j^-lLiwV?QX&k&~Z_;-ok;u(FPp9l;Q~5d3(e!O@~dNMME)`BsZX4T&ChRF5#^)y68k zvQh!7c)5s|$wN@`12exU_ktGRR4B|IRu!an~8V-bi80rHD_PzLUZ{}D{ijw zo9_QGv(9Y6HFlc^ZnqUTkL@|qze?(30r>@|JgYpPM6 zxfr+D=;O&_JCl}z1KXmoz_Ebv+tJiCuKJ{#MSRH ze*SEOW4Qjk-|d{)W8)9bZt&T7-CcFO)qAY9I^T7t;rD^@b5KVU+5nuU0cfMGv<<0) zU(o;Bx9seQ+ghqiwjFPSGh`Ly8ox1)-37=oz2$ zd0+4)U-n0T@<0C%41ypRlm<}{6Oi{ZF9WaeO7v=PAm>fqLgekR>mi(JeZ7R)%y<*wjdSGkJwUFSM3i1%VQx#^!tx3~j(zULDm2HlVbzUEuL z<9mMK7d0?vXsLN)%dN29CYx=u-3~jE$RGXB0In*Yt~vU8Z=l$ly@e8Q_jaNfMD#8Z0#) zqm7;nAYl+A=*=i*Fo?Mnm`KJ3X0wT{S<1HT#Y*<&Kz8IXj$=1Y;AHmVbk1f!&gEPV z<^nF`5U${Aj^OlAjciR7+prDQY|D<+uoJsdiwSZDFU;{XKT|S` z!t=kogg^P4kbn4xh=2K)kpK9PJpc1QfuEapms?~J)fQV!=ntWA3jbOqWmZ{5V71jm zbNvH^)>%iT4K@(jXd|Jmwi4MzB)Tz#8xJK;fpm)BSVKxJwUmBm((aUc>M5mxPErDj zLzPOWiQD0%eM-M%CNZ;^O-h8~Ym)A*FiG_fpUiITO~O9xL&m-wN5b(OPdiEfza^Z) zDP)|+d1Rc=`E+stmy&Tg*HYj*ZYSXm?x4V(+)2h=+(p9O+(&`?d6-^2!Xson%9Hfw zDPE#4FY^Zdd6PF8$XmR}Al~OAX7Mp!(#}_Wg?!ETr2N1S6!9ZJk@7P?GnHTXg(>{X zAEf-rpM?Cy-=zG*Kg9gYf291+|HLAcs{xhf%u#HSMNG2TVseJ&NsWz(EVGQ%a?1&= zu!7Xexr>!ZUpUcv>nWeU^oQhavWaq=ZDxWkwjdABk8QJ!BCo!I)J{8@;Qif+UF|`^ zp7x|U1OBmzeeA;=``VY;_HzIQ2Re|sSUl&T%w2-pLf4;uJcv znvyx+`B?e;Eo6X;TtqJyyO_i!E@6(pj-aoZ8JWvm#*$>(U2vsq=<8b7(veSPS`?dn z_jotEnNeJIL}$Saqx^(wDo+SK)^ z>sjOt-auDx^hUbp&CWeUz>~ z=9BdBDW9Tis!W65_=jKNgubS)akh}`KBw>KJ3K<))AzVFCz>i=k`_%xfBu8?5B-Bj z7l^-xG2NgWsOTo$#7O+m_45Zof^a39j-gGL1J0<|VM$EI6c@iYVE<@ohUKKYBmGDJ z!PEcrKf?CWmXgF~mz5$B2~>A^N31kX&hA6*O{73P~kf>pEZJ zWQo({kdY&p!c-}9hlWxk&WkuHFrCT>OiE)G*J&=yi4YUXYx!F9*Kn!jwLCA;YHO`7 zjV+%7bY8m)=baSdOtXQo*=Q3zVcJfnAPi`TidN>H@ayV9g96+}TQ6si28)5*oKoJ7Q;QpDJ3 zUVw_q%qYqt!|TdVe4#0kLNQmEY^T;m)}&KrudWcM*o$h+i%wC5BK=}H*|H+j*eK>$ zR%AD36ju;XG5Z7lNIwLD<#~)rB*IU`P9(xi#yDp~GN@!kYdJVEFL-M)6hS7(A<5(j z$&;EqdBpfMd|igW@DCKK!xtJ5Idc1%_axBRX3*g>nWA^8pf%bU zwQg*=eqmUaWwVTNIl2nt*AbCN}5{dY!>Zy@NaDYH9lzwDSrrX;PjW z$IE8vnq%PGBCSxE6YKWq+lVo;#W;nE;q<@mh2hya)ZvG zQ>k@YbA!SlH#pHbtf#%+;!0;ube5df``h4Dp=TXfwdsz%`!@EjTamhq%Y!R%bL7}% zP3djcY}>(hRMORt2ZsN$i@^Fm?IXyCpTzA1BVvkVP>W9YG5g|N%coe8!3UWW_Ny8(mo#eLA-`l~F3)q-;6~-d&inlLOlZ=cn9>|# zV{Wk_ZttSIfcEY8e-C1hSicjnZx*YI#$;7%R)dS2Qt-vC>|3 zknOlcz2rq~Sj4&&2RaLfwp;Uu<(vmXH=}a1nqi|Y)m(|#%%<7GZQxLAt_}IB&}xB~ z)Pr0lI9M8=48GRBG~p8&xlEnrp}jn3Y?22hjQegL@ysqW7$W(>8x z4v~F&t*Qw{FFH=Dyz+S+{htjMX?>xGf`iR=CYgaM3Pi6X%wl^`g9yo;d+nIh;1#)! z>O1ZAh$@N#$J_pEMB(5|*_q{7Kkw5^jY9&f@=n??MGYy{Uy?=^y&1}QW>L%%*0ED` zb!p?Z!4O*gAuY(J55t&15hW~TJ-b}{b^I5TOgin!qc6jm$ZSek#s+rFvl^+=e&@V< z++TMnCDaB*h_e2amW1d>A(NOx8Ozy7y)%zc>rcy|16?U#1e2LdIV;%29^{p8{b{Yp zp&R`f$rR>M!Adr>7lnzs{i>K>wM=re> zGH`riF}1AyYgsS6cGj%oYPa{o^^Q2>P7ip(3*PYl?#r`hmz2A&=M*oT?|z*8cHBRw zdF&y=5e+|@A&3lRyE&z0C7vAQp(hG31S2sXQ&EHk%F=n2vu1m$u^L;j7dPSrZpQ<7 z3a=>NEnYZ(mgh3Q#P_)3_{+}=!VrmgBq;;MWwVRD>1cxxx*#8YF-TchT2oT#9gE4B ziFqhSC6;0}Hej2wzN~UisrPE!h$A?KTX8oYz+-p@FDc(BFRdx@zKf6XDZa*!_|5T; zUzi~r(Mo^Stm5jhW(Xn!?T~{!^h5!MV5D+<)xy$wVN+3r1t>)|mZJ`vumgLQ*H%@9 zI)oj-F`U8eIERPu1fIhyIIn!as;0au>>@tLxA+-ZEe^l`)Wr29UL*l5(nbUtWX6X8Y3KDc;FC*M(ReX z8?SDHx=q!MP&Y~4NcH?iGmP!Y07eee9&`caETxVu)N?I|IK}PU$73zf#op&KU-L76 z$%@r!i)dxpOIzcNr+C}y;-Zm1mOqr=m*36xmCws>$iK-~tMs3n&ZP8X8n8o7e{xM`pB$7iOJsHAyiYR3{o7l?%&Tx(gc!Vc- zh8K8+H+Y-(G4`8jjK+TxUKMMieT7y)C zG#hCS(p;o@Nb`{vAbZ~|EkZb2(|97dCMQH<7gsY6ku=tP za;!>XRO(zqyS+LxD@Bj3m4|T|>2r$w+yy^i3E8H7bX``btuBjP=4D8&){H-|_wg}I z7Xg2>rL)EEWcZJaQX?5fIf;osd8X@>j9*0Cv|T&2Q@gZV_1dGo+NX0QSRB=fKWtvz zs_0!cEiFA+Gcs-6uFY!-;jD{WuQhkLZL^8MP&0+5lcRPR-k9S}tP$>R+|UVy^d|VX zxnM&cm)wJj4o;41VsynG62Vt-{YOMD6p6>X64*;!8}}mZ>B?$Ob2E2vpBgDa&DBD! z)K(q-AAm7~G+a}-&!3G}Yp*r8XYC{Bap5k~#k)+m-<@`kc_KZ{JS{xkJpDW)JX1Y0 zJbMBg1HT0Q!DhigFfEu73syUua~#?)%HepG zo<8Sk2>b7se_#Cf-hU5I-v4~OnSZW?urA$xaW|VTJ#lHgmS{;9u%NZE zJnLy=ZJsT_57{Q$VY}>FJ7mYAM%w|q`#$Xjuq)2zf-cRayKEN%7g~+8gkz^me@O0J z<#d_&pn6fa=q}x+SM-w_bhjST!#bf4bXJe)cAe81-J{F8pi8=gonIbF6u;-vLDI<} zoAz{|%YU)(qJtSiA!C@xEQ*-V0!s9NPU=C6)V(;As9)w)^F^QAd!Xk&>sik&+{ta+&N=ST$K1m!yvR$u%m>`hM>Jvy zjw-@gN;Ip9V=XbP!OsSou#x|BrslWUYImYoU zV|j+@yv9u4U>dJ7gV&kE+brTk7E{Va%DGG#ml(~HOyGG7TEPBiY1YazEYs30#$qkr z60NEEE!v{2iN#q0KP!pv6{{GZ88ut$`Y*;mTB@(ltQ+ zHAsUsMEz8tp~_aCdhvr=GLLte&0Ean9g6u_kLnRUqi6NBg193hcICrt6Unz%3C#Em`Sv}2!{V0-Qh0AJhQL{D zKl%0$ekCCrQjSlCtd~`||o37w@ov;;l0R86t1ngv5Ab&q% zt&sdlTrvThk44et!6bJ%1z-1VBR8}A!F`U;$BMgL3!SIXqPxooSndUczDA=sfS3zY<>ox zCtY2rf@FIfpM6RUz4=T#j|od5$wqWBa&d$sR|n4;Y$862nQpaH^HaoFfhH|C%}<5P z>K^k#zrtKt@`lJ<5+q0v@PAO@l(>CF>(^V7u5y zY`64SK*M+zkv>E1@M{yR7mbay(uWVp&fb*9`tT{s;k#Y#nJ^M-vyRX_(u|s(54EgZ zzvbG}L8DPok7P#|4iHa6oJX>krCeD#%$6KZii%fmjN}Lc+R|!dWh{{~ZyZOwPSB4s z%2`Gw3mcCMRTJbiL2?K+C>IJ+#4>`6X4Z)HcbBk`N`j1KA*C#)j9Rh@(uZP-35MWR z_a1yMRm`Q5TIMo`YzDHBVk#*M*xa9`RO7{F(U&rcnZs!2GM^fXnMEZX$R>31v)viT zP$p1F_s!duwM;HPKAB@zv5+!K2}ZC-GNvV8HDqyLKpEA{_ARR2x=}WHX001rk001rq0S6UFP)}0;08In{03O2t z092@RJ%2<;Q&mC$0Bgtq00s~M01kfP5sC&+Q!g?A0CCs=002$^003ZWPk_K2HMt6ikIt^kNrhY_jUQxjWugKh-;Uy}1ablV?ZcJOI0~5@IF@2dBCY8x# zMlfTTNz63n8)gBsj45R{GTWJhOgU4-oMo;v_n4>5E9N6ZnEz<>ng$vtO$&{O##_@_ z(?b)k8K8;R4AbOl3N&Lh(=@X*^E4|prJ9YJ9h&``YRy^A70pe}ea#P=pEbW}{?_WW zSldL~RNGwZs%@ohqxIEx&<1P6w2|64ZHhKsJ6v0!9jl$JouU0kyHLAayH>kdyGwge zTcJIvy`a6Wy{CPueXadj`@5FtG&+N>p{}XUqI1`^(*@`{>q2zBb7?`%U*3%dmR30qev{Y)jUY^=CV=J=h2~ij8N}*bH_A zTgZ-Qr?4~Gx$O7sN_IWFmEFT0W~?QUl`+$AUzGXkKf3mfljx%zNIA_j<^WlQI z{#+V2lAFkV%`M|LbBDOo+%4`U_lalthI~`r!n^Qoct5@q-;0mr%seY|~tA4M(Tz^`BMSnwoU;j-1PXDXkYS0=4LlZ-DgNMP-(A5xXh%^i| zq#7~}BMn7{$%Yw*Zw!kKs|*_rI}8U66^7G>D~8*KCx%ys_lDmLHq7FBxG^?iSL}iP za7Wx7hvWWuAWp?g@rICLMOkCBLPn)$6cyx$6yy}-XN~NYo-w8*t5-%kMfJ)oC`r%A z$jUDXwf93QU3y8F9S-~7SeS!9%)uXFml=^!Fltn~V?5%2l)Z|Qs8Frcs`*Je= zN118wXWA{1Wrwr=H`TbAPm}i#e7+r@Z^!5V1D}kLu+kC76(zLI|! zBEVsYo@4$geT+l;7{|KDsD>D4mpJbK)IILMh8Snp`-J}+nP5juv@=ZnpJK9yWYhnK zmI)UQ0+s*?x$`8pauN8|5k>UyD$Cd|=<+Z%t!ME(xZ{*JZy*R91t>F-#Czhe>pj%ocJi|}{M?(dl0w@#*G zK7Yqr{2hz%ts|*hVBL=DL_1dI>yYW|n8DW}+SkGEU$+*=48C*mr370v&4!bSxsMj-+mZbvvpP?O0imLuQa;h9HONAP0M3-C7(o z1l8%x|6le92>5sR-_{Cf|L<!{(GXpe@_(H z>)+jf&l?!_&u%~`ySf5GI*rbqm{nBZU7VYrO|KVwTQbhkFBx8x<-lYYj45&exnmue z;@t6$mfpSjb|_0t6zx!cZk-^zm#ji| z$#y`MtOBZJdux}hLJr9)WS6W04xNq}U2NAWZS6W$TZc|56Ahaol+odOi=+foxg9-Q1v3G`pGPyQAJgzI;83}uYkq~3e=IQnx$bWkH!rOPOz&u zzn~A&Ce~FkV}If4Jdh( zAahJcN%0sO%1Uz8(3hE;k)EgelyA?V(KM>%rsrkmW@o1t6%~vdGg@7WU#AZCUXi*f z2cn}Lky$V<-_h@6@8@M@*NwNg_lFgf46l=unV(lMk%r%_tl|E&qZctc8Z^D_TI>o_2e02ttiC;^W665!v_o^xbO z=v6R!f_*zKX&xDAZCw0m40jne!DT>tX2Gc3BA0==`6CO)db@<=<+<4Did|@w&MF$4 zmFexMuUs7U)oHbG5|D&OqY3Csv=bdbN6{a&6k?f%v=nk@`Y{ukZOmQf1EXk=MyCnT zbkRi7f+k(FT(eJ8uBo8~%ni*;?PppOEm(ZCeYMfrRP9i0mi7znbnP7NJnd5LUhN@m zwf403vGxb;2VG-bGo6dBmCj2Sp^MRt&=u&$(=uc=EkRD{9_rrce%1ZXajC_$&N9{ssSrf3Mfj0z%Nc>V5T{ z^gZ?cX!#JYAElq6|5m?1zfr$UU#&l-zo~z#f3N>w&=?vTM1z~blNJm?v}EXGNH7dC z>;jbWSNu%XIOV>n~DXt-*)Ww>j2YA9*hlJv<*K$=Bzisw`|yMd=}A5#nz+N& zg_a>jY|q_K(!gK_3uvD~TUi+$EQubtUFAZ_y4nRBTkiJk%841^Co^|aVBXtePp*I6P@D`W61DM<3d zMh}Vg*#5Q;G&LK=@sg)x6v6w`d+?Bz>;!+wB8a4?EtU*cV((#?Xj?FKbY9P-^Y2v%kg?_9}7uMuJh01tPdYH`#dh z#Li16ju$7cwH(~Qo*UhNUuUy>L}XW)^oEo7Npn+VOkP-z_?

LPf@V65&F-5NFaX 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�!hjLIAYD07A2wkB+41=*S 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 M^v`*(x()yU0MYPzGynhq literal 0 HcmV?d00001 diff --git a/src/components/about/CapabilityCard/CapabilityCard.tsx b/src/components/about/CapabilityCard/CapabilityCard.tsx index 817f532..f56979f 100644 --- a/src/components/about/CapabilityCard/CapabilityCard.tsx +++ b/src/components/about/CapabilityCard/CapabilityCard.tsx @@ -33,7 +33,7 @@ const CapabilityCard = ({ cap, isDarkMode }: CapabilityCardProps) => ( {cap.tags.map(tag => ( (

(

How TrustVC Powers Multiple Ecosystems diff --git a/src/components/common/AddressBookOverlay/AddressBookOverlay.tsx b/src/components/common/AddressBookOverlay/AddressBookOverlay.tsx index 7dd12db..238aeca 100644 --- a/src/components/common/AddressBookOverlay/AddressBookOverlay.tsx +++ b/src/components/common/AddressBookOverlay/AddressBookOverlay.tsx @@ -73,7 +73,7 @@ const AddressBookOverlay: React.FC = ({ {/* Header */}
Address Book @@ -102,7 +102,7 @@ const AddressBookOverlay: React.FC = ({
Address Book @@ -241,7 +241,7 @@ const AddressBookOverlay: React.FC = ({ {/* Wallet Name */}
= ({
{copiedAddress === entry.address ? ( = ({ border: '1px solid rgba(169, 178, 187, 0.33)', }} > - + Dismiss diff --git a/src/components/common/Button/Button.tsx b/src/components/common/Button/Button.tsx index 428a1ec..82bfd9c 100644 --- a/src/components/common/Button/Button.tsx +++ b/src/components/common/Button/Button.tsx @@ -19,7 +19,7 @@ const buttonSizeStyles = { // Base styles for all button components const baseButtonStyles = - 'flex flex-col justify-center items-center gap-2.5 box-border transition-colors duration-200 ease-out cursor-pointer font-gilroy font-bold text-center align-middle' + 'flex flex-col justify-center items-center gap-2.5 box-border transition-colors duration-200 ease-out cursor-pointer font-urbanist font-bold text-center align-middle' // Button type styles const getButtonTypeStyles = (btnType: 'solid' | 'transparent') => @@ -174,7 +174,7 @@ export const TextButton: FunctionComponent = ({ onClick={onClick} disabled={disabled} className={clsx( - 'bg-transparent border-none p-0 cursor-pointer font-gilroy font-bold', + 'bg-transparent border-none p-0 cursor-pointer font-urbanist font-bold', 'text-primary-50', `${disabled ? 'cursor-not-allowed opacity-50' : ''}`, className diff --git a/src/components/common/FormAlert/FormAlert.tsx b/src/components/common/FormAlert/FormAlert.tsx index 229e59b..e777752 100644 --- a/src/components/common/FormAlert/FormAlert.tsx +++ b/src/components/common/FormAlert/FormAlert.tsx @@ -13,7 +13,7 @@ const FormAlert = ({ isDarkMode, error, success }: FormAlertProps) => { role={error ? 'alert' : 'status'} aria-live={error ? 'assertive' : 'polite'} aria-atomic="true" - className={`form-alert w-full px-4 py-3 rounded-lg text-sm font-medium font-gilroy flex items-start gap-2 ${ + className={`form-alert w-full px-4 py-3 rounded-lg text-sm font-medium font-urbanist flex items-start gap-2 ${ error ? 'form-alert-error' : isDarkMode diff --git a/src/components/common/Icons/Icons.tsx b/src/components/common/Icons/Icons.tsx index 845455e..d69a113 100644 --- a/src/components/common/Icons/Icons.tsx +++ b/src/components/common/Icons/Icons.tsx @@ -223,7 +223,7 @@ export const FileIcon = ({ fill="white" fontSize="9" fontWeight="700" - fontFamily="Gilroy, sans-serif" + fontFamily="Urbanist, sans-serif" > {ext} diff --git a/src/components/common/Navbar/Navbar.tsx b/src/components/common/Navbar/Navbar.tsx index 0e47a95..dafc516 100644 --- a/src/components/common/Navbar/Navbar.tsx +++ b/src/components/common/Navbar/Navbar.tsx @@ -109,7 +109,7 @@ const Navbar = ({ isDarkMode, setIsDarkMode: _setIsDarkMode }: NavbarProps) => { }} >
{ }} >
{ }} >
{ to="/contact" className="contact-button w-full min-h-[48px] px-2 py-2 rounded-full overflow-hidden flex items-center justify-center" > -
+
Contact Us
@@ -274,7 +274,7 @@ const Navbar = ({ isDarkMode, setIsDarkMode: _setIsDarkMode }: NavbarProps) => {
{ { {/* Ecosystem and Gallery temporarily removed - restore from git */} { /> { setIsMobileMenuOpen(false)} - className="contact-button w-full px-6 py-3 rounded-full text-white text-lg font-bold font-['Gilroy'] block text-center mt-2" + className="contact-button w-full px-6 py-3 rounded-full text-white text-lg font-bold font-urbanist block text-center mt-2" > Contact Us diff --git a/src/components/common/PartnerCard/index.tsx b/src/components/common/PartnerCard/index.tsx index e3291c9..50f9928 100644 --- a/src/components/common/PartnerCard/index.tsx +++ b/src/components/common/PartnerCard/index.tsx @@ -84,7 +84,7 @@ const PartnerCard = ({ partner, isDarkMode }: PartnerCardProps) => { {/* Company name */}

diff --git a/src/components/common/Tag/Tag.tsx b/src/components/common/Tag/Tag.tsx index 8f432f4..fe4afbe 100644 --- a/src/components/common/Tag/Tag.tsx +++ b/src/components/common/Tag/Tag.tsx @@ -51,7 +51,7 @@ export const TagBorderedLg: FunctionComponent = ({ }) => { return ( {children} diff --git a/src/components/common/TextAreaField/TextAreaField.tsx b/src/components/common/TextAreaField/TextAreaField.tsx index c04857b..0c9e104 100644 --- a/src/components/common/TextAreaField/TextAreaField.tsx +++ b/src/components/common/TextAreaField/TextAreaField.tsx @@ -46,7 +46,7 @@ const TextAreaField = ({ rows={rows} aria-invalid={!!error} aria-describedby={error ? `${id}-error` : undefined} - className={`w-full px-3 py-2 rounded-lg border text-sm font-medium font-gilroy outline-none transition-colors resize-none ${ + className={`w-full px-3 py-2 rounded-lg border text-sm font-medium font-urbanist outline-none transition-colors resize-none ${ isDarkMode ? `bg-transparent border-white/10 text-neutral-60 placeholder:text-neutral-30 focus:border-primary-60 ${error ? 'border-red-500 focus:border-red-500' : ''}` : `bg-white/70 border-black/10 text-neutral-10 placeholder:text-neutral-30 focus:border-primary-60 ${error ? 'border-red-500 focus:border-red-500' : ''}` diff --git a/src/components/common/TextField/TextField.tsx b/src/components/common/TextField/TextField.tsx index af33add..8ba9513 100644 --- a/src/components/common/TextField/TextField.tsx +++ b/src/components/common/TextField/TextField.tsx @@ -46,7 +46,7 @@ const TextField = ({ required={required} aria-invalid={!!error} aria-describedby={error ? `${id}-error` : undefined} - className={`w-full h-10 px-3 rounded-lg border text-sm font-medium font-gilroy outline-none transition-colors ${ + className={`w-full h-10 px-3 rounded-lg border text-sm font-medium font-urbanist outline-none transition-colors ${ isDarkMode ? `bg-transparent border-white/10 text-neutral-60 placeholder:text-neutral-30 focus:border-primary-60 ${error ? 'border-red-500 focus:border-red-500' : ''}` : `bg-white/70 border-black/10 text-neutral-10 placeholder:text-neutral-30 focus:border-primary-60 ${error ? 'border-red-500 focus:border-red-500' : ''}` diff --git a/src/components/home/PartnersSection/index.tsx b/src/components/home/PartnersSection/index.tsx index 59a3df0..3ba99ae 100644 --- a/src/components/home/PartnersSection/index.tsx +++ b/src/components/home/PartnersSection/index.tsx @@ -17,7 +17,7 @@ const PartnersSection = ({ isDarkMode }: PartnersSectionProps) => {

{ @@ -1084,7 +1084,7 @@ const Settings = ({ isDarkMode }: SettingsProps) => { fill="white" /> - + Save @@ -1131,7 +1131,7 @@ const Settings = ({ isDarkMode }: SettingsProps) => { {/* Name */}
Date: Thu, 23 Jul 2026 18:46:46 +0800 Subject: [PATCH 09/10] Feat/sync main 20260723 (#88) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Develop (#84) * feat: ga gtm integration (#75) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader * fix: update decrypt string imports * fix: tests * chore: remove ACTION_LOADING_FEATURE.md * chore: e2e tests (#69) * chore: e2e tests for txns * fix: update data test ids * fix: update tests * fix: actions * fix: actions * fix: actions * fix: actions * fix: actions * fix: increase timeout * fix: increase timeout * fix: add timeouts and video recording * fix: reduce wait timeout * fix: timeouts * fix: timeouts * fix: add video recording * fix: remove switch network popup * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: double call metamask * fix: local networ rpc change * fix: local networ rpc change * fix: local networ rpc change * ci: trigger e2e workflow * fix: reject internal blockchain trnsactions * fix: e2e wallet setpup * fix: e2e wallet setpup * fix: tokenId * fix: token id * feat: matic pol (#70) * chore: develop to main (#65) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor * feat: develop (#68) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- * chore: bump @trustvc/trustvc to ^2.12.4 Co-Authored-By: Claude Opus 4.7 (1M context) * Tt 989/partner integration (#56) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/partner card layout (#57) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel speed (#58) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 989/fix carausel ios (#59) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * Tt 1334/about us page (#60) * feat: add About page with capabilities and new SVG assets - Introduced a new About page that highlights TrustVC's core capabilities. - Added SVG images for visual representation of capabilities, including single-source, unified foundation, global interoperability, privacy, tamper evidence, and ecosystem approach. - Updated routing to include the About page and modified the Navbar for navigation. - Enhanced CSS for the About page's light and dark themes, including background images and card styles. - Implemented responsive design adjustments for mobile views. * feat: implement CapabilityCard component and refactor About page - Added CapabilityCard component to encapsulate the rendering of individual capability details, including title, description, icon, and tags. - Updated About page to utilize CapabilityCard for displaying core capabilities, enhancing code organization and readability. - Refactored tests for About page to improve clarity and consistency in test descriptions. - Adjusted dark and light mode styles for CapabilityCard to ensure visual consistency across themes. * refactor: update Navbar tests to reflect changes in navigation items - Removed references to 'Home' in Navbar tests and replaced them with 'About'. - Updated assertions to check for the presence of 'About', 'Partners', and 'News & Updates' in the Navbar. - Adjusted test cases to ensure correct styling checks for 'About' based on the current route. * feat: add EcosystemCard component and integrate into About page - Introduced EcosystemCard component to encapsulate the rendering of ecosystem-related content, including a heading, subtitle, and image. - Updated About page to utilize EcosystemCard, enhancing code organization and readability. - Added comprehensive tests for EcosystemCard to ensure correct rendering and styling. - Removed redundant CSS styles related to the ecosystem card from index.css. * refactor: update App tests to check for new navigation elements - Replaced assertions for 'Home' and 'News & Updates' with checks for 'About', 'Partners', and 'News & Updates' to align with recent navigation changes. - Ensured that the tests verify the presence of multiple instances of 'About' and 'Partners' for improved coverage. * Update src/pages/About/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update src/index.css Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: adjust background size in dark mode styles - Changed background size from '100% cover' to '100% auto' for improved layout consistency in dark mode. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Hotfix/button color isue (#61) * chore: sync to main (#55) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: manishdex25 * feat: add new partner SVG images - Added AEOTRADE, Angsana Technology, ASTROn, and Automaxis SVG files to the partners directory. - Each SVG includes a rectangle filled with a pattern and an embedded image for branding purposes. * feat: add marquee animation and remove unused partner SVGs * feat: add Partners link to Navbar and scroll to top on route change * fix: update partner logo URLs and enhance accessibility features * feat: add comprehensive tests for Partners and PartnerCard components * Remove multiple partner SVG files from the project, including AEOTRADE, Angsana Technology, ASTROn, Automaxis, Banco, Bank of China, and BlockPeer. This cleanup is part of ongoing efforts to streamline assets and improve project maintainability. * refactor: update partner data structure and enhance PartnersSection - Refactored partner data to include new logo and banner image paths. - Updated PartnersSection to utilize the new partner data structure, enabling responsive images and a marquee animation for partner logos. - Adjusted Tailwind CSS configurations for improved animation performance. - Cleaned up unused partner SVG references in the codebase. * fix: update marquee duration and enhance partner logo tests - Increased marquee animation duration from 900s to 1400s for improved visual experience. - Updated tests to ensure at least one partner logo is rendered and adjusted loading attributes for better performance. - Enhanced test descriptions for clarity and accuracy regarding partner logo rendering and visibility. * fix: reduce marquee animation duration for improved performance * fix: refine marquee styling for improved visual consistency * feat: add partners page styling and animation enhancements * fix: enhance rendering performance in PartnersSection by adding transform properties * refactor: remove unused marquee keyframes and update Partners test cases to use full width class * style: update button styles and enhance AttachmentFileList component with solid color * style: enhance button color handling in AttachmentFileList component for dark mode * style: improve Safari marquee animation performance and prevent compositing issues - Updated CSS for marquee animation to promote GPU layer before animation starts, enhancing performance on Safari. - Adjusted PartnersSection component to avoid using 3D transforms on elements with WebkitMaskImage to prevent icons from disappearing during animation. - Added decoding attribute to partner images for better loading performance. --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#63) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * chore: sync to main (#55) (#66) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Cursor * chore: sync to main (#55) (#67) * fix: merge conflicts (#49) * fix: merge conflicts * fix: remove consoles * fix: stabilize dropdown and news text styling (#50) * fix: stabilize dropdown and news text styling Prevent global button/text styles from breaking Contact enquiry dropdown visuals and News article link readability, while aligning news sub-body text to the left for consistent content presentation across states. Made-with: Cursor * feat: enhance styling for news articles and select field components * fix: metamask transaction message (#51) * fix: metamask traction error messages * fix: test cases * fix: update links and improve code formatting --------- * fix: merge (#54) * fix: merge * fix: update test mocks and add obfuscation notice for documents * fix: stub AssetManagementApplication * fix: expired tag * fix: unknown error metamask --------- --------- Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> * feat: qr document loader (#64) * feat: qr document loader… * fix: replace dead Amoy RPC endpoint in e2e workflow (#90) rpc-amoy.polygon.technology no longer resolves in DNS (verified via multiple resolvers), causing the two network-dependent amoy-verify e2e tests to time out on all branches since 2026-07-17. Replace with polygon-amoy.drpc.org, verified healthy. Co-authored-by: Claude Fable 5 --------- Co-authored-by: manishdex25 Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) Co-authored-by: rongquan1 <85145303+rongquan1@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Cursor --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 64bf0ca..784851e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -46,7 +46,7 @@ jobs: VITE_APP_NETWORK: local VITE_NETWORK_TYPE: testnet VITE_RPC_URL_1337: http://127.0.0.1:8545 - VITE_RPC_URL_80002: https://rpc-amoy.polygon.technology/ + VITE_RPC_URL_80002: https://polygon-amoy.drpc.org VITE_RPC_URL_137: https://rpc.ankr.com/polygon # Analytics disabled in E2E — no events sent to GA4/GTM during test runs VITE_GTM_CONTAINER_ID: '' From 38b29c60fd64cd15fb9e40f16636361ac238df30 Mon Sep 17 00:00:00 2001 From: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Date: Wed, 29 Jul 2026 07:32:58 +0530 Subject: [PATCH 10/10] feat: gasless transactions (#89) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: e2e tests for txns * feat: gasless transactions * fix: add legacy-peer-deps to resolve permissionless/ox/viem conflict permissionless@0.3.7 declares peerOptional ox@^0.11.3 but viem@2.55.1 ships ox@0.14.30, which is out of range. trustvc@2.15.0-beta.2 requires both viem@^2.53.1 and permissionless@^0.3.6, so neither can be downgraded. legacy-peer-deps makes npm skip the conflicting optional peer check. Co-Authored-By: Claude Sonnet 4.6 * chore: regenerate package-lock.json with sentry and react-ga4 entries Lock file was missing @sentry/react, @sentry/vite-plugin, and react-ga4 that were added during the upstream merge, causing npm ci to fail in CI. Co-Authored-By: Claude Sonnet 4.6 * fix: move whitelist fallback tests into gasless section for CI compatibility The two whitelist-fallback tests require hasGaslessConfig=true (PIMLICO_API_KEY set) to reach the whitelist check. In CI without a .env file the module-level constant is undefined, so the hook skips delegation/whitelist entirely and the assertions on checkPaymasterWhitelist always failed. Moving them into the gasless section which uses vi.stubEnv + vi.resetModules + dynamic imports ensures PIMLICO_API_KEY is set when these tests run. Co-Authored-By: Claude Sonnet 4.6 * fix: add @playwright/test explicitly to ensure playwright-core is installed synpress-cache imports playwright-core at runtime. Since @playwright/test was only a transitive peer dep of synpress (not listed directly), it was not installed under legacy-peer-deps, causing ERR_MODULE_NOT_FOUND in CI during the e2e:setup-wallet step. Pinning to 1.48.2 matches the version already resolved in the lock file. * fix: exclude amoy-verify and pol-verify specs from main e2e run The pattern /verify-.*\.spec\.ts/ only matched files starting with "verify-", leaving amoy-verify.spec.ts and pol-verify.spec.ts in the main MetaMask suite. Those specs hit external RPC endpoints (Amoy/Polygon mainnet) which are unreliable in CI and have no MetaMask dependency. Widened to /.*verify.*\.spec\.ts/ so all verify specs (local, amoy, pol) run only via playwright.verify.config.ts. * chore: remove push trigger from e2e workflow E2E runs on every push to main/develop were expensive and unnecessary. Keeping only pull_request (gates PRs) and workflow_dispatch (manual runs). * fix: move @testing-library/dom to devDeps; disable e2e retries on dirty chain - @testing-library/dom belongs in devDependencies (test-only, not shipped) - retries disabled in playwright.config.ts: every spec mutates Hardhat chain state (transfer/reject/return), so a retry after partial failure hits an already-modified chain and fails for a different reason — retries here give false signal, not recovery Co-Authored-By: Claude Sonnet 4.6 * fix: apply CodeRabbit review fixes for gasless transaction feature - Extract shared makeGaslessHook factory to eliminate ~90-line duplication across 10 hooks; each hook is now a ~20-line thin wrapper - Add paymasterStorage.ts helper with custom event for same-tab reactivity - Make ActionSelectionForm reactive to paymaster localStorage changes - Add try/catch around eligibility checks to fall back to paid path on RPC failure - Add tokenRegistryAddress + tokenId to hasGaslessConfig for AcceptReturned/RejectReturned - Fix blank error messages for unknown/gasless errors with Error.message fallback - Add aria-invalid, aria-describedby, role="alert" to paymaster address input - Merge duplicate .check-gasless-content-success-text CSS rules - Replace hard-coded pixel dimensions with fluid values in pay-on-behalf CSS - Replace gap shorthand with column-gap to preserve row-gap: 0px * fix: show both children and errorMessage in DocumentTransferMessage Previously the component rendered errorMessage OR children — never both. After the error-fallback fix in makeGaslessHook (e.message for unknown errors), errorMessage became truthy for contract-level reverts, hiding address/context children that E2E tests depend on. Now children always render; errorMessage appends below when present, giving users both the context (current addresses) and the error detail. * chore: reset paymaster address on page reload (in-memory store) Swap localStorage for a module-level Map so the paymaster address clears on every page load. Also drops the cross-tab 'storage' event listener in ActionSelectionForm since it is no longer relevant. TODO: restore localStorage persistence when the feature is ready. --------- Co-authored-by: Claude Sonnet 4.6 --- .npmrc | 1 + .../local/w3c/tr_accept_surrender.json | 43 + .../local/w3c/tr_reject_surrender.json | 43 + e2e/helpers/actions.ts | 2 +- e2e/playwright.config.ts | 5 +- e2e/setup-contracts.cjs | 1 - e2e/tests/nominate.spec.ts | 2 - e2e/tests/reject-return-to-issuer.spec.ts | 3 - .../transfer-and-reject-beneficiary.spec.ts | 11 - e2e/tests/transfer-and-reject-owners.spec.ts | 7 - package-lock.json | 4966 +++++------------ package.json | 8 +- .../ActionSelectionForm.tsx | 27 + src/components/common/Icons/Icons.tsx | 37 + src/components/common/Icons/index.ts | 1 + .../DocumentTransferMessage.test.tsx | 6 +- .../DocumentTransferMessage.tsx | 3 +- .../TokenInformationContext.tsx | 84 +- .../home/VerifySection/VerifyResult.tsx | 221 +- src/gasless/buildSmartAccountClient.ts | 90 + src/gasless/checkDelegation.test.ts | 109 + src/gasless/checkDelegation.ts | 31 + src/gasless/checkPaymasterWhitelist.test.ts | 132 + src/gasless/checkPaymasterWhitelist.ts | 39 + src/gasless/gaslessHooks.test.tsx | 1050 ++++ src/gasless/index.ts | 13 + src/gasless/makeGaslessHook.ts | 169 + src/gasless/paymasterStorage.ts | 22 + src/gasless/useGaslessAcceptReturned.ts | 23 + src/gasless/useGaslessNominate.ts | 23 + src/gasless/useGaslessRejectReturned.ts | 23 + .../useGaslessRejectTransferBeneficiary.ts | 26 + src/gasless/useGaslessRejectTransferHolder.ts | 26 + src/gasless/useGaslessRejectTransferOwners.ts | 26 + src/gasless/useGaslessReturnToIssuer.ts | 22 + src/gasless/useGaslessTransferBeneficiary.ts | 27 + src/gasless/useGaslessTransferHolder.ts | 23 + src/gasless/useGaslessTransferOwners.ts | 24 + src/hooks/useContractFunctionHook.tsx | 2 +- src/index.css | 284 +- 40 files changed, 3929 insertions(+), 3726 deletions(-) create mode 100644 .npmrc create mode 100644 e2e/fixtures/local/w3c/tr_accept_surrender.json create mode 100644 e2e/fixtures/local/w3c/tr_reject_surrender.json create mode 100644 src/gasless/buildSmartAccountClient.ts create mode 100644 src/gasless/checkDelegation.test.ts create mode 100644 src/gasless/checkDelegation.ts create mode 100644 src/gasless/checkPaymasterWhitelist.test.ts create mode 100644 src/gasless/checkPaymasterWhitelist.ts create mode 100644 src/gasless/gaslessHooks.test.tsx create mode 100644 src/gasless/index.ts create mode 100644 src/gasless/makeGaslessHook.ts create mode 100644 src/gasless/paymasterStorage.ts create mode 100644 src/gasless/useGaslessAcceptReturned.ts create mode 100644 src/gasless/useGaslessNominate.ts create mode 100644 src/gasless/useGaslessRejectReturned.ts create mode 100644 src/gasless/useGaslessRejectTransferBeneficiary.ts create mode 100644 src/gasless/useGaslessRejectTransferHolder.ts create mode 100644 src/gasless/useGaslessRejectTransferOwners.ts create mode 100644 src/gasless/useGaslessReturnToIssuer.ts create mode 100644 src/gasless/useGaslessTransferBeneficiary.ts create mode 100644 src/gasless/useGaslessTransferHolder.ts create mode 100644 src/gasless/useGaslessTransferOwners.ts diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..521a9f7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true diff --git a/e2e/fixtures/local/w3c/tr_accept_surrender.json b/e2e/fixtures/local/w3c/tr_accept_surrender.json new file mode 100644 index 0000000..f99d02c --- /dev/null +++ b/e2e/fixtures/local/w3c/tr_accept_surrender.json @@ -0,0 +1,43 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://trustvc.io/context/bill-of-lading-carrier.json", + "https://trustvc.io/context/attachments-context.json", + "https://trustvc.io/context/render-method-context-v2.json", + "https://trustvc.io/context/transferable-records-context.json", + "https://w3id.org/security/data-integrity/v2" + ], + "renderMethod": [ + { + "type": "EMBEDDED_RENDERER", + "templateName": "BILL_OF_LADING_CARRIER", + "id": "https://generic-templates.tradetrust.io" + } + ], + "credentialSubject": { + "type": ["BillOfLadingCarrier"], + "blNumber": "232323", + "scac": "MAEU" + }, + "type": ["VerifiableCredential"], + "credentialStatus": { + "type": "TransferableRecords", + "tokenNetwork": { + "chain": "ETH", + "chainId": 1337 + }, + "tokenRegistry": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "tokenId": "08c94837a51152b18287ec2304c1115c4611b530f8a18290de2fe4192b22df9b" + }, + "issuer": "did:web:trustvc.github.io:did:1", + "validFrom": "2025-08-28T03:31:39.440Z", + "id": "urn:uuid:019e8335-667c-7cc6-8633-3f56ce15ed63", + "proof": { + "type": "DataIntegrityProof", + "created": "2026-06-01T12:42:55Z", + "verificationMethod": "did:web:trustvc.github.io:did:1#multikey-1", + "cryptosuite": "ecdsa-sd-2023", + "proofPurpose": "assertionMethod", + "proofValue": "u2V0AhVhAnbvMfCuJT-Y2Hm2YTJ_AqlQPO2hjknc1Hh7gkxN7MtptShIVuWX7TAkTKIFPsywmoLoqK-K_E66q4VZ2e_jBmlgjgCQDi_mCpdxBQ_7N6uRAjvf-vuBgMbEwycehUWVM_nPor0xYICODl1NEMILZcbeyrBViJzWDpqx07b9CjHS-X_brwmAljlhA1a-RmJbUIrxTBoGUBiwxDiShGfY8MGybG0xJZEd7fo-EoIUhLaho32GfrrhASDERsDTRaOUDdtE0zXc8rjSlmFhATgTmZTbc6NVq3fJMV9QE3HIJdHGuUp3Cbtad5otxHGC41ZIVk4ufCbt4fnXXqgXv4v9PzoFDvwIs50tpDDKBSVhA5rPpfOr3xN_hIhc2X44-ZPNwDgLFcJII_92eNzhIhEYfqvTaTUt8KRFaV5juge7pd08oJ97bOYRohI54A0V2slhA-oYB3N8MdYlDW3SPdY9YWzVi1o4U8meHHdnMSiEUPbNVCEOupKoy6vDaq-EavbjPm23Ij4qBS0U9O9eQ6nRzQFhAyb6Lugc_7R86dU7aBE6hmoPEeU5E0V6LdRqxmuXeT2vgGsy3iZn6sohxgBmrUx931W3ykrJcMIra4XFpmJ0O-1hA7Dh_qM-nfLDUDxuMjvYQ109hpOXiJAfkonuUg0dF3avrZaS8rQfAx9r_FGJW1ZZ17ymrqky8WPikbU_B_89DM1hAiiJSvoocwPUMVvMdTH7nJapNsfqsIBr2N0f0ENVdnPTkz_IpcgQ5PzfjQQpPu_iOXlQEwGaPiZG6thFh3_7gslhASYThKvR12aI59TUgRzbLnqcTo61o6BBkgALevWTdJVnuzFCuIcl1HXjoC-3Rrc1AitT3GCf7nG2QaSbuF-3aW1hAkzYMpC-KuTm_vKUs1v_DOgy2L_z51Gvc6Aa8iD5N6pflbEDM8OmkYS5voXkXg6HwSH2hfw2huYdLt1tTBVhHOVhAJH0D8Ic3aFiL4NkB39l3R-8w9Sv0SByn-yl4O28GgS54_sjI1qpUFh7tQnJMqzgCop6illtoPrFwuLKYNsTZoVhAI-6ZpMR6oa2BUAN-ZFT7bI6ziwyB-uVjcBcnJZpVq2-0XXZrcd3faEXrd6owSEtOKODmAiYEsM6fcryKUHXcWFhAcMLgzs0SX1WZ1TrAER-3sr_2cZ4FSLBkHYtXN_-FlSt7RmraogU-3x1TrSVOarZjyOTVjM3HpeIPlZOQK1pfP1hAW3_xDpvG4y_vkoE_uvHpOxXtwgLL7hqU4KD77UGqBJ6NS47vJoBVoWPjejSjqfGFgP269dVCK0vmUNXiK4CyPVhA5EuT9JHjjvErid8cqGckJQdnNvl3cC22v21-JHXHgXInNvykPLyfCyGvFre2kWKDiay8pc7I_Q1L0vOpJbuCy4JnL2lzc3VlcmovdmFsaWRGcm9t" + } +} diff --git a/e2e/fixtures/local/w3c/tr_reject_surrender.json b/e2e/fixtures/local/w3c/tr_reject_surrender.json new file mode 100644 index 0000000..ebe8910 --- /dev/null +++ b/e2e/fixtures/local/w3c/tr_reject_surrender.json @@ -0,0 +1,43 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://trustvc.io/context/bill-of-lading-carrier.json", + "https://trustvc.io/context/attachments-context.json", + "https://trustvc.io/context/render-method-context-v2.json", + "https://trustvc.io/context/transferable-records-context.json", + "https://w3id.org/security/data-integrity/v2" + ], + "renderMethod": [ + { + "type": "EMBEDDED_RENDERER", + "templateName": "BILL_OF_LADING_CARRIER", + "id": "https://generic-templates.tradetrust.io" + } + ], + "credentialSubject": { + "type": ["BillOfLadingCarrier"], + "blNumber": "232323", + "scac": "MAEU" + }, + "type": ["VerifiableCredential"], + "credentialStatus": { + "type": "TransferableRecords", + "tokenNetwork": { + "chain": "ETH", + "chainId": 1337 + }, + "tokenRegistry": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "tokenId": "8c67260e6f796368a680742e409d5fada0c58ac1abaa9baf38e9ebeacb7caf93" + }, + "issuer": "did:web:trustvc.github.io:did:1", + "validFrom": "2025-09-28T03:31:39.440Z", + "id": "urn:uuid:019e8337-6604-711f-871c-8bcdf26ad76a", + "proof": { + "type": "DataIntegrityProof", + "created": "2026-06-01T12:45:06Z", + "verificationMethod": "did:web:trustvc.github.io:did:1#multikey-1", + "cryptosuite": "ecdsa-sd-2023", + "proofPurpose": "assertionMethod", + "proofValue": "u2V0AhVhAhH-THDccLgk-kGFXiT0Gm1Il8dmIsxFfCfiRy8Bvx620_6ctv67s7MFmnIQmI_Uk5m-LbL7CL0s7WOuXKSGvwVgjgCQCLIVwK1SzwbtKTwRv2ZLYuVkkUloho4ZatK0tztq9gv1YIOSpzh4waucKxiIn7LplaJKz1Nlixap6s0MuCw22cE_djlhAZ7xgk5BKgIgdVucZFp-4xMgwx80SVZQy7X9PBGlJjKu1xl-orf0Y0XBfm4GAYQCdzN6ovQIVFbDXramyLOHF6VhAZmEbNsxKgsC2DyeeLIinnqXz1USDqHguBJO8yro3AjYl71DSuvIy0egw-L_kfQ1MiT6KIbfeFWyDab3GV96rGVhAqqHdHGshTOgcadiFl090Vlrio_O0owGs2Ioiqt4AjquR-EKQLFYH5VGy4ov17b7x3k8I_j-YUKnI1pGUsmYpJFhA0kFRKW7BX9xbhLM1WUKHGZF4_HIOAO1kZTla9KbU6RLsCTF-KkusDkcnYrJeY4JijgTJKY3yOPTRKRbWHiBlSVhAI-8WNwwkQeTIEAtZA0s8YC58jQ0Np3896xZACnH05rM7Oq1mveZaD8AserBFxrG0kszHZ7dIm63LQPz4K_34aFhAQbgz0QHdywlF-B-5w6zPTVE3L2dv124cfr28mrE5LGFiN-B9n9LFO84rpn8T2UjQooDiizw6S0Ms9Fa6EN2bPVhASUSRsVCqqvNKEN6LymmczOxUOUzfO5mBAJu4Cl-wOlCnbz9Tf8d1QNthBEIHDWeFM4GknbRNlcNxXenvdcuhJFhA3lG5z5PctIC91yROIg0yPDRMviU_rjlhXhxTOyD1LFkjaycgAdrAXYF8gX6U3zMyEBPg7d0Gw_HaxutPJnakzVhAklFIK5YAjInODbDSHeMOtniALvYlEPuHc8PKvhR1qKJkSuUUViPtszRQWP4fq62kQz7S09G2wiDUSoJAAFqdHlhADWJWwFeVayrt9TI2pX78xpY2WYR2o_xTHY2mcL9K-cjbV3tOBPtJJ30UajeowVHYtLYcI7xawwICkcz--G34JFhAu0ERWg0cRqaaDKsFI9t94-yMak0DiATn1ppq6DwSFNDjbBUN1jKk5-qqzaWv5NqoUtiLhUMXrt5HiKKOdQt3xFhAorDjUPv32qY0mSOjkAp5y3wMTgk9LGdAK-rfaUlExUNWSE_1EWAdVGxNA_7yLX1ihDh4xOT2OnJRXD0zjPGrplhAtfvdCjsM5Eye15prlXTV9C5LFJuhYL9qDl8Xz-ku-mOJndJ1iVDYgVsiWUQoGyPWT8ld9yhutljPeEaP9nlRz1hA5XZyq3G58ZvCTzuR69CecMrg0SgtRcrUZyloizu74fIlk4awAnR2gO5wkUJpDjl-U-b4yiOmOwMjZWgvzsw6kYJnL2lzc3VlcmovdmFsaWRGcm9t" + } +} diff --git a/e2e/helpers/actions.ts b/e2e/helpers/actions.ts index 4a2c7b6..c7b0bbb 100644 --- a/e2e/helpers/actions.ts +++ b/e2e/helpers/actions.ts @@ -190,7 +190,7 @@ export async function hardhatRpcNode(method: string, params: unknown[] = []) { export async function revokeMetamaskPermissions( page: Page, - metamask: MetaMask + _metamask: MetaMask ) { // Revoke dapp permissions so the next connect uses Account 2 (not the cached Account 1) await page.evaluate(async () => { diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 84836dd..ded28aa 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -3,12 +3,13 @@ import { defineConfig, devices } from '@playwright/test' export default defineConfig({ testDir: './tests', // Verification (read-only) specs run via playwright.verify.config.ts — no MetaMask. - testIgnore: /verify-.*\.spec\.ts/, + // Excludes: verify-*.spec.ts, amoy-verify.spec.ts, pol-verify.spec.ts + testIgnore: /.*verify.*\.spec\.ts/, timeout: 120_000, // per-test timeout (2 min) expect: { timeout: 30_000 }, // per-assertion timeout fullyParallel: false, forbidOnly: !!process.env.CI, - retries: 0, + retries: 0, // all specs here mutate Hardhat chain state; retries hit dirty state workers: 1, // MetaMask requires a single browser context reporter: 'html', use: { diff --git a/e2e/setup-contracts.cjs b/e2e/setup-contracts.cjs index 97318b1..fef2387 100644 --- a/e2e/setup-contracts.cjs +++ b/e2e/setup-contracts.cjs @@ -133,7 +133,6 @@ const v5Contracts = require('@trustvc/trustvc/token-registry-v5/contracts') // Transfer/Reject Holder tokenId: '0x31884d9f2926120a5779cad07bc5c83ee4ddcf99e88307c8bddf78509cfb2467', - ...defaultToken, }, { diff --git a/e2e/tests/nominate.spec.ts b/e2e/tests/nominate.spec.ts index 76af8d3..05d15e8 100644 --- a/e2e/tests/nominate.spec.ts +++ b/e2e/tests/nominate.spec.ts @@ -5,8 +5,6 @@ import { uploadAndVerify, connectMetaMask } from '../helpers/actions' const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const NEW_HOLDER = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // Hardhat account #1 - const NEW_BENEFICIARY = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // Hardhat account #1 const DOCUMENT_PATH = path.resolve( __dirname, diff --git a/e2e/tests/reject-return-to-issuer.spec.ts b/e2e/tests/reject-return-to-issuer.spec.ts index 2efd91d..64dc427 100644 --- a/e2e/tests/reject-return-to-issuer.spec.ts +++ b/e2e/tests/reject-return-to-issuer.spec.ts @@ -95,8 +95,5 @@ test.describe('Return to Issuer → Reject Return to Issuer', () => { timeout: 10_000, }) }) - // ── Step 2: Accept Return to Issuer ───────────────────────────────── - // Continues on the same page — dismiss overlay, then accept. - // Requires: RestorerRole on the Token Registry (Account #0 as deployer) }) }) diff --git a/e2e/tests/transfer-and-reject-beneficiary.spec.ts b/e2e/tests/transfer-and-reject-beneficiary.spec.ts index 7fc7353..7d9ccfb 100644 --- a/e2e/tests/transfer-and-reject-beneficiary.spec.ts +++ b/e2e/tests/transfer-and-reject-beneficiary.spec.ts @@ -95,17 +95,6 @@ test.describe ) await connectMetaMask(page, metamask) - // await page.locator('[data-testid="connectToWallet"]').click() - // await page - // .locator('[data-testid="connectToMetamask"]') - // .waitFor({ state: 'visible', timeout: 10_000 }) - // await page.locator('[data-testid="connectToMetamask"]').click() - // await metamask.connectToDapp() - // await page - // .locator('[data-testid="connect-blockchain-continue"]') - // .waitFor({ state: 'visible', timeout: 15_000 }) - // await page.locator('[data-testid="connect-blockchain-continue"]').click() - await expect( page.locator('[data-testid="manageAssetDropdown"]') ).toBeVisible({ timeout: 15_000 }) diff --git a/e2e/tests/transfer-and-reject-owners.spec.ts b/e2e/tests/transfer-and-reject-owners.spec.ts index d53f4c4..0f8816e 100644 --- a/e2e/tests/transfer-and-reject-owners.spec.ts +++ b/e2e/tests/transfer-and-reject-owners.spec.ts @@ -77,13 +77,6 @@ test.describe.serial('Transfer Owners → Reject Transfer Owners', () => { await expect( page.locator('text=Transfer Ownership/Holdership Success') ).toBeVisible({ timeout: 60_000 }) - // const dialog = page.getByRole('dialog') - // await expect(dialog.getByText(NEW_OWNER, { exact: false })).toBeVisible({ - // timeout: 10_000, - // }) - // await expect(dialog.getByText(NEW_HOLDER, { exact: false })).toBeVisible({ - // timeout: 10_000, - // }) }) // ── Test 2: Reject Transfer Owners ────────────────────────────────────── diff --git a/package-lock.json b/package-lock.json index b8f2485..230a40c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,13 @@ "@sanity/image-url": "^2.1.1", "@sentry/react": "^10.62.0", "@trustvc/decentralized-renderer-react-components": "^1.0.3", - "@trustvc/trustvc": "^2.14.1", + "@trustvc/trustvc": "^2.15.0-beta.2", "@types/lodash": "^4.17.24", "clsx": "^2.1.1", "date-fns": "^4.1.0", "lucide-react": "^0.563.0", "magic-sdk": "^33.6.2", + "permissionless": "^0.3.7", "qrcode.react": "^4.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -25,12 +26,15 @@ "react-ga4": "^3.0.1", "react-router-dom": "^7.12.0", "react-tooltip": "^5.30.0", - "swiper": "^12.0.3" + "swiper": "^12.0.3", + "viem": "^2.55.1" }, "devDependencies": { "@eslint/js": "^9.17.0", + "@playwright/test": "1.48.2", "@sentry/vite-plugin": "^5.3.0", "@synthetixio/synpress": "4.0.5", + "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.1.0", "@testing-library/user-event": "^14.5.2", @@ -60,6 +64,16 @@ "wait-on": "^8.0.1" } }, + "node_modules/@account-abstraction/contracts": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@account-abstraction/contracts/-/contracts-0.8.0.tgz", + "integrity": "sha512-8krPx/gpnoT+5xAroagVCbeA7FbUigMZWXFKKPm+oghyr29Dksssdx5sI7xGv9212i4JPaDDUGFk58dpuwVgHA==", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "^5.1.0", + "@uniswap/v3-periphery": "^1.4.3" + } + }, "node_modules/@adobe/css-tools": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", @@ -833,6 +847,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -841,6 +856,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "dev": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -885,6 +901,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", @@ -920,6 +937,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", @@ -936,6 +954,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -960,6 +979,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -968,6 +988,7 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" @@ -990,245 +1011,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", @@ -1312,7 +1094,8 @@ "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", @@ -1509,6 +1292,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@digitalbazaar/bbs-2023-cryptosuite/-/bbs-2023-cryptosuite-2.0.1.tgz", "integrity": "sha512-Uw7aDSuCehLUsiSsTi2ob1hQ8AgVq+jV3OgvPsOzy/AmIh2yG9kg2tNCv6PngWPyOm3VCzolwh+5MzWySASiww==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/bls12-381-multikey": "^2.0.0", "@digitalbazaar/di-sd-primitives": "^3.0.4", @@ -1519,15 +1303,6 @@ "node": ">=18" } }, - "node_modules/@digitalbazaar/bbs-2023-cryptosuite/node_modules/cborg": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.5.8.tgz", - "integrity": "sha512-6/viltD51JklRhq4L7jC3zgy6gryuG5xfZ3kzpE+PravtyeQLeQmCYLREhQH7pWENg5pY4Yu/XCd6a7dKScVlw==", - "license": "Apache-2.0", - "bin": { - "cborg": "lib/bin.js" - } - }, "node_modules/@digitalbazaar/bbs-signatures": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@digitalbazaar/bbs-signatures/-/bbs-signatures-3.1.0.tgz", @@ -1541,26 +1316,42 @@ "node": ">=18" } }, - "node_modules/@digitalbazaar/bls12-381-multikey": { + "node_modules/@digitalbazaar/bbs-signatures/node_modules/@noble/curves": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/bls12-381-multikey/-/bls12-381-multikey-2.2.0.tgz", - "integrity": "sha512-C71W5QIVSkLK24XsDWENOqihfy8ITKXqP2c+aKtx09j4vbHstwG6grn4sF9qKEQ2FOMm3KPIrL2byiIIqt61ow==", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.2.0.tgz", + "integrity": "sha512-T/BoHgFXirb0ENSPBquzX0rcjXeM6Lo892a2jlYJkqk83LqZx0l1Of7DzlKJ6jkpvMrkHSnAcgb5JegL8SeIkQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "2.2.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@digitalbazaar/bls12-381-multikey": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/bls12-381-multikey/-/bls12-381-multikey-2.1.0.tgz", + "integrity": "sha512-JelU85fNhvHl2/mqRdmrtrE2ZQJ0//+UwI0l/YFmvsOr6YN2GuKPzdkfXjpm7f3UvnBqz5f8QKFTb9mVa7mVVg==", "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/bbs-signatures": "^3.0.0", - "@noble/curves": "^2.2.0", + "@noble/curves": "^1.3.0", "base58-universal": "^2.0.0", "base64url-universal": "^2.0.0", - "cborg": "^5.1.1" + "cborg": "^4.2.0" }, "engines": { - "node": ">=22" + "node": ">=18" } }, "node_modules/@digitalbazaar/data-integrity": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@digitalbazaar/data-integrity/-/data-integrity-2.5.0.tgz", "integrity": "sha512-ohIieLfgtPQU9BYfj0eKNiz55/ZDOk5YSE9FN/Hn0eXzI8WQzLkzRvC8pvBnzuzXDgCsjPdSqYvzok5PoClMBQ==", + "license": "BSD-3-Clause", "dependencies": { "base58-universal": "^2.0.0", "base64url-universal": "^2.0.0", @@ -1589,6 +1380,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-4.3.0.tgz", "integrity": "sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==", + "license": "BSD-3-Clause", "dependencies": { "ky": "^1.14.2", "undici": "^6.23.0" @@ -1601,6 +1393,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.1.0.tgz", "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", + "license": "Apache-2.0", "bin": { "canonicalize": "bin/canonicalize.js" } @@ -1609,6 +1402,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-9.0.0.tgz", "integrity": "sha512-pjMIdkXfC1T2wrX9B9i2uXhGdyCmgec3qgMht+TDj+S0qX3bjWMQUfL7NeqEhuRTi8G5ESzmL9uGlST7nzSEWg==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/http-client": "^4.2.0", "canonicalize": "^2.1.0", @@ -1623,6 +1417,7 @@ "version": "1.14.3", "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz", "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -1634,6 +1429,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -1645,6 +1441,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-5.0.0.tgz", "integrity": "sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==", + "license": "BSD-3-Clause", "dependencies": { "setimmediate": "^1.0.5" }, @@ -1653,9 +1450,9 @@ } }, "node_modules/@digitalbazaar/di-sd-primitives/node_modules/undici": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.26.0.tgz", - "integrity": "sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", "license": "MIT", "engines": { "node": ">=18.17" @@ -1664,12 +1461,14 @@ "node_modules/@digitalbazaar/di-sd-primitives/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/@digitalbazaar/ecdsa-multikey": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@digitalbazaar/ecdsa-multikey/-/ecdsa-multikey-1.8.0.tgz", "integrity": "sha512-Xo4oBCb0bJv6PYNBrLBZfR/jA2uNd9Bi+YTnadFtxTbhMQrSN0nTw3OnTBOOC7zxtL3t4N00ZweQM4zhsV6gVQ==", + "license": "BSD-3-Clause", "dependencies": { "base58-universal": "^2.0.0", "base64url-universal": "^2.0.0" @@ -1682,6 +1481,7 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/@digitalbazaar/ecdsa-sd-2023-cryptosuite/-/ecdsa-sd-2023-cryptosuite-3.4.1.tgz", "integrity": "sha512-PzKQneakxUUS/kzDgUZ0ZcZKuHhMhAelW2Bp/rryHEV43VeI3meoJkuQ0s7sfMlD1OWkKWrNClMr1znwBaQiLQ==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/di-sd-primitives": "^3.0.4", "@digitalbazaar/ecdsa-multikey": "^1.1.3", @@ -1694,19 +1494,11 @@ "node": ">=18" } }, - "node_modules/@digitalbazaar/ecdsa-sd-2023-cryptosuite/node_modules/cborg": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.5.8.tgz", - "integrity": "sha512-6/viltD51JklRhq4L7jC3zgy6gryuG5xfZ3kzpE+PravtyeQLeQmCYLREhQH7pWENg5pY4Yu/XCd6a7dKScVlw==", - "license": "Apache-2.0", - "bin": { - "cborg": "lib/bin.js" - } - }, "node_modules/@digitalbazaar/http-client": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.1.tgz", "integrity": "sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==", + "license": "BSD-3-Clause", "dependencies": { "ky": "^0.33.3", "ky-universal": "^0.11.0", @@ -1719,41 +1511,8 @@ "node_modules/@digitalbazaar/security-context": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@digitalbazaar/security-context/-/security-context-1.0.1.tgz", - "integrity": "sha512-0WZa6tPiTZZF8leBtQgYAfXQePFQp2z5ivpCEN/iZguYYZ0TB9qRmWtan5XH6mNFuusHtMcyIzAcReyE6rZPhA==" - }, - "node_modules/@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } + "integrity": "sha512-0WZa6tPiTZZF8leBtQgYAfXQePFQp2z5ivpCEN/iZguYYZ0TB9qRmWtan5XH6mNFuusHtMcyIzAcReyE6rZPhA==", + "license": "BSD-3-Clause" }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", @@ -3386,6 +3145,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@govtechsg/jsonld/-/jsonld-0.1.1.tgz", "integrity": "sha512-G3mz6/ryS4tIWTV7FonallTuj4Oy2JjLkBdCn7wjKShb3AG3/PY6XCpNupz8+rpvDF5BGtYvptpW9HRArnjyMQ==", + "license": "BSD-3-Clause", "dependencies": { "canonicalize": "^1.0.1", "cross-fetch": "^3.1.4", @@ -3400,6 +3160,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", "dependencies": { "node-fetch": "^2.7.0" } @@ -3408,6 +3169,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -3418,7 +3180,8 @@ "node_modules/@govtechsg/jsonld/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/@hapi/address": { "version": "5.1.1", @@ -3526,6 +3289,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -3538,512 +3302,32 @@ "node": ">=12" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "license": "ISC", - "peer": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "peer": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dependencies": { - "sprintf-js": "~1.0.2" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "peer": true, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", - "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", - "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/console": "30.3.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-changed-files": "30.3.0", - "jest-config": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-resolve-dependencies": "30.3.0", - "jest-runner": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "jest-watcher": "30.3.0", - "pretty-format": "30.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", - "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-mock": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", - "license": "MIT", - "peer": true, - "dependencies": { - "expect": "30.3.0", - "jest-snapshot": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", - "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", - "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "@sinonjs/fake-timers": "^15.0.0", - "@types/node": "*", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", - "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/types": "30.3.0", - "jest-mock": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", - "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", - "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", - "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/console": "30.3.0", - "@jest/types": "30.3.0", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", - "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/test-result": "30.3.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", - "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.3.0", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", - "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { @@ -4178,6 +3462,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@mattrglobal/bbs-signatures/-/bbs-signatures-1.4.0.tgz", "integrity": "sha512-uBK1IWw48fqloO9W/yoDncTs9rfwfbG/53cOrrCQL7XkyZe4DtB40HcLbi3i+yxTYs5wytf1Qr4Z5RpzpW10jw==", + "license": "Apache-2.0", "dependencies": { "@stablelib/random": "1.0.0" }, @@ -4192,6 +3477,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@mattrglobal/bls12381-key-pair/-/bls12381-key-pair-1.2.2.tgz", "integrity": "sha512-wbbj5sN+0OHChyXdPHY5v4VM54C3bAKzLY0EbQZphHwMOe5Vo/Kij8x+4Nu0Cvx7kAIVxDk418jUo8BwlaE0Tw==", + "license": "Apache-2.0", "dependencies": { "@mattrglobal/bbs-signatures": "1.4.0", "bs58": "4.0.1", @@ -4205,6 +3491,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@mattrglobal/jsonld-signatures-bbs/-/jsonld-signatures-bbs-1.2.0.tgz", "integrity": "sha512-iW/kwlUM412a0AkJEqwaYZm/QhFeTCtebI3L9v9ZSm68wfvPdL2Gha8MkpKNnaqK8MIFEDIFUmL1iVk5qxvNYA==", + "license": "Apache-2.0", "dependencies": { "@mattrglobal/bbs-signatures": "1.2.0", "@mattrglobal/bls12381-key-pair": "1.1.0", @@ -4221,6 +3508,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@mattrglobal/bbs-signatures/-/bbs-signatures-1.2.0.tgz", "integrity": "sha512-DwSzMKMWXfVpw1NDtVY57LHqi6GZFRbRqDrmtDBVr4P/4sOoawGev62J7uvKxIdLamqPX47iCY/Qf2tZ6b5N6w==", + "license": "Apache-2.0", "dependencies": { "@stablelib/random": "1.0.0" }, @@ -4235,6 +3523,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@mattrglobal/bls12381-key-pair/-/bls12381-key-pair-1.1.0.tgz", "integrity": "sha512-idyPlUtc3SBZVtgyGpZYG9w4D/WPzMX0AFDrcSNncNCCZXHwWnGNDOssp+9pU/NhEtuiI285GAlUXjD8Esu12Q==", + "license": "Apache-2.0", "dependencies": { "@mattrglobal/bbs-signatures": "1.2.0", "bs58": "4.0.1", @@ -4249,6 +3538,7 @@ "resolved": "https://registry.npmjs.org/@mattrglobal/node-bbs-signatures/-/node-bbs-signatures-0.17.0.tgz", "integrity": "sha512-midEd1qGYfAKjILyIdEgyY7tbVwIFR7ozWli8AaxBaiDie2oBaj6O1A2rh/GCOKTpBZ3Thbi+CE0QZntWf+Xzg==", "hasInstallScript": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "@mapbox/node-pre-gyp": "1.0.11", @@ -4263,6 +3553,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-4.0.1.tgz", "integrity": "sha512-ltEqMQB37ZxZnsgmI+9rqHYkz1M6PqUykuS1t2aQNuH1oiLrUDYz5nyVkHQDgjFd7CFKTIWeLiNhwdwFrH5o5A==", + "license": "BSD-3-Clause", "dependencies": { "canonicalize": "^1.0.1", "lru-cache": "^5.1.1", @@ -4279,6 +3570,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-7.0.0.tgz", "integrity": "sha512-J/nA+llcYYjErPHG9WFpXvR82TOg5fbHk/7rXbx4Ts854DPReaKAAd0hAZ+s5/P2WIIAZPIHCqA+iz1QrOqeiQ==", + "license": "BSD-3-Clause", "dependencies": { "base64url": "^3.0.1", "crypto-ld": "^3.7.0", @@ -4295,6 +3587,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz", "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==", + "license": "BSD-3-Clause", "dependencies": { "semver": "^6.3.0", "setimmediate": "^1.0.5" @@ -4307,6 +3600,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "license": "MIT", "dependencies": { "type-fest": "^0.8.0" }, @@ -4318,6 +3612,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -4327,6 +3622,7 @@ "resolved": "https://registry.npmjs.org/@mattrglobal/node-bbs-signatures/-/node-bbs-signatures-0.18.1.tgz", "integrity": "sha512-s9ccL/1TTvCP1N//4QR84j/d5D/stx/AI1kPcRgiE4O3KrxyF7ZdL9ca8fmFuN6yh9LAbn/OiGRnOXgvn38Dgg==", "hasInstallScript": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "@mapbox/node-pre-gyp": "1.0.11", @@ -4337,29 +3633,40 @@ "yarn": "1.x" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/curves": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.2.0.tgz", - "integrity": "sha512-T/BoHgFXirb0ENSPBquzX0rcjXeM6Lo892a2jlYJkqk83LqZx0l1Of7DzlKJ6jkpvMrkHSnAcgb5JegL8SeIkQ==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", "license": "MIT", "dependencies": { - "@noble/hashes": "2.2.0" + "@noble/hashes": "1.8.0" }, "engines": { - "node": ">= 20.19.0" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -4619,6 +3926,12 @@ "node": ">= 12" } }, + "node_modules/@openzeppelin/contracts": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.6.1.tgz", + "integrity": "sha512-Ly6SlsVJ3mj+b18W3R8gNufB7dTICT105fJhodGAGgyC2oqnBAhqSiNDJ8V8DLY05cCz81GLI0CU5vNYA1EC/w==", + "license": "MIT" + }, "node_modules/@peculiar/asn1-schema": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", @@ -4662,31 +3975,18 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, "node_modules/@playwright/test": { "version": "1.48.2", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "playwright": "1.48.2" }, @@ -5176,162 +4476,173 @@ } }, "node_modules/@scure/bip32": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.2.tgz", - "integrity": "sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.2.0", - "@noble/hashes": "~1.3.2", - "@scure/base": "~1.1.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", "license": "MIT", "dependencies": { - "@noble/hashes": "1.3.2" + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, + "node_modules/@scure/bip32/node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", "license": "MIT", - "engines": { - "node": ">= 16" - }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", - "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", - "dev": true, + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", "license": "MIT", "dependencies": { - "@noble/hashes": "~1.3.0", - "@scure/base": "~1.1.0" + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@sentry/babel-plugin-component-annotate": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-5.3.0.tgz", - "integrity": "sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==", - "dev": true, + "node_modules/@scure/bip39/node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", "license": "MIT", - "engines": { - "node": ">= 18" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@sentry/browser": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.62.0.tgz", - "integrity": "sha512-uJi0yPssB3Nt/cZ8/S8opW42gaM59/6IyNtPFYD7C0ciudi/nIo5QMVpCYBBI3jnKFOIQLlsMT4pDlOLuxxNuQ==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.67.0.tgz", + "integrity": "sha512-/ZhsAvte4rYhg0A0RtSFFgAgXhyMOfQIeOAfMfptN+X6IVSYOfkA9jtrP+Ej4+6vlaUFWRir1HweF56y63dEEA==", "license": "MIT", "dependencies": { - "@sentry/browser-utils": "10.62.0", - "@sentry/core": "10.62.0", - "@sentry/feedback": "10.62.0", - "@sentry/replay": "10.62.0", - "@sentry/replay-canvas": "10.62.0" + "@sentry/browser-utils": "10.67.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.67.0", + "@sentry/feedback": "10.67.0", + "@sentry/replay": "10.67.0", + "@sentry/replay-canvas": "10.67.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/browser-utils": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.62.0.tgz", - "integrity": "sha512-mS9HVVuWIdye9o0xUGFmzNOBqktF4n5kugrF8NCOYYDrr5ZV8Cx7BlquHQn5UpCeViVhZtcDlEm4iOK7++Px7A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.67.0.tgz", + "integrity": "sha512-HUzaf0xAnPAB+OHBkD7N1Py+CTbD5InHulQ/pdhX4JctWtxuwD8odMD1LzdPnW8J6gVHlDVvcVBR8mXMZYSLSw==", "license": "MIT", "dependencies": { - "@sentry/core": "10.62.0" + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.67.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/browser-utils/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, "engines": { "node": ">=18" } }, "node_modules/@sentry/browser/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, "engines": { "node": ">=18" } }, - "node_modules/@sentry/bundler-plugin-core": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-5.3.0.tgz", - "integrity": "sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==", + "node_modules/@sentry/bundler-plugins": { + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugins/-/bundler-plugins-10.67.0.tgz", + "integrity": "sha512-HKLhbMZJsabZlXTog8CTa1ReeDW/mf1cwN7O8K+DKhe/kGHB3whHRseqsyjxyJwPdzC/0lM+8rgfqgxpc7jR9A==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.18.5", - "@sentry/babel-plugin-component-annotate": "5.3.0", - "@sentry/cli": "^2.58.5", - "dotenv": "^16.3.1", + "@sentry/cli": "^2.58.6", + "@sentry/core": "10.67.0", + "dotenv": "^17.4.2", "find-up": "^5.0.0", "glob": "^13.0.6", "magic-string": "~0.30.8" }, "engines": { "node": ">= 18" + }, + "peerDependencies": { + "rollup": ">=3.2.0", + "webpack": ">=5.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/@sentry/core": { + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/balanced-match": { + "node_modules/@sentry/bundler-plugins/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", @@ -5341,7 +4652,7 @@ "node": "18 || 20 || >=22" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/brace-expansion": { + "node_modules/@sentry/bundler-plugins/node_modules/brace-expansion": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", @@ -5354,7 +4665,7 @@ "node": "18 || 20 || >=22" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/glob": { + "node_modules/@sentry/bundler-plugins/node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", @@ -5372,17 +4683,17 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "node_modules/@sentry/bundler-plugins/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/minimatch": { + "node_modules/@sentry/bundler-plugins/node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", @@ -5398,7 +4709,7 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/path-scurry": { + "node_modules/@sentry/bundler-plugins/node_modules/path-scurry": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", @@ -5616,6 +4927,15 @@ "node": ">= 6" } }, + "node_modules/@sentry/conventions": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.16.0.tgz", + "integrity": "sha512-fO9PLmHdVURcSPUpWCItWAtgKiMwGdJHbovoSEyLplX5sxs2ugvI4CBPTrkkgqhObnZOD0CnWBKDzSVQYBKEyQ==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -5641,22 +4961,25 @@ "license": "0BSD" }, "node_modules/@sentry/feedback": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.62.0.tgz", - "integrity": "sha512-d0BVjJVny6qpBgGJgWL0fbcoQHjtD3z3R8EK/KzTS3RO92JX5n3A536n5D/rh0gZFgcIwiUzBXegmyPOSQn9ng==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.67.0.tgz", + "integrity": "sha512-I4ML2/SF3enwikb6ZSoRiqolQrx0zSzTSnUgwCmugICF/jpHW0th1pCray9R+t1Zzibw/Dpj4t/DNXaSDRa2MA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.62.0" + "@sentry/core": "10.67.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/feedback/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, "engines": { "node": ">=18" } @@ -5771,13 +5094,14 @@ "license": "0BSD" }, "node_modules/@sentry/react": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.62.0.tgz", - "integrity": "sha512-PChimVpY0wzs3H/hJqyl87/ITTHwIZWTSY68QoENZyLnp7DvLcFiZYub/gFws1pzDPhtIQXVLU72fbmUjT5PSg==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.67.0.tgz", + "integrity": "sha512-fS0DplcP9eMxBIRurPC/uxa4NrFK+l9ZsnvQo7wZvNutc7DpTAH0hgFt6laVNCe57s1pFo+OZuKsYBA6JDvH4Q==", "license": "MIT", "dependencies": { - "@sentry/browser": "10.62.0", - "@sentry/core": "10.62.0" + "@sentry/browser": "10.67.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.67.0" }, "engines": { "node": ">=18" @@ -5787,78 +5111,65 @@ } }, "node_modules/@sentry/react/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, "engines": { "node": ">=18" } }, "node_modules/@sentry/replay": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.62.0.tgz", - "integrity": "sha512-rWp4hBhZOmdQhisxcKzAwTGiRk/LvWnNaElWe7nbRhjsM/usp2095yfjq4iJ47v9MtO7xxY6eUz++fLBycqXKg==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.67.0.tgz", + "integrity": "sha512-nkEUgPCR82EcyJkCf3XCE9H0R5KisCqyCAaSGxe7NpAoQbvASHx4MUNgXVAn+D0M494gvPZh6lFH7JgzqTcSqQ==", "license": "MIT", "dependencies": { - "@sentry/browser-utils": "10.62.0", - "@sentry/core": "10.62.0" + "@sentry/browser-utils": "10.67.0", + "@sentry/core": "10.67.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/replay-canvas": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.62.0.tgz", - "integrity": "sha512-CzPAxmpe5US/ABGA1TzpjFKOFZN5uqlzrRh/uM9/daVuzLVKIAQ0XRNxo/PPEXvlDm/PoMdI5L0qIODuIKnyyw==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.67.0.tgz", + "integrity": "sha512-neNA4T6MFtZzMdKYetiR+LZd9BNSd0q2szMn0wk+A15PqHE/IN7a34V6JZc9rCtmzB0wldh0eWGOBb49MSNKjA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.62.0", - "@sentry/replay": "10.62.0" + "@sentry/core": "10.67.0", + "@sentry/replay": "10.67.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/replay-canvas/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, "engines": { "node": ">=18" } }, "node_modules/@sentry/replay/node_modules/@sentry/core": { - "version": "10.62.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.62.0.tgz", - "integrity": "sha512-tV69fMg2sS5DUFmQSnS7Jd5qJAp0izxwcsvBVz2ieTM9VMRi99IfOSYW9UYr3p1yfuksk41kefN5PEbeedUE+A==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/rollup-plugin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/rollup-plugin/-/rollup-plugin-5.3.0.tgz", - "integrity": "sha512-hgPGPYdQJ/G1cGYOxAb7d4z3V+/k/E5/P/5TFPEEBLuIbFFk+JG0CISUDJdzXJjO382Lb99PBJuXGbueBmO79w==", - "dev": true, + "version": "10.67.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", + "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "5.3.0", - "magic-string": "~0.30.8" + "@sentry/conventions": "^0.16.0" }, "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "rollup": ">=3.2.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "node": ">=18" } }, "node_modules/@sentry/tracing": { @@ -5917,46 +5228,18 @@ "license": "0BSD" }, "node_modules/@sentry/vite-plugin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-5.3.0.tgz", - "integrity": "sha512-qcoSzo4n2MulVQ70UUPLq6dTleb2a2HwL2wuwvAgWhPChrYTuk6A6mDg6aQb9fairPAwFPiU9PzOANpoDJcz1A==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-5.4.0.tgz", + "integrity": "sha512-fFJgCxs5hDyAm9BbZJ+LbA+LK2tjX5OoD0v0ARU4StR6KQmGUduoPs69yJ9AfqZ0om3Rlp5JDliiwFcNkasORA==", "dev": true, "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "5.3.0", - "@sentry/rollup-plugin": "5.3.0" + "@sentry/bundler-plugins": "^10.64.0" }, "engines": { "node": ">= 18" } }, - "node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", - "license": "MIT", - "peer": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, "node_modules/@smithy/abort-controller": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", @@ -6541,6 +5824,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "license": "MIT", "dependencies": { "@stablelib/int": "^1.0.1" } @@ -6548,12 +5832,14 @@ "node_modules/@stablelib/int": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", - "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==", + "license": "MIT" }, "node_modules/@stablelib/random": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.0.tgz", "integrity": "sha512-G9vwwKrNCGMI/uHL6XeWe2Nk4BuxkYyWZagGaDU9wrsuV+9hUwNI1lok2WVo8uJDa2zx7ahNwN7Ij983hOUFEw==", + "license": "MIT", "dependencies": { "@stablelib/binary": "^1.0.0", "@stablelib/wipe": "^1.0.0" @@ -6562,7 +5848,8 @@ "node_modules/@stablelib/wipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", - "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==", + "license": "MIT" }, "node_modules/@standard-schema/spec": { "version": "1.1.0", @@ -6588,109 +5875,262 @@ "@playwright/test": "1.48.2" } }, - "node_modules/@synthetixio/synpress": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@synthetixio/synpress/-/synpress-4.0.5.tgz", - "integrity": "sha512-pyfgNXR3BwIz8hcTvGK7aaafoWWW7nCCEvhcCRm6ue+YOYCvT1P/wCIJ6RH1GXspjl6TZ674qC6ia3AiWzobLw==", + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/@adraffy/ens-normalize": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", "dev": true, - "license": "MIT", - "dependencies": { - "@synthetixio/ethereum-wallet-mock": "0.0.6", - "@synthetixio/synpress-cache": "0.0.6", - "@synthetixio/synpress-core": "0.0.6", - "@synthetixio/synpress-metamask": "0.0.6" - }, - "bin": { - "synpress": "dist/cli.js" - }, - "peerDependencies": { - "@playwright/test": "1.48.2" - } + "license": "MIT" }, - "node_modules/@synthetixio/synpress-cache": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@synthetixio/synpress-cache/-/synpress-cache-0.0.6.tgz", - "integrity": "sha512-6fwHeysfpjI09NFoO3sZ6SpA2T6Jr3JP0iY4A0IrISRFWg0j7CooQ9IIMYrW3tyuIoGBr1XlJWQN4ID8JqqIMw==", + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "dev": true, "license": "MIT", "dependencies": { - "axios": "1.6.7", - "chalk": "5.3.0", - "commander": "12.0.0", - "esbuild": "0.20.0", - "fs-extra": "11.2.0", - "glob": "10.3.10", - "gradient-string": "2.0.2", - "progress": "2.0.3", - "tsup": "8.0.2", - "unzipper": "0.10.14", - "zod": "3.22.4" - }, - "bin": { - "synpress-cache": "dist/cli/index.js" + "@noble/hashes": "1.3.2" }, - "peerDependencies": { - "playwright-core": "1.48.2" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", - "integrity": "sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==", - "cpu": [ - "ppc64" - ], + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], "engines": { - "node": ">=12" + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-arm": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.0.tgz", - "integrity": "sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==", - "cpu": [ - "arm" - ], + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/@scure/bip32": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.2.tgz", + "integrity": "sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@noble/curves": "~1.2.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz", - "integrity": "sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==", - "cpu": [ - "arm64" - ], + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.0.tgz", - "integrity": "sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==", - "cpu": [ - "x64" - ], + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/abitype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz", + "integrity": "sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/isows": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz", + "integrity": "sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wagmi-dev" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/viem": { + "version": "2.9.9", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.9.9.tgz", + "integrity": "sha512-SUIHBL6M5IIlqDCMEQwAAvHzeglaM4FEqM6bCI+srLXtFYmrpV4tWhnpobQRNwh4f7HIksmKLLZ+cytv8FfnJQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.0", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@scure/bip32": "1.3.2", + "@scure/bip39": "1.2.1", + "abitype": "1.0.0", + "isows": "1.0.3", + "ws": "8.13.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@synthetixio/ethereum-wallet-mock/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@synthetixio/synpress": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@synthetixio/synpress/-/synpress-4.0.5.tgz", + "integrity": "sha512-pyfgNXR3BwIz8hcTvGK7aaafoWWW7nCCEvhcCRm6ue+YOYCvT1P/wCIJ6RH1GXspjl6TZ674qC6ia3AiWzobLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@synthetixio/ethereum-wallet-mock": "0.0.6", + "@synthetixio/synpress-cache": "0.0.6", + "@synthetixio/synpress-core": "0.0.6", + "@synthetixio/synpress-metamask": "0.0.6" + }, + "bin": { + "synpress": "dist/cli.js" + }, + "peerDependencies": { + "@playwright/test": "1.48.2" + } + }, + "node_modules/@synthetixio/synpress-cache": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@synthetixio/synpress-cache/-/synpress-cache-0.0.6.tgz", + "integrity": "sha512-6fwHeysfpjI09NFoO3sZ6SpA2T6Jr3JP0iY4A0IrISRFWg0j7CooQ9IIMYrW3tyuIoGBr1XlJWQN4ID8JqqIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "1.6.7", + "chalk": "5.3.0", + "commander": "12.0.0", + "esbuild": "0.20.0", + "fs-extra": "11.2.0", + "glob": "10.3.10", + "gradient-string": "2.0.2", + "progress": "2.0.3", + "tsup": "8.0.2", + "unzipper": "0.10.14", + "zod": "3.22.4" + }, + "bin": { + "synpress-cache": "dist/cli/index.js" + }, + "peerDependencies": { + "playwright-core": "1.48.2" + } + }, + "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", + "integrity": "sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-arm": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.0.tgz", + "integrity": "sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz", + "integrity": "sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@synthetixio/synpress-cache/node_modules/@esbuild/android-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.0.tgz", + "integrity": "sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", "optional": true, @@ -7275,7 +6715,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -7359,6 +6799,7 @@ "version": "2.21.0", "resolved": "https://registry.npmjs.org/@tradetrust-tt/dnsprove/-/dnsprove-2.21.0.tgz", "integrity": "sha512-acxJGS07WLfLDli1E4uvT5IbPcmh9vzVelgEdhxzi2KE50r3k/vvkwUQl1ctgkw152cIxnqR20cch8x3HLLvcw==", + "license": "Apache-2.0", "dependencies": { "axios": "1.7.2", "debug": "^4.3.1", @@ -7395,6 +6836,7 @@ "version": "5.5.1", "resolved": "https://registry.npmjs.org/@tradetrust-tt/token-registry/-/token-registry-5.5.1.tgz", "integrity": "sha512-yxOdjRLSI0fPptFbicYpnb/fn4Ngbi/LuGDCQKL0vb7PLCvhT8DLpiAFbFs0cc+QAb439lnZjhPg+UbWQHufRA==", + "license": "Apache-2.0", "dependencies": { "ethers": "^6.13.4" } @@ -7522,10 +6964,17 @@ } } }, + "node_modules/@tradetrust-tt/token-registry/node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, "node_modules/@tradetrust-tt/token-registry/node_modules/@noble/curves": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", "dependencies": { "@noble/hashes": "1.3.2" }, @@ -7537,6 +6986,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", "engines": { "node": ">= 16" }, @@ -7548,6 +6998,7 @@ "version": "22.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } @@ -7555,12 +7006,13 @@ "node_modules/@tradetrust-tt/token-registry/node_modules/aes-js": { "version": "4.0.0-beta.5", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" }, "node_modules/@tradetrust-tt/token-registry/node_modules/ethers": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", - "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.17.0.tgz", + "integrity": "sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang==", "funding": [ { "type": "individual", @@ -7571,14 +7023,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.1", + "@adraffy/ens-normalize": "1.11.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", - "ws": "8.17.1" + "ws": "8.21.0" }, "engines": { "node": ">=14.0.0" @@ -7587,38 +7040,21 @@ "node_modules/@tradetrust-tt/token-registry/node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" }, "node_modules/@tradetrust-tt/token-registry/node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, - "node_modules/@tradetrust-tt/token-registry/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/@tradetrust-tt/tradetrust": { "version": "6.10.3", "resolved": "https://registry.npmjs.org/@tradetrust-tt/tradetrust/-/tradetrust-6.10.3.tgz", "integrity": "sha512-2A/o6GguA31V7GnOfvhG1zANuxKdlBS5+k6jvAMeh/VotZEDvoOOA+mTArt5Fv+BKHhpgh7J8dS0DUohfVAiqg==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@govtechsg/jsonld": "^0.1.1", "@trustvc/w3c-vc": "^1.2.17", @@ -7643,6 +7079,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/@trustvc/w3c-context/-/w3c-context-1.2.13.tgz", "integrity": "sha512-Qii0ExOuTZhBirmzPhdX0o0R1P8DOc8UYEmU+XQ5ouOmQNOqyMkikS0IvFXTb7LmUD3I2d8pT6BMKyY2S8Ac/A==", + "license": "Apache-2.0", "dependencies": { "did-resolver": "^4.1.0", "jsonld-signatures": "^7.0.0" @@ -7655,6 +7092,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/@trustvc/w3c-credential-status/-/w3c-credential-status-1.2.13.tgz", "integrity": "sha512-GNT+r00pscDdjSnTEbH3XQgidKKPblurZnWtCu8OydDilXkMH4p7Lc7JrvvCoIn6W2Iwv0em6107gB7rsW3yXA==", + "license": "Apache-2.0", "dependencies": { "@trustvc/w3c-context": "^1.2.13", "@trustvc/w3c-issuer": "^1.2.4", @@ -7669,6 +7107,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/@trustvc/w3c-issuer/-/w3c-issuer-1.2.4.tgz", "integrity": "sha512-BRxdb+VxKVj3N/ukivpPF0oP1dvlMOSZjoOLF+F4jMsJVcs2+8QIJbvCQJNiB6I+ji6On4uvvRPOmc8tYhOt+w==", + "license": "Apache-2.0", "dependencies": { "@mattrglobal/bls12381-key-pair": "^1.2.1", "bip39": "^3.1.0", @@ -7684,6 +7123,7 @@ "version": "1.2.17", "resolved": "https://registry.npmjs.org/@trustvc/w3c-vc/-/w3c-vc-1.2.17.tgz", "integrity": "sha512-R7dz16D5mmb7tsPt71o/XAqaKaNA0J0du0ZOa16i7x3I9yPCx11jwCYdb0NYzsCXrWa318mqS2u7MCtzvEVBBQ==", + "license": "Apache-2.0", "dependencies": { "@mattrglobal/jsonld-signatures-bbs": "^1.2.0", "@trustvc/w3c-credential-status": "^1.2.13", @@ -7709,6 +7149,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -7717,6 +7158,7 @@ "version": "8.20.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -7731,17 +7173,20 @@ "node_modules/@tradetrust-tt/tradetrust/node_modules/did-resolver": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", - "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==", + "license": "Apache-2.0" }, "node_modules/@tradetrust-tt/tradetrust/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/@tradetrust-tt/tradetrust/node_modules/jsonld-signatures": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-7.0.0.tgz", "integrity": "sha512-J/nA+llcYYjErPHG9WFpXvR82TOg5fbHk/7rXbx4Ts854DPReaKAAd0hAZ+s5/P2WIIAZPIHCqA+iz1QrOqeiQ==", + "license": "BSD-3-Clause", "dependencies": { "base64url": "^3.0.1", "crypto-ld": "^3.7.0", @@ -7758,6 +7203,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-4.0.1.tgz", "integrity": "sha512-ltEqMQB37ZxZnsgmI+9rqHYkz1M6PqUykuS1t2aQNuH1oiLrUDYz5nyVkHQDgjFd7CFKTIWeLiNhwdwFrH5o5A==", + "license": "BSD-3-Clause", "dependencies": { "canonicalize": "^1.0.1", "lru-cache": "^5.1.1", @@ -7774,6 +7220,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz", "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==", + "license": "BSD-3-Clause", "dependencies": { "semver": "^6.3.0", "setimmediate": "^1.0.5" @@ -7786,6 +7233,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "license": "MIT", "dependencies": { "type-fest": "^0.8.0" }, @@ -7797,6 +7245,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -7868,12 +7317,20 @@ "react": ">=16.8.0" } }, - "node_modules/@trustvc/document-store": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@trustvc/document-store/-/document-store-1.0.3.tgz", - "integrity": "sha512-YIECQwcoreIfyTbol1/5u9CGK6mbg0Q0bSN2/Ks388zLus1IXELWK5EHYuyrFPbb9d8ajsvz7m+ySsMIY9574w==" + "node_modules/@trustvc/decentralized-renderer-react-components/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", + "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@trustvc/trustvc": { + "node_modules/@trustvc/decentralized-renderer-react-components/node_modules/@trustvc/trustvc": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/@trustvc/trustvc/-/trustvc-2.14.1.tgz", "integrity": "sha512-vGR6/s8nn69sl3Ntr/rE8+kg64RuqsRN2AeB0yeNOAUwTWEmQRk16cvB4g1xW7+CsLc5yI5sRuAqeAmbhHdV0g==", @@ -7908,6 +7365,69 @@ "ethers": "^5.8.0" } }, + "node_modules/@trustvc/decentralized-renderer-react-components/node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/@trustvc/document-store": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@trustvc/document-store/-/document-store-1.0.3.tgz", + "integrity": "sha512-YIECQwcoreIfyTbol1/5u9CGK6mbg0Q0bSN2/Ks388zLus1IXELWK5EHYuyrFPbb9d8ajsvz7m+ySsMIY9574w==", + "license": "Apache-2.0" + }, + "node_modules/@trustvc/eip7702": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@trustvc/eip7702/-/eip7702-1.0.0-beta.1.tgz", + "integrity": "sha512-cOGuZVLHd0+Uu7rZ/Dp2iF1VuNq+L+pWWGe+tPD/u74rSvCAzIc17dIk5HOwRBiC5awh1rXG46vLG8IRc5O01Q==", + "license": "MIT", + "dependencies": { + "@account-abstraction/contracts": "^0.8.0", + "@openzeppelin/contracts": "^5.6.1" + } + }, + "node_modules/@trustvc/trustvc": { + "version": "2.15.0-beta.2", + "resolved": "https://registry.npmjs.org/@trustvc/trustvc/-/trustvc-2.15.0-beta.2.tgz", + "integrity": "sha512-o9Mw3DDY5Fd8Qxj1K7soKZEZBQUDwdAFJqgkQB4KEgiLiSAENR1YfYHSdGxaL1biY+IkLgSBRe/IexQei4gW/Q==", + "license": "Apache-2.0", + "dependencies": { + "@tradetrust-tt/dnsprove": "^2.18.0", + "@tradetrust-tt/ethers-aws-kms-signer": "^2.1.4", + "@tradetrust-tt/token-registry-v4": "npm:@tradetrust-tt/token-registry@^4.16.0", + "@tradetrust-tt/token-registry-v5": "npm:@tradetrust-tt/token-registry@^5.5.0", + "@tradetrust-tt/tradetrust": "^6.10.3", + "@tradetrust-tt/tt-verify": "^9.7.5", + "@trustvc/document-store": "^1.0.3", + "@trustvc/eip7702": "^1.0.0-beta.1", + "@trustvc/w3c": "^2.2.0", + "@trustvc/w3c-context": "^2.2.0", + "@trustvc/w3c-credential-status": "^2.2.0", + "@trustvc/w3c-issuer": "^2.2.0", + "@trustvc/w3c-vc": "^2.2.0", + "ethers": "^5.8.0", + "ethersV6": "npm:ethers@^6.14.4", + "js-sha3": "^0.9.3", + "node-fetch": "^2.7.0", + "node-forge": "^1.3.3", + "permissionless": "^0.3.6", + "ts-chacha20": "^1.2.0", + "viem": "^2.53.1" + }, + "engines": { + "node": ">=20.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-linux-x64-gnu": "~4.40.0" + }, + "peerDependencies": { + "ethers": "^5.8.0" + } + }, "node_modules/@trustvc/trustvc/node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.40.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", @@ -7961,7 +7481,8 @@ "node_modules/@trustvc/w3c-context/node_modules/did-resolver": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", - "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==", + "license": "Apache-2.0" }, "node_modules/@trustvc/w3c-credential-status": { "version": "2.2.0", @@ -7999,7 +7520,8 @@ "node_modules/@trustvc/w3c-issuer/node_modules/did-resolver": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", - "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==", + "license": "Apache-2.0" }, "node_modules/@trustvc/w3c-issuer/node_modules/web-did-resolver": { "version": "2.0.32", @@ -8043,7 +7565,8 @@ "node_modules/@trustvc/w3c-vc/node_modules/did-resolver": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", - "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==", + "license": "Apache-2.0" }, "node_modules/@trustvc/w3c-vc/node_modules/uuid": { "version": "10.0.0", @@ -8054,21 +7577,11 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@typechain/ethers-v5": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz", @@ -8091,12 +7604,13 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -8109,6 +7623,7 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, "dependencies": { "@babel/types": "^7.0.0" } @@ -8117,6 +7632,7 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -8126,6 +7642,7 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, "dependencies": { "@babel/types": "^7.28.2" } @@ -8157,33 +7674,6 @@ "@types/node": "*" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT", - "peer": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -8211,24 +7701,17 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "license": "MIT", - "peer": true - }, "node_modules/@types/prop-types": { "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "devOptional": true + "dev": true }, "node_modules/@types/react": { "version": "18.3.27", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", - "devOptional": true, + "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -8243,13 +7726,6 @@ "@types/react": "^18.0.0" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "license": "MIT", - "peer": true - }, "node_modules/@types/tinycolor2": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", @@ -8257,23 +7733,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT", - "peer": true - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.53.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz", @@ -8529,354 +7988,127 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC", - "peer": true + "node_modules/@uniswap/lib": { + "version": "4.0.1-alpha", + "resolved": "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz", + "integrity": "sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==", + "license": "GPL-3.0-or-later", + "engines": { + "node": ">=10" + } }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true + "node_modules/@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==", + "license": "GPL-3.0-or-later", + "engines": { + "node": ">=10" + } }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true + "node_modules/@uniswap/v3-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz", + "integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==", + "license": "BUSL-1.1", + "engines": { + "node": ">=10" + } }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true + "node_modules/@uniswap/v3-periphery": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz", + "integrity": "sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@openzeppelin/contracts": "3.4.2-solc-0.7", + "@uniswap/lib": "^4.0.1-alpha", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v3-core": "^1.0.0", + "base64-sol": "1.0.1" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true + "node_modules/@uniswap/v3-periphery/node_modules/@openzeppelin/contracts": { + "version": "3.4.2-solc-0.7", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz", + "integrity": "sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==", + "license": "MIT" }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], + "node_modules/@viem/anvil": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@viem/anvil/-/anvil-0.0.7.tgz", + "integrity": "sha512-F+3ljCT1bEt8T4Fzm9gWpIgO3Dc7bzG1TtUtkStkJFMuummqZ8kvYc3UFMo5j3F51fSWZZvEkjs3+i7qf0AOqQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true + "dependencies": { + "execa": "^7.1.1", + "get-port": "^6.1.2", + "http-proxy": "^1.18.1", + "ws": "^8.13.0" + } }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], + "node_modules/@viem/anvil/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true + "node_modules/@viem/anvil/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14.18.0" + } }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], + "node_modules/@viem/anvil/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], + "node_modules/@viem/anvil/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@viem/anvil": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@viem/anvil/-/anvil-0.0.7.tgz", - "integrity": "sha512-F+3ljCT1bEt8T4Fzm9gWpIgO3Dc7bzG1TtUtkStkJFMuummqZ8kvYc3UFMo5j3F51fSWZZvEkjs3+i7qf0AOqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^7.1.1", - "get-port": "^6.1.2", - "http-proxy": "^1.18.1", - "ws": "^8.13.0" - } - }, - "node_modules/@viem/anvil/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@viem/anvil/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/@viem/anvil/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@viem/anvil/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/@viem/anvil/node_modules/npm-run-path": { "version": "5.3.0", @@ -9104,17 +8336,16 @@ "optional": true }, "node_modules/abitype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz", - "integrity": "sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==", - "dev": true, + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", + "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/wevm" }, "peerDependencies": { "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" + "zod": "^3.22.0 || ^4.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -9129,6 +8360,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, @@ -9215,6 +8447,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -9231,6 +8464,7 @@ "version": "8.20.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -9245,7 +8479,8 @@ "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/ansi-align": { "version": "3.0.1", @@ -9306,6 +8541,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "devOptional": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -9321,6 +8557,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, "engines": { "node": ">=8" } @@ -9329,6 +8566,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -9349,6 +8587,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -9405,6 +8644,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "license": "MIT", + "optional": true, "engines": { "node": ">=6" } @@ -9552,6 +8792,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } @@ -9606,6 +8847,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -9686,6 +8928,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", "engines": { "node": "*" } @@ -9693,110 +8936,20 @@ "node_modules/aws4": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==" + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" }, "node_modules/axios": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", - "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/transform": "30.3.0", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.3.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", - "license": "BSD-3-Clause", - "peer": true, - "workspaces": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "license": "ISC", - "peer": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", - "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/babel__core": "^7.20.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -9832,59 +8985,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true }, - "node_modules/babel-preset-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", - "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", "license": "MIT", - "peer": true, - "dependencies": { - "babel-plugin-jest-hoist": "30.3.0", - "babel-preset-current-node-syntax": "^1.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-x": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", "dependencies": { "safe-buffer": "^5.0.1" } @@ -9893,6 +9004,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/base58-universal/-/base58-universal-2.0.0.tgz", "integrity": "sha512-BgkgF8zVLOAygszG4W8NkLm7iXrw80VYAOcedrzANrIhS14+4W6zVqjyGTFUBM/FpqkHUt8aAYd4DbBBfn3zKg==", + "license": "BSD-3-Clause", "engines": { "node": ">=14" } @@ -9918,10 +9030,17 @@ ], "license": "MIT" }, + "node_modules/base64-sol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-sol/-/base64-sol-1.0.1.tgz", + "integrity": "sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==", + "license": "MIT" + }, "node_modules/base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -9930,6 +9049,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-2.0.0.tgz", "integrity": "sha512-6Hpg7EBf3t148C3+fMzjf+CHnADVDafWzlJUXAqqqbm4MKNXbsoPdOkWeRTjNlkYG7TpyjIpRO1Gk0SnsFD1rw==", + "license": "BSD-3-Clause", "dependencies": { "base64url": "^3.0.1" }, @@ -9941,6 +9061,7 @@ "version": "2.9.14", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "dev": true, "bin": { "baseline-browser-mapping": "dist/cli.js" } @@ -9949,6 +9070,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } @@ -9999,6 +9121,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "license": "ISC", "dependencies": { "@noble/hashes": "^1.2.0" } @@ -10140,6 +9263,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -10335,6 +9459,7 @@ "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -10379,20 +9504,11 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", "dependencies": { "base-x": "^3.0.2" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -10422,6 +9538,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, "license": "MIT" }, "node_modules/buffer-indexof-polyfill": { @@ -10460,6 +9577,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "license": "MIT", "optional": true }, "node_modules/bundle-require": { @@ -10549,16 +9667,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -10572,6 +9680,7 @@ "version": "1.0.30001764", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz", "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==", + "dev": true, "funding": [ { "type": "opencollective", @@ -10590,7 +9699,8 @@ "node_modules/canonicalize": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", - "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==" + "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==", + "license": "Apache-2.0" }, "node_modules/canvas": { "version": "2.11.2", @@ -10611,12 +9721,14 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" }, "node_modules/cbor": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "license": "MIT", "dependencies": { "nofilter": "^3.1.0" }, @@ -10625,9 +9737,9 @@ } }, "node_modules/cborg": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.1.tgz", - "integrity": "sha512-BDbSRIp6XrQXkTc7g+DN0RB9RrDPTUfals2ecWUlt3juPLjbAvy/V72mJcXY0Ehu0Dq/3WpNCOCT68HUTbW+lw==", + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.5.8.tgz", + "integrity": "sha512-6/viltD51JklRhq4L7jC3zgy6gryuG5xfZ3kzpE+PravtyeQLeQmCYLREhQH7pWENg5pY4Yu/XCd6a7dKScVlw==", "license": "Apache-2.0", "bin": { "cborg": "lib/bin.js" @@ -10666,6 +9778,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "devOptional": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10677,20 +9790,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - } - }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT", "optional": true }, "node_modules/check-error": { @@ -10748,22 +9852,6 @@ "node": ">=10" } }, - "node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/cipher-base": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", @@ -10778,13 +9866,6 @@ "node": ">= 0.10" } }, - "node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", - "license": "MIT", - "peer": true - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -10818,6 +9899,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", "optional": true, "dependencies": { "restore-cursor": "^3.1.0" @@ -10830,83 +9912,17 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", "optional": true, "engines": { "node": ">= 10" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "peer": true - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -10920,28 +9936,11 @@ "node": ">=6" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "license": "MIT", - "peer": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", - "license": "MIT", - "peer": true - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10952,7 +9951,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "node_modules/color-support": { "version": "1.1.3", @@ -10987,6 +9987,7 @@ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", "license": "MIT", + "optional": true, "dependencies": { "array-back": "^3.1.0", "find-replace": "^3.0.0", @@ -11001,6 +10002,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/command-line-commands/-/command-line-commands-3.0.2.tgz", "integrity": "sha512-ac6PdCtdR6q7S3HN+JiVLIWGHY30PRYIEl2qPo+FuEuzwAUk0UYyimrngrg7FvF/mCr4Jgoqv5ZnHZgads50rw==", + "license": "MIT", "optional": true, "dependencies": { "array-back": "^4.0.1" @@ -11013,6 +10015,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -11023,6 +10026,7 @@ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", "license": "MIT", + "optional": true, "dependencies": { "array-back": "^4.0.2", "chalk": "^2.4.2", @@ -11038,6 +10042,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "license": "MIT", + "optional": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -11050,6 +10055,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -11059,6 +10065,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "license": "MIT", + "optional": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -11073,6 +10080,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", + "optional": true, "dependencies": { "color-name": "1.1.3" } @@ -11081,13 +10089,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/command-line-usage/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "license": "MIT", + "optional": true, "engines": { "node": ">=0.8.0" } @@ -11097,6 +10107,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "license": "MIT", + "optional": true, "engines": { "node": ">=4" } @@ -11106,6 +10117,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "license": "MIT", + "optional": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -11118,6 +10130,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -11134,7 +10147,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true }, "node_modules/console-browserify": { "version": "1.2.0", @@ -11159,7 +10173,8 @@ "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "node_modules/cookie": { "version": "1.1.1", @@ -11259,6 +10274,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", "dependencies": { "node-fetch": "^2.7.0" } @@ -11267,6 +10283,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -11306,6 +10323,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/crypto-ld/-/crypto-ld-3.9.0.tgz", "integrity": "sha512-PFE7V6A2QNnUp6iiPVEZI4p8wsztkEWLbY1BAXVnclm/aw4KGwpJ+1Ds4vQUCJ5BsWxj15fwE5rHQ8AWaWB2nw==", + "license": "BSD-3-Clause", "dependencies": { "base64url-universal": "^1.0.1", "bs58": "^4.0.1", @@ -11323,6 +10341,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz", "integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==", + "license": "BSD-3-Clause", "dependencies": { "base64url": "^3.0.0" }, @@ -11376,6 +10395,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" }, @@ -11387,6 +10407,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -11510,21 +10531,6 @@ "node": ">=8" } }, - "node_modules/dedent": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", - "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", - "license": "MIT", - "peer": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -11539,6 +10545,7 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", + "optional": true, "engines": { "node": ">=4.0.0" } @@ -11549,16 +10556,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -11644,20 +10641,11 @@ "node": ">=8" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/did-resolver": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-3.2.2.tgz", - "integrity": "sha512-Eeo2F524VM5N3W4GwglZrnul2y6TLTwMQP3In62JdG34NZoqihYyOZLk+5wUW8sSgvIYIcJM8Dlt3xsdKZZ3tg==" + "integrity": "sha512-Eeo2F524VM5N3W4GwglZrnul2y6TLTwMQP3In62JdG34NZoqihYyOZLk+5wUW8sSgvIYIcJM8Dlt3xsdKZZ3tg==", + "license": "Apache-2.0" }, "node_modules/didyoumean": { "version": "1.2.2", @@ -11728,7 +10716,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/domain-browser": { "version": "4.22.0", @@ -11744,9 +10732,9 @@ } }, "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -11822,12 +10810,14 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -11836,7 +10826,8 @@ "node_modules/electron-to-chromium": { "version": "1.5.267", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==" + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true }, "node_modules/elliptic": { "version": "6.6.1", @@ -11859,23 +10850,11 @@ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", "license": "MIT" }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/enquirer": { "version": "2.4.1", @@ -12149,6 +11128,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "engines": { "node": ">=6" } @@ -12333,20 +11313,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -12611,12 +11577,14 @@ "node_modules/ethr-did-registry": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/ethr-did-registry/-/ethr-did-registry-0.0.3.tgz", - "integrity": "sha512-4BPvMGkxAK9vTduCq6D5b8ZqjteD2cvDIPPriXP6nnmPhWKFSxypo+AFvyQ0omJGa0cGTR+dkdI/8jiF7U/qaw==" + "integrity": "sha512-4BPvMGkxAK9vTduCq6D5b8ZqjteD2cvDIPPriXP6nnmPhWKFSxypo+AFvyQ0omJGa0cGTR+dkdI/8jiF7U/qaw==", + "license": "Apache-2.0" }, "node_modules/ethr-did-resolver": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/ethr-did-resolver/-/ethr-did-resolver-4.3.5.tgz", "integrity": "sha512-BQO7PQwuqqczK+4AWQhys/sgegDVIFr6+lSoSYXlIbG0oRH0l7PkSuf7VEFKclEJ3JlJ1t9kjDIdj7Ba7euTJg==", + "license": "Apache-2.0", "dependencies": { "@ethersproject/abi": "^5.1.0", "@ethersproject/abstract-signer": "^5.1.0", @@ -12641,6 +11609,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -12684,6 +11653,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -12707,36 +11677,9 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, - "node_modules/exit-x": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/expect-utils": "30.3.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -12749,12 +11692,14 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", "optional": true, "dependencies": { "chardet": "^0.7.0", @@ -12769,6 +11714,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -12783,7 +11729,8 @@ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "engines": [ "node >=0.6.0" - ] + ], + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -12830,9 +11777,9 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", "funding": [ { "type": "github", @@ -12842,7 +11789,8 @@ "type": "opencollective", "url": "https://opencollective.com/fastify" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/fast-xml-parser": { "version": "5.3.6", @@ -12871,16 +11819,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "bser": "2.1.1" - } - }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -12895,6 +11833,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -12913,6 +11852,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", "optional": true, "dependencies": { "escape-string-regexp": "^1.0.5" @@ -12928,6 +11868,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.8.0" @@ -12962,6 +11903,7 @@ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "license": "MIT", + "optional": true, "dependencies": { "array-back": "^3.0.1" }, @@ -13018,6 +11960,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/flatley/-/flatley-5.2.0.tgz", "integrity": "sha512-vsb0/03uIHu7/3jRqABweblFUJMLokz1uMrcgFlvx6OAr6V3FiSic2iXeiJCj+cciTiQeumSDsIFAAnN1yvu4w==", + "license": "BSD-3-Clause", "dependencies": { "is-buffer": "^1.1.6" } @@ -13066,6 +12009,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" @@ -13081,6 +12025,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", "engines": { "node": "*" } @@ -13104,6 +12049,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" }, @@ -13135,6 +12081,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", @@ -13182,12 +12129,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -13374,6 +12323,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -13382,6 +12332,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -13454,16 +12405,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/get-port": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/get-port/-/get-port-6.1.2.tgz", @@ -13493,6 +12434,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -13521,6 +12463,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" } @@ -13529,6 +12472,7 @@ "version": "0.0.7", "resolved": "https://registry.npmjs.org/git-config/-/git-config-0.0.7.tgz", "integrity": "sha512-LidZlYZXWzVjS+M3TEwhtYBaYwLeOZrXci1tBgqp/vDdZTBMl02atvwb6G35L64ibscYoPnxfbwwUS+VZAISLA==", + "license": "BSD-3-Clause", "optional": true, "dependencies": { "iniparser": "~1.0.5" @@ -13538,6 +12482,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -13569,6 +12514,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -13577,6 +12523,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -13650,6 +12597,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, "license": "ISC" }, "node_modules/gradient-string": { @@ -13691,6 +12639,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", "engines": { "node": ">=4" } @@ -13700,6 +12649,7 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", + "license": "MIT", "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -13869,6 +12819,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "devOptional": true, "engines": { "node": ">=8" } @@ -14015,7 +12966,8 @@ "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "node_modules/http-errors": { "version": "2.0.1", @@ -14070,6 +13022,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -14104,6 +13057,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -14195,99 +13149,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "license": "MIT", - "peer": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -14306,6 +13172,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "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.", + "devOptional": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -14331,6 +13198,7 @@ "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "license": "MIT", "optional": true, "dependencies": { "ansi-escapes": "^4.2.1", @@ -14355,12 +13223,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT", "optional": true }, "node_modules/inquirer/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "optional": true, "dependencies": { "emoji-regex": "^8.0.0", @@ -14375,6 +13245,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "optional": true, "dependencies": { "ansi-regex": "^5.0.1" @@ -14507,7 +13378,8 @@ "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" }, "node_modules/is-callable": { "version": "1.2.7", @@ -14592,20 +13464,11 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, "engines": { "node": ">=8" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/is-generator-function": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", @@ -14773,6 +13636,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14829,7 +13693,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" }, "node_modules/is-unicode-supported": { "version": "0.1.0", @@ -14892,7 +13757,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isomorphic-timers-promises": { "version": "1.0.1", @@ -14905,14 +13771,13 @@ } }, "node_modules/isows": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz", - "integrity": "sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==", - "dev": true, + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/wagmi-dev" + "url": "https://github.com/sponsors/wevm" } ], "license": "MIT", @@ -14923,50 +13788,23 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -14980,6 +13818,7 @@ "version": "5.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", @@ -14993,6 +13832,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -15022,6 +13862,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -15032,1071 +13873,128 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", - "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/core": "30.3.0", - "@jest/types": "30.3.0", - "import-local": "^3.2.0", - "jest-cli": "30.3.0" - }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "jiti": "bin/jiti.js" } }, - "node_modules/jest-changed-files": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", - "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", - "license": "MIT", - "peer": true, + "node_modules/joi": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.2.1.tgz", + "integrity": "sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "execa": "^5.1.1", - "jest-util": "30.3.0", - "p-limit": "^3.1.0" + "@hapi/address": "^5.1.1", + "@hapi/formula": "^3.0.2", + "@hapi/hoek": "^11.0.7", + "@hapi/pinpoint": "^2.0.1", + "@hapi/tlds": "^1.1.1", + "@hapi/topo": "^6.0.2", + "@standard-schema/spec": "^1.1.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 20" } }, - "node_modules/jest-circus": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", - "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "co": "^4.6.0", - "dedent": "^1.6.0", - "is-generator-fn": "^2.1.0", - "jest-each": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "p-limit": "^3.1.0", - "pretty-format": "30.3.0", - "pure-rand": "^7.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, + "node_modules/js-base64": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.8.1.tgz", + "integrity": "sha512-5xVjhUZlHHeuO2W7w2rDFj/Kl1xLX+HjZxdOQwCsUOifl6UaoH1o1wsbsTMz+r0aeC7gCijvru02j6TfKZWzKg==", + "license": "BSD-3-Clause" + }, + "node_modules/js-sha3": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", + "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "argparse": "^2.0.1" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" }, - "node_modules/jest-cli": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", - "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", - "license": "MIT", - "peer": true, + "node_modules/jsdom": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, "dependencies": { - "@jest/core": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "exit-x": "^0.2.2", - "import-local": "^3.2.0", - "jest-config": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "yargs": "^17.7.2" - }, - "bin": { - "jest": "bin/jest.js" + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { - "node-notifier": { + "canvas": { "optional": true } } }, - "node_modules/jest-config": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", - "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.3.0", - "@jest/types": "30.3.0", - "babel-jest": "30.3.0", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "deepmerge": "^4.3.1", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-circus": "30.3.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-runner": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "parse-json": "^5.2.0", - "pretty-format": "30.3.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "esbuild-register": ">=3.4.0", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "esbuild-register": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-config/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-diff": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/diff-sequences": "30.3.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-diff/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", - "license": "MIT", - "peer": true, - "dependencies": { - "detect-newline": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", - "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "jest-util": "30.3.0", - "pretty-format": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-environment-node": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", - "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", - "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", - "picomatch": "^4.0.3", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-leak-detector": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", - "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-matcher-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", - "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.3.0", - "pretty-format": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-message-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", - "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.3.0", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3", - "pretty-format": "30.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-mock": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", - "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-util": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", - "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", - "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", - "license": "MIT", - "peer": true, - "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", - "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/console": "30.3.0", - "@jest/environment": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-leak-detector": "30.3.0", - "jest-message-util": "30.3.0", - "jest-resolve": "30.3.0", - "jest-runtime": "30.3.0", - "jest-util": "30.3.0", - "jest-watcher": "30.3.0", - "jest-worker": "30.3.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", - "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/globals": "30.3.0", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", - "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.3.0", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.3.0", - "graceful-fs": "^4.2.11", - "jest-diff": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "pretty-format": "30.3.0", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", - "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-validate": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", - "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", - "camelcase": "^6.3.0", - "chalk": "^4.1.2", - "leven": "^3.1.0", - "pretty-format": "30.3.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT", - "peer": true - }, - "node_modules/jest-watcher": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", - "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "jest-util": "30.3.0", - "string-length": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", - "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.3.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.2.1.tgz", - "integrity": "sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/address": "^5.1.1", - "@hapi/formula": "^3.0.2", - "@hapi/hoek": "^11.0.7", - "@hapi/pinpoint": "^2.0.1", - "@hapi/tlds": "^1.1.1", - "@hapi/topo": "^6.0.2", - "@standard-schema/spec": "^1.1.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/js-base64": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", - "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==" - }, - "node_modules/js-sha3": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", - "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", - "dev": true, - "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -16114,7 +14012,8 @@ "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -16140,7 +14039,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" }, "node_modules/json5": { "version": "2.2.3", @@ -16157,6 +14057,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -16166,6 +14067,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-6.0.0.tgz", "integrity": "sha512-1SkN2RXhMCTCSkX+bzHvr9ycM2HTmjWyV41hn2xG7k6BqlCgRjw0zHmuqfphjBRPqi1gKMIqgBCe/0RZMcWrAA==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/http-client": "^3.2.0", "canonicalize": "^1.0.1", @@ -16180,6 +14082,7 @@ "version": "11.6.0", "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-11.6.0.tgz", "integrity": "sha512-hzYNZXnfy4cUFf9aiFBtduUz+cknbfBLWtTKvoqVyP2ECPwqfsfkHWFlhccWfAKV/LJkPLyKZRwC1B4T5LO4ZQ==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/security-context": "^1.0.0", "jsonld": "^9.0.0", @@ -16195,6 +14098,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-7.0.0.tgz", "integrity": "sha512-J/nA+llcYYjErPHG9WFpXvR82TOg5fbHk/7rXbx4Ts854DPReaKAAd0hAZ+s5/P2WIIAZPIHCqA+iz1QrOqeiQ==", + "license": "BSD-3-Clause", "dependencies": { "base64url": "^3.0.1", "crypto-ld": "^3.7.0", @@ -16211,6 +14115,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-4.0.1.tgz", "integrity": "sha512-ltEqMQB37ZxZnsgmI+9rqHYkz1M6PqUykuS1t2aQNuH1oiLrUDYz5nyVkHQDgjFd7CFKTIWeLiNhwdwFrH5o5A==", + "license": "BSD-3-Clause", "dependencies": { "canonicalize": "^1.0.1", "lru-cache": "^5.1.1", @@ -16227,6 +14132,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz", "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==", + "license": "BSD-3-Clause", "dependencies": { "semver": "^6.3.0", "setimmediate": "^1.0.5" @@ -16239,6 +14145,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "license": "MIT", "dependencies": { "type-fest": "^0.8.0" }, @@ -16250,6 +14157,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -16258,6 +14166,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-4.3.0.tgz", "integrity": "sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==", + "license": "BSD-3-Clause", "dependencies": { "ky": "^1.14.2", "undici": "^6.23.0" @@ -16270,6 +14179,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.1.0.tgz", "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", + "license": "Apache-2.0", "bin": { "canonicalize": "bin/canonicalize.js" } @@ -16278,6 +14188,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-9.0.0.tgz", "integrity": "sha512-pjMIdkXfC1T2wrX9B9i2uXhGdyCmgec3qgMht+TDj+S0qX3bjWMQUfL7NeqEhuRTi8G5ESzmL9uGlST7nzSEWg==", + "license": "BSD-3-Clause", "dependencies": { "@digitalbazaar/http-client": "^4.2.0", "canonicalize": "^2.1.0", @@ -16292,6 +14203,7 @@ "version": "1.14.3", "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz", "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -16303,6 +14215,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -16314,6 +14227,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-5.0.0.tgz", "integrity": "sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==", + "license": "BSD-3-Clause", "dependencies": { "setimmediate": "^1.0.5" }, @@ -16322,9 +14236,9 @@ } }, "node_modules/jsonld-signatures/node_modules/undici": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.26.0.tgz", - "integrity": "sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", "license": "MIT", "engines": { "node": ">=18.17" @@ -16333,12 +14247,14 @@ "node_modules/jsonld-signatures/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/jsonld/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -16349,12 +14265,14 @@ "node_modules/jsonld/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -16409,6 +14327,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -16417,6 +14336,7 @@ "version": "0.33.3", "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -16428,6 +14348,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "node-fetch": "^3.2.10" @@ -16452,6 +14373,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -16465,16 +14387,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -16565,7 +14477,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -16648,7 +14561,7 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, - "peer": true, + "license": "MIT", "bin": { "lz-string": "bin/bin.js" } @@ -16697,6 +14610,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, "dependencies": { "semver": "^7.5.3" }, @@ -16711,6 +14625,7 @@ "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -16737,18 +14652,9 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/make-promises-safe/-/make-promises-safe-5.1.0.tgz", "integrity": "sha512-AfdZ49rtyhQR/6cqVKGoH7y4ql7XkS5HJI1lZm0/5N6CQosy1eYbBJ/qbhkKHzo17UH7M918Bysf6XB9f3kS1g==", + "license": "MIT", "optional": true }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -16798,6 +14704,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, "license": "MIT" }, "node_modules/merge2": { @@ -16928,6 +14835,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -16971,6 +14879,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -16991,6 +14900,7 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" @@ -17035,6 +14945,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "license": "MIT", + "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -17259,12 +15170,14 @@ "node_modules/multiformats": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==", + "license": "(Apache-2.0 AND MIT)" }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC", "optional": true }, "node_modules/mz": { @@ -17302,26 +15215,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", - "license": "MIT", - "peer": true, - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/neo-async": { "version": "2.6.2", @@ -17333,6 +15231,7 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/neon-cli/-/neon-cli-0.10.1.tgz", "integrity": "sha512-kOd9ELaYETe1J1nBEOYD7koAZVj6xR9TGwOPccAsWmwL5amkaXXXwXHCUHkBAWujlgSZY5f2pT+pFGkzoHExYQ==", + "license": "SEE LICENSE IN LICENSE-*", "optional": true, "dependencies": { "chalk": "^4.1.0", @@ -17358,9 +15257,9 @@ } }, "node_modules/neon-cli/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "optional": true, "bin": { @@ -17381,6 +15280,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", "dependencies": { "clone": "2.x" }, @@ -17403,6 +15303,7 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } @@ -17453,6 +15354,7 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.0.0" } @@ -17469,17 +15371,11 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "license": "MIT", - "peer": true - }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true }, "node_modules/node-stdlib-browser": { "version": "1.3.1", @@ -17531,6 +15427,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "license": "MIT", "engines": { "node": ">=12.19" } @@ -17555,6 +15452,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -17563,6 +15461,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -17595,6 +15494,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", "engines": { "node": "*" } @@ -17732,6 +15632,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "devOptional": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -17741,6 +15642,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "devOptional": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -17801,10 +15703,101 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ox": { + "version": "0.14.30", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.30.tgz", + "integrity": "sha512-LI11uu+8iiM1B3CLckgd++YF1a0A2k5wDoM9ZeQMiL21BOzQs6L//BLS6hb1HSEKCyycdDIQLsVQx9MjpcC0hA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.2.3", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, + "node_modules/ox/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/abitype": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.4.tgz", + "integrity": "sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -17846,25 +15839,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true }, "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.2.0.tgz", + "integrity": "sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", @@ -17951,6 +15946,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, "engines": { "node": ">=8" } @@ -17959,6 +15955,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17968,6 +15965,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -17981,6 +15979,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -17995,7 +15994,8 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -18077,7 +16077,23 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/permissionless": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/permissionless/-/permissionless-0.3.7.tgz", + "integrity": "sha512-r1UGWkVMqFzzJ0UcKEVHh6XvOm7+SfTvy7AoGA7ZlxpE96XR+zbtb+rRAA3DOQuq6/ifov5NvUyt1xf4zxbR0g==", + "license": "MIT", + "peerDependencies": { + "ox": "^0.11.3", + "viem": "^2.44.4" + }, + "peerDependenciesMeta": { + "ox": { + "optional": true + } + } }, "node_modules/picocolors": { "version": "1.1.1", @@ -18088,6 +16104,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -18108,6 +16125,7 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, "engines": { "node": ">= 6" } @@ -18131,7 +16149,6 @@ "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "playwright-core": "1.48.2" }, @@ -18151,7 +16168,6 @@ "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -18170,7 +16186,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -18388,7 +16403,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -18403,7 +16418,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -18462,6 +16477,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, @@ -18497,23 +16513,6 @@ "node": ">=6" } }, - "node_modules/pure-rand": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT", - "peer": true - }, "node_modules/pvtsutils": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", @@ -18562,6 +16561,7 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "license": "MIT", "engines": { "node": ">=0.4.x" } @@ -18647,6 +16647,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz", "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==", + "license": "BSD-3-Clause", "dependencies": { "setimmediate": "^1.0.5" }, @@ -18700,7 +16701,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/react-pdf": { "version": "7.7.3", @@ -18846,6 +16847,7 @@ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", "license": "MIT", + "optional": true, "engines": { "node": ">=6" } @@ -18895,6 +16897,7 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -18925,6 +16928,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -18938,6 +16942,7 @@ "version": "6.5.5", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.6" } @@ -18946,6 +16951,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -18968,6 +16974,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -18977,6 +16984,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -19005,29 +17013,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "license": "MIT", - "peer": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -19040,6 +17025,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", "optional": true, "dependencies": { "onetime": "^5.1.0", @@ -19053,6 +17039,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC", "optional": true }, "node_modules/reusify": { @@ -19068,7 +17055,8 @@ "node_modules/rfc4648": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.2.tgz", - "integrity": "sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==" + "integrity": "sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==", + "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", @@ -19233,6 +17221,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.12.0" @@ -19264,12 +17253,14 @@ "node_modules/runtypes": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/runtypes/-/runtypes-6.7.0.tgz", - "integrity": "sha512-3TLdfFX8YHNFOhwHrSJza6uxVBmBrEjnNQlNXvXCdItS0Pdskfg5vVXUTWIN+Y23QR09jWpSl99UHkA83m4uWA==" + "integrity": "sha512-3TLdfFX8YHNFOhwHrSJza6uxVBmBrEjnNQlNXvXCdItS0Pdskfg5vVXUTWIN+Y23QR09jWpSl99UHkA83m4uWA==", + "license": "MIT" }, "node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "tslib": "^1.9.0" @@ -19282,6 +17273,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD", "optional": true }, "node_modules/safe-array-concat": { @@ -19401,6 +17393,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -19415,6 +17408,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -19525,6 +17519,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -19536,6 +17531,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -19618,6 +17614,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -19676,6 +17673,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19686,6 +17684,7 @@ "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -19762,6 +17761,7 @@ "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -19772,6 +17772,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", "optional": true, "dependencies": { "spdx-expression-parse": "^3.0.0", @@ -19782,12 +17783,14 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0", "optional": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", "optional": true, "dependencies": { "spdx-exceptions": "^2.1.0", @@ -19798,19 +17801,14 @@ "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "license": "CC0-1.0", "optional": true }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -19831,29 +17829,6 @@ "node": ">=0.10.0" } }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -19937,50 +17912,17 @@ "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "license": "WTFPL OR MIT", - "peer": true - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -19998,6 +17940,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20010,12 +17953,14 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -20117,6 +18062,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -20132,6 +18078,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -20143,6 +18090,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "engines": { "node": ">=12" }, @@ -20150,20 +18098,11 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -20185,6 +18124,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "engines": { "node": ">=8" }, @@ -20236,6 +18176,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "devOptional": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -20279,27 +18220,12 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synckit": { - "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, "node_modules/table-layout": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", "license": "MIT", + "optional": true, "dependencies": { "array-back": "^4.0.1", "deep-extend": "~0.6.0", @@ -20315,6 +18241,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -20324,6 +18251,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -20484,6 +18412,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT", "optional": true }, "node_modules/through2": { @@ -20647,13 +18576,6 @@ "node": ">=0.6.0" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/to-buffer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", @@ -20694,6 +18616,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT", "optional": true }, "node_modules/totalist": { @@ -20767,22 +18690,6 @@ "integrity": "sha512-PTyPoWYHc2we8P2NTn5hpYG211popWbkjiw+k63xqjeMrx9pPtXSclz9F3fu0Tpr+vfR1xxcQFwsEkh1cXMLqw==", "license": "MIT" }, - "node_modules/ts-command-line-args": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", - "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", - "license": "ISC", - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - }, - "bin": { - "write-markdown": "dist/write-markdown.js" - } - }, "node_modules/ts-essentials": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", @@ -20878,6 +18785,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/ts-typed-json/-/ts-typed-json-0.3.2.tgz", "integrity": "sha512-Tdu3BWzaer7R5RvBIJcg9r8HrTZgpJmsX+1meXMJzYypbkj8NK2oJN0yvm4Dp/Iv6tzFa/L5jKRmEVTga6K3nA==", + "license": "MIT", "optional": true }, "node_modules/tslib": { @@ -21499,20 +19407,11 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "devOptional": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -21521,76 +19420,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typechain": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", - "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.3.0" - } - }, - "node_modules/typechain/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typechain/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "license": "MIT", - "peer": true - }, - "node_modules/typechain/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "license": "MIT", - "peer": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -21674,6 +19503,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21710,6 +19540,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -21766,6 +19597,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -21781,41 +19613,6 @@ "node": ">= 0.8" } }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, "node_modules/unzipper": { "version": "0.10.14", "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", @@ -21879,6 +19676,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, "funding": [ { "type": "opencollective", @@ -21961,29 +19759,16 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "license": "ISC", - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", "optional": true, "dependencies": { "spdx-correct": "^3.0.0", @@ -21994,6 +19779,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "license": "ISC", "optional": true, "dependencies": { "builtins": "^1.0.3" @@ -22003,6 +19789,7 @@ "version": "13.15.35", "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -22014,6 +19801,7 @@ "engines": [ "node >=0.6.0" ], + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -22021,10 +19809,9 @@ } }, "node_modules/viem": { - "version": "2.9.9", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.9.9.tgz", - "integrity": "sha512-SUIHBL6M5IIlqDCMEQwAAvHzeglaM4FEqM6bCI+srLXtFYmrpV4tWhnpobQRNwh4f7HIksmKLLZ+cytv8FfnJQ==", - "dev": true, + "version": "2.55.1", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.55.1.tgz", + "integrity": "sha512-sajvEmONS3dEDFh0jKXGugTU8ImyGoIV3sEHSWNRhgkH484v/+6DjZAplRhcdeqNV/VBxOs/l3raOG4NaXvX9A==", "funding": [ { "type": "github", @@ -22033,14 +19820,14 @@ ], "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.0", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@scure/bip32": "1.3.2", - "@scure/bip39": "1.2.1", - "abitype": "1.0.0", - "isows": "1.0.3", - "ws": "8.13.0" + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.2.3", + "isows": "1.0.7", + "ox": "0.14.30", + "ws": "8.21.0" }, "peerDependencies": { "typescript": ">=5.0.4" @@ -22051,61 +19838,33 @@ } } }, - "node_modules/viem/node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", - "dev": true, - "license": "MIT" - }, "node_modules/viem/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", "license": "MIT", "dependencies": { - "@noble/hashes": "1.3.2" + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/viem/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/vite": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", @@ -23367,16 +21126,6 @@ "tslib": "^2.1.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -23409,6 +21158,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -23474,6 +21224,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -23694,6 +21445,7 @@ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", "license": "MIT", + "optional": true, "dependencies": { "reduce-flatten": "^2.0.0", "typical": "^5.2.0" @@ -23707,6 +21459,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -23722,6 +21475,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -23739,6 +21493,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -23754,12 +21509,14 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -23773,6 +21530,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -23784,6 +21542,7 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, "engines": { "node": ">=12" }, @@ -23795,27 +21554,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "devOptional": true, "license": "ISC" }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "peer": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -23861,6 +21607,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -23872,9 +21619,9 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, "license": "ISC", "bin": { @@ -23887,25 +21634,6 @@ "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "peer": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -23944,45 +21672,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "peer": true - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 45ee537..17e5ca9 100644 --- a/package.json +++ b/package.json @@ -34,12 +34,13 @@ "@sanity/image-url": "^2.1.1", "@sentry/react": "^10.62.0", "@trustvc/decentralized-renderer-react-components": "^1.0.3", - "@trustvc/trustvc": "^2.14.1", + "@trustvc/trustvc": "^2.15.0-beta.2", "@types/lodash": "^4.17.24", "clsx": "^2.1.1", "date-fns": "^4.1.0", "lucide-react": "^0.563.0", "magic-sdk": "^33.6.2", + "permissionless": "^0.3.7", "qrcode.react": "^4.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -47,12 +48,15 @@ "react-ga4": "^3.0.1", "react-router-dom": "^7.12.0", "react-tooltip": "^5.30.0", - "swiper": "^12.0.3" + "swiper": "^12.0.3", + "viem": "^2.55.1" }, "devDependencies": { "@eslint/js": "^9.17.0", + "@playwright/test": "1.48.2", "@sentry/vite-plugin": "^5.3.0", "@synthetixio/synpress": "4.0.5", + "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.1.0", "@testing-library/user-event": "^14.5.2", diff --git a/src/components/AssetManagementPanel/AssetManagementForm/FormVariants/ActionSelectionForm/ActionSelectionForm.tsx b/src/components/AssetManagementPanel/AssetManagementForm/FormVariants/ActionSelectionForm/ActionSelectionForm.tsx index b3fa1f8..feaa4a5 100644 --- a/src/components/AssetManagementPanel/AssetManagementForm/FormVariants/ActionSelectionForm/ActionSelectionForm.tsx +++ b/src/components/AssetManagementPanel/AssetManagementForm/FormVariants/ActionSelectionForm/ActionSelectionForm.tsx @@ -10,6 +10,11 @@ import { AssetManagementDropdown } from '../../AssetManagementDropdown' import ConnectToBlockchainModel from '../../../../ConnectToBlockchain' import { Button, ButtonSize } from '../../../../common/Button' import { Tag } from '../../../../common/Tag' +import { CheckCircle } from '../../../../../../src/components/common/Icons' +import { + getPaymasterAddress, + PAYMASTER_CHANGE_EVENT, +} from '../../../../../gasless/paymasterStorage' interface ActionSelectionFormProps { beneficiary?: string @@ -108,6 +113,18 @@ export const ActionSelectionForm: FunctionComponent< } }, [holder, resolveAddress]) + const [savedPaymaster, setSavedPaymaster] = useState(() => + getPaymasterAddress(account) + ) + useEffect(() => { + const update = () => setSavedPaymaster(getPaymasterAddress(account)) + update() + window.addEventListener(PAYMASTER_CHANGE_EVENT, update) + return () => { + window.removeEventListener(PAYMASTER_CHANGE_EVENT, update) + } + }, [account]) + const canManage = canTransferHolder || canTransferBeneficiary || @@ -189,6 +206,16 @@ export const ActionSelectionForm: FunctionComponent<
{!isTokenBurnt && (
+ {!!account && !!savedPaymaster && ( +
+
+ + + Pay-on-behalf is enabled for all transactions. + +
+
+ )}
{account ? ( <> diff --git a/src/components/common/Icons/Icons.tsx b/src/components/common/Icons/Icons.tsx index d69a113..9450449 100644 --- a/src/components/common/Icons/Icons.tsx +++ b/src/components/common/Icons/Icons.tsx @@ -1,3 +1,4 @@ +import { SVGProps } from 'react' import { getFileExtension } from '../../../utils/helper' export const CheckCircle = () => ( @@ -230,3 +231,39 @@ export const FileIcon = ({ ) } + +export const InfoMsgIcon = ({ + fontSize = 24, + stroke = '#FF8200', + ...props +}: SVGProps) => { + return ( + + + + + + ) +} diff --git a/src/components/common/Icons/index.ts b/src/components/common/Icons/index.ts index 927cbf2..52c3cf3 100644 --- a/src/components/common/Icons/index.ts +++ b/src/components/common/Icons/index.ts @@ -9,4 +9,5 @@ export { ExclamationCircle, ChevronUp, ChevronDown, + InfoMsgIcon, } from './Icons' diff --git a/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.test.tsx b/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.test.tsx index ec8616e..1484a1e 100644 --- a/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.test.tsx +++ b/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.test.tsx @@ -49,7 +49,7 @@ describe('DocumentTransferMessage', () => { }) describe('errorMessage prop', () => { - it('renders errorMessage text instead of children when errorMessage is provided', () => { + it('renders both errorMessage and children when errorMessage is provided', () => { renderWithOverlay( { ) expect(screen.getByText('User Rejected Transaction')).toBeInTheDocument() - expect( - screen.queryByText('default child content') - ).not.toBeInTheDocument() + expect(screen.getByText('default child content')).toBeInTheDocument() }) it('renders children when errorMessage is undefined', () => { diff --git a/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.tsx b/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.tsx index faa31f7..a37377f 100644 --- a/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.tsx +++ b/src/components/common/Overlay/OverlayContent/DocumentTransferMessage.tsx @@ -96,7 +96,8 @@ export const DocumentTransferMessage: FunctionComponent< {/* Content */}
- {errorMessage ?

{errorMessage}

: children} + {children} + {errorMessage &&

{errorMessage}

}
{/* Footer Buttons */} diff --git a/src/components/common/contexts/TokenInformationContext/TokenInformationContext.tsx b/src/components/common/contexts/TokenInformationContext/TokenInformationContext.tsx index f094e04..2b5b721 100644 --- a/src/components/common/contexts/TokenInformationContext/TokenInformationContext.tsx +++ b/src/components/common/contexts/TokenInformationContext/TokenInformationContext.tsx @@ -12,6 +12,18 @@ import { ContractFunctionState, useContractFunctionHook, } from '../../../../hooks/useContractFunctionHook' +import { + useGaslessTransferHolder, + useGaslessTransferBeneficiary, + useGaslessTransferOwners, + useGaslessNominate, + useGaslessRejectTransferHolder, + useGaslessRejectTransferBeneficiary, + useGaslessRejectTransferOwners, + useGaslessReturnToIssuer, + useGaslessAcceptReturned, + useGaslessRejectReturned, +} from '../../../../gasless' import { useProviderContext } from '../providerContext' import { useTokenRegistryContract } from '../../../../hooks/useTokenRegistryContract' import { useTitleEscrowContract } from '../../../../hooks/useTitleEscrowContract' @@ -187,11 +199,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: changeHolderState, reset: resetChangeHolder, errorMessage: changeHolderErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'transferHolder', + } = useGaslessTransferHolder( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner // move to hook itself + providerOrSigner, + documentChainId ) const { @@ -199,11 +210,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: destroyTokenState, reset: resetDestroyingTokenState, errorMessage: destroyTokenErrorMessage, - } = useContractFunctionHook( - tokenRegistry, - 'acceptReturned', + } = useGaslessAcceptReturned( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -211,11 +221,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: endorseBeneficiaryState, reset: resetEndorseBeneficiary, errorMessage: endorseBeneficiaryErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'transferBeneficiary', + } = useGaslessTransferBeneficiary( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -223,11 +232,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: nominateState, reset: resetNominate, errorMessage: nominateErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'nominate', + } = useGaslessNominate( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -235,11 +243,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: rejectTransferHolderState, reset: resetRejectTransferHolder, errorMessage: rejectTransferHolderErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'rejectTransferHolder', + } = useGaslessRejectTransferHolder( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -247,11 +254,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: rejectTransferOwnerState, reset: resetRejectTransferOwner, errorMessage: rejectTransferOwnerErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'rejectTransferBeneficiary', + } = useGaslessRejectTransferBeneficiary( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -259,23 +265,21 @@ export const TokenInformationContextProvider: FunctionComponent< state: rejectTransferOwnerHolderState, reset: resetRejectTransferOwnerHolder, errorMessage: rejectTransferOwnerHolderErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'rejectTransferOwners', + } = useGaslessRejectTransferOwners( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { - send: restoreToken, // restoreToken function does not return any value + send: restoreToken, state: restoreTokenState, reset: resetRestoreTokenState, errorMessage: restoreTokenErrorMessage, - } = useContractFunctionHook( - tokenRegistry, - 'rejectReturned', + } = useGaslessRejectReturned( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -283,11 +287,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: returnToIssuerState, reset: resetReturnToIssuer, errorMessage: returnToIssuerErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'returnToIssuer', + } = useGaslessReturnToIssuer( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const { @@ -295,11 +298,10 @@ export const TokenInformationContextProvider: FunctionComponent< state: transferOwnerHoldersState, reset: resetTransferOwners, errorMessage: transferOwnersErrorMessage, - } = useContractFunctionHook( - titleEscrow, - 'transferOwners', + } = useGaslessTransferOwners( { titleEscrowAddress, tokenRegistryAddress, tokenId }, - providerOrSigner + providerOrSigner, + documentChainId ) const resetProviders = useCallback(() => { diff --git a/src/components/home/VerifySection/VerifyResult.tsx b/src/components/home/VerifySection/VerifyResult.tsx index 6d6cb66..82af303 100644 --- a/src/components/home/VerifySection/VerifyResult.tsx +++ b/src/components/home/VerifySection/VerifyResult.tsx @@ -1,10 +1,10 @@ -import React, { useEffect, useState } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import NetworkTooltip from './NetworkTooltip' import DocumentRenderer from './DocumentRenderer' import InvalidAttachmentsBanner from './InvalidAttachmentsBanner' import ObfuscatedMessage from './ObfuscatedMessage' import { makeExplorerAddressURL } from './useVerify' -import { CheckCircle, CrossCircle } from '../../common/Icons' +import { CheckCircle, CrossCircle, InfoMsgIcon } from '../../common/Icons' import { DocumentAttachment } from '../../../utils/helper' import { getMagicLinkIconSrc } from '../../../utils/magicWallet' import Connected from '../../ConnectToBlockchain/Connected' @@ -14,6 +14,16 @@ import { } from '../../common/contexts/providerContext' import { AssetManagementApplication } from '../../AssetManagementPanel/AssetManagementApplication' import { TextButton } from '../../common/Button/Button' +import { checkPaymasterWhitelist } from '../../../gasless/checkPaymasterWhitelist' +import { checkEIP7702Delegation } from '../../../gasless/checkDelegation' +import { + getPaymasterAddress, + setPaymasterAddress as savePaymasterAddress, + removePaymasterAddress as clearPaymasterAddress, +} from '../../../gasless/paymasterStorage' +import { getRpcUrl } from '../../../utils/helper' +import { isAddress, createPublicClient, http } from 'viem' +import InfoIcon from '../../../../src/components/icons/info' interface VerifyResultProps { fileName: string @@ -61,7 +71,8 @@ const VerifyResult: React.FC = ({ refreshEndorsementChain, isExpired, }) => { - const { changeNetwork, currentChainId } = useProviderContext() + const { changeNetwork, currentChainId, providerType, account } = + useProviderContext() // Switch provider to the document's chain when a transferable document is loaded useEffect(() => { @@ -70,6 +81,133 @@ const VerifyResult: React.FC = ({ } }, [isTransferable, chainId, currentChainId, changeNetwork]) + // ── EIP-7702 delegation check ──────────────────────────────────────────── + const [isDelegated, setIsDelegated] = useState(false) + + useEffect(() => { + if (!account || !chainId) { + setIsDelegated(false) + return + } + const rpcUrl = getRpcUrl(chainId) + if (!rpcUrl) { + setIsDelegated(false) + return + } + let cancelled = false + checkEIP7702Delegation(account, rpcUrl).then(result => { + if (!cancelled) setIsDelegated(result) + }) + return () => { + cancelled = true + } + }, [account, chainId]) + + // ── Gasless card state ─────────────────────────────────────────────────── + const [paymasterAddress, setPaymasterAddress] = useState('') + const [gaslessStatus, setGaslessStatus] = useState< + 'idle' | 'checking' | 'success' | 'error' + >('idle') + const [gaslessError, setGaslessError] = useState('') + + // Reset gasless state whenever the wallet changes + useEffect(() => { + setGaslessStatus('idle') + setGaslessError('') + setPaymasterAddress('') + }, [account]) + + const checkGasless = useCallback( + async (address: string) => { + const trimmed = address.trim() + if (!isAddress(trimmed, { strict: false })) return + + if (!chainId || !tokenRegistryAddress || !tokenId) { + setGaslessError( + 'Document information missing — cannot verify paymaster.' + ) + setGaslessStatus('error') + return + } + if (!account) { + setGaslessError('Please connect your wallet first.') + setGaslessStatus('error') + return + } + + setGaslessStatus('checking') + setGaslessError('') + try { + const rpcUrl = getRpcUrl(chainId) + console.log('[checkGasless] rpcUrl:', rpcUrl, 'chainId:', chainId) + if (!rpcUrl) throw new Error('No RPC URL for chain') + + const publicClient = createPublicClient({ transport: http(rpcUrl) }) + const titleEscrowAddress = await publicClient.readContract({ + address: tokenRegistryAddress as `0x${string}`, + abi: [ + { + name: 'ownerOf', + type: 'function', + inputs: [{ name: 'tokenId', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + ], + functionName: 'ownerOf', + args: [BigInt(tokenId)], + }) + console.log('[checkGasless] titleEscrowAddress:', titleEscrowAddress) + + const result = await checkPaymasterWhitelist( + trimmed, + account, + titleEscrowAddress as string, + rpcUrl + ) + console.log('[checkGasless] whitelist result:', result) + + if (result.isCallerAuthorized && result.isTitleEscrowAuthorized) { + savePaymasterAddress(account, trimmed) + setGaslessStatus('success') + } else { + console.warn( + '[checkGasless] not whitelisted — isCallerAuthorized:', + result.isCallerAuthorized, + 'isTitleEscrowAuthorized:', + result.isTitleEscrowAuthorized + ) + clearPaymasterAddress(account) + setGaslessError('This address is not applicable to you') + setGaslessStatus('error') + } + } catch (err) { + console.error('[checkGasless] error:', err) + const msg = err instanceof Error ? err.message : String(err) + if ( + msg.includes('No RPC URL') || + msg.includes('network') || + msg.includes('fetch') + ) { + setGaslessError('Network error — please try again.') + } else { + setGaslessError('Invalid Paymaster Address') + } + setGaslessStatus('error') + } + }, + [account, chainId, tokenRegistryAddress, tokenId] + ) + + // Auto-verify stored paymaster once delegation is confirmed + useEffect(() => { + if (!isDelegated || !account) return + const stored = getPaymasterAddress(account) + if (!stored) return + setPaymasterAddress(stored) + checkGasless(stored) + }, [isDelegated, account, checkGasless]) + const showNftLinks = !!isTransferable const [isTooltipVisible, setIsTooltipVisible] = useState(false) @@ -127,7 +265,6 @@ const VerifyResult: React.FC = ({ }) setIsTooltipVisible(true) } - const { providerType, account } = useProviderContext() return (
{/* ── Network info card ── */} @@ -213,7 +350,81 @@ const VerifyResult: React.FC = ({ {/* ── Main result card ── */}
{/* Header */} -
+
+ {isDelegated && gaslessStatus === 'success' ? ( +
+
+ + + This wallet has Pay-on-Behalf enabled. Transaction fees are + covered for you, so you'll see a Signature Request + instead of a Transaction Request when confirming. + +
+
+ ) : isDelegated ? ( +
+
+
+ +
+ + We have detected that you have the pay-on-behalf feature. + To enable it, please enter your paymaster address: + +
+ { + const val = e.target.value + setPaymasterAddress(val) + const trimmed = val.trim() + if (isAddress(trimmed, { strict: false })) { + checkGasless(trimmed) + } else if (trimmed.length > 0) { + setGaslessStatus('error') + setGaslessError('Invalid Paymaster Address') + } else { + setGaslessStatus('idle') + setGaslessError('') + } + }} + disabled={gaslessStatus === 'checking'} + /> + {gaslessStatus === 'error' && ( + + )} +
+
+
+
+
+ ) : null}