commit 1844fb8b457625913d063ecfe7d8c76ddeb35be8 Author: Asgarsk Date: Thu Nov 28 18:39:11 2024 +0530 Added new header and product dropable diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a3dae2b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use official Node.js image as the base image +FROM node:20-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy package.json and package-lock.json first to leverage Docker cache for npm install +COPY package*.json ./ + +# Install the application dependencies +RUN npm install + +# Copy the rest of the application files into the container +COPY . . + +# Expose port 5173, which Vite uses by default +EXPOSE 5173 + +# Run the application with `--host 0.0.0.0` to make it accessible externally +CMD ["npm", "run", "dev"] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..0910ddb --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,112 @@ +pipeline { + agent any + + environment { + DOCKER_IMAGE = 'jassimsm/tech4biz-reactjs' + DOCKER_TAG = 'latest' + DOCKER_USERNAME = "jassimsm" + DOCKER_PASSWORD = "dckr_pat_c9HutePXaqreGfKi48H0WPWWfBs" + SSH_CREDENTIALS = 'tech4biz-demo' + REMOTE_SERVER = 'ubuntu@160.187.167.157' + REMOTE_WORKSPACE = '/home/ubuntu' + GIT_CREDENTIALS = 'git-cred' + + } + + stages { + stage('Add Host Key') { + steps { + script { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + mkdir -p ~/.ssh + ssh-keyscan -H 160.187.167.157 >> ~/.ssh/known_hosts + ''' + } + } + } + } + stage('Checkout and Install Dependencies on Remote Server') { + steps { + script { + withCredentials([usernamePassword(credentialsId: GIT_CREDENTIALS, usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + ssh ${REMOTE_SERVER} "mkdir -p ${REMOTE_WORKSPACE} && cd ${REMOTE_WORKSPACE} && rm -rf Tech4Biz-Website && \ + git clone https://${GIT_USERNAME}:${GIT_PASSWORD}@git.tech4biz.wiki/Tech4Biz-Services/Tech4Biz-Website.git && \ + cd Tech4Biz-Website && git checkout main" + ''' + } + } + } + } + } + + + stage('Build Docker Image on Remote Server') { + steps { + script { + try { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + ssh ${REMOTE_SERVER} "cd ${REMOTE_WORKSPACE}/Tech4Biz-Website && docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} ." + ''' + } + } catch (Exception e) { + error "Failed to build Docker image on remote server: ${e.message}" + } + } + } + } + + stage('Push Docker Image from Remote Server') { + steps { + script { + try { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + ssh ${REMOTE_SERVER} "echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin && docker push ${DOCKER_IMAGE}:${DOCKER_TAG}" + ''' + } + } catch (Exception e) { + error "Failed to push Docker image from remote server: ${e.message}" + } + } + } + } + + stage('Deploy') { + steps { + script { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + ssh ${REMOTE_SERVER} "cd ${REMOTE_WORKSPACE}/Tech4Biz-Website && \ + docker pull ${DOCKER_IMAGE}:${DOCKER_TAG} && \ + docker stop tech4biz-container || true && \ + docker rm tech4biz-container || true && \ + docker run -d -p 5173:5173 --name tech4biz-container ${DOCKER_IMAGE}:${DOCKER_TAG}" + ''' + } + } + } + } + + stage('Update Nginx Configuration') { + steps { + script { + sshagent(credentials: [SSH_CREDENTIALS]) { + sh ''' + ssh ${REMOTE_SERVER} "sudo nginx -t && sudo systemctl reload nginx" + ''' + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..f768e33 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh diff --git a/certificates/localhost-key.pem b/certificates/localhost-key.pem new file mode 100644 index 0000000..586fab5 --- /dev/null +++ b/certificates/localhost-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0yxzB1wr+alBS +BI5uWzp/u4/V9jkt/QFPMC2MLWyanemD50hDBRs0lZxmiYoLHqUDWZNPg/jdSj8d +VV+bcjdpfIH8s95TewTovG/szuGLZpu33DFSi/WB/1mulS2qflW/5A4h/3XgrgU6 +Zze1sEvGBHEzI/obBkt/pebmt0AUruYlUonQW23JWLaLCsjTd9kMVGpqG8mRreaH +N3sYCEMKa3flyucToEA32OYXLkuQgmgs5txcdGXQp/0ELstoxzvTNdJcCyBSZ2V8 +5JzR/yt58MXjH6xcHq3VYEOqvGOmuGmbZxa6QfevGml7ivO0FWjHneSnnCFm5kKs +rehy+uZNAgMBAAECggEAQrABJYca6QlyIy7HEvHXvDIFNlkiclI232zYADLpMoc5 +EYyIXSBPDrB5BmGJZ9yf5YJvEg+OBqJScZGCOKaCxghFMl9ujMB96RNI/cK581+f +5Mv17YruvkrgW8NvGsqK+sM2a1f9tSi7iPV12TD0YlBVKRYGNV23D5i0eTnzCy1x +JruG5088zPnLoDy8T9WRTfYEnqXFxQscsTyDF9+2rZ+Vyr2YHxIt55w7IIrHFiUR +OczY4UJhmMIF0grddHNaTrjxtjAhCR+ysKq+qLs8QLZf2uXz3RawIohe7Rbl47D0 +E3R6fD3AeeLmc3wokz40s8RO8BV0ce6iWiH56i8uiQKBgQDq+NXy2vUXLM3CTYHB +onUmJbWybmyN4g7aJLHcoPzhVonr5e/cToh/uWqmDGcQlo7iNS9TZh23VdpaUbn0 +ZEm2y0GhPA9K1WJl20F+NQT8/HPF4pdBdAr8fUSjDpqi61+AYTr0W/pGD1pFp60S +H+kxd/BjrbPEKZVR39Kn9pMJ7wKBgQDE+Q4T02IvmJjXdOqjz1SnC5CQfzpb1AqJ +3xFGZTlFuy9uXY+9I5KVlfssMD8MXv+UzjQruk0/W8dnDdxvf35xi3z8zIQSDJxU +frJQB/qH/xoVnPgBe9eoAxus68p16ymONqEnNfjwmGhjeADpcV22uqVn2lMP9gN7 +sGiVhWU/gwKBgQDqs/9RA3DI41HrgWvYtKN7pTMmtbHszx6yuvCGRrARjVVasmSy +lCc4HUbv8XeJVDoIrcNF9Lw+Ap2Glhe+i+Ytlj1KBinoP9h3kViL7f27jZc+1CTt +ljHbHm1OyimgDqdoHra6mp0VGgS7is8PSZyucvVFO55SlI64J2/NojghNQKBgH8I +CFYs65O6nEfH9VNz8SpSQQePpfl3BNzp6eA2g/s+v1Y0LPFUMcMbGQPkkaTO15IG +cosI+ay06iLCQ7n8xXVA+ninBT4GuAOeOi13F9IBabcqpp9+WRTX/E9HOilWYlR/ +UutQ2Z2BDUGpMR1cqY2hTe9uVEdk59YrbSeRAj01AoGAU34mB2IROZEytgHwpcde +upFIEizd80UVemoKU8pF2/9XgXDTHjSC9c4NF4WSmAWQsIcXpJaCkDyr+qNhO6zz +/acU3HYaCB6zL/TEUme2D6suF6r6jxL/Dplh3rSunODbWJnb7doyonp+vuYXRuvE +8K/7IqtqgiDXoTK8fqc5ArM= +-----END PRIVATE KEY----- diff --git a/certificates/localhost.pem b/certificates/localhost.pem new file mode 100644 index 0000000..d1a8fb3 --- /dev/null +++ b/certificates/localhost.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEOTCCAqGgAwIBAgIQbxETXs1CjgYgD/b+KdTWeDANBgkqhkiG9w0BAQsFADB5 +MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExJzAlBgNVBAsMHmNvbXBA +Y29tcC1PcHRpUGxleC0zMDYwIChDT01QKTEuMCwGA1UEAwwlbWtjZXJ0IGNvbXBA +Y29tcC1PcHRpUGxleC0zMDYwIChDT01QKTAeFw0yNDExMTgxMTEzMjRaFw0yNzAy +MTgxMTEzMjRaMFIxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZp +Y2F0ZTEnMCUGA1UECwweY29tcEBjb21wLU9wdGlQbGV4LTMwNjAgKENPTVApMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtMscwdcK/mpQUgSObls6f7uP +1fY5Lf0BTzAtjC1smp3pg+dIQwUbNJWcZomKCx6lA1mTT4P43Uo/HVVfm3I3aXyB +/LPeU3sE6Lxv7M7hi2abt9wxUov1gf9ZrpUtqn5Vv+QOIf914K4FOmc3tbBLxgRx +MyP6GwZLf6Xm5rdAFK7mJVKJ0FttyVi2iwrI03fZDFRqahvJka3mhzd7GAhDCmt3 +5crnE6BAN9jmFy5LkIJoLObcXHRl0Kf9BC7LaMc70zXSXAsgUmdlfOSc0f8refDF +4x+sXB6t1WBDqrxjprhpm2cWukH3rxppe4rztBVox53kp5whZuZCrK3ocvrmTQID +AQABo2QwYjAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYD +VR0jBBgwFoAUESjQ1/iXrVC2pXmwsifWkOsW1JYwGgYDVR0RBBMwEYIJbG9jYWxo +b3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBgQCCXjtWpgqhWL6kxuHpc2Mi7/Qn +GDQFsgxJg5ydLJbvgglf2+IocGEro4IfU1xIbfT3gsoTbbl2SERq/jrhBzQzrFh6 +rdrpRfuXAI2/bubPmO3gbPAx0P0yf0ADpwIrxQKqy+sWipMdVaFef644MK+C6jHx +9LOpo48WQWXkbd/wFPVyU0XIcofjTaB41ITPUuAk+/rMyBCGcUSZvDgsMo0Aguf6 +8oO+bk6v2jBORkcel0FAWOaK9IIrG6vg1w1A5OWI0whCDsV01Zty7vqdRibTKb00 +yswGas/nTZCIcaPnZ9pBLwUvzwsJrlsB9xEjASu4TlOGxbXOQI1d0kbvyZDLsR8A +/jmQT/UPXpUhIrxeYTQugco8w3K1r8SXPp5bHVgdj7aAt+vv68xlujkKN/FKlOii +rfc1IqH5YKQ0a9LO8wm4XAI9RxXubt6Of/hdlwPeJA2BTG2PmaDwYWZSpN0YnCul +sOkAe0EWYwFN3iga7JqsyhQVTzQH0ChHIYa+dBQ= +-----END CERTIFICATE----- diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..238d2e4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,38 @@ +import js from '@eslint/js' +import globals from 'globals' +import react from 'eslint-plugin-react' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' + +export default [ + { ignores: ['dist'] }, + { + files: ['**/*.{js,jsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + settings: { react: { version: '18.3' } }, + plugins: { + react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...js.configs.recommended.rules, + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + ...reactHooks.configs.recommended.rules, + 'react/jsx-no-target-blank': 'off', + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +] diff --git a/index.html b/index.html new file mode 100644 index 0000000..c0968f8 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Tech4biz-Update + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..852585c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6440 @@ +{ + "name": "tech4biz-update", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tech4biz-update", + "version": "0.0.0", + "dependencies": { + "@react-spring/web": "^9.7.5", + "@tanstack/react-virtual": "^3.10.9", + "@types/react-window": "^1.8.8", + "embla-carousel-react": "^8.5.1", + "framer-motion": "^11.11.17", + "gsap": "^3.12.5", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lucide-react": "^0.454.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-error-boundary": "^4.1.2", + "react-feather": "^2.0.10", + "react-helmet": "^6.1.0", + "react-helmet-async": "^2.0.5", + "react-icons": "^5.3.0", + "react-intersection-observer": "^9.13.1", + "react-router-dom": "^6.28.0", + "react-swipeable": "^7.0.2", + "react-virtuoso": "^4.12.0", + "react-window": "^1.8.10", + "recharts": "^2.13.3", + "split-type": "^0.3.4" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-basic-ssl": "^1.1.0", + "@vitejs/plugin-react": "^4.3.3", + "autoprefixer": "^10.4.20", + "eslint": "^9.13.0", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.11.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", + "vite": "^5.4.10", + "vite-plugin-compression": "^0.5.1" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", + "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", + "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", + "license": "MIT", + "dependencies": { + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", + "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", + "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", + "license": "MIT" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", + "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", + "license": "MIT", + "dependencies": { + "@react-spring/rafz": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", + "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", + "license": "MIT" + }, + "node_modules/@react-spring/web": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz", + "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/core": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", + "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", + "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" + } + }, + "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.9.tgz", + "integrity": "sha512-OXO2uBjFqA4Ibr2O3y0YMnkrRWGVNqcvHQXmGvMu6IK8chZl3PrDxFXdGZ2iZkSrKh3/qUYoFqYe+Rx23RoU0g==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.10.9" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz", + "integrity": "sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "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, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-window": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", + "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", + "dev": true, + "license": "ISC" + }, + "node_modules/embla-carousel": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.1.tgz", + "integrity": "sha512-JUb5+FOHobSiWQ2EJNaueCNT/cQU9L6XWBbWmorWPQT9bkbk+fhsuLr8wWrzXKagO3oWszBO7MSx+GfaRk4E6A==", + "license": "MIT" + }, + "node_modules/embla-carousel-react": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.5.1.tgz", + "integrity": "sha512-z9Y0K84BJvhChXgqn2CFYbfEi6AwEr+FFVVKm/MqbTQ2zIzO1VQri6w67LcfpVF0AjbhwVMywDZqY4alYkjW5w==", + "license": "MIT", + "dependencies": { + "embla-carousel": "8.5.1", + "embla-carousel-reactive-utils": "8.5.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.5.1.tgz", + "integrity": "sha512-n7VSoGIiiDIc4MfXF3ZRTO59KDp820QDuyBDGlt5/65+lumPHxX2JLz0EZ23hZ4eg4vZGUXwMkYv02fw2JVo/A==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.5.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==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.14.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.0", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz", + "integrity": "sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "11.11.17", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.17.tgz", + "integrity": "sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "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, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "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/gsap": { + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz", + "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==", + "license": "Standard 'no charge' license: https://gsap.com/standard-license. Club GSAP members get more: https://gsap.com/licensing/. Why GreenSock doesn't employ an MIT license: https://gsap.com/why-license/" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.454.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.454.0.tgz", + "integrity": "sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-import/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-boundary": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.1.2.tgz", + "integrity": "sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-feather": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/react-feather/-/react-feather-2.0.10.tgz", + "integrity": "sha512-BLhukwJ+Z92Nmdcs+EMw6dy1Z/VLiJTzEQACDUEnWMClhYnFykJCGWQx+NmwP/qQHGX/5CzQ+TGi8ofg2+HzVQ==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=16.8.6" + } + }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/react-helmet-async": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.5.tgz", + "integrity": "sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-intersection-observer": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.13.1.tgz", + "integrity": "sha512-tSzDaTy0qwNPLJHg8XZhlyHTgGW6drFKTtvjdL+p6um12rcnp8Z5XstE+QNBJ7c64n5o0Lj4ilUleA41bmDoMw==", + "license": "MIT", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.21.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-smooth": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-swipeable": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-7.0.2.tgz", + "integrity": "sha512-v1Qx1l+aC2fdxKa9aKJiaU/ZxmJ5o98RMoFwUqAAzVWUcxgfHFXDDruCKXhw6zIYXm6V64JiHgP9f6mlME5l8w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-virtuoso": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.12.0.tgz", + "integrity": "sha512-oHrKlU7xHsrnBQ89ecZoMPAK0tHnI9s1hsFW3KKg5ZGeZ5SWvbGhg/QFJFY4XETAzoCUeu+Xaxn1OUb/PGtPlA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16 || >=17 || >= 18", + "react-dom": ">=16 || >=17 || >= 18" + } + }, + "node_modules/react-window": { + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", + "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.13.3.tgz", + "integrity": "sha512-YDZ9dOfK9t3ycwxgKbrnDlRC4BHdjlY73fet3a0C1+qGMjXVZe6+VXmpOIIhzkje5MMEL8AN4hLIe4AMskBzlA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/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" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "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, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-type": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/split-type/-/split-type-0.3.4.tgz", + "integrity": "sha512-otEk9vnD8qwfLsk3Lx0gz+qRkNIJCx0mlyL47ImP/DjMuV39d75Lpfwjn9fHteDRz0aoOblSzQjSNT9+Sswxcg==", + "license": "ISC" + }, + "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, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "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, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-compression": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz", + "integrity": "sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "debug": "^4.3.3", + "fs-extra": "^10.0.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dev": true, + "license": "MIT", + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "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==", + "dev": true, + "license": "MIT", + "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/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..fb69664 --- /dev/null +++ b/package.json @@ -0,0 +1,56 @@ +{ + "name": "tech4biz-update", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@react-spring/web": "^9.7.5", + "@tanstack/react-virtual": "^3.10.9", + "@types/react-window": "^1.8.8", + "embla-carousel-react": "^8.5.1", + "framer-motion": "^11.11.17", + "gsap": "^3.12.5", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lucide-react": "^0.454.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-error-boundary": "^4.1.2", + "react-feather": "^2.0.10", + "react-helmet": "^6.1.0", + "react-helmet-async": "^2.0.5", + "react-icons": "^5.3.0", + "react-intersection-observer": "^9.13.1", + "react-router-dom": "^6.28.0", + "react-swipeable": "^7.0.2", + "react-virtuoso": "^4.12.0", + "react-window": "^1.8.10", + "recharts": "^2.13.3", + "split-type": "^0.3.4" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-basic-ssl": "^1.1.0", + "@vitejs/plugin-react": "^4.3.3", + "autoprefixer": "^10.4.20", + "eslint": "^9.13.0", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.11.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", + "vite": "^5.4.10", + "vite-plugin-compression": "^0.5.1" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..aabb7db --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { + createBrowserRouter, + RouterProvider, + createRoutesFromElements, + Route +} from 'react-router-dom'; +import { HelmetProvider } from 'react-helmet-async'; +import Home from './pages/Home'; +import Services from './pages/ServicePage'; + +const router = createBrowserRouter( + createRoutesFromElements( + <> + } /> + } /> + + ), + { + future: { + v7_startTransition: true, + v7_relativeSplatPath: true, + v7_fetcherPersist: true, + v7_normalizeFormMethod: true, + v7_partialHydration: true, + v7_skipActionErrorRevalidation: true + } + } +); + +const App = () => { + return ( + + + + ); +}; + +export default App; \ No newline at end of file diff --git a/src/assets/AI-service.webp b/src/assets/AI-service.webp new file mode 100644 index 0000000..c402995 Binary files /dev/null and b/src/assets/AI-service.webp differ diff --git a/src/assets/Case Studies Slider/3D-Visual-Img.webp b/src/assets/Case Studies Slider/3D-Visual-Img.webp new file mode 100644 index 0000000..6532a25 Binary files /dev/null and b/src/assets/Case Studies Slider/3D-Visual-Img.webp differ diff --git a/src/assets/Case Studies Slider/automating.webp b/src/assets/Case Studies Slider/automating.webp new file mode 100644 index 0000000..008aeb2 Binary files /dev/null and b/src/assets/Case Studies Slider/automating.webp differ diff --git a/src/assets/Case Studies Slider/decentralized-banner.webp b/src/assets/Case Studies Slider/decentralized-banner.webp new file mode 100644 index 0000000..858e30e Binary files /dev/null and b/src/assets/Case Studies Slider/decentralized-banner.webp differ diff --git a/src/assets/Case Studies Slider/empower.webp b/src/assets/Case Studies Slider/empower.webp new file mode 100644 index 0000000..fa55853 Binary files /dev/null and b/src/assets/Case Studies Slider/empower.webp differ diff --git a/src/assets/Case Studies Slider/fitness.webp b/src/assets/Case Studies Slider/fitness.webp new file mode 100644 index 0000000..8968d7e Binary files /dev/null and b/src/assets/Case Studies Slider/fitness.webp differ diff --git a/src/assets/Case Studies Slider/iotconnecctivity.webp b/src/assets/Case Studies Slider/iotconnecctivity.webp new file mode 100644 index 0000000..e688329 Binary files /dev/null and b/src/assets/Case Studies Slider/iotconnecctivity.webp differ diff --git a/src/assets/Case Studies Slider/transforming-blockchain.webp b/src/assets/Case Studies Slider/transforming-blockchain.webp new file mode 100644 index 0000000..78c950f Binary files /dev/null and b/src/assets/Case Studies Slider/transforming-blockchain.webp differ diff --git a/src/assets/Case Studies Slider/urban-connectivity.webp b/src/assets/Case Studies Slider/urban-connectivity.webp new file mode 100644 index 0000000..a8b90d6 Binary files /dev/null and b/src/assets/Case Studies Slider/urban-connectivity.webp differ diff --git a/src/assets/Cloud Infrastructure section/Enterprise Cloud Infrastructure.webp b/src/assets/Cloud Infrastructure section/Enterprise Cloud Infrastructure.webp new file mode 100644 index 0000000..575fb9e Binary files /dev/null and b/src/assets/Cloud Infrastructure section/Enterprise Cloud Infrastructure.webp differ diff --git a/src/assets/Cloud Infrastructure section/Infrastructure as a Service Platform.webp b/src/assets/Cloud Infrastructure section/Infrastructure as a Service Platform.webp new file mode 100644 index 0000000..40fcc3c Binary files /dev/null and b/src/assets/Cloud Infrastructure section/Infrastructure as a Service Platform.webp differ diff --git a/src/assets/Cloud Infrastructure section/Platform as a Service Architecture.webp b/src/assets/Cloud Infrastructure section/Platform as a Service Architecture.webp new file mode 100644 index 0000000..97326d8 Binary files /dev/null and b/src/assets/Cloud Infrastructure section/Platform as a Service Architecture.webp differ diff --git a/src/assets/Cloud Infrastructure section/Software as a Service Solutions.webp b/src/assets/Cloud Infrastructure section/Software as a Service Solutions.webp new file mode 100644 index 0000000..5b0f78c Binary files /dev/null and b/src/assets/Cloud Infrastructure section/Software as a Service Solutions.webp differ diff --git a/src/assets/Cloud-Service.webp b/src/assets/Cloud-Service.webp new file mode 100644 index 0000000..9eb6d55 Binary files /dev/null and b/src/assets/Cloud-Service.webp differ diff --git a/src/assets/CloudCTA/arrow-shape.png b/src/assets/CloudCTA/arrow-shape.png new file mode 100644 index 0000000..82b654e Binary files /dev/null and b/src/assets/CloudCTA/arrow-shape.png differ diff --git a/src/assets/Header-slide/Img-1.webp b/src/assets/Header-slide/Img-1.webp new file mode 100644 index 0000000..a53edf3 Binary files /dev/null and b/src/assets/Header-slide/Img-1.webp differ diff --git a/src/assets/Header-slide/Img-2.webp b/src/assets/Header-slide/Img-2.webp new file mode 100644 index 0000000..402f4da Binary files /dev/null and b/src/assets/Header-slide/Img-2.webp differ diff --git a/src/assets/Header-slide/Img-3.webp b/src/assets/Header-slide/Img-3.webp new file mode 100644 index 0000000..361529c Binary files /dev/null and b/src/assets/Header-slide/Img-3.webp differ diff --git a/src/assets/Header-slide/Img-4.webp b/src/assets/Header-slide/Img-4.webp new file mode 100644 index 0000000..8fc25ff Binary files /dev/null and b/src/assets/Header-slide/Img-4.webp differ diff --git a/src/assets/Header/Product-Card/cloud-drive-storage-platform.webp b/src/assets/Header/Product-Card/cloud-drive-storage-platform.webp new file mode 100644 index 0000000..ca59000 Binary files /dev/null and b/src/assets/Header/Product-Card/cloud-drive-storage-platform.webp differ diff --git a/src/assets/Header/Product-Card/cloudtopiaa-enterprise-solutions.webp b/src/assets/Header/Product-Card/cloudtopiaa-enterprise-solutions.webp new file mode 100644 index 0000000..7485062 Binary files /dev/null and b/src/assets/Header/Product-Card/cloudtopiaa-enterprise-solutions.webp differ diff --git a/src/assets/Header/Product-Card/codenuk-coding-solution-platform.webp b/src/assets/Header/Product-Card/codenuk-coding-solution-platform.webp new file mode 100644 index 0000000..9fd0305 Binary files /dev/null and b/src/assets/Header/Product-Card/codenuk-coding-solution-platform.webp differ diff --git a/src/assets/Header/Product-Card/learning-management-system.webp b/src/assets/Header/Product-Card/learning-management-system.webp new file mode 100644 index 0000000..7b6c4aa Binary files /dev/null and b/src/assets/Header/Product-Card/learning-management-system.webp differ diff --git a/src/assets/Logo/AWS-Partner-Netwrok-tech4biz.webp b/src/assets/Logo/AWS-Partner-Netwrok-tech4biz.webp new file mode 100644 index 0000000..c4c23c6 Binary files /dev/null and b/src/assets/Logo/AWS-Partner-Netwrok-tech4biz.webp differ diff --git a/src/assets/Logo/AZURE-Partner-Tech4biz.webp b/src/assets/Logo/AZURE-Partner-Tech4biz.webp new file mode 100644 index 0000000..51912cf Binary files /dev/null and b/src/assets/Logo/AZURE-Partner-Tech4biz.webp differ diff --git a/src/assets/Logo/Cloudtopiaa-Tech4biz.webp b/src/assets/Logo/Cloudtopiaa-Tech4biz.webp new file mode 100644 index 0000000..40d7380 Binary files /dev/null and b/src/assets/Logo/Cloudtopiaa-Tech4biz.webp differ diff --git a/src/assets/Logo/IBM-Tech4biz-partner.webp b/src/assets/Logo/IBM-Tech4biz-partner.webp new file mode 100644 index 0000000..bf33c3c Binary files /dev/null and b/src/assets/Logo/IBM-Tech4biz-partner.webp differ diff --git a/src/assets/Logo/ISO-Partner-Tech4biz.webp b/src/assets/Logo/ISO-Partner-Tech4biz.webp new file mode 100644 index 0000000..26925e2 Binary files /dev/null and b/src/assets/Logo/ISO-Partner-Tech4biz.webp differ diff --git a/src/assets/Logo/OPENAI-Partner-Tech4biz.webp b/src/assets/Logo/OPENAI-Partner-Tech4biz.webp new file mode 100644 index 0000000..0e5fee1 Binary files /dev/null and b/src/assets/Logo/OPENAI-Partner-Tech4biz.webp differ diff --git a/src/assets/Logo/Tech4biz-logo.webp b/src/assets/Logo/Tech4biz-logo.webp new file mode 100644 index 0000000..af933a8 Binary files /dev/null and b/src/assets/Logo/Tech4biz-logo.webp differ diff --git a/src/assets/Our-Product-Img/advanced-risk-analytics-trading-platform-ml-investment-dashboard.webp b/src/assets/Our-Product-Img/advanced-risk-analytics-trading-platform-ml-investment-dashboard.webp new file mode 100644 index 0000000..2f79f6c Binary files /dev/null and b/src/assets/Our-Product-Img/advanced-risk-analytics-trading-platform-ml-investment-dashboard.webp differ diff --git a/src/assets/Our-Product-Img/connected-retail-management-iot-customer-experience-platform.webp b/src/assets/Our-Product-Img/connected-retail-management-iot-customer-experience-platform.webp new file mode 100644 index 0000000..cba55d9 Binary files /dev/null and b/src/assets/Our-Product-Img/connected-retail-management-iot-customer-experience-platform.webp differ diff --git a/src/assets/Our-Product-Img/digital-commerce-intelligence-platform-pricing-analytics-dashboard.webp b/src/assets/Our-Product-Img/digital-commerce-intelligence-platform-pricing-analytics-dashboard.webp new file mode 100644 index 0000000..848378e Binary files /dev/null and b/src/assets/Our-Product-Img/digital-commerce-intelligence-platform-pricing-analytics-dashboard.webp differ diff --git a/src/assets/Our-Product-Img/digital-learning-experience-mixed-reality-education-platform.webp b/src/assets/Our-Product-Img/digital-learning-experience-mixed-reality-education-platform.webp new file mode 100644 index 0000000..04133d8 Binary files /dev/null and b/src/assets/Our-Product-Img/digital-learning-experience-mixed-reality-education-platform.webp differ diff --git a/src/assets/Our-Product-Img/enterprise-cloud-commerce-scalable-business-platform.webp b/src/assets/Our-Product-Img/enterprise-cloud-commerce-scalable-business-platform.webp new file mode 100644 index 0000000..2774ecc Binary files /dev/null and b/src/assets/Our-Product-Img/enterprise-cloud-commerce-scalable-business-platform.webp differ diff --git a/src/assets/Our-Product-Img/enterprise-security-defense-platform-dashboard-ai-threat-detection.webp b/src/assets/Our-Product-Img/enterprise-security-defense-platform-dashboard-ai-threat-detection.webp new file mode 100644 index 0000000..6726238 Binary files /dev/null and b/src/assets/Our-Product-Img/enterprise-security-defense-platform-dashboard-ai-threat-detection.webp differ diff --git a/src/assets/Our-Product-Img/enterprise-speech-recognition-ai-voice-analysis-platform.webp b/src/assets/Our-Product-Img/enterprise-speech-recognition-ai-voice-analysis-platform.webp new file mode 100644 index 0000000..72f1941 Binary files /dev/null and b/src/assets/Our-Product-Img/enterprise-speech-recognition-ai-voice-analysis-platform.webp differ diff --git a/src/assets/Our-Product-Img/smart-retail-automation-inventory-management-platform.webp b/src/assets/Our-Product-Img/smart-retail-automation-inventory-management-platform.webp new file mode 100644 index 0000000..6a67f8a Binary files /dev/null and b/src/assets/Our-Product-Img/smart-retail-automation-inventory-management-platform.webp differ diff --git a/src/assets/Product-Show-Case/ASIC-AI-Deployment.webp b/src/assets/Product-Show-Case/ASIC-AI-Deployment.webp new file mode 100644 index 0000000..ae4a7ac Binary files /dev/null and b/src/assets/Product-Show-Case/ASIC-AI-Deployment.webp differ diff --git a/src/assets/Product-Show-Case/Accelerated-Performance.webp b/src/assets/Product-Show-Case/Accelerated-Performance.webp new file mode 100644 index 0000000..1205810 Binary files /dev/null and b/src/assets/Product-Show-Case/Accelerated-Performance.webp differ diff --git a/src/assets/Product-Show-Case/Adaptive-Solutions.webp b/src/assets/Product-Show-Case/Adaptive-Solutions.webp new file mode 100644 index 0000000..ff9119b Binary files /dev/null and b/src/assets/Product-Show-Case/Adaptive-Solutions.webp differ diff --git a/src/assets/Product-Show-Case/Advanced-FPGA-Architecture.webp b/src/assets/Product-Show-Case/Advanced-FPGA-Architecture.webp new file mode 100644 index 0000000..5c0da3b Binary files /dev/null and b/src/assets/Product-Show-Case/Advanced-FPGA-Architecture.webp differ diff --git a/src/assets/Service-Section/Cloud-Service.webp b/src/assets/Service-Section/Cloud-Service.webp new file mode 100644 index 0000000..9eb6d55 Binary files /dev/null and b/src/assets/Service-Section/Cloud-Service.webp differ diff --git a/src/assets/Service-Section/Software Engineering Solutions.webp b/src/assets/Service-Section/Software Engineering Solutions.webp new file mode 100644 index 0000000..e5b4ddc Binary files /dev/null and b/src/assets/Service-Section/Software Engineering Solutions.webp differ diff --git a/src/assets/Service-Section/VLSI Design Services.webp b/src/assets/Service-Section/VLSI Design Services.webp new file mode 100644 index 0000000..f3ab6fd Binary files /dev/null and b/src/assets/Service-Section/VLSI Design Services.webp differ diff --git a/src/assets/Service-Section/placeholder.jpg b/src/assets/Service-Section/placeholder.jpg new file mode 100644 index 0000000..7e35296 Binary files /dev/null and b/src/assets/Service-Section/placeholder.jpg differ diff --git a/src/assets/Service-Section/service-main.webp b/src/assets/Service-Section/service-main.webp new file mode 100644 index 0000000..892bb40 Binary files /dev/null and b/src/assets/Service-Section/service-main.webp differ diff --git a/src/assets/Tech4biz-logo.png b/src/assets/Tech4biz-logo.png new file mode 100644 index 0000000..823f2ef Binary files /dev/null and b/src/assets/Tech4biz-logo.png differ diff --git a/src/assets/Tech4biz.mp4 b/src/assets/Tech4biz.mp4 new file mode 100644 index 0000000..0ebeb4b Binary files /dev/null and b/src/assets/Tech4biz.mp4 differ diff --git a/src/assets/Videos/cloud-infra.mp4 b/src/assets/Videos/cloud-infra.mp4 new file mode 100644 index 0000000..a1ff7e1 Binary files /dev/null and b/src/assets/Videos/cloud-infra.mp4 differ diff --git a/src/assets/Videos/deployment.mp4 b/src/assets/Videos/deployment.mp4 new file mode 100644 index 0000000..f286835 Binary files /dev/null and b/src/assets/Videos/deployment.mp4 differ diff --git a/src/assets/Videos/solutions.mp4 b/src/assets/Videos/solutions.mp4 new file mode 100644 index 0000000..d500981 Binary files /dev/null and b/src/assets/Videos/solutions.mp4 differ diff --git a/src/assets/demo-card.jpg b/src/assets/demo-card.jpg new file mode 100644 index 0000000..85d0c6c Binary files /dev/null and b/src/assets/demo-card.jpg differ diff --git a/src/assets/placeholder.jpg b/src/assets/placeholder.jpg new file mode 100644 index 0000000..7e35296 Binary files /dev/null and b/src/assets/placeholder.jpg differ diff --git a/src/assets/png.png b/src/assets/png.png new file mode 100644 index 0000000..33f23a7 Binary files /dev/null and b/src/assets/png.png differ diff --git a/src/assets/refference img/SlideLayout.png b/src/assets/refference img/SlideLayout.png new file mode 100644 index 0000000..8ad29b6 Binary files /dev/null and b/src/assets/refference img/SlideLayout.png differ diff --git a/src/assets/service-main.webp b/src/assets/service-main.webp new file mode 100644 index 0000000..892bb40 Binary files /dev/null and b/src/assets/service-main.webp differ diff --git a/src/assets/speech-bubble.png b/src/assets/speech-bubble.png new file mode 100644 index 0000000..2c236a0 Binary files /dev/null and b/src/assets/speech-bubble.png differ diff --git a/src/assets/tech4biz-hero-background.mp4 b/src/assets/tech4biz-hero-background.mp4 new file mode 100644 index 0000000..80bae3f Binary files /dev/null and b/src/assets/tech4biz-hero-background.mp4 differ diff --git a/src/components/CloudCTA/CloudCTA.jsx b/src/components/CloudCTA/CloudCTA.jsx new file mode 100644 index 0000000..ea5f87f --- /dev/null +++ b/src/components/CloudCTA/CloudCTA.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { motion } from 'framer-motion'; +import { cloudConfig } from './config'; +import { useInViewAnimation } from './hooks/useInViewAnimation'; +import { containerVariants } from './utils/variants'; +import CTAContent from './components/CTAContent'; +import CTAButton from './components/CTAButton'; +import styles from './styles/CloudCTA.module.css'; + +const CloudCTA = () => { + const { ref, controls } = useInViewAnimation(); + + return ( +
+
+ + + + + +
+
+ ); +}; + +export default CloudCTA; \ No newline at end of file diff --git a/src/components/CloudCTA/components/CTAButton.jsx b/src/components/CloudCTA/components/CTAButton.jsx new file mode 100644 index 0000000..11c2b78 --- /dev/null +++ b/src/components/CloudCTA/components/CTAButton.jsx @@ -0,0 +1,42 @@ +import React, { memo } from 'react'; +import { motion } from 'framer-motion'; +import { itemVariants } from '../utils/variants'; +import styles from '../styles/CloudCTA.module.css'; + +const CTAButton = memo(({ text }) => { + return ( + + {text} + + + ); +}); + +CTAButton.displayName = 'CTAButton'; +export default CTAButton; diff --git a/src/components/CloudCTA/components/CTAContent.jsx b/src/components/CloudCTA/components/CTAContent.jsx new file mode 100644 index 0000000..5b95d86 --- /dev/null +++ b/src/components/CloudCTA/components/CTAContent.jsx @@ -0,0 +1,68 @@ +import React, { memo, useEffect } from 'react'; +import { motion } from 'framer-motion'; +import { itemVariants } from '../utils/variants'; +import OptimizedImage from '@/components/common/OptimizedImage'; +import { preloadImage } from '../utils/performance'; +import styles from '../styles/CloudCTA.module.css'; + +const CTAContent = memo(({ heading, description, image }) => { + useEffect(() => { + preloadImage(image.src); + }, [image.src]); + + return ( +
+
+ + {heading} + + +
+ +
+ +
+
+ ); +}); + +CTAContent.displayName = 'CTAContent'; +export default CTAContent; \ No newline at end of file diff --git a/src/components/CloudCTA/config/content.js b/src/components/CloudCTA/config/content.js new file mode 100644 index 0000000..ad0fdab --- /dev/null +++ b/src/components/CloudCTA/config/content.js @@ -0,0 +1,20 @@ +import arrowShape from '@assets/CloudCTA/arrow-shape.png'; + +export const cloudConfig = { + heading: "MAXIMIZE YOUR CLOUD INVESTMENT", + description: "We help companies save thousands of dollars by optimizing their cloud server deployments across top platforms like AWS, Azure, and Google Cloud, while also cutting labor costs, so you can focus on driving business growth and performance.", + button: { + text: "Start Optimizing Today", + ariaLabel: "Start cloud optimization process" + }, + images: { + arrow: { + src: arrowShape, + alt: "Decorative arrow shape", + srcSet: `${arrowShape} 1x, ${arrowShape.replace('.png', '@2x.png')} 2x`, + sizes: "(max-width: 768px) 100vw, 50vw", + width: 180, + height: 180 + } + } +}; diff --git a/src/components/CloudCTA/config/index.js b/src/components/CloudCTA/config/index.js new file mode 100644 index 0000000..0d4fab6 --- /dev/null +++ b/src/components/CloudCTA/config/index.js @@ -0,0 +1,2 @@ +export { cloudConfig } from './content'; +export { cloudCTASchema } from './schema'; \ No newline at end of file diff --git a/src/components/CloudCTA/config/meta.js b/src/components/CloudCTA/config/meta.js new file mode 100644 index 0000000..c8f59fd --- /dev/null +++ b/src/components/CloudCTA/config/meta.js @@ -0,0 +1,11 @@ +export const ctaMeta = { + title: "Cloud Investment Optimization | Your Company", + description: "Optimize your cloud infrastructure costs across AWS, Azure, and Google Cloud platforms. Start saving today with our expert solutions.", + keywords: "cloud optimization, AWS optimization, Azure optimization, Google Cloud optimization, cloud cost savings", + openGraph: { + title: "Maximize Your Cloud Investment", + description: "Save thousands on cloud infrastructure with expert optimization", + image: "/og-cloud-optimization.jpg", + type: "website" + } +}; diff --git a/src/components/CloudCTA/config/schema.js b/src/components/CloudCTA/config/schema.js new file mode 100644 index 0000000..24e97c3 --- /dev/null +++ b/src/components/CloudCTA/config/schema.js @@ -0,0 +1,34 @@ +export const cloudCTASchema = { + "@context": "https://schema.org", + "@type": "Service", + "name": "Cloud Investment Optimization", + "description": "Cloud server deployment and optimization services for AWS, Azure, and Google Cloud platforms", + "provider": { + "@type": "Organization", + "name": "Your Company Name", + "url": "https://yourcompany.com" + }, + "offers": { + "@type": "Offer", + "description": "Cloud optimization services to reduce infrastructure and labor costs", + "price": "0", + "priceCurrency": "USD", + "availability": "https://schema.org/InStock" + }, + "serviceType": "Cloud Optimization", + "areaServed": "Worldwide", + "hasOfferCatalog": { + "@type": "OfferCatalog", + "name": "Cloud Optimization Services", + "itemListElement": [ + { + "@type": "Offer", + "itemOffered": { + "@type": "Service", + "name": "Cloud Cost Optimization", + "description": "Reduce your cloud infrastructure costs" + } + } + ] + } +}; diff --git a/src/components/CloudCTA/hooks/useInViewAnimation.js b/src/components/CloudCTA/hooks/useInViewAnimation.js new file mode 100644 index 0000000..189b036 --- /dev/null +++ b/src/components/CloudCTA/hooks/useInViewAnimation.js @@ -0,0 +1,19 @@ +import { useEffect, useRef } from 'react'; +import { useAnimation, useInView } from 'framer-motion'; +import { debouncedAnimation } from '../utils/performance'; + +export const useInViewAnimation = () => { + const ref = useRef(null); + const isInView = useInView(ref, { once: true }); + const controls = useAnimation(); + + useEffect(() => { + if (isInView) { + debouncedAnimation(() => { + controls.start("visible"); + }); + } + }, [isInView, controls]); + + return { ref, controls }; +}; diff --git a/src/components/CloudCTA/index.jsx b/src/components/CloudCTA/index.jsx new file mode 100644 index 0000000..944ac0a --- /dev/null +++ b/src/components/CloudCTA/index.jsx @@ -0,0 +1,14 @@ +import React, { lazy, Suspense } from 'react'; +import { ErrorBoundary } from '@/components/common/ErrorBoundary'; + +const CloudCTA = lazy(() => import('./CloudCTA')); + +const CloudCTAWrapper = () => ( + + }> + + + +); + +export default CloudCTAWrapper; diff --git a/src/components/CloudCTA/styles/CloudCTA.module.css b/src/components/CloudCTA/styles/CloudCTA.module.css new file mode 100644 index 0000000..c5b013d --- /dev/null +++ b/src/components/CloudCTA/styles/CloudCTA.module.css @@ -0,0 +1,112 @@ +:root { + --breakpoint-sm: 640px; + --breakpoint-md: 768px; + --breakpoint-lg: 1024px; + --breakpoint-xl: 1280px; + --breakpoint-2xl: 1536px; +} + +.container { + @apply w-full bg-white p-4 sm:p-6 md:p-8; +} + +.wrapper { + @apply max-w-[80rem] mx-auto; +} + +.content { + @apply bg-[#1F2937] rounded-[1.5rem] p-6 sm:p-8 md:p-12 flex flex-col gap-[1rem] relative overflow-hidden + border border-white/10 shadow-2xl; +} + +.contentWrapper { + @apply flex flex-col md:flex-row md:items-center md:gap-16 gap-6; +} + +.textContainer { + @apply w-full md:flex-[0.65]; +} + +.contentHeading { + @apply text-white text-[28px] sm:text-[30px] md:text-[32px] md:whitespace-nowrap font-[600] tracking-[0.03em] leading-[1.25] mb-4 font-syne uppercase; +} + +.divider { + @apply w-[7rem] sm:w-[8rem] md:w-[9rem] h-[3px] bg-white/90 mb-6 md:mb-8; +} + +.contentDescription { + @apply text-white/80 text-[14px] sm:text-[16px] md:text-[18px] font-[400] leading-[1.6] font-poppins; +} + +.buttonContainer { + @apply mt-6 sm:mt-8; +} + +.button { + @apply bg-[#f4791f] text-white px-6 sm:px-8 py-3 sm:py-3.5 rounded-full text-[15px] sm:text-[16px] md:text-[17px] font-medium + flex items-center gap-2 hover:bg-[#ff8827] transition-all duration-300 text-nowrap + shadow-lg hover:shadow-xl hover:translate-y-[-2px] justify-center w-full sm:w-auto; +} + +.buttonText { + @apply whitespace-nowrap; +} + +.buttonIcon { + @apply h-4 w-4 sm:h-5 sm:w-5; +} + +.imageContainer { + @apply hidden md:flex md:flex-[0.35] items-center justify-end relative; +} + +.floatingImage { + @apply absolute !important; + min-width: 400px !important; + max-width: 400px !important; + width: 400px !important; + height: 120px !important; + right: -45px !important; + bottom: -120px !important; + opacity: 100 !important; + object-fit: contain !important; + filter: brightness(1.2) !important; + will-change: transform, opacity !important; +} + +@media (max-width: 480px) { + .content { + @apply p-5; + } + + .contentHeading { + @apply text-[28px] leading-[1] mb-[0.5rem]; + } + + .contentDescription { + @apply text-[14px] leading-[1.5]; + } + + .divider { + @apply w-[6rem] mb-5; + } + + .button { + @apply px-5 py-2.5 text-[14px]; + } + + .buttonIcon { + @apply h-4 w-4; + } +} + +@media (min-width: 768px) { + .content { + @apply flex-row items-center justify-between; + } + + .buttonContainer { + @apply mt-0; + } +} \ No newline at end of file diff --git a/src/components/CloudCTA/utils/breakpoints.js b/src/components/CloudCTA/utils/breakpoints.js new file mode 100644 index 0000000..cc7026c --- /dev/null +++ b/src/components/CloudCTA/utils/breakpoints.js @@ -0,0 +1,15 @@ +export const breakpoints = { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px' +}; + +export const mediaQueries = { + sm: `@media (min-width: ${breakpoints.sm})`, + md: `@media (min-width: ${breakpoints.md})`, + lg: `@media (min-width: ${breakpoints.lg})`, + xl: `@media (min-width: ${breakpoints.xl})`, + '2xl': `@media (min-width: ${breakpoints['2xl']})` +}; diff --git a/src/components/CloudCTA/utils/performance.js b/src/components/CloudCTA/utils/performance.js new file mode 100644 index 0000000..97c392b --- /dev/null +++ b/src/components/CloudCTA/utils/performance.js @@ -0,0 +1,24 @@ +const debounce = (func, wait) => { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +}; + +export const debouncedAnimation = debounce((callback) => { + requestAnimationFrame(callback); +}, 16); + +export const preloadImage = (src) => { + return new Promise((resolve, reject) => { + const img = new Image(); + img.src = src; + img.onload = resolve; + img.onerror = reject; + }); +}; diff --git a/src/components/CloudCTA/utils/variants.js b/src/components/CloudCTA/utils/variants.js new file mode 100644 index 0000000..258f025 --- /dev/null +++ b/src/components/CloudCTA/utils/variants.js @@ -0,0 +1,19 @@ +export const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + duration: 0.6, + staggerChildren: 0.2 + } + } +}; + +export const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.5 } + } +}; diff --git a/src/components/CloudSlider/CloudSlider.jsx b/src/components/CloudSlider/CloudSlider.jsx new file mode 100644 index 0000000..62454bd --- /dev/null +++ b/src/components/CloudSlider/CloudSlider.jsx @@ -0,0 +1,173 @@ +import React, { useCallback } from 'react'; +import useEmblaCarousel from 'embla-carousel-react'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; +import { slides } from './sliderData'; +import styles from './CloudSlider.module.css'; +import { motion } from 'framer-motion'; + +const DeploymentPoint = ({ point, index, isVisible, isMobile }) => ( + +
+
+

{`${index + 1}. ${point.title}`}

+ {point.isNew && ( + New + )} +
+

{point.description}

+
+
+); + +export default function CloudSlider() { + const [progress, setProgress] = React.useState(0); + const progressRef = React.useRef(null); + const [currentSlide, setCurrentSlide] = React.useState(0); + const [isMobile, setIsMobile] = React.useState(false); + + const [emblaRef, emblaApi] = useEmblaCarousel({ + loop: true, + align: 'center', + skipSnaps: false, + containScroll: false, + dragFree: false, + startIndex: 0, + slidesToScroll: 1, + speed: 15, + breakpoints: { + '(max-width: 768px)': { + align: 'center', + containScroll: 'keepSnaps', + dragFree: true + } + } + }); + + React.useEffect(() => { + if (!emblaApi) return; + + const onSelect = () => { + setCurrentSlide(emblaApi.selectedScrollSnap()); + }; + + emblaApi.on('select', onSelect); + onSelect(); // Initial call to set current slide + + if (progressRef.current) { + clearInterval(progressRef.current); + } + + const startProgress = () => { + let currentProgress = 0; + progressRef.current = setInterval(() => { + currentProgress += 1; + setProgress(currentProgress); + + if (currentProgress >= 100) { + setProgress(0); + scrollNext(); + currentProgress = 0; + } + }, 50); // 50ms * 100 steps = 5 seconds per slide + }; + + startProgress(); + + return () => { + emblaApi.off('select', onSelect); + if (progressRef.current) { + clearInterval(progressRef.current); + } + }; + }, [emblaApi]); + + React.useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth <= 768); + }; + + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); + + const scrollPrev = useCallback(() => { + if (emblaApi) emblaApi.scrollPrev(); + }, [emblaApi]); + + const scrollNext = useCallback(() => { + if (emblaApi) emblaApi.scrollNext(); + }, [emblaApi]); + + return ( +
+

+ Cloud Infrastructure + Deployments +

+ +
+
+ {slides.map((slide, index) => ( +
+
+
+
+ +
+

{slide.title}

+
+ {slide.points.map((point, idx) => ( +
+ +
+ ))} +
+
+
+ {currentSlide === index && ( +
+ )} +
+
+
+ ))} +
+
+ +
+ + +
+
+ ); +} \ No newline at end of file diff --git a/src/components/CloudSlider/CloudSlider.module.css b/src/components/CloudSlider/CloudSlider.module.css new file mode 100644 index 0000000..79349ba --- /dev/null +++ b/src/components/CloudSlider/CloudSlider.module.css @@ -0,0 +1,245 @@ +.container { + @apply min-h-screen bg-[#1F2937] flex flex-col items-center justify-center p-4; +} + +.title { + @apply text-5xl font-bold text-center mb-16 font-sans; +} + +.titleWhite { + @apply text-white; +} + +.titleBlue { + @apply text-blue-500; +} + +.sliderContainer { + @apply relative w-full max-w-[1200px] mx-auto; +} + +.slide { + @apply rounded-xl relative overflow-hidden w-full mx-auto; + min-height: 552px; + height: auto; + padding: 2rem; + + @media (max-width: 768px) { + min-height: auto; + padding: 1rem; + } +} + +.slideBackground { + @apply absolute inset-0 z-0; +} + +.gradientOverlay { + @apply absolute inset-0 bg-gradient-to-br from-purple-500/10 to-emerald-500/5 pointer-events-none; +} + +.contentWrapper { + @apply h-full flex flex-col relative z-10; + justify-content: space-between; + min-height: 552px; + + @media (max-width: 768px) { + height: 100%; + justify-content: flex-start; + gap: 1.5rem; + } +} + +.slideTitle { + @apply text-[24px] text-white font-syne font-semibold text-left; + + @media (max-width: 768px) { + font-size: 20px; + position: relative; + top: 0; + left: 0; + margin-bottom: 1rem; + } +} + +.pointsContainer { + @apply flex flex-col relative; + display: grid; + grid-template-columns: repeat(3, minmax(200px, 1fr)); + gap: 24px; + padding-top: 32px; + overflow: hidden; + + @media (max-width: 768px) { + display: flex; + flex-direction: column; + gap: 12px; + padding: 0; + margin: 0; + width: 100%; + height: calc(100% - 60px); + overflow-y: auto; + } +} + +.pointWrapper { + @apply flex justify-center; + transform-style: preserve-3d; + perspective: 1000px; + + @media (max-width: 768px) { + transform-style: flat; + perspective: none; + width: 100%; + } +} + +.navigationButtons { + @apply flex justify-center gap-4 mt-8; +} + +.navButton { + @apply p-2 rounded-full bg-gray-800/30 hover:bg-gray-700/30 transition-colors backdrop-blur-sm; +} + +.navIcon { + @apply w-5 h-5 text-white/80; +} + +.progressBarContainer { + @apply absolute bottom-0 left-0 right-0 h-1 bg-gray-800/50; + z-index: 20; +} + +.progressBar { + @apply h-full bg-blue-500; + transition: width 50ms linear; +} + +.deploymentPoint { + @apply flex items-start gap-3; + position: relative; + + @media (max-width: 768px) { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: 12px; + padding: 0.75rem; + width: 100%; + display: flex; + align-items: flex-start; + transition: all 0.2s ease; + /* Removed backdrop-filter: blur(8px); */ + } +} + +/* Removed the .starIcon class below +.starIcon { + @apply mt-1 text-blue-500; +} + +@media (max-width: 768px) { + .starIcon { + color: rgb(96, 165, 250); + transform: scale(0.7); + margin-right: 0.5rem; + } +} +*/ + +.pointTitle { + @apply text-white font-medium tracking-wide font-poppins text-[18px] leading-[27px]; + + @media (max-width: 768px) { + font-size: 16px; + line-height: 1.3; + letter-spacing: 0.02em; + } +} + +.newTag { + @apply px-1.5 py-0.5 text-[11px] bg-[#22c55e]/90 text-white rounded-[2px] uppercase tracking-wide font-medium; +} + +.pointDescription { + @apply text-gray-400 font-poppins font-medium text-[14px] leading-[21px] mt-1.5 max-w-[280px]; + + @media (max-width: 768px) { + display: none; /* Hide descriptions only on mobile */ + font-size: 13px; + line-height: 20px; + max-width: 100%; + } +} + +.embla { + @apply relative w-full max-w-[1400px] mx-auto overflow-hidden; + padding: 1.6rem; + + @media (max-width: 768px) { + padding: 1rem; + } +} + +.emblaContainer { + @apply flex; + transform-style: preserve-3d; + backface-visibility: hidden; + will-change: transform; + transition: transform 200ms ease; +} + +.emblaSlide { + flex: 0 0 80%; + margin: 0 2%; + position: relative; + overflow: hidden; + + @media (max-width: 768px) { + flex: 0 0 calc(100% - 2rem); + margin: 0 1rem; + scroll-snap-align: center; + } +} + +.slideContent { + @apply rounded-xl p-12 relative overflow-hidden; + transform: translateZ(0); + will-change: transform; + background: linear-gradient(to bottom right, rgba(31, 41, 55, 1), rgba(17, 24, 39, 1)); + min-height: 552px; + + @media (max-width: 768px) { + height: 480px; + padding: 1.25rem; + background: linear-gradient(200.96deg, rgba(31, 41, 55, 0.95), rgba(17, 24, 39, 0.98)); + } +} + +/* Additional adjustments to ensure proper spacing and sizing */ +@media (max-width: 768px) { + .pointsContainer { + gap: 12px; + } + + .deploymentPoint { + padding: 0.75rem; + /* backdrop-filter removed */ + } + + .slideContent { + padding: 1.25rem; + } + + .pointWrapper { + width: 100%; + } + + .pointTitle { + font-size: 16px; + } + + .newTag { + font-size: 10px; + } +} \ No newline at end of file diff --git a/src/components/CloudSlider/sliderData.js b/src/components/CloudSlider/sliderData.js new file mode 100644 index 0000000..15974b5 --- /dev/null +++ b/src/components/CloudSlider/sliderData.js @@ -0,0 +1,131 @@ +import SaaSImage from '@/assets/Cloud Infrastructure section/Software as a Service Solutions.webp'; +import PaaSImage from '@/assets/Cloud Infrastructure section/Platform as a Service Architecture.webp'; +import IaaSImage from '@/assets/Cloud Infrastructure section/Infrastructure as a Service Platform.webp'; +import EnterpriseImage from '@/assets/Cloud Infrastructure section/Enterprise Cloud Infrastructure.webp'; + +export const slides = [ + { + title: "Public Cloud Orchestration and Design", + backgroundImage: SaaSImage, + points: [ + { + title: "Flexible Deployment", + description: "Choose from multiple deployment options that best suit your infrastructure needs", + isNew: false + }, + { + title: "Auto-scaling", + description: "Automatically adjust resources based on demand and workload patterns", + isNew: false + }, + { + title: "Multi-region Support", + description: "Deploy across multiple geographic regions for improved availability", + isNew: false + }, + { + title: "Container Orchestration", + description: "Integrated container management with Kubernetes support", + isNew: true + }, + { + title: "Infrastructure as Code", + description: "Define and manage infrastructure using modern IaC tools", + isNew: true + } + ] + }, + { + title: "Security and Compliance Features", + backgroundImage: PaaSImage, + points: [ + { + title: "Advanced Encryption", + description: "Industry-standard encryption protocols to protect data at rest and in transit", + isNew: false + }, + { + title: "Compliance Framework", + description: "Built-in compliance tools for HIPAA, GDPR, and other regulatory requirements", + isNew: false + }, + { + title: "Identity Management", + description: "Robust IAM capabilities with role-based access control and SSO integration", + isNew: true + }, + { + title: "Security Monitoring", + description: "24/7 threat detection and automated security incident response", + isNew: true + }, + { + title: "Audit Logging", + description: "Comprehensive audit trails and logging for all system activities", + isNew: false + } + ] + }, + { + title: "Performance and Scalability", + backgroundImage: IaaSImage, + points: [ + { + title: "Global CDN", + description: "Worldwide content delivery network for optimal performance", + isNew: true + }, + { + title: "Load Balancing", + description: "Intelligent traffic distribution for high availability", + isNew: false + }, + { + title: "Elastic Resources", + description: "Dynamic resource allocation based on real-time demands", + isNew: false + }, + { + title: "Performance Monitoring", + description: "Real-time metrics and performance analytics", + isNew: true + }, + { + title: "Disaster Recovery", + description: "Automated backup and recovery solutions", + isNew: false + } + ] + }, + { + title: "Enterprise Integration", + backgroundImage: EnterpriseImage, + points: [ + { + title: "API Management", + description: "Comprehensive API gateway and management tools", + isNew: true + }, + { + title: "Hybrid Cloud", + description: "Seamless integration between public and private clouds", + isNew: false + }, + { + title: "Data Migration", + description: "Enterprise-grade tools for secure data transfer", + isNew: false + }, + { + title: "DevOps Pipeline", + description: "Integrated CI/CD tools for automated deployments", + isNew: true + }, + { + title: "Enterprise Support", + description: "24/7 dedicated support and consulting services", + isNew: false + } + ] + } +]; diff --git a/src/components/ExperienceSection/ExperienceService.jsx b/src/components/ExperienceSection/ExperienceService.jsx new file mode 100644 index 0000000..739c8f4 --- /dev/null +++ b/src/components/ExperienceSection/ExperienceService.jsx @@ -0,0 +1,71 @@ +import React, { Suspense } from 'react'; +import ErrorBoundary from '../common/ErrorBoundary'; +import { SECTION_CONFIG } from './config/constants'; +import { experienceSchema } from './config/schema'; +import './styles/ExperienceSection.css'; +import { Helmet } from 'react-helmet-async'; +import { useExperienceData } from './hooks/useExperienceData'; + +const ExperienceHeader = React.lazy(() => import('./components/ExperienceHeader')); +const ExperienceCard = React.lazy(() => import('./components/ExperienceCard')); + +const ExperienceService = () => { + const { experiences, isLoading, error } = useExperienceData(); + + if (error) { + return ( +
+

Something went wrong while loading experiences.

+

Please try again later.

+
+ ); + } + + return ( + +
+ + + + {SECTION_CONFIG.title} + + + + + {/* Open Graph Meta Tags */} + + + + + + + {/* Twitter Card Meta Tags */} + + + + + + + }> + + + +
+ {isLoading ? ( +
Loading experiences...
+ ) : ( + experiences.map((experience, index) => ( + }> + + + )) + )} +
+
+
+ ); +}; + +export default ExperienceService; diff --git a/src/components/ExperienceSection/components/ExperienceCard.jsx b/src/components/ExperienceSection/components/ExperienceCard.jsx new file mode 100644 index 0000000..38500ee --- /dev/null +++ b/src/components/ExperienceSection/components/ExperienceCard.jsx @@ -0,0 +1,56 @@ +import React, { useRef, useEffect } from 'react'; +import { motion } from 'framer-motion'; +import { ArrowRight } from 'lucide-react'; +import gsap from 'gsap'; +import { ANIMATION_CONFIG } from '../config/constants'; +import '../styles/ExperienceCard.css'; + +const ExperienceCard = ({ icon: Icon, title, description, stats }) => { + const cardRef = useRef(null); + + useEffect(() => { + const card = cardRef.current; + gsap.fromTo( + card, + ANIMATION_CONFIG.card.initial, + { + ...ANIMATION_CONFIG.card.animate, + scrollTrigger: { + trigger: card, + ...ANIMATION_CONFIG.card.trigger, + }, + } + ); + }, []); + + return ( +
+ + ); +}; + +export default React.memo(ExperienceCard); diff --git a/src/components/ExperienceSection/components/ExperienceHeader.jsx b/src/components/ExperienceSection/components/ExperienceHeader.jsx new file mode 100644 index 0000000..4aa879b --- /dev/null +++ b/src/components/ExperienceSection/components/ExperienceHeader.jsx @@ -0,0 +1,57 @@ +import React, { useRef, useEffect } from 'react'; +import gsap from 'gsap'; +import { ANIMATION_CONFIG, SECTION_CONFIG } from '../config/constants'; +import '../styles/ExperienceHeader.css'; + +const ExperienceHeader = () => { + const headerRef = useRef(null); + + useEffect(() => { + const ctx = gsap.context(() => { + const tl = gsap.timeline({ + scrollTrigger: { + trigger: headerRef.current, + ...ANIMATION_CONFIG.header.trigger, + }, + }); + + tl.from(".header-subtitle", { + opacity: 0, + y: -20, + duration: ANIMATION_CONFIG.header.duration, + ease: ANIMATION_CONFIG.header.ease, + }) + .from( + ".header-title", + { + opacity: 0, + y: 30, + duration: ANIMATION_CONFIG.header.duration, + ease: ANIMATION_CONFIG.header.ease, + }, + "-=0.3" + ) + .from( + ".header-line", + { + scaleX: 0, + duration: ANIMATION_CONFIG.header.duration, + ease: "power3.inOut", + }, + "-=0.5" + ); + }, headerRef); + + return () => ctx.revert(); + }, []); + + return ( +
+

{SECTION_CONFIG.subtitle}

+

{SECTION_CONFIG.title}

+
+
+ ); +}; + +export default React.memo(ExperienceHeader); diff --git a/src/components/ExperienceSection/config/animations.js b/src/components/ExperienceSection/config/animations.js new file mode 100644 index 0000000..cf4c608 --- /dev/null +++ b/src/components/ExperienceSection/config/animations.js @@ -0,0 +1,28 @@ +export const ANIMATION_CONFIG = { + card: { + initial: { + opacity: 0, + y: 50, + scale: 0.95, + }, + animate: { + opacity: 1, + y: 0, + scale: 1, + duration: 0.8, + ease: "power3.out" + }, + trigger: { + start: "top bottom-=100", + toggleActions: "play none none reverse" + } + }, + header: { + duration: 0.8, + ease: "power3.out", + trigger: { + start: "top center+=100", + toggleActions: "play none none reverse" + } + } +}; diff --git a/src/components/ExperienceSection/config/constants.js b/src/components/ExperienceSection/config/constants.js new file mode 100644 index 0000000..c1084ab --- /dev/null +++ b/src/components/ExperienceSection/config/constants.js @@ -0,0 +1,65 @@ +import { Monitor, Cpu, Box, BatteryCharging } from 'lucide-react'; + +export const SECTION_CONFIG = { + title: "How Our Services Will Help You to Grow Your Business", + subtitle: "Our Working Process", + metaDescription: "Explore our innovative services in AI, Quantum Computing, 3D Design, and EV Technology to accelerate your business growth.", + experiences: [ + { + id: "exp-0", + icon: Monitor, + title: "AI in Medical Industry", + description: "Using efficient AI infrastructure, our primary focus is to disrupt and revolutionize the healthcare business by innovatively redefining the quality of medical services.", + stats: "100% AI-Driven" + }, + { + id: "exp-1", + icon: Cpu, + title: "Quantum Computing Acceleration", + description: "With faster hardware's accelerating the efficiency of quantum computing setups, complex computing problems and demands can be handled in a limited timeframe.", + stats: "100x Faster" + }, + { + id: "exp-2", + icon: Box, + title: "3D Design Engineering", + description: "Modern design and engineering approaches for 3D project or product outcome is a reliable approach to achieving a more efficient, budget-friendly, and solution-providing design and infrastructure outcome.", + stats: "$200k Saved" + }, + { + id: "exp-3", + icon: BatteryCharging, + title: "EV PCB Board Designs", + description: "Use advanced technological infrastructure to curb emissions, driving your business and the consumers associated with it towards a safer and better future.", + stats: "Zero Emission" + } + ] +}; + +export const ANIMATION_CONFIG = { + card: { + initial: { + opacity: 0, + y: 50, + scale: 0.95, + }, + animate: { + opacity: 1, + y: 0, + scale: 1, + duration: 0.8, + ease: "power3.out" + }, + trigger: { + start: "top bottom-=100", + toggleActions: "play none none reverse" + } + }, + header: { + duration: 0.8, + ease: "power3.out", + trigger: { + start: "top center+=100" + } + } +}; diff --git a/src/components/ExperienceSection/config/schema.js b/src/components/ExperienceSection/config/schema.js new file mode 100644 index 0000000..69c6c74 --- /dev/null +++ b/src/components/ExperienceSection/config/schema.js @@ -0,0 +1,12 @@ +export const experienceSchema = { + "@context": "https://schema.org", + "@type": "Service", + "name": "Business Growth Services", + "provider": { + "@type": "Organization", + "name": "Your Company Name" + }, + "serviceType": ["AI Services", "Quantum Computing", "3D Design", "EV Technology"], + "description": "Comprehensive business growth services including AI in healthcare, quantum computing acceleration, 3D design engineering, and EV PCB board designs.", + "areaServed": "Worldwide" +}; diff --git a/src/components/ExperienceSection/hooks/useExperienceData.js b/src/components/ExperienceSection/hooks/useExperienceData.js new file mode 100644 index 0000000..68a67ae --- /dev/null +++ b/src/components/ExperienceSection/hooks/useExperienceData.js @@ -0,0 +1,26 @@ +import { useState, useEffect, useMemo } from 'react'; +import { SECTION_CONFIG } from '../config/constants'; +import { processExperienceData } from '../utils/experienceHelpers'; + +export const useExperienceData = () => { + const [experiences, setExperiences] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + + const memoizedProcessedData = useMemo(() => { + return processExperienceData(SECTION_CONFIG.experiences); + }, []); + + useEffect(() => { + try { + setExperiences(memoizedProcessedData); + setIsLoading(false); + } catch (err) { + console.error("Error processing experience data:", err); + setError(err); + setIsLoading(false); + } + }, [memoizedProcessedData]); + + return { experiences, isLoading, error }; +}; diff --git a/src/components/ExperienceSection/hooks/useScrollAnimation.js b/src/components/ExperienceSection/hooks/useScrollAnimation.js new file mode 100644 index 0000000..e699e8f --- /dev/null +++ b/src/components/ExperienceSection/hooks/useScrollAnimation.js @@ -0,0 +1,35 @@ +import { useEffect, useRef } from 'react'; +import gsap from 'gsap'; +import ScrollTrigger from 'gsap/ScrollTrigger'; + +gsap.registerPlugin(ScrollTrigger); + +export const useScrollAnimation = (options = {}) => { + const elementRef = useRef(null); + + useEffect(() => { + const element = elementRef.current; + const animation = gsap.fromTo( + element, + { opacity: 0, y: 50 }, + { + opacity: 1, + y: 0, + duration: 0.8, + scrollTrigger: { + trigger: element, + start: "top bottom-=100", + toggleActions: "play none none reverse", + ...options + } + } + ); + + return () => { + if (animation) animation.kill(); + ScrollTrigger.getAll().forEach(trigger => trigger.kill()); + }; + }, [options]); + + return elementRef; +}; diff --git a/src/components/ExperienceSection/styles/ExperienceCard.css b/src/components/ExperienceSection/styles/ExperienceCard.css new file mode 100644 index 0000000..b31ded4 --- /dev/null +++ b/src/components/ExperienceSection/styles/ExperienceCard.css @@ -0,0 +1,43 @@ +.experience-card { + @apply relative bg-white rounded-2xl p-6 lg:p-8 shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1; +} + +.card-pattern { + @apply absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-bl-full opacity-20 transition-all duration-300; +} + +.group:hover .card-pattern { + @apply bg-blue-100; +} + +.experience-card-content { + @apply relative; +} + +.card-icon-wrapper { + @apply p-3 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl shadow-lg; +} + +.card-title { + @apply text-xl lg:text-2xl font-bold text-gray-800 mb-2 line-clamp-2; +} + +.card-stats { + @apply inline-block px-3 py-1 bg-blue-50 text-blue-600 text-sm font-semibold rounded-full; +} + +.experience-description { + @apply text-gray-600 leading-relaxed mb-6 line-clamp-4 lg:line-clamp-none; +} + +.experience-button { + @apply inline-flex items-center text-blue-600 font-semibold cursor-pointer; +} + +.experience-button-icon { + @apply w-5 h-5 transition-transform duration-300; +} + +.group:hover .experience-button-icon { + @apply translate-x-1; +} diff --git a/src/components/ExperienceSection/styles/ExperienceHeader.css b/src/components/ExperienceSection/styles/ExperienceHeader.css new file mode 100644 index 0000000..9e1e305 --- /dev/null +++ b/src/components/ExperienceSection/styles/ExperienceHeader.css @@ -0,0 +1,15 @@ +.section-header { + @apply text-center mb-16 lg:mb-24; +} + +.header-subtitle { + @apply text-sm lg:text-base font-bold text-blue-600 tracking-wider uppercase mb-4; +} + +.header-title { + @apply text-3xl lg:text-5xl font-bold text-gray-900 mb-6 max-w-3xl mx-auto leading-tight; +} + +.header-line { + @apply w-24 h-1 bg-gradient-to-r from-blue-500 to-blue-600 mx-auto rounded-full; +} diff --git a/src/components/ExperienceSection/styles/ExperienceSection.css b/src/components/ExperienceSection/styles/ExperienceSection.css new file mode 100644 index 0000000..aba8a76 --- /dev/null +++ b/src/components/ExperienceSection/styles/ExperienceSection.css @@ -0,0 +1,44 @@ +.card-pattern { + @apply absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-bl-full opacity-20 transition-all duration-300 group-hover:bg-blue-100; +} + +.card-icon-wrapper { + @apply p-3 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl shadow-lg; +} + +.card-title { + @apply text-xl lg:text-2xl font-bold text-gray-800 mb-2 line-clamp-2; +} + +.card-stats { + @apply inline-block px-3 py-1 bg-blue-50 text-blue-600 text-sm font-semibold rounded-full; +} + +.section-header { + @apply text-center mb-16 lg:mb-24; +} + +.header-subtitle { + @apply text-sm lg:text-base font-bold text-blue-600 tracking-wider uppercase mb-4; +} + +.header-title { + @apply text-3xl lg:text-5xl font-bold text-gray-900 mb-6 max-w-3xl mx-auto leading-tight; +} + +.header-line { + @apply w-24 h-1 bg-gradient-to-r from-blue-500 to-blue-600 mx-auto rounded-full; +} + +.experience-section { + /* Additional styles if needed */ +} + +.experience-grid { + /* Additional styles if needed */ +} + +.header-placeholder, +.card-placeholder { + border-radius: 0.5rem; +} diff --git a/src/components/ExperienceSection/utils/experienceHelpers.js b/src/components/ExperienceSection/utils/experienceHelpers.js new file mode 100644 index 0000000..80c9964 --- /dev/null +++ b/src/components/ExperienceSection/utils/experienceHelpers.js @@ -0,0 +1,25 @@ +export const processExperienceData = (experiences) => { + return experiences.map((experience, index) => ({ + ...experience, + id: `exp-${index}`, + animationDelay: index * 0.2, + className: `experience-card-${index}` + })); +}; + +export const debounce = (func, wait) => { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +}; + +export const validateExperienceData = (experience) => { + const requiredFields = ['title', 'description', 'icon']; + return requiredFields.every(field => !!experience[field]); +}; diff --git a/src/components/Header/Navbar.jsx b/src/components/Header/Navbar.jsx new file mode 100644 index 0000000..e0d2ca3 --- /dev/null +++ b/src/components/Header/Navbar.jsx @@ -0,0 +1,197 @@ +import React, { useState, useEffect, useRef, lazy, Suspense, useCallback, memo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FiSearch, FiChevronDown, FiMenu, FiX } from 'react-icons/fi'; +import { Link } from 'react-router-dom'; +import ErrorBoundary from '../common/ErrorBoundary'; +import OptimizedImage from '../common/OptimizedImage'; +import { menuItems, languages, mobileMenuVariants } from './constants/navigationData'; +import { headerSchema } from './schema/headerSchema'; +import styles from './styles/Header.module.css'; +import Logo from '@/assets/Logo/Tech4biz-logo.webp'; + +const SearchOverlay = lazy(() => import('./components/SearchOverlay')); +const DesktopNav = lazy(() => import('./components/DesktopNav')); +const MobileNav = lazy(() => import('./components/MobileNav')); +const LanguageSelector = lazy(() => import('./components/LanguageSelector')); + +const Navbar = () => { + // State management with hooks + const [state, setState] = useState({ + isProductsOpen: false, + isLanguageOpen: false, + isMobileLanguageOpen: false, + isMobileMenuOpen: false, + isSearchOpen: false, + selectedLanguage: 'English', + isSticky: false + }); + + const desktopLanguageRef = useRef(null); + const mobileLanguageRef = useRef(null); + + // Event handlers with useCallback + const handleClickOutside = useCallback((event) => { + if (desktopLanguageRef.current && !desktopLanguageRef.current.contains(event.target)) { + setState(prev => ({ ...prev, isLanguageOpen: false })); + } + if (mobileLanguageRef.current && !mobileLanguageRef.current.contains(event.target)) { + setState(prev => ({ ...prev, isMobileLanguageOpen: false })); + } + }, []); + + const handleScroll = useCallback(() => { + setState(prev => ({ ...prev, isSticky: window.scrollY > 0 })); + }, []); + + // Effect for event listeners + useEffect(() => { + document.addEventListener('mousedown', handleClickOutside); + window.addEventListener('scroll', handleScroll); + + // Inject schema + const script = document.createElement('script'); + script.type = 'application/ld+json'; + script.text = JSON.stringify(headerSchema); + document.head.appendChild(script); + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + window.removeEventListener('scroll', handleScroll); + document.head.removeChild(script); + }; + }, [handleClickOutside, handleScroll]); + + return ( + + Loading...
}> + setState(prev => ({ ...prev, isSearchOpen: false }))} /> + + + + + ); +}; + +export default memo(Navbar); \ No newline at end of file diff --git a/src/components/Header/components/DesktopNav.jsx b/src/components/Header/components/DesktopNav.jsx new file mode 100644 index 0000000..c22fb83 --- /dev/null +++ b/src/components/Header/components/DesktopNav.jsx @@ -0,0 +1,73 @@ +import React, { memo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FiChevronDown } from 'react-icons/fi'; +import { Link } from 'react-router-dom'; +import { menuItems } from '../constants/navigationData'; +import ProductShowcase from './ProductShowcase'; + +const DesktopNav = memo(({ isProductsOpen, setIsProductsOpen }) => { + const handleMouseEnter = () => { + setIsProductsOpen(true); + }; + + const handleMouseLeave = () => { + setIsProductsOpen(false); + }; + + const getItemPath = (item) => { + switch (item) { + case 'HOME': + return '/'; + case 'SERVICES': + return '/services'; + case 'ABOUT': + return '/about'; + case 'CONTACT': + return '/contact'; + default: + return '#'; + } + }; + + return ( +
+ {menuItems.map((item) => ( +
+ {item === 'PRODUCTS' ? ( +
+ + + {isProductsOpen && } + +
+ ) : ( + + {item} + + )} +
+ ))} +
+ ); +}); + +DesktopNav.displayName = 'DesktopNav'; + +export default DesktopNav; \ No newline at end of file diff --git a/src/components/Header/components/LanguageSelector.jsx b/src/components/Header/components/LanguageSelector.jsx new file mode 100644 index 0000000..d5e48a8 --- /dev/null +++ b/src/components/Header/components/LanguageSelector.jsx @@ -0,0 +1,66 @@ +import React, { memo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FiChevronDown } from 'react-icons/fi'; +import { languages } from '../constants/navigationData'; +import styles from '../styles/Header.module.css'; + +const LanguageSelector = memo(({ + isDesktop = true, + isOpen, + selectedLanguage, + languageRef, + setState +}) => { + const containerClasses = isDesktop + ? "hidden md:block relative" + : "relative"; + + return ( +
+ + + + {isOpen && ( + + {languages.map((language) => ( + + ))} + + )} + +
+ ); +}); + +LanguageSelector.displayName = 'LanguageSelector'; + +export default LanguageSelector; \ No newline at end of file diff --git a/src/components/Header/components/MobileNav.jsx b/src/components/Header/components/MobileNav.jsx new file mode 100644 index 0000000..f4a2d4a --- /dev/null +++ b/src/components/Header/components/MobileNav.jsx @@ -0,0 +1,44 @@ +import React, { memo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FiChevronDown, FiX } from 'react-icons/fi'; +import { menuItems, mobileMenuVariants } from '../constants/navigationData'; +import styles from '../styles/Header.module.css'; + +const MobileNav = memo(({ isMobileMenuOpen, setState }) => { + return ( + + {isMobileMenuOpen && ( + + + + )} + + ); +}); + +MobileNav.displayName = 'MobileNav'; + +export default MobileNav; \ No newline at end of file diff --git a/src/components/Header/components/ProductShowcase.jsx b/src/components/Header/components/ProductShowcase.jsx new file mode 100644 index 0000000..74b8998 --- /dev/null +++ b/src/components/Header/components/ProductShowcase.jsx @@ -0,0 +1,155 @@ +import React from 'react'; +import { motion } from 'framer-motion'; + +// Import images +import lmsImage from '@/assets/Header/Product-Card/learning-management-system.webp'; +import codenukImage from '@/assets/Header/Product-Card/codenuk-coding-solution-platform.webp'; +import cloudtopiaaImage from '@/assets/Header/Product-Card/cloudtopiaa-enterprise-solutions.webp'; +import cloudDriveImage from '@/assets/Header/Product-Card/cloud-drive-storage-platform.webp'; + +const containerVariants = { + initial: { + opacity: 0, + height: 0, + transformOrigin: "top" + }, + animate: { + opacity: 1, + height: "auto", + transition: { + height: { + duration: 0.3, + ease: "easeOut" + }, + opacity: { + duration: 0.2, + ease: "easeOut" + } + } + }, + exit: { + opacity: 0, + height: 0, + transition: { + height: { + duration: 0.3, + ease: "easeIn" + }, + opacity: { + duration: 0.2, + ease: "easeIn" + } + } + } +}; + +const ProductShowcase = () => { + const products = [ + { + id: 1, + name: 'CloudDriv', + image: cloudDriveImage, + description: 'Secure cloud storage for seamless sharing and collaboration.' + }, + { + id: 2, + name: 'Codenuk', + image: codenukImage, + description: 'Breakthrough coding challenges instantly with Codenuk.' + }, + { + id: 3, + name: 'LMS', + image: lmsImage, + description: 'Streamline education delivery with our comprehensive Learning Management System.' + }, + { + id: 4, + name: 'Cloudtopiaa', + image: cloudtopiaaImage, + description: 'Secure, scalable cloud solutions that power your business growth.' + } + ]; + + const productList = [ + "Product name one", + "Product name two", + "Product name three", + "Product name four", + "Product name five", + "Product name six", + "Product name seven", + "Product name eight" + ]; + + return ( + +
+
+
+ {products.map((product) => ( + +
+ {product.name} +
+

+ {product.name} +

+

+ {product.description} +

+
+ ))} +
+ +
+

All Products

+
+ {productList.map((product, index) => ( + +

+ {product} +

+ {index === 0 && ( + <> +

+ Breakthrough coding challenges instantly with Codenuk. Secure cloud storage for seamless sharing and collaboration. +

+ + + )} +
+ ))} +
+
+
+
+
+ ); +}; + +export default ProductShowcase; diff --git a/src/components/Header/components/SearchOverlay.jsx b/src/components/Header/components/SearchOverlay.jsx new file mode 100644 index 0000000..4df4470 --- /dev/null +++ b/src/components/Header/components/SearchOverlay.jsx @@ -0,0 +1,67 @@ +import React, { useCallback, memo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FiSearch, FiX } from 'react-icons/fi'; +import { debounce } from 'lodash'; + +const SearchOverlay = memo(({ isOpen, onClose }) => { + const handleSearch = useCallback( + debounce((searchTerm) => { + // Implement search logic here + console.log('Searching for:', searchTerm); + }, 300), + [] + ); + + return ( + + {isOpen && ( + <> + + + +
+
+
+
+
+ + )} +
+ ); +}); + +SearchOverlay.displayName = 'SearchOverlay'; + +export default SearchOverlay; \ No newline at end of file diff --git a/src/components/Header/constants/navigationData.js b/src/components/Header/constants/navigationData.js new file mode 100644 index 0000000..3173c41 --- /dev/null +++ b/src/components/Header/constants/navigationData.js @@ -0,0 +1,13 @@ +export const menuItems = [ + 'HOME', + 'PRODUCTS', + 'SERVICES', + 'ABOUT', + 'CONTACT' +]; +export const languages = ['English', 'Spanish', 'French']; + +export const mobileMenuVariants = { + closed: { opacity: 0, x: "100%" }, + open: { opacity: 1, x: 0 } +}; \ No newline at end of file diff --git a/src/components/Header/schema/headerSchema.js b/src/components/Header/schema/headerSchema.js new file mode 100644 index 0000000..73c3841 --- /dev/null +++ b/src/components/Header/schema/headerSchema.js @@ -0,0 +1,17 @@ +export const headerSchema = { + "@context": "https://schema.org", + "@type": "Organization", + "name": "Tech4biz", + "url": "https://tech4biz.com", + "logo": { + "@type": "ImageObject", + "url": "https://tech4biz.com/logo.webp", + "width": "180", + "height": "36" + }, + "sameAs": [ + "https://facebook.com/tech4biz", + "https://twitter.com/tech4biz", + "https://linkedin.com/company/tech4biz" + ] + }; \ No newline at end of file diff --git a/src/components/Header/styles/Header.module.css b/src/components/Header/styles/Header.module.css new file mode 100644 index 0000000..2c03b98 --- /dev/null +++ b/src/components/Header/styles/Header.module.css @@ -0,0 +1,23 @@ +.navContainer { + @apply fixed top-0 left-0 right-0 w-full bg-white transition-all duration-300 z-40; + } + + .stickyNav { + @apply shadow-md; + } + + .navLink { + @apply text-gray-600 hover:text-[#1E0E62] transition-colors font-poppins font-bold text-[14px]; + } + + .activeNavLink { + @apply text-[#1E0E62]; + } + + .languageButton { + @apply flex items-center justify-between text-gray-600 hover:text-[#1E0E62] transition-colors border rounded-md px-3 py-1; + } + + .searchButton { + @apply text-gray-600 hover:text-[#1E0E62] transition-colors; + } \ No newline at end of file diff --git a/src/components/Hero/ErrorBoundary.jsx b/src/components/Hero/ErrorBoundary.jsx new file mode 100644 index 0000000..01907d4 --- /dev/null +++ b/src/components/Hero/ErrorBoundary.jsx @@ -0,0 +1,38 @@ +import React from 'react'; + +class HeroErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + console.error('Hero component error:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+
+

Something went wrong

+ +
+
+ ); + } + + return this.props.children; + } +} + +export default HeroErrorBoundary; \ No newline at end of file diff --git a/src/components/Hero/Hero.jsx b/src/components/Hero/Hero.jsx new file mode 100644 index 0000000..c28f80a --- /dev/null +++ b/src/components/Hero/Hero.jsx @@ -0,0 +1,123 @@ +import React, { lazy, Suspense } from 'react'; +import { motion } from 'framer-motion'; +import { Helmet } from 'react-helmet-async'; +import { debounce } from 'lodash'; +import styles from './styles/styles.module.css'; +import { ANIMATION_VARIANTS } from './constants/index'; +import HeroErrorBoundary from './ErrorBoundary'; +import AsyncComponent from '../utils/AsyncComponent'; + +const VideoPreview = lazy(() => import('./components/VideoPreview')); +const LogoCarousel = lazy(() => import('./components/LogoCarousel')); + +const Hero = () => { + const handleButtonClick = debounce((action) => { + console.log(`Button clicked: ${action}`); + }, 300); + + return ( + +
+ + Tech4biz - The Reliable And Affordable IT Support Company + + + + + + + The Leading IT Solutions Company for Businesses + + + + Tech4Biz provides reliable IT solutions, from cloud services and data management to network security and support. Our expertise helps businesses thrive, ensuring security, efficiency, and growth. + + + + handleButtonClick('mission')} + aria-label="Learn about our mission" + > + + Our Mission → + + + + handleButtonClick('contact')} + aria-label="Contact us" + > + + Choose Us → + + + + + + + } + /> + + + } + /> + +
+
+ ); +} + +export default Hero; \ No newline at end of file diff --git a/src/components/Hero/components/LogoCarousel.jsx b/src/components/Hero/components/LogoCarousel.jsx new file mode 100644 index 0000000..08c6ff1 --- /dev/null +++ b/src/components/Hero/components/LogoCarousel.jsx @@ -0,0 +1,55 @@ +import React, { memo } from 'react'; +import { motion } from 'framer-motion'; +import { TRUSTED_BRANDS } from '../constants'; +import styles from '../styles/styles.module.css'; + +const LogoCarousel = memo(() => { + const duplicatedBrands = [...TRUSTED_BRANDS, ...TRUSTED_BRANDS]; + + const carouselVariants = { + animate: { + x: [0, -50 * TRUSTED_BRANDS.length], + transition: { + x: { + repeat: Infinity, + repeatType: "loop", + duration: 20, + ease: "linear", + }, + }, + }, + }; + + return ( +
+

+ TRUSTED BY INDUSTRY LEADERS +

+
+ + {duplicatedBrands.map((brand, index) => ( + + {`${brand.name} + + ))} + +
+
+ ); +}); + +LogoCarousel.displayName = 'LogoCarousel'; +export default LogoCarousel; \ No newline at end of file diff --git a/src/components/Hero/components/VideoPreview.jsx b/src/components/Hero/components/VideoPreview.jsx new file mode 100644 index 0000000..ba85218 --- /dev/null +++ b/src/components/Hero/components/VideoPreview.jsx @@ -0,0 +1,260 @@ +import React, { memo, useState, useRef, useEffect, useCallback, useMemo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { HERO_CONTENT } from '../constants/index'; +import styles from '../styles/styles.module.css'; +import { debounce } from 'lodash'; + +const VideoPreview = memo(() => { + const [isPlaying, setIsPlaying] = useState(false); + const [currentIndex, setCurrentIndex] = useState(0); + const [isVideoLoaded, setIsVideoLoaded] = useState(false); + const videoRef = useRef(null); + const observerRef = useRef(null); + const intervalRef = useRef(null); + + // Memoize current slide data + const currentSlide = useMemo(() => + HERO_CONTENT.slides[currentIndex], + [currentIndex] + ); + + // Intersection Observer setup + useEffect(() => { + const options = { + root: null, + rootMargin: '50px', + threshold: 0.1 + }; + + observerRef.current = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (!entry.isIntersecting && isPlaying) { + handlePlayPause(); + } + }); + }, options); + + if (videoRef.current) { + observerRef.current.observe(videoRef.current); + } + + return () => { + if (observerRef.current) { + observerRef.current.disconnect(); + } + }; + }, [isPlaying]); + + const handlePlayPause = () => { + if (videoRef.current) { + if (isPlaying) { + videoRef.current.pause(); + setIsPlaying(false); + } else { + videoRef.current.play() + .then(() => { + setIsPlaying(true); + }) + .catch((error) => { + console.error("Video playback failed:", error); + setIsPlaying(false); + }); + } + } + }; + + // Video cleanup on unmount + useEffect(() => { + return () => { + if (videoRef.current) { + videoRef.current.pause(); + } + }; + }, []); + + // Handle slide interval + useEffect(() => { + if (!isPlaying) { + intervalRef.current = setInterval(() => { + setCurrentIndex((prev) => (prev + 1) % HERO_CONTENT.slides.length); + }, 5000); + } else { + clearInterval(intervalRef.current); + } + + return () => clearInterval(intervalRef.current); + }, [isPlaying]); + + // Update slide variants for smoother transitions + const slideVariants = useMemo(() => ({ + heading: { + enter: { + x: -100, + opacity: 0 + }, + center: { + x: 0, + opacity: 1 + }, + exit: { + x: 100, + opacity: 0 + } + }, + subheading: { + enter: { + x: 100, + opacity: 0 + }, + center: { + x: 0, + opacity: 1 + }, + exit: { + x: -100, + opacity: 0 + } + } + }), []); + + // Add background transition variants + const backgroundVariants = useMemo(() => ({ + initial: { + scale: 1.05, + opacity: 0 + }, + animate: { + scale: 1, + opacity: 1 + }, + exit: { + scale: 1.05, + opacity: 0 + } + }), []); + + // Optimized slide transition with debounce + const debouncedSlideChange = useCallback( + debounce((newIndex) => { + setCurrentIndex(newIndex); + }, 200), + [] + ); + + return ( + + + + + {!isPlaying && ( + + + + +
+ + + {currentSlide.heading} + + + + + + {currentSlide.subheading} + + +
+
+
+ )} +
+ + + + {isPlaying ? ( + + ) : ( + + )} + + {isPlaying ? 'Pause' : 'Play'} + +
+ ); +}); + +VideoPreview.displayName = 'VideoPreview'; +export default VideoPreview; \ No newline at end of file diff --git a/src/components/Hero/constants/index.js b/src/components/Hero/constants/index.js new file mode 100644 index 0000000..b82d6e9 --- /dev/null +++ b/src/components/Hero/constants/index.js @@ -0,0 +1,55 @@ +import { imagePaths } from '@/constants/images'; + +export const TRUSTED_BRANDS = [ + { id: 1, name: 'AWS', logo: '/src/assets/Logo/AWS-Partner-Netwrok-tech4biz.webp' }, + { id: 2, name: 'Tech4biz', logo: '/src/assets/Logo/Tech4biz-logo.webp' }, + { id: 3, name: 'OpenAI', logo: '/src/assets/Logo/OPENAI-Partner-Tech4biz.webp' }, + { id: 4, name: 'ISO', logo: '/src/assets/Logo/ISO-Partner-Tech4biz.webp' }, + { id: 5, name: 'IBM', logo: '/src/assets/Logo/IBM-Tech4biz-partner.webp' }, + { id: 6, name: 'Cloudtopia', logo: '/src/assets/Logo/Cloudtopiaa-Tech4biz.webp' }, + { id: 7, name: 'Azure', logo: '/src/assets/Logo/AZURE-Partner-Tech4biz.webp' } +]; + +export const ANIMATION_VARIANTS = { + container: { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { delayChildren: 0.4, staggerChildren: 0.3 } + } + }, + item: { + hidden: { y: 30, opacity: 0 }, + visible: { + y: 0, + opacity: 1, + transition: { duration: 0.6, ease: "easeOut" } + } + } +}; + +export const HERO_CONTENT = { + video: imagePaths.video.hero, + slides: [ + { + heading: "Business Technology Solutions", + subheading: "Technology Solutions for Business Efficiency", + background: imagePaths.heroSlides[0] + }, + { + heading: "Cloud-First Business Strategy", + subheading: "Smart Technology for Better Business", + background: imagePaths.heroSlides[1] + }, + { + heading: "AI-Driven Business Growth", + subheading: "Optimizing Growth with Data Strategy", + background: imagePaths.heroSlides[2] + }, + { + heading: "Cybersecurity Excellence", + subheading: "Protecting Your Digital Assets 24/7", + background: imagePaths.heroSlides[3] + } + ] +}; \ No newline at end of file diff --git a/src/components/Hero/index.jsx b/src/components/Hero/index.jsx new file mode 100644 index 0000000..49b3dba --- /dev/null +++ b/src/components/Hero/index.jsx @@ -0,0 +1 @@ +export { default } from './Hero'; \ No newline at end of file diff --git a/src/components/Hero/styles/styles.module.css b/src/components/Hero/styles/styles.module.css new file mode 100644 index 0000000..494e611 --- /dev/null +++ b/src/components/Hero/styles/styles.module.css @@ -0,0 +1,177 @@ +.heroSection { + @apply min-h-screen bg-[#001324] text-white overflow-hidden relative; + } + + .wrapper { + @apply mx-auto px-4 py-8 pt-16 md:py-16 md:pt-24 max-w-7xl; + } + + .heroContent { + @apply max-w-6xl mx-auto text-center space-y-6; + } + + .heading { + @apply text-4xl md:text-6xl lg:text-7xl font-serif leading-tight; + } + + .subheading { + @apply text-lg md:text-xl text-gray-300 max-w-3xl mx-auto; + } + + .ctaContainer { + @apply flex flex-col sm:flex-row gap-4 justify-center pt-6; + } + + .primaryButton { + @apply px-8 py-3 bg-blue-600 rounded-full text-white font-medium + hover:bg-blue-700 transition-colors; + } + + .secondaryButton { + @apply px-8 py-3 border border-white/20 rounded-full text-white font-medium + hover:bg-white/10 transition-colors; + } + + .videoSection { + @apply relative w-full h-[600px] mt-12 rounded-2xl overflow-hidden; + transform: translateZ(0); + will-change: transform; + backface-visibility: hidden; + } + + .backgroundVideo { + @apply absolute inset-0 w-full h-full object-cover; + transition: opacity 0.6s ease-in-out; + transform: translateZ(0); + will-change: opacity; + } + + .backgroundVideo[data-playing="true"] { + opacity: 1; + z-index: 10; + } + + .playButton { + @apply absolute top-4 right-4 z-50 flex items-center gap-2 px-4 py-2 + bg-black/40 rounded-full text-white hover:bg-black/60 + transition-all duration-300; + } + + .backgroundImage { + @apply absolute inset-0 w-full h-full bg-cover bg-center bg-no-repeat; + transition: opacity 0.8s ease-in-out, transform 0.8s ease-in-out; + transform: translateZ(0); + will-change: opacity, transform; + } + + .backgroundImage::after { + @apply content-[''] absolute inset-0 bg-gradient-to-br from-blue-900/60 to-black/60; + } + + .videoContent { + @apply absolute inset-0 flex items-center justify-center z-20 px-4; + pointer-events: none; + } + + .videoHeading { + @apply text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-serif leading-tight + max-w-4xl mx-auto text-center relative z-20 text-white; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } + + .videoSubheading { + @apply block text-base sm:text-lg md:text-xl lg:text-2xl mt-2 md:mt-4 + font-light opacity-90 relative text-white max-w-3xl mx-auto text-center; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } + + @media (prefers-reduced-motion: reduce) { + .videoSubheading { + transition: none; + } + } + + .trustedSection { + @apply mt-20 text-center; + } + + .trustedHeading { + @apply text-sm font-medium tracking-wider text-gray-400 mb-8; + } + + .logoGrid { + @apply flex flex-wrap justify-center items-center gap-8 md:gap-12 opacity-70; + } + + .carouselContainer { + @apply relative overflow-hidden w-full; + } + + .carouselTrack { + @apply flex items-center gap-8 md:gap-12; + } + + .logoItem { + @apply flex-shrink-0 opacity-70 hover:opacity-100 transition-opacity; + } + + .logoImage { + @apply h-6 md:h-8 w-auto object-contain filter brightness-0 invert opacity-50 hover:opacity-100 transition-all duration-300; + } + + .headingWrapper { + @apply relative z-20 flex flex-col items-center justify-center text-center; + perspective: 1000px; + transform-style: preserve-3d; + } + + .videoHeading { + @apply text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-serif leading-tight + max-w-4xl mx-auto text-center relative z-20 text-white; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } + + .videoSubheading { + @apply block text-base sm:text-lg md:text-xl lg:text-2xl mt-2 md:mt-4 + font-light opacity-90 relative text-white max-w-3xl mx-auto text-center; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } + + @media (prefers-reduced-motion: reduce) { + .videoHeading, + .videoSubheading { + @apply transition-none transform-none; + } + } + + .backgroundImage { + @apply absolute inset-0 w-full h-full bg-cover bg-center bg-no-repeat; + } + + .backgroundImage::after { + @apply content-[''] absolute inset-0 bg-gradient-to-br from-blue-900/80 to-black/80; + } + + .videoContent { + @apply absolute inset-0 flex items-center justify-center z-10 px-4; + transform: translateZ(0); + will-change: opacity, transform; + background: transparent; + } + + .headingWrapper { + @apply relative z-20 flex flex-col items-center justify-center; + perspective: 1000px; + } + + .videoHeading { + @apply text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-serif leading-tight + max-w-4xl mx-auto text-center relative z-20 text-white; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } + + .videoSubheading { + @apply block text-base sm:text-lg md:text-xl lg:text-2xl mt-2 md:mt-4 + font-light opacity-90 relative text-white; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); + } \ No newline at end of file diff --git a/src/components/Hero/utils/schema.js b/src/components/Hero/utils/schema.js new file mode 100644 index 0000000..54eff6a --- /dev/null +++ b/src/components/Hero/utils/schema.js @@ -0,0 +1,11 @@ +export const heroSchema = { + "@context": "https://schema.org", + "@type": "WebSite", + "name": "AI Customer Service Solution", + "description": "The only solution that combines an AI chatbot, help desk, and proactive support", + "url": "https://example.com", + "potentialAction": { + "@type": "ViewAction", + "target": "https://example.com/trial" + } +}; \ No newline at end of file diff --git a/src/components/ProductCards/ErrorBoundary.jsx b/src/components/ProductCards/ErrorBoundary.jsx new file mode 100644 index 0000000..22dac03 --- /dev/null +++ b/src/components/ProductCards/ErrorBoundary.jsx @@ -0,0 +1,36 @@ +import React from 'react'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + console.error('ProductCards Error:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+

Something went wrong

+ +
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary; \ No newline at end of file diff --git a/src/components/ProductCards/ProductGrid.jsx b/src/components/ProductCards/ProductGrid.jsx new file mode 100644 index 0000000..b690a8a --- /dev/null +++ b/src/components/ProductCards/ProductGrid.jsx @@ -0,0 +1,143 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { motion } from 'framer-motion'; +import ProductCard from './components/ProductCard'; +import { productImages } from './config/productCard.config'; +import styles from './styles/ProductGrid.module.css'; +import { useScrollPosition } from '../../hooks/useScrollPosition'; +import ProductDots from './components/ProductDots'; +import ProductNavigation from './components/ProductNavigation'; +import { getProductSchema } from './config/productCard.schema'; +import { Helmet } from 'react-helmet-async'; + +const ProductGrid = () => { + const [currentIndex, setCurrentIndex] = useState(0); + const [isMobile, setIsMobile] = useState(false); + const productGridRef = useRef(null); + const isScrolled = useScrollPosition(); + const [touchStart, setTouchStart] = useState(0); + const [touchEnd, setTouchEnd] = useState(0); + + const totalProducts = productImages.length; + + // Check if screen is mobile + useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth <= 639); + }; + + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); + + const handlePrev = () => { + setCurrentIndex((prev) => { + const newIndex = prev === 0 ? totalProducts - 1 : prev - 1; + updateSlidePosition(newIndex); + return newIndex; + }); + }; + + const handleNext = () => { + setCurrentIndex((prev) => { + const newIndex = prev === totalProducts - 1 ? 0 : prev + 1; + updateSlidePosition(newIndex); + return newIndex; + }); + }; + + const handleDotClick = (index) => { + setCurrentIndex(index); + updateSlidePosition(index); + }; + + const updateSlidePosition = (index) => { + if (productGridRef.current && isMobile) { + const containerWidth = productGridRef.current.parentElement.offsetWidth; + const cardWidth = containerWidth - 40; + const gap = 20; + const offset = index * (cardWidth + gap); + const centeringOffset = (containerWidth - cardWidth) / 2; + productGridRef.current.style.transform = `translateX(calc(-${offset}px + ${centeringOffset}px))`; + } + }; + + // Add this useEffect to reset transform on screen resize + useEffect(() => { + if (!isMobile && productGridRef.current) { + productGridRef.current.style.transform = 'translateX(0)'; + } + }, [isMobile]); + + const handleTouchStart = (e) => { + setTouchStart(e.touches[0].clientX); + }; + + const handleTouchMove = (e) => { + setTouchEnd(e.touches[0].clientX); + }; + + const handleTouchEnd = () => { + if (!isMobile) return; + + const touchDiff = touchStart - touchEnd; + const minSwipeDistance = 50; + + if (Math.abs(touchDiff) > minSwipeDistance) { + if (touchDiff > 0) { + handleNext(); + } else { + handlePrev(); + } + } + }; + + return ( + <> + + Our Products - Tech4biz + + + + +
+
+ + ); +}; + +export default ProductGrid; \ No newline at end of file diff --git a/src/components/ProductCards/components/ProductCard.jsx b/src/components/ProductCards/components/ProductCard.jsx new file mode 100644 index 0000000..8ba3bd4 --- /dev/null +++ b/src/components/ProductCards/components/ProductCard.jsx @@ -0,0 +1,106 @@ +import React, { memo, useState, useRef } from 'react'; +import { motion } from 'framer-motion'; +import styles from '../styles/ProductCard.module.css'; +import { useImageLoader } from '../hooks/useImageLoader'; + +const ProductCard = memo(({ product }) => { + const { imageLoaded, handleImageLoad } = useImageLoader(); + const [isPressed, setIsPressed] = useState(false); + const touchTimer = useRef(null); + const touchStartPos = useRef({ x: 0, y: 0 }); + const isTouchActive = useRef(false); + + const handleTouchStart = (e) => { + if (isTouchActive.current) return; + + touchStartPos.current = { + x: e.touches[0].clientX, + y: e.touches[0].clientY + }; + + // Set pressed state immediately for visual feedback + setIsPressed(true); + isTouchActive.current = true; + }; + + const handleTouchMove = (e) => { + if (!touchStartPos.current) return; + + const deltaX = Math.abs(e.touches[0].clientX - touchStartPos.current.x); + const deltaY = Math.abs(e.touches[0].clientY - touchStartPos.current.y); + + // If there's significant horizontal movement, allow sliding + if (deltaX > 50 && deltaX > deltaY * 1.5) { + setIsPressed(false); + isTouchActive.current = false; + } + }; + + const handleTouchEnd = (e) => { + const deltaX = Math.abs(e.changedTouches[0].clientX - touchStartPos.current.x); + const deltaY = Math.abs(e.changedTouches[0].clientY - touchStartPos.current.y); + + // If minimal movement, keep the pressed state for the animation + if (deltaX < 10 && deltaY < 10) { + e.stopPropagation(); + setTimeout(() => { + setIsPressed(false); + isTouchActive.current = false; + }, 1000); // Match this with your CSS transition duration + } else { + setIsPressed(false); + isTouchActive.current = false; + } + }; + + return ( + { + setIsPressed(false); + isTouchActive.current = false; + }} + > + + +
+

{product.title}

+

{product.subtitle}

+

{product.description}

+ + Expand + + + + +
+
+ ); +}); + +ProductCard.displayName = 'ProductCard'; + +export default ProductCard; \ No newline at end of file diff --git a/src/components/ProductCards/components/ProductDots.jsx b/src/components/ProductCards/components/ProductDots.jsx new file mode 100644 index 0000000..d32386b --- /dev/null +++ b/src/components/ProductCards/components/ProductDots.jsx @@ -0,0 +1,23 @@ +import React, { memo } from 'react'; +import styles from '../styles/ProductGrid.module.css'; + +const ProductDots = memo(({ total, current, onClick }) => { + return ( +
+ {Array.from({ length: total }, (_, index) => ( +
+ ); +}); + +ProductDots.displayName = 'ProductDots'; + +export default ProductDots; \ No newline at end of file diff --git a/src/components/ProductCards/components/ProductNavigation.jsx b/src/components/ProductCards/components/ProductNavigation.jsx new file mode 100644 index 0000000..8d76f3f --- /dev/null +++ b/src/components/ProductCards/components/ProductNavigation.jsx @@ -0,0 +1,33 @@ +import React, { memo } from 'react'; +import styles from '../styles/ProductGrid.module.css'; + +const ProductNavigation = memo(({ onPrev, onNext, isMobile }) => { + if (!isMobile) return null; + + return ( +
+ + +
+ ); +}); + +ProductNavigation.displayName = 'ProductNavigation'; + +export default ProductNavigation; \ No newline at end of file diff --git a/src/components/ProductCards/config/productCard.config.js b/src/components/ProductCards/config/productCard.config.js new file mode 100644 index 0000000..0450f33 --- /dev/null +++ b/src/components/ProductCards/config/productCard.config.js @@ -0,0 +1,100 @@ +import { imagePaths } from '@/constants/images'; +import placeholderImage from '@/assets/placeholder.jpg'; + +export const BREAKPOINTS = { + MOBILE: 639, + TABLET: 1023, + DESKTOP: 1279 +}; + +export const CARD_CONFIG = { + width: 280, + height: 450, + gap: 2, + cardsPerView: { + mobile: 1, + tablet: 2, + desktop: 4 + } +}; + +export const productImages = [ + { + id: 1, + title: 'Defending against cyber threats', + subtitle: 'Advanced Security for Financial Systems', + description: 'Award-winning enterprise security platform delivering AI-powered threat detection, 24/7 network monitoring, and automated incident response for maximum business protection.', + path: imagePaths.productCards.securityPlatform, + alt: 'Enterprise Security Platform Dashboard' + }, + { + id: 2, + title: 'Revolutionizing Financial Security', + subtitle: 'AI-Powered Banking Analytics Solutions', + description: 'Enterprise-grade financial analytics platform leveraging artificial intelligence to analyze market patterns, assess portfolio risks, and optimize investment performance.', + path: imagePaths.productCards.riskAnalytics, + alt: 'Financial Analytics Dashboard' + }, + { + id: 3, + title: 'Dynamic Pricing Analytics', + subtitle: 'Smart Pricing for E-commerce Excellence', + description: 'Cloud-based e-commerce analytics suite utilizing machine learning algorithms to optimize pricing strategies, boost conversions, and drive sustainable revenue growth.', + path: imagePaths.productCards.commerceIntelligence, + alt: 'E-Commerce Analytics Dashboard' + }, + { + id: 4, + title: 'Smart Mall Revolution', + subtitle: 'Next-Gen Retail Management Solutions', + description: 'Comprehensive retail operations platform integrating IoT technology, real-time analytics, and smart inventory systems for enhanced customer shopping experiences.', + path: imagePaths.productCards.retailManagement, + alt: 'Retail Management Dashboard' + }, + { + id: 5, + title: 'Smart Voice Tech for IoT', + subtitle: 'Intelligent Voice Processing Systems', + description: 'Premium voice recognition technology featuring advanced natural language processing, multi-dialect support, and intelligent conversation analysis capabilities.', + path: imagePaths.productCards.speechRecognition, + alt: 'Voice Recognition Dashboard' + }, + { + id: 6, + title: 'Meta verse AR', + subtitle: 'Immersive Learning Technologies', + description: 'Next-generation learning management system combining augmented reality technology, adaptive algorithms, and interactive content for personalized education.', + path: imagePaths.productCards.learningPlatform, + alt: 'Education Platform Dashboard' + }, + { + id: 7, + title: 'Smart Retail Automation', + subtitle: 'AI-Driven Retail Transformation', + description: 'Enterprise retail automation solution delivering predictive analytics, automated inventory optimization, and data-driven customer experience personalization.', + path: imagePaths.productCards.retailAutomation, + alt: 'Retail Automation Dashboard' + }, + { + id: 8, + title: 'Transforming E-commerce', + subtitle: 'Enterprise Cloud Commerce Platform', + description: 'High-performance cloud commerce platform providing enterprise scalability, advanced security protocols, and comprehensive business intelligence analytics.', + path: imagePaths.productCards.cloudCommerce, + alt: 'Cloud Commerce Dashboard' + } +].map(product => ({ + ...product, + imageSizes: { + sm: `${product.path}?w=300`, + md: `${product.path}?w=600`, + lg: `${product.path}?w=900` + }, + fallback: placeholderImage +})); + +export const META_CONFIG = { + title: 'Our Products - Tech4biz', + description: 'Explore our innovative product suite featuring enterprise security, retail management, and AI-powered solutions.', + keywords: 'enterprise security, retail management, AI solutions, voice recognition, digital learning' +}; \ No newline at end of file diff --git a/src/components/ProductCards/config/productCard.schema.js b/src/components/ProductCards/config/productCard.schema.js new file mode 100644 index 0000000..13541df --- /dev/null +++ b/src/components/ProductCards/config/productCard.schema.js @@ -0,0 +1,15 @@ +export const getProductSchema = (products) => ({ + "@context": "https://schema.org", + "@type": "ItemList", + "itemListElement": products.map((product, index) => ({ + "@type": "Product", + "position": index + 1, + "name": product.title, + "description": product.description, + "image": product.path, + "offers": { + "@type": "Offer", + "availability": "https://schema.org/InStock" + } + })) + }); \ No newline at end of file diff --git a/src/components/ProductCards/hooks/useImageLoader.js b/src/components/ProductCards/hooks/useImageLoader.js new file mode 100644 index 0000000..d285814 --- /dev/null +++ b/src/components/ProductCards/hooks/useImageLoader.js @@ -0,0 +1,11 @@ +import { useState, useCallback } from 'react'; + +export const useImageLoader = () => { + const [imageLoaded, setImageLoaded] = useState(false); + + const handleImageLoad = useCallback(() => { + setImageLoaded(true); + }, []); + + return { imageLoaded, handleImageLoad }; +}; \ No newline at end of file diff --git a/src/components/ProductCards/hooks/useProductGrid.js b/src/components/ProductCards/hooks/useProductGrid.js new file mode 100644 index 0000000..c00a674 --- /dev/null +++ b/src/components/ProductCards/hooks/useProductGrid.js @@ -0,0 +1,44 @@ +import { useState, useEffect, useCallback, useRef } from 'react'; +import { debounce } from 'lodash'; + +export function useProductGrid(totalProducts) { + const [currentIndex, setCurrentIndex] = useState(0); + const [isMobile, setIsMobile] = useState(false); + const productGridRef = useRef(null); + + const checkMobile = useCallback( + debounce(() => { + setIsMobile(window.innerWidth <= 639); + }, 150), + [] + ); + + useEffect(() => { + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => { + checkMobile.cancel(); + window.removeEventListener('resize', checkMobile); + }; + }, [checkMobile]); + + const handlePrev = useCallback(() => { + setCurrentIndex(prev => prev === 0 ? totalProducts - 1 : prev - 1); + }, [totalProducts]); + + const handleNext = useCallback(() => { + setCurrentIndex(prev => prev === totalProducts - 1 ? 0 : prev + 1); + }, [totalProducts]); + + const handleDotClick = useCallback((index) => { + setCurrentIndex(index); + }, []); + + return { + currentIndex, + isMobile, + handlePrev, + handleNext, + handleDotClick + }; +} \ No newline at end of file diff --git a/src/components/ProductCards/index.js b/src/components/ProductCards/index.js new file mode 100644 index 0000000..b5c0a0b --- /dev/null +++ b/src/components/ProductCards/index.js @@ -0,0 +1,15 @@ +import React, { Suspense } from 'react'; +import ErrorBoundary from './ErrorBoundary'; +import LoadingFallback from '../commonFallback/LoadingFallback'; + +const ProductGrid = React.lazy(() => import('./ProductGrid')); + +export default function ProductCards() { + return ( + + }> + + + + ); +} \ No newline at end of file diff --git a/src/components/ProductCards/styles/ProductCard.module.css b/src/components/ProductCards/styles/ProductCard.module.css new file mode 100644 index 0000000..4373f02 --- /dev/null +++ b/src/components/ProductCards/styles/ProductCard.module.css @@ -0,0 +1,144 @@ +.card { + @apply relative overflow-hidden cursor-pointer; + height: var(--card-height); + background: transparent; + perspective: 1000px; + transform-style: preserve-3d; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + } + + .cardImage { + @apply absolute inset-0 w-full h-full object-cover; + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), + filter 0.5s cubic-bezier(0.4, 0, 0.2, 1); + backface-visibility: hidden; + } + + .card:hover { + transform: translateY(-5px); + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2); + } + + .card:hover .cardImage { + transform: scale(5); + filter: blur(3px); + } + + .card:hover .description { + opacity: 1; + transform: translateX(0); + } + + .card:hover .button { + opacity: 1; + transform: scale(1.05) translateX(0); + } + + .card:hover .title, + .card:hover .subtitle { + transform: translateX(-10px); + } + + .cardContent { + @apply relative z-10 h-full p-6 flex flex-col; + background: linear-gradient( + to bottom, + rgba(0, 0, 0, 0.7) 0%, + rgba(0, 0, 0, 0.4) 30%, + rgba(0, 0, 0, 0.4) 70%, + rgba(0, 0, 0, 0.7) 100% + ); + backface-visibility: hidden; + } + + .title { + @apply text-white text-xl font-bold mb-2; + transform: translateX(0); + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); + } + + .subtitle { + @apply text-gray-200 text-lg mb-4; + transform: translateX(0); + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); + } + + .description { + @apply text-white/90 mb-4 mt-auto; + opacity: 0; + transform: translateX(100%); + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1); + transition-delay: 0.1s; + } + + .button { + @apply inline-flex items-center mt-2 px-6 py-2 text-white font-medium; + opacity: 0; + transform: translateX(-100%); + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1), + background-color 0.3s ease; + transition-delay: 0.2s; + align-self: flex-end; + border-radius: 4px; + text-transform: capitalize; + } + + .button:hover { + transform: scale(1.05) translateX(0); + background-color: rgba(255, 255, 255, 0.1); + } + + .buttonArrow { + @apply ml-2 w-4 h-4; + transition: transform 0.3s ease; + } + + .button:hover .buttonArrow { + transform: translateX(3px); + } + + .revealed .cardContent { + opacity: 1; + transform: translateY(0); + pointer-events: auto; + } + + /* Responsive Styles */ + @media (max-width: 639px) { + .card { + flex: 0 0 calc(100% - 40px); + width: calc(100% - 40px); + margin: 0; + scroll-snap-align: center; + } + } + + @media (max-width: 639px) { + .touched { + transform: translateY(-5px); + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2); + } + + .touched .cardImage { + transform: scale(5); + filter: blur(3px); + } + + .touched .description { + opacity: 1; + transform: translateX(0); + } + + .touched .button { + opacity: 1; + transform: scale(1.05) translateX(0); + } + + .touched .title, + .touched .subtitle { + transform: translateX(-10px); + } + } \ No newline at end of file diff --git a/src/components/ProductCards/styles/ProductGrid.module.css b/src/components/ProductCards/styles/ProductGrid.module.css new file mode 100644 index 0000000..0a41043 --- /dev/null +++ b/src/components/ProductCards/styles/ProductGrid.module.css @@ -0,0 +1,207 @@ +.showcase { + --card-width: 280px; + --card-height: 450px; + --card-gap: 2rem; + --cards-per-view: 4; + position: relative; + padding: 2rem 0; + background: radial-gradient(115.45% 482.04% at -5.28% -13.33%, + #2d1b69 0%, + #1a103f 50%, + #0c0620 100% + ); + overflow: hidden; + } + + .showcase::before { + content: ''; + position: absolute; + inset: 0; + background: + linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px), + linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px); + background-size: 35px 35px; + opacity: 0.5; + } + + .showcase::after { + content: ''; + position: absolute; + inset: 0; + background-image: radial-gradient( + rgba(255, 255, 255, 0.15) 2px, + transparent 2px + ); + background-size: 35px 35px; + background-position: -5px -5px; + opacity: 0.3; + z-index: 1; + } + + .polyOverlay { + @apply absolute inset-0; + background: + linear-gradient(45deg, transparent 48%, rgba(255, 255, 255, 0.05) 50%, transparent 52%), + linear-gradient(-45deg, transparent 48%, rgba(255, 255, 255, 0.05) 50%, transparent 52%); + background-size: 70px 70px; + opacity: 0.4; + z-index: 1; + } + + .glowOverlay { + @apply absolute inset-0; + background: radial-gradient( + circle at 50% 50%, + rgba(45, 27, 105, 0.4) 0%, + transparent 60% + ); + z-index: 1; + } + + .container { + width: 100%; + max-width: 90rem; + margin: 2rem auto 4rem; + padding: 0 1rem; + position: relative; + z-index: 2; + } + + .heading { + @apply text-3xl font-bold text-white capitalize text-center mb-12; + } + + .gridContainer { + position: relative; + overflow: hidden; + padding: 0 var(--card-gap); + z-index: 2; + } + + .grid { + display: grid; + grid-template-columns: repeat(var(--cards-per-view), minmax(var(--card-width), 1fr)); + gap: var(--card-gap); + transition: transform 0.3s ease-in-out; + } + + @media (max-width: 1279px) { + .grid { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + } + + @media (max-width: 1023px) { + .grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + } + + @media (max-width: 639px) { + .showcase { + --cards-per-view: 1; + padding: 2rem 0; + } + + .gridContainer { + padding: 0; + margin: 0; + overflow: hidden; + } + + .grid { + display: flex; + width: 100%; + scroll-snap-type: x mandatory; + gap: 20px; + touch-action: pan-y pan-x pinch-zoom; + pointer-events: auto; + } + + .grid * { + touch-action: pan-y pan-x pinch-zoom; + } + + .card { + flex: 0 0 calc(100% - 20px); + width: calc(100% - 20px); + margin: 0; + scroll-snap-align: center; + } + + .navigation { + display: flex !important; + justify-content: center; + align-items: center; + gap: 1rem; + margin-top: 1.5rem; + } + + .dots { + display: flex !important; + justify-content: center; + gap: 0.5rem; + margin-top: 1rem; + } + + .container { + margin: 1rem auto 1rem; + } + } + + .dots { + display: none; + justify-content: center; + gap: 0.5rem; + margin-top: 1rem; + } + + .dot { + width: 8px; + height: 8px; + border-radius: 50%; + background-color: rgba(75, 85, 99, 0.4); + cursor: pointer; + transition: background-color 0.3s ease; + } + + .activeDot { + background-color: rgba(75, 85, 99, 1); + } + + .navigation { + display: none; + justify-content: center; + align-items: center; + gap: 1rem; + margin-top: 1.5rem; + } + + .navButton { + background-color: rgba(75, 85, 99, 0.8); + border: none; + border-radius: 50%; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background-color 0.3s ease; + z-index: 10; + } + + .navButton:hover { + background-color: rgba(75, 85, 99, 1); + } + + .navButton svg { + width: 24px; + height: 24px; + color: #ffffff; + } + + .navButton:disabled { + opacity: 0.5; + cursor: not-allowed; + } \ No newline at end of file diff --git a/src/components/ProductCards/utils/accessibility.js b/src/components/ProductCards/utils/accessibility.js new file mode 100644 index 0000000..66cd35b --- /dev/null +++ b/src/components/ProductCards/utils/accessibility.js @@ -0,0 +1,23 @@ +export const handleKeyboardNavigation = (event, handlers) => { + switch (event.key) { + case 'ArrowLeft': + handlers.prev(); + break; + case 'ArrowRight': + handlers.next(); + break; + case 'Enter': + case 'Space': + handlers.select(); + break; + default: + break; + } + }; + + export const getAriaLabels = (product) => ({ + card: `Product card for ${product.title}`, + image: product.alt, + title: `Product name: ${product.title}`, + description: `Product description: ${product.description}` + }); \ No newline at end of file diff --git a/src/components/ProductCards/utils/imageutils.js b/src/components/ProductCards/utils/imageutils.js new file mode 100644 index 0000000..4a94d22 --- /dev/null +++ b/src/components/ProductCards/utils/imageutils.js @@ -0,0 +1,24 @@ +export const getResponsiveImageProps = (product) => ({ + src: product.path, + srcSet: ` + ${product.imageSizes.sm} 300w, + ${product.imageSizes.md} 600w, + ${product.imageSizes.lg} 900w + `, + sizes: ` + (max-width: ${BREAKPOINTS.MOBILE}px) 300px, + (max-width: ${BREAKPOINTS.TABLET}px) 600px, + 900px + `, + loading: "lazy", + width: 600, + height: 400, + alt: product.alt + }); + + export const preloadImages = (products) => { + products.forEach(product => { + const img = new Image(); + img.src = product.path; + }); + }; \ No newline at end of file diff --git a/src/components/ProjectShowcase/ProjectCard.jsx b/src/components/ProjectShowcase/ProjectCard.jsx new file mode 100644 index 0000000..b425310 --- /dev/null +++ b/src/components/ProjectShowcase/ProjectCard.jsx @@ -0,0 +1,35 @@ +import { motion } from 'framer-motion' +import { animations } from './config/projectData' +import { ArrowRight } from 'lucide-react' + +export default function ProjectCard({ project }) { + return ( + +
+ {project.title} +
+
+
+

{project.title}

+

{project.description}

+ + Read More + + +
+ + ) +} \ No newline at end of file diff --git a/src/components/ProjectShowcase/ProjectShowcase.jsx b/src/components/ProjectShowcase/ProjectShowcase.jsx new file mode 100644 index 0000000..4e71aab --- /dev/null +++ b/src/components/ProjectShowcase/ProjectShowcase.jsx @@ -0,0 +1,80 @@ +'use client' + +import React, { Suspense, lazy } from 'react' +import { motion } from 'framer-motion' +import { Helmet, HelmetProvider } from 'react-helmet-async' +import ErrorBoundary from '../common/ErrorBoundary' +import { projects, animations } from './config/projectData' +import { projectShowcaseSchema } from './config/schema' +import useProjectAnimation from './hooks/useProjectAnimation' +import styles from './styles/ProjectShowcase.module.css' + +// Lazy load ProjectCard and ProjectHero +const ProjectCard = lazy(() => import('./components/ProjectCard')) +const ProjectHero = lazy(() => import('./components/ProjectHero')) + +export default function ProjectShowcase() { + const { containerRef, isVisible } = useProjectAnimation() + + return ( + + +
+ + AI Processing Solutions - ASIC & FPGA Architecture + + + + + + + + + + + + + + + + + + + + + }> + + + + + + {projects.map((project) => ( + + } + > + + + + ))} + + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/ProjectShowcase/components/ProjectCard.jsx b/src/components/ProjectShowcase/components/ProjectCard.jsx new file mode 100644 index 0000000..06099cf --- /dev/null +++ b/src/components/ProjectShowcase/components/ProjectCard.jsx @@ -0,0 +1,44 @@ +import React, { memo } from 'react' +import { motion } from 'framer-motion' +import { ArrowRight } from 'lucide-react' +import OptimizedImage from '../../common/OptimizedImage' +import { animations } from '../config/projectData' +import styles from '../styles/ProjectCard.module.css' + +const ProjectCard = memo(({ project }) => { + return ( + +
+ +
+
+
+

{project.title}

+

{project.description}

+ + Read More + +
+ + ) +}) + +ProjectCard.displayName = 'ProjectCard' +export default ProjectCard \ No newline at end of file diff --git a/src/components/ProjectShowcase/components/ProjectHero.jsx b/src/components/ProjectShowcase/components/ProjectHero.jsx new file mode 100644 index 0000000..5afcfc2 --- /dev/null +++ b/src/components/ProjectShowcase/components/ProjectHero.jsx @@ -0,0 +1,35 @@ +import React from 'react' +import { motion } from 'framer-motion' +import { ArrowRight } from 'lucide-react' +import { animations } from '../config/projectData' +import styles from '../styles/ProjectHero.module.css' + +export default function ProjectHero() { + return ( + <> + +

+ Empowering businesses with cutting-edge solutions and innovative technology +

+ + Explore Services + +
+ + +

+ We specialize in providing advanced{' '} + AI processing solutions with{' '} + ASIC and{' '} + FPGA architectures. Our expertise helps businesses achieve superior performance while significantly reducing costs compared to traditional cloud solutions. +

+
+ + ) +} \ No newline at end of file diff --git a/src/components/ProjectShowcase/config/animations.js b/src/components/ProjectShowcase/config/animations.js new file mode 100644 index 0000000..03d9fc2 --- /dev/null +++ b/src/components/ProjectShowcase/config/animations.js @@ -0,0 +1,24 @@ +export const animations = { + containerVariants: { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.3, + }, + }, + }, + + itemVariants: { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { + duration: 0.5, + ease: 'easeOut' + }, + }, + } +} diff --git a/src/components/ProjectShowcase/config/projectData.js b/src/components/ProjectShowcase/config/projectData.js new file mode 100644 index 0000000..60a411f --- /dev/null +++ b/src/components/ProjectShowcase/config/projectData.js @@ -0,0 +1,49 @@ +import asicAiDeployment from '@/assets/Product-Show-Case/ASIC-AI-Deployment.webp'; +import advancedFpga from '@/assets/Product-Show-Case/Advanced-FPGA-Architecture.webp'; +import adaptiveSolutions from '@/assets/Product-Show-Case/Adaptive-Solutions.webp'; +import acceleratedPerformance from '@/assets/Product-Show-Case/Accelerated-Performance.webp'; + +export const projects = [ + { + title: 'ASIC AI Deployment', + description: 'Massive AI models can be deployed on our ASIC boards computed performances even better then Google Compute Clouds and AWS FPGA instances saving thousands of query invocation dollars.', + image: asicAiDeployment, + }, + { + title: 'Accelerated Performance', + description: 'With efficient speed, performance, and multi-tasking abilities, achieving accelerated results from the same tasks but larger AI models is now possible.', + image: acceleratedPerformance, + }, + { + title: 'Advanced FPGA Architecture', + description: 'Advanced FPGA architecture designs with Artificial Neural Network (ANN) and Convolution neural network (CNN) for high end AI processing.', + image: advancedFpga, + }, + { + title: 'Adaptive Solutions', + description: 'Updating and adaptation as per customer demands, software acceleration, and fast and efficient systems: are all only a few benefits that we strive to deliver through our high-end AI processing services.', + image: adaptiveSolutions, + }, +] + +export const animations = { + containerVariants: { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.3, + }, + }, + }, + + itemVariants: { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.5 }, + }, + } +} \ No newline at end of file diff --git a/src/components/ProjectShowcase/config/schema.js b/src/components/ProjectShowcase/config/schema.js new file mode 100644 index 0000000..3545e91 --- /dev/null +++ b/src/components/ProjectShowcase/config/schema.js @@ -0,0 +1,12 @@ +export const projectShowcaseSchema = { + "@context": "https://schema.org", + "@type": "Service", + "name": "AI Processing Solutions", + "description": "Advanced AI processing solutions with ASIC and FPGA architectures", + "provider": { + "@type": "Organization", + "name": "Your Company Name" + }, + "serviceType": "AI Processing", + "areaServed": "Worldwide" +} diff --git a/src/components/ProjectShowcase/hooks/useProjectAnimation.js b/src/components/ProjectShowcase/hooks/useProjectAnimation.js new file mode 100644 index 0000000..d07d0b2 --- /dev/null +++ b/src/components/ProjectShowcase/hooks/useProjectAnimation.js @@ -0,0 +1,24 @@ +import { useRef, useState, useEffect } from 'react' +import { debounce } from '../utils/optimizations' + +export default function useProjectAnimation() { + const containerRef = useRef(null) + const [isVisible, setIsVisible] = useState(false) + + useEffect(() => { + const observer = new IntersectionObserver( + debounce(([entry]) => { + setIsVisible(entry.isIntersecting) + }, 100), + { threshold: 0.1 } + ) + + if (containerRef.current) { + observer.observe(containerRef.current) + } + + return () => observer.disconnect() + }, []) + + return { containerRef, isVisible } +} diff --git a/src/components/ProjectShowcase/styles/ProjectCard.module.css b/src/components/ProjectShowcase/styles/ProjectCard.module.css new file mode 100644 index 0000000..cfd9ff0 --- /dev/null +++ b/src/components/ProjectShowcase/styles/ProjectCard.module.css @@ -0,0 +1,31 @@ +.card { + @apply relative overflow-hidden rounded-lg; +} + +.imageContainer { + @apply aspect-[4/3] relative; +} + +.image { + @apply object-cover w-full h-full transition-transform duration-500; +} + +.overlay { + @apply absolute inset-0 bg-black/40 transition-opacity; +} + +.content { + @apply p-6; +} + +.title { + @apply text-xl font-semibold mb-2 text-gray-200; +} + +.description { + @apply text-gray-200 text-sm mb-4; +} + +.button { + @apply inline-flex items-center gap-2 text-sm text-yellow-500 hover:text-yellow-400 transition-colors focus:outline-none focus:ring-2 focus:ring-yellow-500; +} diff --git a/src/components/ProjectShowcase/styles/ProjectHero.module.css b/src/components/ProjectShowcase/styles/ProjectHero.module.css new file mode 100644 index 0000000..690d59f --- /dev/null +++ b/src/components/ProjectShowcase/styles/ProjectHero.module.css @@ -0,0 +1,23 @@ +.heroSection { + @apply mb-24; +} + +.title { + @apply text-4xl md:text-6xl font-bold max-w-4xl mb-8 text-gray-200; +} + +.exploreButton { + @apply inline-flex items-center gap-2 px-6 py-3 rounded-full border border-white/20 hover:bg-white/10 transition-colors focus:outline-none focus:ring-2 focus:ring-yellow-500; +} + +.descriptionSection { + @apply mb-24 max-w-2xl; +} + +.description { + @apply text-lg text-gray-200; +} + +.highlight { + @apply text-yellow-500; +} diff --git a/src/components/ProjectShowcase/styles/ProjectShowcase.module.css b/src/components/ProjectShowcase/styles/ProjectShowcase.module.css new file mode 100644 index 0000000..36343dd --- /dev/null +++ b/src/components/ProjectShowcase/styles/ProjectShowcase.module.css @@ -0,0 +1,15 @@ +.showcaseContainer { + @apply min-h-screen bg-black text-white; + } + + .contentWrapper { + @apply container mx-auto px-4 py-16 md:py-24; + } + + .projectGrid { + @apply grid grid-cols-1 md:grid-cols-2 gap-8; + } + + .cardSkeleton { + @apply animate-pulse bg-gray-800 rounded-lg aspect-[4/3]; + } \ No newline at end of file diff --git a/src/components/ProjectShowcase/utils/optimizations.js b/src/components/ProjectShowcase/utils/optimizations.js new file mode 100644 index 0000000..d9f0de3 --- /dev/null +++ b/src/components/ProjectShowcase/utils/optimizations.js @@ -0,0 +1,22 @@ +export const debounce = (func, wait) => { + let timeout + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout) + func(...args) + } + clearTimeout(timeout) + timeout = setTimeout(later, wait) + } +} + +export const throttle = (func, limit) => { + let inThrottle + return function executedFunction(...args) { + if (!inThrottle) { + func(...args) + inThrottle = true + setTimeout(() => inThrottle = false, limit) + } + } +} diff --git a/src/components/ServiceCards/ServiceCards.jsx b/src/components/ServiceCards/ServiceCards.jsx new file mode 100644 index 0000000..7b69958 --- /dev/null +++ b/src/components/ServiceCards/ServiceCards.jsx @@ -0,0 +1,64 @@ +'use client' + +import React, { useRef, useEffect, Suspense, memo } from 'react' +import { motion, useInView } from 'framer-motion' +import gsap from 'gsap' +import { ScrollTrigger } from 'gsap/ScrollTrigger' +import SplitType from 'split-type' +import { containerVariants } from './animations/variants' +import { services } from './config/serviceCardsConfig' +import ErrorBoundary from '../common/ErrorBoundary' +import './styles/ServiceCards.css' + +const ServiceHeader = React.lazy(() => import('./components/ServiceHeader')) +const ServiceCard = React.lazy(() => import('./components/ServiceCard')) + +gsap.registerPlugin(ScrollTrigger) + +const ServiceCards = () => { + const sectionRef = useRef(null) + const isInView = useInView(sectionRef, { once: true }) + + useEffect(() => { + const ctx = gsap.context(() => { + // Animation setup moved to a separate useEffect to optimize performance + import('./animations/setupAnimations').then(module => { + module.default(sectionRef.current) + }) + }) + + return () => ctx.revert() + }, []) + + return ( + +
+ Loading...
}> + + + + + {services.map((service, index) => ( + }> + + + ))} + + + + ) +} + +export default memo(ServiceCards) \ No newline at end of file diff --git a/src/components/ServiceCards/animations/setupAnimations.js b/src/components/ServiceCards/animations/setupAnimations.js new file mode 100644 index 0000000..dc759a1 --- /dev/null +++ b/src/components/ServiceCards/animations/setupAnimations.js @@ -0,0 +1,51 @@ +import gsap from 'gsap' +import SplitType from 'split-type' + +const setupAnimations = (sectionRef) => { + if (!sectionRef) return + + const heading = sectionRef.querySelector('h2') + const text = sectionRef.querySelector('p') + + if (!heading || !text) return + + const splitHeading = new SplitType(heading, { + types: 'chars,words', + wordClass: 'word-wrap' + }) + + const splitText = new SplitType(text, { + types: 'lines', + linesClass: 'line-wrap' + }) + + gsap.set([splitHeading.chars, splitText.lines], { + opacity: 0, + y: 20, + }) + + const tl = gsap.timeline({ + scrollTrigger: { + trigger: sectionRef, + start: 'top 80%', + toggleActions: 'play none none reverse', + } + }) + + tl.to(splitHeading.chars, { + opacity: 1, + y: 0, + duration: 1, + stagger: 0.02, + ease: "power3.out" + }) + .to(splitText.lines, { + opacity: 1, + y: 0, + duration: 0.8, + stagger: 0.1, + ease: "power3.out" + }, '-=0.5') +} + +export default setupAnimations diff --git a/src/components/ServiceCards/animations/variants.js b/src/components/ServiceCards/animations/variants.js new file mode 100644 index 0000000..fd2b0b9 --- /dev/null +++ b/src/components/ServiceCards/animations/variants.js @@ -0,0 +1,19 @@ +export const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.1 + } + } +} + +export const cardVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.6, ease: "easeOut" } + } +} diff --git a/src/components/ServiceCards/components/ServiceCard.jsx b/src/components/ServiceCards/components/ServiceCard.jsx new file mode 100644 index 0000000..eca770a --- /dev/null +++ b/src/components/ServiceCards/components/ServiceCard.jsx @@ -0,0 +1,51 @@ +import React, { memo } from 'react' +import { motion } from 'framer-motion' +import { ArrowRight } from 'lucide-react' +import { cardVariants } from '../animations/variants' + +const ServiceCard = ({ service, index }) => { + return ( + +
+ {service.category} +
+ +
+
+

+ {service.title} +

+

+ {service.description} +

+
+ + + {service.cta} + + + + +
+
+ ) +} + +export default memo(ServiceCard) diff --git a/src/components/ServiceCards/components/ServiceHeader.jsx b/src/components/ServiceCards/components/ServiceHeader.jsx new file mode 100644 index 0000000..490c643 --- /dev/null +++ b/src/components/ServiceCards/components/ServiceHeader.jsx @@ -0,0 +1,21 @@ +import React, { memo } from 'react' +import { sectionContent } from '../config/serviceCardsConfig' + +const ServiceHeader = () => { + return ( +
+

+ {sectionContent.title} +

+

+ {sectionContent.subtitle} +

+
+ ) +} + +export default memo(ServiceHeader) diff --git a/src/components/ServiceCards/config/meta.js b/src/components/ServiceCards/config/meta.js new file mode 100644 index 0000000..4d9043c --- /dev/null +++ b/src/components/ServiceCards/config/meta.js @@ -0,0 +1,16 @@ +export const serviceCardsMeta = { + title: "Manufacturing Services | Your Company", + description: "Expert manufacturing services including PCBA, PCB Manufacturing, and 3D Printing solutions for your business needs.", + openGraph: { + title: "Manufacturing Services | Your Company", + description: "Expert manufacturing services including PCBA, PCB Manufacturing, and 3D Printing solutions for your business needs.", + images: [ + { + url: "/images/services-og.jpg", + width: 1200, + height: 630, + alt: "Manufacturing Services" + } + ] + } +} diff --git a/src/components/ServiceCards/config/schema.js b/src/components/ServiceCards/config/schema.js new file mode 100644 index 0000000..1f53b42 --- /dev/null +++ b/src/components/ServiceCards/config/schema.js @@ -0,0 +1,19 @@ +import { services } from './serviceCardsConfig' + +export const serviceCardsSchema = { + "@context": "https://schema.org", + "@type": "Service", + "provider": { + "@type": "Organization", + "name": "Your Company Name" + }, + "serviceType": "Manufacturing Services", + "offers": services.map(service => ({ + "@type": "Offer", + "itemOffered": { + "@type": "Service", + "name": service.title, + "description": service.description + } + })) +} diff --git a/src/components/ServiceCards/config/serviceCardsConfig.js b/src/components/ServiceCards/config/serviceCardsConfig.js new file mode 100644 index 0000000..840d4b7 --- /dev/null +++ b/src/components/ServiceCards/config/serviceCardsConfig.js @@ -0,0 +1,43 @@ +export const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.1 + } + } +} + +export const cardVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { duration: 0.6, ease: "easeOut" } + } +} + +export const sectionContent = { + title: "Innovative Manufacturing Solutions", + subtitle: "Leverage our expertise in advanced manufacturing and design services to bring your ideas to life with precision and excellence." +} + +export const services = [ + { + id: 'pcba-manufacturing', + title: "PCBA & PCB Manufacturing", + description: "With our years of experience, we deliver expert PCBA and PCB manufacturing services catered to your business needs and production demands.", + cta: "Let's connect", + bgColor: "bg-[#1E2875]", + category: "Manufacturing" + }, + { + id: '3d-printing', + title: "3D Designing and Printing", + description: "Work with our team of 3d designing and printing experts to reinvent the way you turn ideas into a creative and 3d visual reality.", + cta: "See opportunities", + bgColor: "bg-[#2563EB]", + category: "Design" + } +] \ No newline at end of file diff --git a/src/components/ServiceCards/styles/ServiceCards.css b/src/components/ServiceCards/styles/ServiceCards.css new file mode 100644 index 0000000..20271d1 --- /dev/null +++ b/src/components/ServiceCards/styles/ServiceCards.css @@ -0,0 +1,54 @@ +.service-cards-section { + @apply py-20 bg-gray-50; +} + +.service-cards-grid { + @apply grid grid-cols-1 md:grid-cols-2 gap-6 p-6 max-w-7xl mx-auto; +} + +.service-card { + @apply rounded-2xl p-8 relative overflow-hidden min-h-[500px] flex flex-col; +} + +.service-category { + @apply mb-16; +} + +.service-category span { + @apply text-white/80 text-sm; +} + +.service-content { + @apply flex flex-col h-full justify-between; +} + +.service-text { + @apply space-y-6; +} + +.service-title { + @apply text-white text-4xl md:text-5xl font-medium leading-tight; +} + +.service-description { + @apply text-white/80 text-lg max-w-md; +} + +.service-cta { + @apply mt-8 bg-white text-black rounded-full py-4 px-6 inline-flex items-center justify-between w-full sm:w-64; +} + +.loading-skeleton { + @apply animate-pulse bg-gray-200 rounded-lg h-32 w-full max-w-3xl mx-auto; +} + +.card-skeleton { + @apply animate-pulse bg-gray-200 rounded-2xl h-[500px] w-full; +} + +@media (prefers-reduced-motion: reduce) { + .loading-skeleton, + .card-skeleton { + @apply animate-none; + } +} diff --git a/src/components/ServiceSection/ErrorBoundary.jsx b/src/components/ServiceSection/ErrorBoundary.jsx new file mode 100644 index 0000000..5fbb4c0 --- /dev/null +++ b/src/components/ServiceSection/ErrorBoundary.jsx @@ -0,0 +1,26 @@ +import React, { Component } from 'react'; + +class ErrorBoundary extends Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + console.error("ErrorBoundary caught an error", error, errorInfo); + } + + render() { + if (this.state.hasError) { + return

Something went wrong.

; + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/components/ServiceSection/ServiceSection.css b/src/components/ServiceSection/ServiceSection.css new file mode 100644 index 0000000..be14d9e --- /dev/null +++ b/src/components/ServiceSection/ServiceSection.css @@ -0,0 +1,21 @@ +.lazy-loaded { + opacity: 1 !important; + } + + .scroll-padding { + scroll-padding-top: 5rem; + } + + .text-primary-600 { + transition: all 0.1s ease-out; + } + + @keyframes pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.05); } + 100% { transform: scale(1); } + } + + .number-complete { + animation: pulse 0.5s ease-out; + } \ No newline at end of file diff --git a/src/components/ServiceSection/ServiceSection.jsx b/src/components/ServiceSection/ServiceSection.jsx new file mode 100644 index 0000000..df043a8 --- /dev/null +++ b/src/components/ServiceSection/ServiceSection.jsx @@ -0,0 +1,56 @@ +import { memo } from 'react'; +import { motion } from 'framer-motion'; +import { HiArrowRight } from 'react-icons/hi'; +import StatNumber from './components/StatNumber'; +import ServiceCard from './components/ServiceCard'; +import { useServiceSection } from './hooks/useServiceSection'; +import { content, servicePaths } from './config/ServiceSection-module-content'; +import { fadeInUp, slideIn } from './config/animations'; +import styles from './styles/ServiceSection.module.css'; +import { Helmet } from 'react-helmet-async'; +import { getServiceMetaTags, servicesSEOData } from './utils/schema'; + +const ServiceSection = memo(() => { + const { imageRef, secondImageRef, isScrolled } = useServiceSection(); + const { first, second } = content.services; + + return ( + <> + + {servicesSEOData.title} + {getServiceMetaTags().map((tag, index) => + tag.name ? ( + + ) : ( + + ) + )} + + +
+ + + +
+ + ); +}); + +ServiceSection.displayName = 'ServiceSection'; +export default ServiceSection; \ No newline at end of file diff --git a/src/components/ServiceSection/components/ServiceCard.jsx b/src/components/ServiceSection/components/ServiceCard.jsx new file mode 100644 index 0000000..49987af --- /dev/null +++ b/src/components/ServiceSection/components/ServiceCard.jsx @@ -0,0 +1,61 @@ +import { memo } from 'react'; +import { motion } from 'framer-motion'; +import { HiArrowRight } from 'react-icons/hi'; +import StatNumber from './StatNumber'; +import { fadeInUp, slideIn } from '../config/animations'; +import { getOptimizedImageProps } from '../utils/imageOptimizer'; +import styles from '../styles/ServiceSection.module.css'; + +const ServiceCard = memo(({ data, imagePath, imageRef, direction, reverse }) => { + return ( +
+ + + {data.title} + + + + {data.subtitle} + + + + {data.description} + + + + Explore our services + + +
+ {data.stats.map((stat, index) => ( + + ))} +
+
+ + + + +
+ ); +}); + +ServiceCard.displayName = 'ServiceCard'; +export default ServiceCard; \ No newline at end of file diff --git a/src/components/ServiceSection/components/StatNumber.jsx b/src/components/ServiceSection/components/StatNumber.jsx new file mode 100644 index 0000000..e9d13ec --- /dev/null +++ b/src/components/ServiceSection/components/StatNumber.jsx @@ -0,0 +1,37 @@ +import { memo, useRef, useEffect } from 'react'; +import { motion, useInView } from 'framer-motion'; +import { useCountAnimation } from '@/hooks/useCountAnimation'; +import { fadeInUp } from '../config/animations'; + +const StatNumber = memo(({ number, label }) => { + const ref = useRef(null); + const isInView = useInView(ref, { once: true }); + const rawNumber = parseInt(number); + const [count, setHasAnimated] = useCountAnimation(rawNumber, 2000, true); + + useEffect(() => { + if (isInView) { + setHasAnimated(true); + } + }, [isInView, setHasAnimated]); + + return ( + + + {count}{number.includes('+') ? '+' : number.includes('%') ? '%' : ''} + + + {label} + + + ); +}); + +StatNumber.displayName = 'StatNumber'; +export default StatNumber; \ No newline at end of file diff --git a/src/components/ServiceSection/config/ServiceSection-module-content.js b/src/components/ServiceSection/config/ServiceSection-module-content.js new file mode 100644 index 0000000..7726760 --- /dev/null +++ b/src/components/ServiceSection/config/ServiceSection-module-content.js @@ -0,0 +1,34 @@ +import { imagePaths } from '@/constants/images'; + +export const content = { + services: { + first: { + title: "Software Development Solutions", + subtitle: "Expert Development Services & Continuous Support", + description: "Providing expert services for software design, engineering, support, and continuous improvement all in one comprehensive platform.", + stats: [ + { number: '12+', label: 'Expert Engineers' }, + { number: '100+', label: 'Successful Projects' }, + { number: '4+', label: 'Years of Excellence' } + ] + }, + second: { + title: "VLSI Design Services", + subtitle: "Analog & Digital Circuit Design Services", + description: "Tech4Biz provides a full range of VLSI services, from analog and mixed-signal verification to IP development, RF design, and turnkey solutions—all tailored to meet your needs with precision.", + stats: [ + { number: '50+', label: 'VLSI Designs' }, + { number: '99%', label: 'Design Accuracy' }, + { number: '24/7', label: 'Technical Support' } + ] + } + } +}; + +export const servicePaths = { + services: { + main: imagePaths.serviceSection.main, + second: imagePaths.serviceSection.cloud, + placeholder: imagePaths.serviceSection.placeholder + } +}; \ No newline at end of file diff --git a/src/components/ServiceSection/config/animations.js b/src/components/ServiceSection/config/animations.js new file mode 100644 index 0000000..e5f9007 --- /dev/null +++ b/src/components/ServiceSection/config/animations.js @@ -0,0 +1,32 @@ +export const fadeInUp = { + initial: { opacity: 0, y: 20 }, + whileInView: { opacity: 1, y: 0 }, + viewport: { once: true }, + transition: { duration: 0.5 } +}; + +export const slideIn = (direction) => ({ + initial: { + opacity: 0, + x: direction === 'left' ? -50 : 50, + width: '100%' + }, + whileInView: { + opacity: 1, + x: 0, + width: '100%' + }, + viewport: { once: true }, + transition: { duration: 0.5 } +}); + +export const pulseAnimation = { + initial: { scale: 1 }, + animate: { + scale: [1, 1.05, 1], + transition: { + duration: 0.5, + ease: "easeOut" + } + } +}; \ No newline at end of file diff --git a/src/components/ServiceSection/hooks/useServiceSection.js b/src/components/ServiceSection/hooks/useServiceSection.js new file mode 100644 index 0000000..5245ce0 --- /dev/null +++ b/src/components/ServiceSection/hooks/useServiceSection.js @@ -0,0 +1,37 @@ +import { useCallback, useRef, useEffect } from 'react'; +import { useLazyLoad } from '@/hooks/useLazyLoad'; +import { useScrollPosition } from '@/hooks/useScrollPosition'; +import { debounce } from '@/utils/helpers'; + +export const useServiceSection = () => { + const imageRef = useLazyLoad(); + const secondImageRef = useLazyLoad(); + const isScrolled = useScrollPosition(); + + const handleScroll = useCallback((e) => { + if (!imageRef.current || !secondImageRef.current) return; + + const { top: firstTop } = imageRef.current.getBoundingClientRect(); + const { top: secondTop } = secondImageRef.current.getBoundingClientRect(); + + if (firstTop < window.innerHeight) { + imageRef.current.classList.add('lazy-loaded'); + } + + if (secondTop < window.innerHeight) { + secondImageRef.current.classList.add('lazy-loaded'); + } + }, []); + + useEffect(() => { + const debouncedScroll = debounce(handleScroll, 100); + window.addEventListener('scroll', debouncedScroll); + return () => window.removeEventListener('scroll', debouncedScroll); + }, [handleScroll]); + + return { + imageRef, + secondImageRef, + isScrolled + }; +}; \ No newline at end of file diff --git a/src/components/ServiceSection/index.jsx b/src/components/ServiceSection/index.jsx new file mode 100644 index 0000000..faf6f04 --- /dev/null +++ b/src/components/ServiceSection/index.jsx @@ -0,0 +1,17 @@ +import { lazy, Suspense } from 'react'; +import LoadingSpinner from '@/components/common/LoadingSpinner'; +import ErrorBoundary from './ErrorBoundary'; + +const ServiceSection = lazy(() => import('./ServiceSection')); + +const ServiceSectionWrapper = () => { + return ( + + }> + + + + ); +}; + +export default ServiceSectionWrapper; \ No newline at end of file diff --git a/src/components/ServiceSection/styles/ServiceSection.module.css b/src/components/ServiceSection/styles/ServiceSection.module.css new file mode 100644 index 0000000..ac04243 --- /dev/null +++ b/src/components/ServiceSection/styles/ServiceSection.module.css @@ -0,0 +1,57 @@ +.serviceSection { + @apply container mx-auto px-4 py-16 lg:py-20 space-y-32 overflow-hidden; +} + +.serviceContainer { + @apply flex flex-col lg:flex-row items-center gap-12 w-full overflow-hidden; +} + +.reverse { + @apply lg:flex-row-reverse; +} + +.contentContainer { + @apply lg:w-1/2 space-y-6; +} + +.title { + @apply text-2xl sm:text-4xl lg:text-5xl font-bold text-gray-900; +} + +.subtitle { + @apply text-lg sm:text-xl lg:text-2xl text-gray-600 font-medium; +} + +.description { + @apply text-gray-600 leading-relaxed; +} + +.exploreLink { + @apply inline-flex items-center gap-2 font-medium cursor-pointer + bg-gradient-to-r from-indigo-500 to-blue-500 + text-white px-4 py-2 rounded-md + hover:from-indigo-600 hover:to-blue-600 + active:from-indigo-700 active:to-blue-700 + transition-all duration-300 + focus:outline-none; +} + +.arrowIcon { + @apply transition-transform; +} + +.statsContainer { + @apply pt-8 grid grid-cols-3 gap-4 lg:flex lg:flex-wrap lg:gap-8; +} + +.imageContainer { + @apply w-full h-[300px] lg:h-auto lg:w-1/2 relative overflow-hidden rounded-lg aspect-[6/4]; +} + +.serviceImage { + @apply w-full h-full object-cover transition-all duration-300 hover:scale-105; +} + +.scrollPadding { + @apply scroll-mt-20; +} \ No newline at end of file diff --git a/src/components/ServiceSection/styles/animations.module.css b/src/components/ServiceSection/styles/animations.module.css new file mode 100644 index 0000000..7075e08 --- /dev/null +++ b/src/components/ServiceSection/styles/animations.module.css @@ -0,0 +1,92 @@ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.05); } + 100% { transform: scale(1); } +} + +.fadeInUp { + animation: fadeInUp 0.5s ease-out forwards; +} + +.slideInLeft { + animation: slideInLeft 0.5s ease-out forwards; +} + +.slideInRight { + animation: slideInRight 0.5s ease-out forwards; +} + +.pulse { + animation: pulse 0.5s ease-out; +} + +/* Animation delays */ +.delay-100 { + animation-delay: 100ms; +} + +.delay-200 { + animation-delay: 200ms; +} + +.delay-300 { + animation-delay: 300ms; +} + +/* Animation utilities */ +.animate-once { + animation-fill-mode: forwards; +} + +.will-change-transform { + will-change: transform; +} + +.backface-hidden { + backface-visibility: hidden; +} + +/* Performance optimizations */ +@media (prefers-reduced-motion: reduce) { + .fadeInUp, + .slideInLeft, + .slideInRight, + .pulse { + animation: none; + opacity: 1; + transform: none; + } +} \ No newline at end of file diff --git a/src/components/ServiceSection/utils/imageOptimizer.js b/src/components/ServiceSection/utils/imageOptimizer.js new file mode 100644 index 0000000..2ff660e --- /dev/null +++ b/src/components/ServiceSection/utils/imageOptimizer.js @@ -0,0 +1,16 @@ +import { imagePaths } from '@/constants/images'; + +export const getOptimizedImageProps = (image, alt) => ({ + src: image, + alt, + loading: "lazy", + srcSet: `${image} 300w, ${image} 600w, ${image} 900w`, + sizes: "(max-width: 768px) 100vw, 50vw", + width: "100%", + height: "auto", + decoding: "async", + onError: (e) => { + e.target.src = imagePaths.serviceSection.placeholder; + console.error(`Failed to load image: ${alt}`); + } +}); \ No newline at end of file diff --git a/src/components/ServiceSection/utils/schema.js b/src/components/ServiceSection/utils/schema.js new file mode 100644 index 0000000..a75af15 --- /dev/null +++ b/src/components/ServiceSection/utils/schema.js @@ -0,0 +1,23 @@ +export const servicesSEOData = { + title: "Our Services - Software Engineering & VLSI Design", + description: "Expert software engineering solutions and VLSI design services. Comprehensive development, support, and continuous improvement platform.", + keywords: "software engineering, VLSI design, development services, technical support", + structuredData: { + "@context": "https://schema.org", + "@type": "Service", + "name": "Tech4Biz Services", + "serviceType": ["Software Engineering", "VLSI Design"], + "provider": { + "@type": "Organization", + "name": "Tech4Biz" + } + } +}; + +export const getServiceMetaTags = () => [ + { name: "description", content: servicesSEOData.description }, + { name: "keywords", content: servicesSEOData.keywords }, + { property: "og:title", content: servicesSEOData.title }, + { property: "og:description", content: servicesSEOData.description }, + { property: "og:type", content: "website" } +]; \ No newline at end of file diff --git a/src/components/common/ErrorBoundary.jsx b/src/components/common/ErrorBoundary.jsx new file mode 100644 index 0000000..83c7d26 --- /dev/null +++ b/src/components/common/ErrorBoundary.jsx @@ -0,0 +1,43 @@ +import React from 'react'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error) { + return { hasError: true, error }; + } + + componentDidCatch(error, info) { + // You can log the error to an error reporting service here + console.error("ErrorBoundary caught an error:", error, info); + } + + handleRetry = () => { + this.setState({ hasError: false, error: null }); + // Optionally, you can add logic to retry fetching data or re-rendering components + }; + + render() { + if (this.state.hasError) { + return ( +
+

Oops! Something went wrong.

+

We encountered an unexpected error. Please try again.

+ +
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/components/common/OptimizedImage.jsx b/src/components/common/OptimizedImage.jsx new file mode 100644 index 0000000..f1a9dc5 --- /dev/null +++ b/src/components/common/OptimizedImage.jsx @@ -0,0 +1,30 @@ +import React from 'react'; + +const OptimizedImage = ({ + src, + alt, + width, + height, + className, + priority = false, + sizes = "100vw", + quality = 75, + onError, + onLoad +}) => { + return ( + {alt} + ); +}; + +export default OptimizedImage; diff --git a/src/components/commonFallback/LoadingFallback.jsx b/src/components/commonFallback/LoadingFallback.jsx new file mode 100644 index 0000000..64a50a3 --- /dev/null +++ b/src/components/commonFallback/LoadingFallback.jsx @@ -0,0 +1,9 @@ +import React from 'react'; +import styles from './LoadingFallback.module.css'; + +export const LoadingFallback = () => ( +
+
+ Loading notifications... +
+); \ No newline at end of file diff --git a/src/components/commonFallback/LoadingFallback.module.css b/src/components/commonFallback/LoadingFallback.module.css new file mode 100644 index 0000000..09d79c8 --- /dev/null +++ b/src/components/commonFallback/LoadingFallback.module.css @@ -0,0 +1,7 @@ +.loaderContainer { + @apply flex items-center justify-center p-4; + } + + .loader { + @apply border-4 border-tech4biz-500 border-t-transparent rounded-full h-6 w-6 animate-spin; + } \ No newline at end of file diff --git a/src/components/footer/Footer.jsx b/src/components/footer/Footer.jsx new file mode 100644 index 0000000..e3840fe --- /dev/null +++ b/src/components/footer/Footer.jsx @@ -0,0 +1,109 @@ +'use client' + +import { motion } from 'framer-motion' +import { containerVariants, itemVariants, footerLinks, socialIcons, legalLinks } from './config/footerConfig' +import { useState } from 'react' +import { ChevronDown } from 'lucide-react' + +export default function Footer() { + const [expandedSection, setExpandedSection] = useState(null) + + const toggleSection = (title) => { + setExpandedSection(expandedSection === title ? null : title) + } + + return ( + +
+ {/* Main Footer Links */} +
+ {Object.entries(footerLinks).map(([title, items]) => ( +
+ + +
+ ))} +
+ + {/* Social Media Section */} +
+
+
+ {socialIcons.map((Icon, index) => ( + + + + ))} +
+
+
+ + {/* Bottom Section */} +
+
+ Company Logo +
+ +

+ Copyright © {new Date().getFullYear()} Company Name, Inc. +

+ +
+ {legalLinks.map((item) => ( + + {item} + + ))} +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/components/footer/config/footerConfig.js b/src/components/footer/config/footerConfig.js new file mode 100644 index 0000000..bc7cb52 --- /dev/null +++ b/src/components/footer/config/footerConfig.js @@ -0,0 +1,76 @@ +import { Facebook, Instagram, Youtube, Twitter, Linkedin, Share2 } from 'lucide-react' + +export const containerVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { + duration: 0.6, + staggerChildren: 0.1 + } + } +} + +export const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0 + } +} + +export const footerLinks = { + 'Solutions': [ + 'Cloud Infrastructure', + 'PCBA & PCB Manufacturing', + '3D Designing and Printing', + 'Software Development', + 'Hardware Design', + 'VLSI Design', + 'IoT Solutions', + 'AI Integration', + 'Cloud Optimization', + 'Circuit Design' + ], + 'Resources': [ + 'Case Studies', + 'Technical Blog', + 'Documentation', + 'API Reference', + 'Knowledge Base', + 'Community Forum', + 'Video Tutorials', + 'Whitepapers', + 'Research Papers', + 'Industry Reports' + ], + 'Company': [ + 'About Us', + 'Careers', + 'Contact', + 'Partners', + 'News & Press', + 'Events', + 'Customer Stories', + 'Sustainability', + 'Investor Relations', + 'Legal Information' + ], + 'Support': [ + 'Help Center', + 'Technical Support', + 'Customer Service', + 'Training', + 'Consulting', + 'System Status', + 'Security', + 'Compliance', + 'Developer Tools', + 'Service Level Agreements' + ] +} + +export const socialIcons = [Facebook, Instagram, Youtube, Twitter, Linkedin, Share2] + +export const legalLinks = ['Legal Stuff', 'Privacy Policy', 'Security', 'Website Accessibility', 'Manage Cookies'] \ No newline at end of file diff --git a/src/components/serviceSlider/CardSlider.jsx b/src/components/serviceSlider/CardSlider.jsx new file mode 100644 index 0000000..c6e38c2 --- /dev/null +++ b/src/components/serviceSlider/CardSlider.jsx @@ -0,0 +1,103 @@ +import { memo, lazy, Suspense, useEffect, useCallback } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { Helmet } from 'react-helmet-async'; +import { slides } from './config/sliderData'; +import { sliderSchema, metaTags } from './config/schema'; +import useSlider from './hooks/useSlider'; +import styles from './styles/slider.module.css'; + +// Importing utility for debouncing +const debounce = (func, delay) => { + let timeoutId; + return (...args) => { + if (timeoutId) clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + func(...args); + }, delay); + }; +}; + +const Controls = lazy(() => import('./components/Controls')); +const MobileLayout = lazy(() => import('./components/MobileLayout')); +const DesktopLayout = lazy(() => import('./components/DesktopLayout')); + +const CardSlider = memo(() => { + const { currentSlide, isPlaying, nextSlide, prevSlide, togglePlayPause } = useSlider(slides.length); + + // Debounced resize handler + const handleResize = useCallback( + debounce(() => { + // Add any resize-related logic here if needed + }, 300), + [] + ); + + useEffect(() => { + window.addEventListener('resize', handleResize); + // Cleanup on unmount + return () => { + window.removeEventListener('resize', handleResize); + }; + }, [handleResize]); + + // Virtualization: Render only current, previous, and next slides + const getVisibleSlides = () => { + const visible = []; + if (currentSlide > 0) visible.push(currentSlide - 1); + visible.push(currentSlide); + if (currentSlide < slides.length - 1) visible.push(currentSlide + 1); + return visible; + }; + + const visibleSlides = getVisibleSlides(); + + return ( + <> + + {metaTags.title} + + + + + +
+ + {visibleSlides.map((slideIndex) => ( + currentSlide ? 100 : -100 }} + animate={{ opacity: 1, x: 0 }} + exit={{ opacity: 0, x: slideIndex > currentSlide ? -100 : 100 }} + transition={{ duration: 0.5 }} + className="w-full h-full" + > + Loading Mobile Layout...
}> + + + Loading Desktop Layout...
}> + + + + ))} + + + Loading Controls...
}> + + +
+ + ); +}); + +CardSlider.displayName = 'CardSlider'; + +export default CardSlider; \ No newline at end of file diff --git a/src/components/serviceSlider/components/Controls.jsx b/src/components/serviceSlider/components/Controls.jsx new file mode 100644 index 0000000..2700159 --- /dev/null +++ b/src/components/serviceSlider/components/Controls.jsx @@ -0,0 +1,55 @@ +import { memo } from 'react'; +import { ChevronLeft, ChevronRight, Pause, Play } from 'lucide-react'; +import styles from '../styles/slider.module.css'; +import { ARIA_LABELS } from '../utils/constants'; + +const Controls = memo(({ + isPlaying, + currentSlide, + totalSlides, + onPrevClick, + onNextClick, + onPlayPauseClick +}) => { + return ( + <> +
+ +
+ +
+ +
+ {currentSlide + 1}/{totalSlides} +
+ +
+ + ); +}); + +Controls.displayName = 'Controls'; + +export default Controls; \ No newline at end of file diff --git a/src/components/serviceSlider/components/DesktopLayout.jsx b/src/components/serviceSlider/components/DesktopLayout.jsx new file mode 100644 index 0000000..a19cf20 --- /dev/null +++ b/src/components/serviceSlider/components/DesktopLayout.jsx @@ -0,0 +1,60 @@ +import { memo } from 'react'; +import { motion } from 'framer-motion'; +import { ChevronRight } from 'lucide-react'; +import OptimizedImage from '@/components/common/OptimizedImage'; +import styles from '../styles/slider.module.css'; + +const DesktopLayout = memo(({ slide }) => { + return ( +
+ + +
+ +
+ + {slide.title} + + + {slide.description} + + + Read more + + +
+
+ ); +}); + +DesktopLayout.displayName = 'DesktopLayout'; + +export default DesktopLayout; \ No newline at end of file diff --git a/src/components/serviceSlider/components/MobileLayout.jsx b/src/components/serviceSlider/components/MobileLayout.jsx new file mode 100644 index 0000000..45dde59 --- /dev/null +++ b/src/components/serviceSlider/components/MobileLayout.jsx @@ -0,0 +1,59 @@ +import { memo } from 'react'; +import { motion } from 'framer-motion'; +import { ChevronRight } from 'lucide-react'; +import OptimizedImage from '@/components/common/OptimizedImage'; +import styles from '../styles/slider.module.css'; + +const MobileLayout = memo(({ slide }) => { + return ( +
+ + +
+ +
+ + {slide.title} + + + {slide.description} + + + Read more + + +
+
+ ); +}); + +MobileLayout.displayName = 'MobileLayout'; + +export default MobileLayout; \ No newline at end of file diff --git a/src/components/serviceSlider/config/schema.js b/src/components/serviceSlider/config/schema.js new file mode 100644 index 0000000..2b3831d --- /dev/null +++ b/src/components/serviceSlider/config/schema.js @@ -0,0 +1,18 @@ +export const sliderSchema = { + "@context": "https://schema.org", + "@type": "ItemList", + "itemListElement": [ + { + "@type": "ListItem", + "position": 1, + "name": "Case Studies Slider", + "description": "Interactive showcase of technical case studies and projects" + } + ] + }; + + export const metaTags = { + title: "Case Studies & Projects | Interactive Showcase", + description: "Explore our technical case studies showcasing innovative solutions in technology, blockchain, IoT, and more.", + keywords: "case studies, technical projects, innovation, technology solutions", + }; \ No newline at end of file diff --git a/src/components/serviceSlider/config/sliderData.js b/src/components/serviceSlider/config/sliderData.js new file mode 100644 index 0000000..0fd83e8 --- /dev/null +++ b/src/components/serviceSlider/config/sliderData.js @@ -0,0 +1,59 @@ +import urbanConnectivity from '@/assets/Case Studies Slider/urban-connectivity.webp'; +import transformingBlockchain from '@/assets/Case Studies Slider/transforming-blockchain.webp'; +import iotConnectivity from '@/assets/Case Studies Slider/iotconnecctivity.webp'; +import fitness from '@/assets/Case Studies Slider/fitness.webp'; +import empower from '@/assets/Case Studies Slider/empower.webp'; +import decentralizedBanner from '@/assets/Case Studies Slider/decentralized-banner.webp'; +import automating from '@/assets/Case Studies Slider/automating.webp'; +import visualImg from '@/assets/Case Studies Slider/3D-Visual-Img.webp'; + +export const slides = [ + { + id: 1, + image: urbanConnectivity, + title: 'Transforming Urban Connectivity with 5G Technology', + description: 'A Technical Case Study on Revolutionizing Urban Infrastructure and Services.', + }, + { + id: 2, + image: transformingBlockchain, + title: 'Transforming with Blockchain Technology', + description: 'A Case Study on Building an EVM-Compatible Smart Contract Platform', + }, + { + id: 3, + image: iotConnectivity, + title: 'Revamping IoT Connectivity with Redesigned BLE Board', + description: 'A Case Study on Revamping BLE Board Technology for Enhanced Efficiency and Reliability.', + }, + { + id: 4, + image: fitness, + title: 'Transforming Fitness Training with AR & VR Simulations', + description: 'Leveraging Cutting-Edge Technologies for Enhanced Instructor Training and Immersive Learning.', + }, + { + id: 5, + image: empower, + title: 'Empowering Healthcare Data Management', + description: 'Transforming Healthcare Infrastructure for Scalability and Security with AWS Cloud Services.', + }, + { + id: 6, + image: decentralizedBanner, + title: 'Decentralized Processing with Edge Computing in Manufacturing', + description: 'A Comprehensive Case Study on Implementing Decentralized Processing with Edge Computing in Manufacturing.', + }, + { + id: 7, + image: automating, + title: 'Automating Manufacturing Excellence Revolutionizing Operations with RPA', + description: 'Empowering Efficiency, Accuracy and Customer Satisfaction through Robotic Process Automation.', + }, + { + id: 8, + image: visualImg, + title: '3D Visualization', + description: 'A 3d Visual world like no other for world-class movies and storytelling with compact metaphysics libraries, making characters real.', + } +]; \ No newline at end of file diff --git a/src/components/serviceSlider/hooks/useSlider.js b/src/components/serviceSlider/hooks/useSlider.js new file mode 100644 index 0000000..7b756d6 --- /dev/null +++ b/src/components/serviceSlider/hooks/useSlider.js @@ -0,0 +1,37 @@ +import { useState, useEffect, useCallback } from 'react'; +import { SLIDE_INTERVAL } from '../utils/constants'; + +const useSlider = (totalSlides) => { + const [currentSlide, setCurrentSlide] = useState(0); + const [isPlaying, setIsPlaying] = useState(true); + + const nextSlide = useCallback(() => { + setCurrentSlide((prev) => (prev + 1) % totalSlides); + }, [totalSlides]); + + const prevSlide = useCallback(() => { + setCurrentSlide((prev) => (prev - 1 + totalSlides) % totalSlides); + }, [totalSlides]); + + const togglePlayPause = useCallback(() => { + setIsPlaying(prev => !prev); + }, []); + + useEffect(() => { + let interval; + if (isPlaying) { + interval = setInterval(nextSlide, SLIDE_INTERVAL); + } + return () => clearInterval(interval); + }, [isPlaying, nextSlide]); + + return { + currentSlide, + isPlaying, + nextSlide, + prevSlide, + togglePlayPause + }; +}; + +export default useSlider; \ No newline at end of file diff --git a/src/components/serviceSlider/index.js b/src/components/serviceSlider/index.js new file mode 100644 index 0000000..afc6329 --- /dev/null +++ b/src/components/serviceSlider/index.js @@ -0,0 +1,16 @@ +import { lazy, Suspense } from 'react'; +import ErrorBoundary from '@/components/common/ErrorBoundary'; + +const CardSlider = lazy(() => import('./CardSlider')); + +const ServiceSlider = () => { + return ( + + }> + + + + ); +}; + +export default ServiceSlider; \ No newline at end of file diff --git a/src/components/serviceSlider/styles/slider.module.css b/src/components/serviceSlider/styles/slider.module.css new file mode 100644 index 0000000..682a631 --- /dev/null +++ b/src/components/serviceSlider/styles/slider.module.css @@ -0,0 +1,27 @@ +.slider-container { + @apply relative w-full h-[800px] bg-gray-900 overflow-hidden; +} + +.slider-controls { + @apply bg-gray-800/50 p-4 hover:bg-gray-700/50 transition-colors; +} + +.slider-button { + @apply flex items-center space-x-2 bg-blue-600 text-white rounded-sm w-fit hover:bg-blue-700 transition-colors; +} + +.mobile-button { + @apply px-4 py-2; +} + +.desktop-button { + @apply px-6 py-3; +} + +.image-gradient-mobile { + @apply absolute inset-0 bg-gradient-to-b from-transparent to-black opacity-30; +} + +.image-gradient-desktop { + @apply absolute inset-0 bg-gradient-to-r from-transparent to-black opacity-30; +} diff --git a/src/components/serviceSlider/utils/constants.js b/src/components/serviceSlider/utils/constants.js new file mode 100644 index 0000000..c402448 --- /dev/null +++ b/src/components/serviceSlider/utils/constants.js @@ -0,0 +1,18 @@ +export const SLIDE_INTERVAL = 5000; +export const ANIMATION_DURATION = 0.7; +export const ANIMATION_DELAY = { + TITLE: 0.3, + DESCRIPTION: 0.4, + BUTTON: 0.5 +}; + +export const BREAKPOINTS = { + MOBILE: 'lg' +}; + +export const ARIA_LABELS = { + PLAY: 'Play slideshow', + PAUSE: 'Pause slideshow', + PREV: 'Previous slide', + NEXT: 'Next slide' +}; diff --git a/src/components/utils/AsyncComponent.jsx b/src/components/utils/AsyncComponent.jsx new file mode 100644 index 0000000..ecf39ad --- /dev/null +++ b/src/components/utils/AsyncComponent.jsx @@ -0,0 +1,11 @@ +import React, { Suspense } from 'react'; + +const AsyncComponent = ({ component: Component, fallback }) => { + return ( + + + + ); +}; + +export default AsyncComponent; \ No newline at end of file diff --git a/src/constants/images.js b/src/constants/images.js new file mode 100644 index 0000000..c44c52d --- /dev/null +++ b/src/constants/images.js @@ -0,0 +1,88 @@ +import awsLogo from '@/assets/Logo/AWS-Partner-Netwrok-tech4biz.webp' +import tech4bizLogo from '@/assets/Logo/Tech4biz-logo.webp' +import openaiLogo from '@/assets/Logo/OPENAI-Partner-Tech4biz.webp' +import isoLogo from '@/assets/Logo/ISO-Partner-Tech4biz.webp' +import ibmLogo from '@/assets/Logo/IBM-Tech4biz-partner.webp' +import cloudtopiaLogo from '@/assets/Logo/Cloudtopiaa-Tech4biz.webp' +import azureLogo from '@/assets/Logo/AZURE-Partner-Tech4biz.webp' +import heroVideo from '@/assets/Tech4biz.mp4' + +// Import hero slide images +import heroSlide1 from '@/assets/Header-slide/Img-1.webp' +import heroSlide2 from '@/assets/Header-slide/Img-2.webp' +import heroSlide3 from '@/assets/Header-slide/Img-3.webp' +import heroSlide4 from '@/assets/Header-slide/Img-4.webp' + +// Import product card images +import cloudDriveImage from '@/assets/Header/Product-Card/cloud-drive-storage-platform.webp'; +import codenukImage from '@/assets/Header/Product-Card/codenuk-coding-solution-platform.webp'; +import learningManagementSystemImage from '@/assets/Header/Product-Card/learning-management-system.webp'; +import cloudtopiaaImage from '@/assets/Header/Product-Card/cloudtopiaa-enterprise-solutions.webp'; + +// Our Product Images +import securityPlatformImage from '@/assets/Our-Product-Img/enterprise-security-defense-platform-dashboard-ai-threat-detection.webp'; +import riskAnalyticsImage from '@/assets/Our-Product-Img/advanced-risk-analytics-trading-platform-ml-investment-dashboard.webp'; +import commerceIntelligenceImage from '@/assets/Our-Product-Img/digital-commerce-intelligence-platform-pricing-analytics-dashboard.webp'; +import retailManagementImage from '@/assets/Our-Product-Img/connected-retail-management-iot-customer-experience-platform.webp'; +import speechRecognitionImage from '@/assets/Our-Product-Img/enterprise-speech-recognition-ai-voice-analysis-platform.webp'; +import learningPlatformImage from '@/assets/Our-Product-Img/digital-learning-experience-mixed-reality-education-platform.webp'; +import retailAutomationImage from '@/assets/Our-Product-Img/smart-retail-automation-inventory-management-platform.webp'; +import cloudCommerceImage from '@/assets/Our-Product-Img/enterprise-cloud-commerce-scalable-business-platform.webp'; + +// Service Section Images +import serviceMainImage from '@/assets/Service-Section/Software Engineering Solutions.webp'; +import serviceCloudImage from '@/assets/Service-Section/VLSI Design Services.webp'; +import servicePlaceholder from '@/assets/Service-Section/placeholder.jpg'; + +export const imagePaths = { + carouselLogos: [ + awsLogo, + tech4bizLogo, + openaiLogo, + isoLogo, + ibmLogo, + cloudtopiaLogo, + azureLogo + ], + companyLogo: { + tech4bizLogo + }, + heroSlides: [ + heroSlide1, + heroSlide2, + heroSlide3, + heroSlide4 + ], + cards: { + clouddrive: cloudDriveImage, + codenuk: codenukImage, + learningManagementSystem: learningManagementSystemImage, + cloudtopiaa: cloudtopiaaImage + }, + video: { + hero: heroVideo, + heroMobile: heroVideo, + poster: 'https://example.com/path-to-poster.jpg' + }, + mobileCards: { + clouddrive: cloudDriveImage, + codenuk: codenukImage, + learningManagementSystem: learningManagementSystemImage, + cloudtopiaa: cloudtopiaaImage + }, + productCards: { + securityPlatform: securityPlatformImage, + riskAnalytics: riskAnalyticsImage, + commerceIntelligence: commerceIntelligenceImage, + retailManagement: retailManagementImage, + speechRecognition: speechRecognitionImage, + learningPlatform: learningPlatformImage, + retailAutomation: retailAutomationImage, + cloudCommerce: cloudCommerceImage + }, + serviceSection: { + main: serviceMainImage, + cloud: serviceCloudImage, + placeholder: servicePlaceholder + } +}; \ No newline at end of file diff --git a/src/css/App.css b/src/css/App.css new file mode 100644 index 0000000..87108b2 --- /dev/null +++ b/src/css/App.css @@ -0,0 +1,33 @@ +/* Add to your global CSS file */ +.scrollbar-hide { + -ms-overflow-style: none !important; + scrollbar-width: none !important; +} +.scrollbar-hide::-webkit-scrollbar { + display: none !important; + width: 0 !important; + height: 0 !important; +} + +/* Add new class for the container */ +.carousel-container { + overflow: hidden !important; + -webkit-mask-image: -webkit-linear-gradient(left, transparent 0%, black 5%, black 95%, transparent 100%); + mask-image: linear-gradient(to right, transparent 0%, black 5%, black 95%, transparent 100%); +} +/* src/index.css */ +@keyframes scroll { + from { + transform: translateX(0); + } + to { + transform: translateX(-50%); + } +} + +.animate-scroll { + display: flex; + animation: scroll linear infinite; +} +@import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap'); diff --git a/src/hooks/useCountAnimation.js b/src/hooks/useCountAnimation.js new file mode 100644 index 0000000..b714ec3 --- /dev/null +++ b/src/hooks/useCountAnimation.js @@ -0,0 +1,32 @@ +import { useState, useEffect } from 'react'; + +export const useCountAnimation = (end, duration = 2000, startOnView = false) => { + const [count, setCount] = useState(0); + const [hasAnimated, setHasAnimated] = useState(!startOnView); + + useEffect(() => { + if (!hasAnimated) return; + + const startNumber = 0; + const endNumber = parseInt(end); + const steps = 30; // Number of steps in the animation + const stepDuration = duration / steps; + + let current = startNumber; + const increment = (endNumber - startNumber) / steps; + + const timer = setInterval(() => { + current += increment; + if (current >= endNumber) { + setCount(endNumber); + clearInterval(timer); + } else { + setCount(Math.floor(current)); + } + }, stepDuration); + + return () => clearInterval(timer); + }, [end, duration, hasAnimated]); + + return [count, setHasAnimated]; +}; \ No newline at end of file diff --git a/src/hooks/useDebounce.js b/src/hooks/useDebounce.js new file mode 100644 index 0000000..fdc3ea3 --- /dev/null +++ b/src/hooks/useDebounce.js @@ -0,0 +1,9 @@ +import { useCallback } from 'react'; +import debounce from 'lodash/debounce'; + +export const useDebounce = (callback, delay = 150) => { + return useCallback( + debounce((...args) => callback(...args), delay), + [callback, delay] + ); +}; diff --git a/src/hooks/useLazyLoad.js b/src/hooks/useLazyLoad.js new file mode 100644 index 0000000..5cc0dc8 --- /dev/null +++ b/src/hooks/useLazyLoad.js @@ -0,0 +1,30 @@ +import { useEffect, useRef } from 'react'; + +export const useLazyLoad = (options = {}) => { + const elementRef = useRef(null); + const observerRef = useRef(null); + + useEffect(() => { + observerRef.current = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting && elementRef.current) { + elementRef.current.src = elementRef.current.dataset.src; + elementRef.current.classList.add('lazy-loaded'); + observerRef.current.unobserve(entry.target); + } + }); + }, options); + + if (elementRef.current) { + observerRef.current.observe(elementRef.current); + } + + return () => { + if (observerRef.current) { + observerRef.current.disconnect(); + } + }; + }, [options]); + + return elementRef; +}; \ No newline at end of file diff --git a/src/hooks/useScrollPosition.js b/src/hooks/useScrollPosition.js new file mode 100644 index 0000000..4c58441 --- /dev/null +++ b/src/hooks/useScrollPosition.js @@ -0,0 +1,24 @@ +import { useState, useEffect, useCallback } from 'react'; +import { debounce } from 'lodash'; + +export const useScrollPosition = () => { + const [isScrolled, setIsScrolled] = useState(false); + + const handleScroll = useCallback( + debounce(() => { + setIsScrolled(window.scrollY > 0); + }, 100), // Adjust the debounce delay as needed + [] + ); + + useEffect(() => { + window.addEventListener('scroll', handleScroll); + + return () => { + handleScroll.cancel(); // Cancel any pending debounced calls on cleanup + window.removeEventListener('scroll', handleScroll); + }; + }, [handleScroll]); + + return isScrolled; +}; \ No newline at end of file diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/src/index.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..b9a1a6d --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' + +createRoot(document.getElementById('root')).render( + + + , +) diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx new file mode 100644 index 0000000..6afee94 --- /dev/null +++ b/src/pages/Home.jsx @@ -0,0 +1,32 @@ +import React from 'react'; +import Header from '../components/Header/Navbar'; +import Hero from '../components/Hero'; +import ProductGrid from '../components/ProductCards/ProductGrid'; +import ServiceSection from '../components/ServiceSection/ServiceSection'; +import CloudCTA from '../components/CloudCTA/CloudCTA'; +import CloudSlider from '../components/CloudSlider/CloudSlider'; +import CardSlider from '../components/serviceSlider/CardSlider'; +import ExperienceService from '../components/ExperienceSection/ExperienceService'; +import ProjectShowcase from '../components/ProjectShowcase/ProjectShowcase'; +import ServiceCards from '../components/ServiceCards/ServiceCards'; +import Footer from '../components/footer/Footer'; + +const Home = () => { + return ( + <> +
+ + + + + + + + + +