commit b7e599d0b287863d18994689a1f40c78f6320a17 Author: Alaguraj0361 Date: Thu Jan 22 21:28:51 2026 +0530 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/README.md b/README.md new file mode 100644 index 0000000..e215bc4 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..05e726d --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..e9ffa30 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a5f992b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7811 @@ +{ + "name": "odoo-next-frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "odoo-next-frontend", + "version": "0.1.0", + "dependencies": { + "@stripe/react-stripe-js": "^5.4.1", + "@stripe/stripe-js": "^8.6.3", + "bcryptjs": "^3.0.3", + "clsx": "^2.1.1", + "cookies-next": "^6.1.1", + "framer-motion": "^12.27.5", + "jsonwebtoken": "^9.0.3", + "lucide-react": "^0.562.0", + "mongoose": "^9.1.5", + "next": "16.1.4", + "nodemailer": "^7.0.12", + "react": "19.2.3", + "react-dom": "19.2.3", + "tailwind-merge": "^3.4.0" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.6", + "@types/jsonwebtoken": "^9.0.10", + "@types/node": "^20", + "@types/nodemailer": "^7.0.5", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.1.4", + "typescript": "^5" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sesv2": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sesv2/-/client-sesv2-3.972.0.tgz", + "integrity": "sha512-tFa5HTfas9cm+dRnuQcSLz67rkpslP2Vjy8iW4G+wjTip6BM7jy1CJbRcNiXh8NQj5lDtR0Uqg/7zS5G0vmEBQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.972.0", + "@aws-sdk/credential-provider-node": "3.972.0", + "@aws-sdk/middleware-host-header": "3.972.0", + "@aws-sdk/middleware-logger": "3.972.0", + "@aws-sdk/middleware-recursion-detection": "3.972.0", + "@aws-sdk/middleware-user-agent": "3.972.0", + "@aws-sdk/region-config-resolver": "3.972.0", + "@aws-sdk/signature-v4-multi-region": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@aws-sdk/util-endpoints": "3.972.0", + "@aws-sdk/util-user-agent-browser": "3.972.0", + "@aws-sdk/util-user-agent-node": "3.972.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.972.0.tgz", + "integrity": "sha512-5qw6qLiRE4SUiz0hWy878dSR13tSVhbTWhsvFT8mGHe37NRRiaobm5MA2sWD0deRAuO98djSiV+dhWXa1xIFNw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.972.0", + "@aws-sdk/middleware-host-header": "3.972.0", + "@aws-sdk/middleware-logger": "3.972.0", + "@aws-sdk/middleware-recursion-detection": "3.972.0", + "@aws-sdk/middleware-user-agent": "3.972.0", + "@aws-sdk/region-config-resolver": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@aws-sdk/util-endpoints": "3.972.0", + "@aws-sdk/util-user-agent-browser": "3.972.0", + "@aws-sdk/util-user-agent-node": "3.972.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.972.0.tgz", + "integrity": "sha512-nEeUW2M9F+xdIaD98F5MBcQ4ITtykj3yKbgFZ6J0JtL3bq+Z90szQ6Yy8H/BLPYXTs3V4n9ifnBo8cprRDiE6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@aws-sdk/xml-builder": "3.972.0", + "@smithy/core": "^3.20.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/signature-v4": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.0.tgz", + "integrity": "sha512-kKHoNv+maHlPQOAhYamhap0PObd16SAb3jwaY0KYgNTiSbeXlbGUZPLioo9oA3wU10zItJzx83ClU7d7h40luA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.0.tgz", + "integrity": "sha512-xzEi81L7I5jGUbpmqEHCe7zZr54hCABdj4H+3LzktHYuovV/oqnvoDdvZpGFR0e/KAw1+PL38NbGrpG30j6qlA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.0.tgz", + "integrity": "sha512-ruhAMceUIq2aknFd3jhWxmO0P0Efab5efjyIXOkI9i80g+zDY5VekeSxfqRKStEEJSKSCHDLQuOu0BnAn4Rzew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/credential-provider-env": "3.972.0", + "@aws-sdk/credential-provider-http": "3.972.0", + "@aws-sdk/credential-provider-login": "3.972.0", + "@aws-sdk/credential-provider-process": "3.972.0", + "@aws-sdk/credential-provider-sso": "3.972.0", + "@aws-sdk/credential-provider-web-identity": "3.972.0", + "@aws-sdk/nested-clients": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.0.tgz", + "integrity": "sha512-SsrsFJsEYAJHO4N/r2P0aK6o8si6f1lprR+Ej8J731XJqTckSGs/HFHcbxOyW/iKt+LNUvZa59/VlJmjhF4bEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/nested-clients": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.0.tgz", + "integrity": "sha512-wwJDpEGl6+sOygic8QKu0OHVB8SiodqF1fr5jvUlSFfS6tJss/E9vBc2aFjl7zI6KpAIYfIzIgM006lRrZtWCQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.972.0", + "@aws-sdk/credential-provider-http": "3.972.0", + "@aws-sdk/credential-provider-ini": "3.972.0", + "@aws-sdk/credential-provider-process": "3.972.0", + "@aws-sdk/credential-provider-sso": "3.972.0", + "@aws-sdk/credential-provider-web-identity": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.0.tgz", + "integrity": "sha512-nmzYhamLDJ8K+v3zWck79IaKMc350xZnWsf/GeaXO6E3MewSzd3lYkTiMi7lEp3/UwDm9NHfPguoPm+mhlSWQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.0.tgz", + "integrity": "sha512-6mYyfk1SrMZ15cH9T53yAF4YSnvq4yU1Xlgm3nqV1gZVQzmF5kr4t/F3BU3ygbvzi4uSwWxG3I3TYYS5eMlAyg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.972.0", + "@aws-sdk/core": "3.972.0", + "@aws-sdk/token-providers": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.0.tgz", + "integrity": "sha512-vsJXBGL8H54kz4T6do3p5elATj5d1izVGUXMluRJntm9/I0be/zUYtdd4oDTM2kSUmd4Zhyw3fMQ9lw7CVhd4A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/nested-clients": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.0.tgz", + "integrity": "sha512-3eztFI6F9/eHtkIaWKN3nT+PM+eQ6p1MALDuNshFk323ixuCZzOOVT8oUqtZa30Z6dycNXJwhlIq7NhUVFfimw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.0.tgz", + "integrity": "sha512-ZvdyVRwzK+ra31v1pQrgbqR/KsLD+wwJjHgko6JfoKUBIcEfAwJzQKO6HspHxdHWTVUz6MgvwskheR/TTYZl2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.0.tgz", + "integrity": "sha512-F2SmUeO+S6l1h6dydNet3BQIk173uAkcfU1HDkw/bUdRLAnh15D3HP9vCZ7oCPBNcdEICbXYDmx0BR9rRUHGlQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.0.tgz", + "integrity": "sha512-0bcKFXWx+NZ7tIlOo7KjQ+O2rydiHdIQahrq+fN6k9Osky29v17guy68urUKfhTobR6iY6KvxkroFWaFtTgS5w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@aws-sdk/util-arn-parser": "3.972.0", + "@smithy/core": "^3.20.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/signature-v4": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-stream": "^4.5.10", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.0.tgz", + "integrity": "sha512-kFHQm2OCBJCzGWRafgdWHGFjitUXY/OxXngymcX4l8CiyiNDZB27HDDBg2yLj3OUJc4z4fexLMmP8r9vgag19g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@aws-sdk/util-endpoints": "3.972.0", + "@smithy/core": "^3.20.6", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.972.0.tgz", + "integrity": "sha512-QGlbnuGzSQJVG6bR9Qw6G0Blh6abFR4VxNa61ttMbzy9jt28xmk2iGtrYLrQPlCCPhY6enHqjTWm3n3LOb0wAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.972.0", + "@aws-sdk/middleware-host-header": "3.972.0", + "@aws-sdk/middleware-logger": "3.972.0", + "@aws-sdk/middleware-recursion-detection": "3.972.0", + "@aws-sdk/middleware-user-agent": "3.972.0", + "@aws-sdk/region-config-resolver": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@aws-sdk/util-endpoints": "3.972.0", + "@aws-sdk/util-user-agent-browser": "3.972.0", + "@aws-sdk/util-user-agent-node": "3.972.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.6", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.7", + "@smithy/middleware-retry": "^4.4.23", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.22", + "@smithy/util-defaults-mode-node": "^4.2.25", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.0.tgz", + "integrity": "sha512-JyOf+R/6vJW8OEVFCAyzEOn2reri/Q+L0z9zx4JQSKWvTmJ1qeFO25sOm8VIfB8URKhfGRTQF30pfYaH2zxt/A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.972.0.tgz", + "integrity": "sha512-2udiRijmjpN81Pvajje4TsjbXDZNP6K9bYUanBYH8hXa/tZG5qfGCySD+TyX0sgDxCQmEDMg3LaQdfjNHBDEgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/signature-v4": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.972.0.tgz", + "integrity": "sha512-kWlXG+y5nZhgXGEtb72Je+EvqepBPs8E3vZse//1PYLWs2speFqbGE/ywCXmzEJgHgVqSB/u/lqBvs5WlYmSqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.972.0", + "@aws-sdk/nested-clients": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.972.0.tgz", + "integrity": "sha512-U7xBIbLSetONxb2bNzHyDgND3oKGoIfmknrEVnoEU4GUSs+0augUOIn9DIWGUO2ETcRFdsRUnmx9KhPT9Ojbug==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.0.tgz", + "integrity": "sha512-RM5Mmo/KJ593iMSrALlHEOcc9YOIyOsDmS5x2NLOMdEmzv1o00fcpAkCQ02IGu1eFneBFT7uX0Mpag0HI+Cz2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.972.0.tgz", + "integrity": "sha512-6JHsl1V/a1ZW8D8AFfd4R52fwZPnZ5H4U6DS8m/bWT8qad72NvbOFAC7U2cDtFs2TShqUO3TEiX/EJibtY3ijg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.3.tgz", + "integrity": "sha512-FNUqAjlKAGA7GM05kywE99q8wiPHPZqrzhq3wXRga6PRD6A0kzT85Pb0AzYBVTBRpSrKyyr6M92Y6bnSBVp2BA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.0.tgz", + "integrity": "sha512-eOLdkQyoRbDgioTS3Orr7iVsVEutJyMZxvyZ6WAF95IrF0kfWx5Rd/KXnfbnG/VKa2CvjZiitWfouLzfVEyvJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.972.0", + "@smithy/types": "^4.12.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.0.tgz", + "integrity": "sha512-GOy+AiSrE9kGiojiwlZvVVSXwylu4+fmP0MJfvras/MwP09RB/YtQuOVR1E0fKQc6OMwaTNBjgAbOEhxuWFbAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.972.0", + "@aws-sdk/types": "3.972.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.0.tgz", + "integrity": "sha512-POaGMcXnozzqBUyJM3HLUZ9GR6OKJWPGJEmhtTnxZXt8B6JcJ/6K3xRJ5H/j8oovVLz8Wg6vFxAHv8lvuASxMg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz", + "integrity": "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "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.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "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.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "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.1", + "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/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "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.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.5.tgz", + "integrity": "sha512-k64Lbyb7ycCSXHSLzxVdb2xsKGPMvYZfCICXvDsI8Z65CeWQzTEKS4YmGbnqw+U9RBvLPTsB6UCmwkgsDTGWIw==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@next/env": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.4.tgz", + "integrity": "sha512-gkrXnZyxPUy0Gg6SrPQPccbNVLSP3vmW8LU5dwEttEEC1RwDivk8w4O+sZIjFvPrSICXyhQDCG+y3VmjlJf+9A==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.4.tgz", + "integrity": "sha512-38WMjGP8y+1MN4bcZFs+GTcBe0iem5GGTzFE5GWW/dWdRKde7LOXH3lQT2QuoquVWyfl2S0fQRchGmeacGZ4Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.4.tgz", + "integrity": "sha512-T8atLKuvk13XQUdVLCv1ZzMPgLPW0+DWWbHSQXs0/3TjPrKNxTmUIhOEaoEyl3Z82k8h/gEtqyuoZGv6+Ugawg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.4.tgz", + "integrity": "sha512-AKC/qVjUGUQDSPI6gESTx0xOnOPQ5gttogNS3o6bA83yiaSZJek0Am5yXy82F1KcZCx3DdOwdGPZpQCluonuxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.4.tgz", + "integrity": "sha512-POQ65+pnYOkZNdngWfMEt7r53bzWiKkVNbjpmCt1Zb3V6lxJNXSsjwRuTQ8P/kguxDC8LRkqaL3vvsFrce4dMQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.4.tgz", + "integrity": "sha512-3Wm0zGYVCs6qDFAiSSDL+Z+r46EdtCv/2l+UlIdMbAq9hPJBvGu/rZOeuvCaIUjbArkmXac8HnTyQPJFzFWA0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.4.tgz", + "integrity": "sha512-lWAYAezFinaJiD5Gv8HDidtsZdT3CDaCeqoPoJjeB57OqzvMajpIhlZFce5sCAH6VuX4mdkxCRqecCJFwfm2nQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.4.tgz", + "integrity": "sha512-fHaIpT7x4gA6VQbdEpYUXRGyge/YbRrkG6DXM60XiBqDM2g2NcrsQaIuj375egnGFkJow4RHacgBOEsHfGbiUw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.4.tgz", + "integrity": "sha512-MCrXxrTSE7jPN1NyXJr39E+aNFBrQZtO154LoCz7n99FuKqJDekgxipoodLNWdQP7/DZ5tKMc/efybx1l159hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.4.tgz", + "integrity": "sha512-JSVlm9MDhmTXw/sO2PE/MRj+G6XOSMZB+BcZ0a7d6KwVFZVpkHcb2okyoYFBaco6LeiL53BBklRlOrDDbOeE5w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "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/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", + "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", + "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.21.0.tgz", + "integrity": "sha512-bg2TfzgsERyETAxc/Ims/eJX8eAnIeTi4r4LHpMpfF/2NyO6RsWis0rjKcCPaGksljmOb23BZRiCeT/3NvwkXw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.9", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-stream": "^4.5.10", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", + "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", + "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", + "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", + "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", + "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.10.tgz", + "integrity": "sha512-kwWpNltpxrvPabnjEFvwSmA+66l6s2ReCvgVSzW/z92LU4T28fTdgZ18IdYRYOrisu2NMQ0jUndRScbO65A/zg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.21.0", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-middleware": "^4.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.26", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.26.tgz", + "integrity": "sha512-ozZMoTAr+B2aVYfLYfkssFvc8ZV3p/vLpVQ7/k277xxUOA9ykSPe5obL2j6yHfbdrM/SZV7qj0uk/hSqavHrLw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/smithy-client": "^4.10.11", + "@smithy/types": "^4.12.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", + "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", + "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", + "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz", + "integrity": "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", + "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", + "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", + "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "@smithy/util-uri-escape": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", + "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", + "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", + "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", + "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-uri-escape": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.10.11", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.11.tgz", + "integrity": "sha512-6o804SCyHGMXAb5mFJ+iTy9kVKv7F91a9szN0J+9X6p8A0NrdpUxdaC57aye2ipQkP2C4IAqETEpGZ0Zj77Haw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.21.0", + "@smithy/middleware-endpoint": "^4.4.10", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", + "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", + "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.25", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.25.tgz", + "integrity": "sha512-8ugoNMtss2dJHsXnqsibGPqoaafvWJPACmYKxJ4E6QWaDrixsAemmiMMAVbvwYadjR0H9G2+AlzsInSzRi8PSw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.11", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.28", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.28.tgz", + "integrity": "sha512-mjUdcP8h3E0K/XvNMi9oBXRV3DMCzeRiYIieZ1LQ7jq5tu6GH/GTWym7a1xIIE0pKSoLcpGsaImuQhGPSIJzAA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.6", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.11", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", + "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", + "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", + "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.10.tgz", + "integrity": "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/types": "^4.12.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@stripe/react-stripe-js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-5.4.1.tgz", + "integrity": "sha512-ipeYcAHa4EPmjwfv0lFE+YDVkOQ0TMKkFWamW+BqmnSkEln/hO8rmxGPPWcd9WjqABx6Ro8Xg4pAS7evCcR9cw==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "@stripe/stripe-js": ">=8.0.0 <9.0.0", + "react": ">=16.8.0 <20.0.0", + "react-dom": ">=16.8.0 <20.0.0" + } + }, + "node_modules/@stripe/stripe-js": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-8.6.3.tgz", + "integrity": "sha512-MQsPNsMMprOu+p+BWYvD69aPjD52yQNXZaENRQX7IkbWqu7lp9k04D+RPeHWJEsuyzmCCoHx3Kqqf3tcXPoNvQ==", + "license": "MIT", + "engines": { + "node": ">=12.16" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/bcryptjs": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", + "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "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/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/nodemailer": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.5.tgz", + "integrity": "sha512-7WtR4MFJUNN2UFy0NIowBRJswj5KXjXDhlZY43Hmots5eGu5q/dTeFd/I6GgJA/qj3RqO6dDy4SvfcV3fOVeIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@aws-sdk/client-sesv2": "^3.839.0", + "@types/node": "*" + } + }, + "node_modules/@types/react": { + "version": "19.2.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz", + "integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz", + "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/type-utils": "8.53.1", + "@typescript-eslint/utils": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.53.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz", + "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz", + "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.53.1", + "@typescript-eslint/types": "^8.53.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz", + "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz", + "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz", + "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/utils": "8.53.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz", + "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz", + "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.53.1", + "@typescript-eslint/tsconfig-utils": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/visitor-keys": "8.53.1", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz", + "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.53.1", + "@typescript-eslint/types": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz", + "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.53.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "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-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/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/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "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.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "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.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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/axe-core": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "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/baseline-browser-mapping": { + "version": "2.9.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.16.tgz", + "integrity": "sha512-KeUZdBuxngy825i8xvzaK1Ncnkx0tBmb3k8DkEuqjKRkmtvNTjey2ZsNeh8Dw4lfKvbCOu9oeNx2TKm2vHqcRw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bcryptjs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", + "integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==", + "license": "BSD-3-Clause", + "bin": { + "bcrypt": "bin/bcrypt" + } + }, + "node_modules/bowser": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "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.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bson": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.1.1.tgz", + "integrity": "sha512-TtJgBB+QyOlWjrbM+8bRgH84VM/xrDjyBFgSgGrfZF4xvt6gbEDtcswm27Tn9F9TWsjQybxT8b8VpCP/oJK4Dw==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "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/caniuse-lite": { + "version": "1.0.30001765", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001765.tgz", + "integrity": "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==", + "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/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "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/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/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookies-next": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-6.1.1.tgz", + "integrity": "sha512-8JZBc4IN2m8xqOXyG7uicth6yH3SvynAUGSeV/FQ5lcEclzNGoR0+YCjySdn8r6keZdRyGQr4YJ8qy8F+Jq5uw==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1" + }, + "peerDependencies": { + "next": ">=15.0.0", + "react": ">= 16.8.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "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.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "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/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" + }, + "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.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "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.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.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" + }, + "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-config-next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.4.tgz", + "integrity": "sha512-iCrrNolUPpn/ythx0HcyNRfUBgTkaNBXByisKUbusPGCl8DMkDXXAu7exlSTSLGTIsH9lFE/c4s/3Qiyv2qwdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "16.1.4", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "16.4.0", + "typescript-eslint": "^8.46.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "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.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "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": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "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/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/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "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.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "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.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "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/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-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "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/fast-xml-parser": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "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.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/framer-motion": { + "version": "12.27.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.27.5.tgz", + "integrity": "sha512-yUFof7Y2Y2qDJxLKeA91qMazuA6QBOoLOZ0No2J5VIQuhJLWMmGwT/5qyCfpa9mNNS3C7lOR6NhlC3mLZjLw4g==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.27.5", + "motion-utils": "^12.27.2", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "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.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "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/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "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/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/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.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "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/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "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.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.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.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "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.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "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.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.0.0.tgz", + "integrity": "sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.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/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/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.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "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==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "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/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "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.562.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz", + "integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "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/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/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mongodb": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", + "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.0.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.0.tgz", + "integrity": "sha512-irhhjRVLE20hbkRl4zpAYLnDMM+zIZnp0IDB9akAFFUZp/3XdOfwwddc7y6cNvF2WCEtfTYRwYbIfYa2kVY0og==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/mongoose": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.1.5.tgz", + "integrity": "sha512-N6gypEO+wLmZp8kCYNQmrEWxVMT0KhyHvVttBZoKA/1ngY7aUsBjqHzCPtDgz+i8JAnqMOiEKmuJIDEQu1b9Dw==", + "license": "MIT", + "dependencies": { + "kareem": "3.0.0", + "mongodb": "~7.0", + "mpath": "0.9.0", + "mquery": "6.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/motion-dom": { + "version": "12.27.5", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.27.5.tgz", + "integrity": "sha512-UwBv2AUOkA7/TCHr67NGjg3aRT7nbsanmmenRoR7T6IJXZp34OZB+pooGnKjMd8CqqCsF/+qwT657EkukjgmiQ==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.27.2" + } + }, + "node_modules/motion-utils": { + "version": "12.27.2", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.27.2.tgz", + "integrity": "sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q==", + "license": "MIT" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-6.0.0.tgz", + "integrity": "sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==", + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/next/-/next-16.1.4.tgz", + "integrity": "sha512-gKSecROqisnV7Buen5BfjmXAm7Xlpx9o2ueVQRo5DxQcjC8d330dOM1xiGWc2k3Dcnz0In3VybyRPOsudwgiqQ==", + "license": "MIT", + "dependencies": { + "@next/env": "16.1.4", + "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.1.4", + "@next/swc-darwin-x64": "16.1.4", + "@next/swc-linux-arm64-gnu": "16.1.4", + "@next/swc-linux-arm64-musl": "16.1.4", + "@next/swc-linux-x64-gnu": "16.1.4", + "@next/swc-linux-x64-musl": "16.1.4", + "@next/swc-win32-arm64-msvc": "16.1.4", + "@next/swc-win32-x64-msvc": "16.1.4", + "sharp": "^0.34.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemailer": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.12.tgz", + "integrity": "sha512-H+rnK5bX2Pi/6ms3sN4/jRQvYSMltV6vqup/0SFOrxYYY/qoNvhXPlYq3e+Pm9RFJRwrMGbMIwi81M4dxpomhA==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.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-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "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.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "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.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "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/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/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/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "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/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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==", + "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": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.3" + } + }, + "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/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "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/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, + "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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "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.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "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-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/strnum": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "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/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.53.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz", + "integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.53.1", + "@typescript-eslint/parser": "8.53.1", + "@typescript-eslint/typescript-estree": "8.53.1", + "@typescript-eslint/utils": "8.53.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "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.1" + }, + "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/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "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.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "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/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/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" + } + }, + "node_modules/zod": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4a67b99 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "odoo-next-frontend", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "@stripe/react-stripe-js": "^5.4.1", + "@stripe/stripe-js": "^8.6.3", + "bcryptjs": "^3.0.3", + "clsx": "^2.1.1", + "cookies-next": "^6.1.1", + "framer-motion": "^12.27.5", + "jsonwebtoken": "^9.0.3", + "lucide-react": "^0.562.0", + "mongoose": "^9.1.5", + "next": "16.1.4", + "nodemailer": "^7.0.12", + "react": "19.2.3", + "react-dom": "19.2.3", + "tailwind-merge": "^3.4.0" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.6", + "@types/jsonwebtoken": "^9.0.10", + "@types/node": "^20", + "@types/nodemailer": "^7.0.5", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.1.4", + "typescript": "^5" + } +} diff --git a/public/file.svg b/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/next.svg b/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/window.svg b/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/accounting/accounting.module.css b/src/app/accounting/accounting.module.css new file mode 100644 index 0000000..732ac0e --- /dev/null +++ b/src/app/accounting/accounting.module.css @@ -0,0 +1,161 @@ +.container { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.header { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.statsRow { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} + +.statBox { + background: white; + padding: 1.5rem; + border-radius: 20px; + border: 1px solid #e2e8f0; + display: flex; + flex-direction: column; + gap: 0.5rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.statLabel { + font-size: 0.8rem; + font-weight: 700; + color: #64748b; + text-transform: uppercase; +} + +.statValue { + font-size: 1.5rem; + font-weight: 800; + color: #1e293b; + font-family: var(--font-heading); +} + +.actions { + display: flex; + justify-content: space-between; + align-items: center; + gap: 1rem; +} + +.searchBox { + flex: 1; + max-width: 400px; + position: relative; + display: flex; + align-items: center; +} + +.searchBox svg { + position: absolute; + left: 12px; + color: #94a3b8; +} + +.searchBox input { + width: 100%; + padding: 0.75rem 1rem 0.75rem 2.5rem; + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: var(--transition); +} + +.addBtn { + background: var(--pk-primary); + color: white; + border: none; + padding: 0.75rem 1.25rem; + border-radius: 12px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.exportBtn { + background: white; + border: 1px solid #e2e8f0; + padding: 0.75rem; + border-radius: 12px; + color: #64748b; + cursor: pointer; +} + +.tableWrapper { + background: white; + border-radius: 20px; + border: 1px solid #e2e8f0; + overflow: hidden; + box-shadow: var(--shadow); +} + +.ledgerTable { + width: 100%; + border-collapse: collapse; + text-align: left; +} + +.ledgerTable th { + padding: 1rem 1.5rem; + background: #f8fafc; + color: #64748b; + font-weight: 700; + font-size: 0.85rem; + border-bottom: 1px solid #e2e8f0; +} + +.ledgerTable td { + padding: 1rem 1.5rem; + border-bottom: 1px solid #f1f5f9; + font-size: 0.9rem; + color: #1e293b; +} + +.row:hover { + background: #f8fafc; +} + +.entryNumber { + font-weight: 700; + color: var(--pk-primary); +} + +.amount { + font-weight: 700; + font-family: var(--font-heading); +} + +.statusBadge { + padding: 0.25rem 0.75rem; + border-radius: 999px; + font-size: 0.75rem; + font-weight: 700; +} + +.posted { + background: #dcfce7; + color: #15803d; +} + +.draft { + background: #fef9c3; + color: #854d0e; +} + +.moreIcon { + color: #94a3b8; + cursor: pointer; +} \ No newline at end of file diff --git a/src/app/accounting/page.tsx b/src/app/accounting/page.tsx new file mode 100644 index 0000000..48b4ed8 --- /dev/null +++ b/src/app/accounting/page.tsx @@ -0,0 +1,110 @@ +"use client"; + +import React, { useState } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + BookOpen, + ArrowLeftRight, + FileText, + Settings, + Plus, + Search, + Filter, + Download, + MoreHorizontal, + LayoutDashboard, + Wallet, + Receipt +} from 'lucide-react'; +import styles from './accounting.module.css'; + +const sidebarItems = [ + { icon: , label: 'Accounting Dashboard' }, + { icon: , label: 'Journal Entries', active: true }, + { icon: , label: 'Vendor Bills' }, + { icon: , label: 'Bank Sync' }, +]; + +const journalEntries = [ + { id: 'BNK1/2026/001', date: '2026-01-20', journal: 'Bank', partner: 'Azure Interior', reference: 'INV/2026/001', amount: '$ 1,250.00', status: 'Posted' }, + { id: 'INV/2026/042', date: '2026-01-21', journal: 'Customer Invoices', partner: 'Deco Addict', reference: 'Sales Order S0002', amount: '$ 4,500.00', status: 'Draft' }, + { id: 'BILL/2026/012', date: '2026-01-21', journal: 'Vendor Bills', partner: 'Fresh Produce Co.', reference: 'Monthly Supply', amount: '$ -850.00', status: 'Posted' }, + { id: 'MISC/2026/005', date: '2026-01-22', journal: 'Miscellaneous', partner: '', reference: 'Year End Adjustment', amount: '$ 0.00', status: 'Posted' }, +]; + +export default function AccountingPage() { + const [search, setSearch] = useState(''); + + return ( + +
+ {/* Ledger Header */} +
+
+
+ Total Assets + $ 245,600.00 +
+
+ Accounts Receivable + $ 12,450.00 +
+
+ Accounts Payable + $ -4,200.00 +
+
+ +
+
+ + setSearch(e.target.value)} /> +
+ + +
+
+ + {/* Ledger Table */} +
+ + + + + + + + + + + + + + + + {journalEntries.map((entry) => ( + + + + + + + + + + + + ))} + +
DateNumberJournalPartnerReferenceAmountStatus
{entry.date}{entry.id}{entry.journal}{entry.partner || '-'}{entry.reference} + {entry.amount} + + + {entry.status} + +
+
+
+
+ ); +} diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts new file mode 100644 index 0000000..3b817df --- /dev/null +++ b/src/app/api/auth/login/route.ts @@ -0,0 +1,47 @@ +import { NextResponse } from 'next/server'; +import dbConnect from '@/lib/mongodb'; +import User from '@/models/User'; +import bcrypt from 'bcryptjs'; +import jwt from 'jsonwebtoken'; + +const JWT_SECRET = process.env.JWT_SECRET || 'your_super_secret_jwt_key'; + +export async function POST(req: Request) { + try { + const { email, password } = await req.json(); + + await dbConnect(); + + const user = await User.findOne({ email }); + if (!user) { + return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 }); + } + + const isMatch = await bcrypt.compare(password, user.password); + if (!isMatch) { + return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 }); + } + + const token = jwt.sign( + { userId: user._id, role: user.role, name: user.name }, + JWT_SECRET, + { expiresIn: '1d' } + ); + + const response = NextResponse.json({ + message: 'Login successful', + user: { id: user._id, name: user.name, email: user.email, role: user.role } + }); + + response.cookies.set('auth_token', token, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + maxAge: 86400, + path: '/', + }); + + return response; + } catch (error: any) { + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} diff --git a/src/app/api/auth/me/route.ts b/src/app/api/auth/me/route.ts new file mode 100644 index 0000000..e7917cb --- /dev/null +++ b/src/app/api/auth/me/route.ts @@ -0,0 +1,28 @@ +import { NextResponse } from 'next/server'; +import jwt from 'jsonwebtoken'; +import { cookies } from 'next/headers'; + +const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key'; + +export async function GET() { + try { + const cookieStore = await cookies(); + const token = cookieStore.get('token')?.value; + + if (!token) { + return NextResponse.json({ error: 'Not authenticated' }, { status: 401 }); + } + + const decoded = jwt.verify(token, JWT_SECRET) as any; + + return NextResponse.json({ + user: { + id: decoded.userId, + name: decoded.name, + role: decoded.role, + } + }); + } catch (error) { + return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); + } +} diff --git a/src/app/api/auth/reset-password/route.ts b/src/app/api/auth/reset-password/route.ts new file mode 100644 index 0000000..3f2e1cd --- /dev/null +++ b/src/app/api/auth/reset-password/route.ts @@ -0,0 +1,63 @@ +import { NextResponse } from 'next/server'; +import dbConnect from '@/lib/mongodb'; +import User from '@/models/User'; +import crypto from 'crypto'; + +export async function POST(req: Request) { + try { + const { email } = await req.json(); + + await dbConnect(); + + const user = await User.findOne({ email }); + if (!user) { + return NextResponse.json({ error: 'User not found' }, { status: 404 }); + } + + const resetToken = crypto.randomBytes(32).toString('hex'); + const resetTokenExpire = new Date(Date.now() + 3600000); // 1 hour + + user.resetPasswordToken = resetToken; + user.resetPasswordExpires = resetTokenExpire; + await user.save(); + + // In a real app, you would send an email here using nodemailer + // console.log(`Reset token: ${resetToken}`); + + return NextResponse.json({ + message: 'Password reset link sent to your email (simulated)', + token: resetToken // Only returning for demonstration purposes + }); + } catch (error: any) { + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} + +export async function PUT(req: Request) { + try { + const { token, newPassword } = await req.json(); + + await dbConnect(); + + const user = await User.findOne({ + resetPasswordToken: token, + resetPasswordExpires: { $gt: Date.now() } + }); + + if (!user) { + return NextResponse.json({ error: 'Invalid or expired token' }, { status: 400 }); + } + + const bcrypt = require('bcryptjs'); + const hashedPassword = await bcrypt.hash(newPassword, 12); + + user.password = hashedPassword; + user.resetPasswordToken = undefined; + user.resetPasswordExpires = undefined; + await user.save(); + + return NextResponse.json({ message: 'Password has been reset successfully' }); + } catch (error: any) { + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} diff --git a/src/app/api/auth/signup/route.ts b/src/app/api/auth/signup/route.ts new file mode 100644 index 0000000..c8342d3 --- /dev/null +++ b/src/app/api/auth/signup/route.ts @@ -0,0 +1,33 @@ +import { NextResponse } from 'next/server'; +import dbConnect from '@/lib/mongodb'; +import User from '@/models/User'; +import bcrypt from 'bcryptjs'; + +export async function POST(req: Request) { + try { + const { name, email, password } = await req.json(); + + await dbConnect(); + + const existingUser = await User.findOne({ email }); + if (existingUser) { + return NextResponse.json({ error: 'Email already in use' }, { status: 400 }); + } + + const hashedPassword = await bcrypt.hash(password, 12); + + const user = await User.create({ + name, + email, + password: hashedPassword, + role: 'admin', // Default first user as admin + }); + + return NextResponse.json({ + message: 'User created successfully', + user: { id: user._id, name: user.name, email: user.email } + }, { status: 201 }); + } catch (error: any) { + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} diff --git a/src/app/auth/auth.module.css b/src/app/auth/auth.module.css new file mode 100644 index 0000000..20ca8eb --- /dev/null +++ b/src/app/auth/auth.module.css @@ -0,0 +1,218 @@ +.authPage { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: radial-gradient(circle at top left, rgba(113, 75, 103, 0.05) 0%, transparent 40%), + radial-gradient(circle at bottom right, rgba(1, 126, 132, 0.05) 0%, transparent 40%), + var(--bg-main); + padding: 2rem; +} + +.authCard { + width: 100%; + max-width: 440px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + border: 1px solid var(--glass-border); + padding: 3rem; + border-radius: 24px; + box-shadow: var(--shadow-lg); + display: flex; + flex-direction: column; + gap: 2rem; +} + +.logoSection { + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; +} + +.logoIcon { + width: 40px; + height: 40px; + background: white; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + color: var(--pk-primary); + font-weight: 800; + font-size: 1.25rem; + box-shadow: var(--shadow); +} + +.logoSection h1 { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-main); +} + +.logoSection h1 span { + font-weight: 400; + color: var(--text-muted); +} + +.header { + text-align: center; +} + +.header h2 { + font-size: 1.5rem; + color: var(--text-main); + margin-bottom: 0.5rem; +} + +.header p { + color: var(--text-muted); + font-size: 0.95rem; +} + +.errorMessage { + background: #fee2e2; + color: #b91c1c; + padding: 0.75rem 1rem; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 500; + border: 1px solid rgba(185, 28, 28, 0.1); +} + +.form { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.inputGroup { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.labelRow { + display: flex; + justify-content: space-between; + align-items: center; +} + +.inputGroup label { + font-size: 0.85rem; + font-weight: 600; + color: var(--text-main); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.forgotPass { + font-size: 0.8rem; + color: var(--pk-primary); + text-decoration: none; + font-weight: 600; +} + +.inputGroup input { + padding: 0.8rem 1rem; + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: var(--transition); + font-family: var(--font-sans); +} + +.inputGroup input:focus { + border-color: var(--pk-primary); + box-shadow: 0 0 0 4px rgba(113, 75, 103, 0.1); +} + +.submitBtn { + margin-top: 1rem; + padding: 1rem; + background: var(--pk-primary); + color: white; + border: none; + border-radius: 14px; + font-weight: 700; + font-size: 1rem; + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; + cursor: pointer; + transition: var(--transition); +} + +.successMessage { + background: #dcfce7; + color: #15803d; + padding: 0.75rem 1rem; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 500; + display: flex; + align-items: center; + gap: 0.5rem; + border: 1px solid rgba(21, 128, 61, 0.1); +} + +.backToLogin { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + margin-top: 1rem; + color: var(--text-muted); + text-decoration: none; + font-size: 0.9rem; + font-weight: 600; + transition: var(--transition); +} + +.backToLogin:hover { + color: var(--pk-primary); +} + +.submitBtn:hover:not(:disabled) { + background: var(--pk-primary-hover); + transform: translateY(-2px); + box-shadow: 0 10px 15px -3px rgba(113, 75, 103, 0.3); +} + +.submitBtn:disabled { + opacity: 0.7; + cursor: not-allowed; +} + +.spinner { + animation: rotate 1s linear infinite; +} + +@keyframes rotate { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +.switchAuth { + text-align: center; + font-size: 0.9rem; + color: var(--text-muted); +} + +.switchAuth a { + color: var(--pk-primary); + text-decoration: none; + font-weight: 700; +} + +.switchAuth a:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx new file mode 100644 index 0000000..458dc7a --- /dev/null +++ b/src/app/auth/login/page.tsx @@ -0,0 +1,98 @@ +"use client"; + +import React, { useState } from 'react'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { LogIn, Mail, Lock, Loader2 } from 'lucide-react'; +import { setCookie } from 'cookies-next'; +import styles from '../auth.module.css'; + +export default function LoginPage() { + const [formData, setFormData] = useState({ email: '', password: '' }); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const router = useRouter(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + + try { + const res = await fetch('http://localhost:5000/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(formData), + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Login failed'); + + // Set token in cookies for the frontend to use + setCookie('auth_token', data.token, { maxAge: 86400, path: '/' }); + + // Store user info in localStorage for quick access + localStorage.setItem('user', JSON.stringify(data.user)); + + router.push('/'); + router.refresh(); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + return ( +
+
+
+
O
+

OdooNext

+
+ +
+

Welcome Back

+

Login to manage your business

+
+ + {error &&
{error}
} + +
+
+ + setFormData({ ...formData, email: e.target.value })} + /> +
+ +
+
+ + Forgot? +
+ setFormData({ ...formData, password: e.target.value })} + /> +
+ + +
+ +

+ Don't have an account? Sign Up +

+
+
+ ); +} diff --git a/src/app/auth/reset-password/page.tsx b/src/app/auth/reset-password/page.tsx new file mode 100644 index 0000000..af43946 --- /dev/null +++ b/src/app/auth/reset-password/page.tsx @@ -0,0 +1,160 @@ +"use client"; + +import React, { useState, useEffect, Suspense } from 'react'; +import Link from 'next/link'; +import { useSearchParams, useRouter } from 'next/navigation'; +import { Mail, Loader2, ArrowLeft, ShieldCheck, Lock } from 'lucide-react'; +import styles from '../auth.module.css'; + +function ResetPasswordForm() { + const searchParams = useSearchParams(); + const router = useRouter(); + const token = searchParams.get('token'); + + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [loading, setLoading] = useState(false); + const [message, setMessage] = useState(''); + const [error, setError] = useState(''); + + // If no token, we show the "Forgot Password" (request link) UI + // If token exists, we show the "Set New Password" UI + const isResetting = !!token; + + const handleRequestLink = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + setMessage(''); + + try { + const res = await fetch('http://localhost:5000/api/auth/forgot-password', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email }), + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Failed to send reset link'); + + setMessage(data.message); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + const handleResetPassword = async (e: React.FormEvent) => { + e.preventDefault(); + if (password !== confirmPassword) { + setError('Passwords do not match'); + return; + } + + setLoading(true); + setError(''); + setMessage(''); + + try { + const res = await fetch('http://localhost:5000/api/auth/reset-password', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ token, password }), + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Reset failed'); + + setMessage('Password reset successful! Redirecting to login...'); + setTimeout(() => router.push('/auth/login'), 2000); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + return ( +
+
+
+
O
+

OdooNext

+
+ +
+

{isResetting ? 'Set New Password' : 'Reset Password'}

+

{isResetting ? 'Enter your new password below' : "We'll send you a link to get back into your account"}

+
+ + {error &&
{error}
} + {message && ( +
+ + {message} +
+ )} + + {!isResetting ? ( +
+
+ + setEmail(e.target.value)} + /> +
+ + +
+ ) : ( +
+
+ + setPassword(e.target.value)} + /> +
+
+ + setConfirmPassword(e.target.value)} + /> +
+ + +
+ )} + + + Back to Login + +
+
+ ); +} + +export default function ResetPasswordPage() { + return ( + Loading...}> + + + ); +} diff --git a/src/app/auth/signup/page.tsx b/src/app/auth/signup/page.tsx new file mode 100644 index 0000000..91a2af1 --- /dev/null +++ b/src/app/auth/signup/page.tsx @@ -0,0 +1,104 @@ +"use client"; + +import React, { useState } from 'react'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { UserPlus, Mail, Lock, User as UserIcon, Loader2 } from 'lucide-react'; +import { setCookie } from 'cookies-next'; +import styles from '../auth.module.css'; + +export default function SignupPage() { + const [formData, setFormData] = useState({ name: '', email: '', password: '' }); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const router = useRouter(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + + try { + const res = await fetch('http://localhost:5000/api/auth/signup', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(formData), + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Signup failed'); + + // Set token and user data similar to login + setCookie('auth_token', data.token, { maxAge: 86400, path: '/' }); + localStorage.setItem('user', JSON.stringify(data.user)); + + router.push('/'); + router.refresh(); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + return ( +
+
+
+
O
+

OdooNext

+
+ +
+

Create Account

+

Get started with your free ERP trial

+
+ + {error &&
{error}
} + +
+
+ + setFormData({ ...formData, name: e.target.value })} + /> +
+ +
+ + setFormData({ ...formData, email: e.target.value })} + /> +
+ +
+ + setFormData({ ...formData, password: e.target.value })} + /> +
+ + +
+ +

+ Already have an account? Login +

+
+
+ ); +} diff --git a/src/app/crm/crm.module.css b/src/app/crm/crm.module.css new file mode 100644 index 0000000..bdc3c35 --- /dev/null +++ b/src/app/crm/crm.module.css @@ -0,0 +1,151 @@ +.kanbanBoard { + display: flex; + gap: 1.5rem; + height: calc(100vh - 180px); + overflow-x: auto; + padding-bottom: 1rem; +} + +.column { + min-width: 300px; + max-width: 300px; + background: #f1f5f9; + border-radius: 12px; + display: flex; + flex-direction: column; +} + +.columnHeader { + padding: 1rem; + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.columnTitle { + display: flex; + align-items: center; + justify-content: space-between; +} + +.columnName { + font-weight: 700; + color: #1e293b; + font-size: 0.95rem; + text-transform: uppercase; + letter-spacing: 0.025em; +} + +.columnBadge { + background: #cbd5e1; + color: #475569; + font-size: 0.75rem; + padding: 0.1rem 0.5rem; + border-radius: 999px; + font-weight: 600; +} + +.columnTotal { + font-size: 0.85rem; + color: #64748b; + font-weight: 500; +} + +.columnContent { + flex: 1; + padding: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.75rem; + overflow-y: auto; +} + +.card { + background: white; + border-radius: 8px; + padding: 0.75rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border: 1px solid transparent; + transition: var(--transition); + cursor: grab; +} + +.card:hover { + border-color: var(--pk-primary); + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +.cardHeader { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 0.5rem; +} + +.cardTitle { + font-weight: 600; + color: #1e293b; + font-size: 0.9rem; + line-height: 1.25; +} + +.cardActions { + color: #94a3b8; + cursor: pointer; +} + +.companyName { + font-size: 0.8rem; + color: #64748b; + margin-bottom: 0.75rem; +} + +.cardFooter { + display: flex; + justify-content: space-between; + align-items: center; +} + +.cardValue { + font-weight: 700; + color: var(--pk-secondary); + font-size: 0.85rem; +} + +.priority { + display: flex; + gap: 2px; +} + +.star { + color: #e2e8f0; + font-size: 14px; +} + +.starActive { + color: #f59e0b; + font-size: 14px; +} + +.addCardBtn { + width: 100%; + padding: 0.6rem; + background: transparent; + border: 1px dashed #cbd5e1; + border-radius: 8px; + color: #64748b; + font-size: 0.85rem; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.addCardBtn:hover { + background: white; + color: var(--pk-primary); + border-color: var(--pk-primary); +} \ No newline at end of file diff --git a/src/app/crm/page.tsx b/src/app/crm/page.tsx new file mode 100644 index 0000000..b8151aa --- /dev/null +++ b/src/app/crm/page.tsx @@ -0,0 +1,105 @@ +"use client"; + +import React from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Users, + LayoutDashboard, + Calendar, + MessageSquare, + MoreVertical, + Plus +} from 'lucide-react'; +import styles from './crm.module.css'; + +const sidebarItems = [ + { icon: , label: 'Dashboard' }, + { icon: , label: 'Pipelines', active: true }, + { icon: , label: 'Activities' }, + { icon: , label: 'Leads' }, +]; + +const kanbanColumns = [ + { + id: 'new', + name: 'New', + count: 3, + total: '$ 12,500', + items: [ + { id: '1', title: 'Plan for new office', company: 'Azure Interior', value: '$ 5,000', priority: 2 }, + { id: '2', title: 'Consultation for kitchen', company: 'Deco Addict', value: '$ 2,500', priority: 1 }, + { id: '3', title: 'Interior design project', company: 'Ready Mat', value: '$ 5,000', priority: 3 }, + ] + }, + { + id: 'qualified', + name: 'Qualified', + count: 2, + total: '$ 45,000', + items: [ + { id: '4', title: 'Full house renovation', company: 'Gemini Corp', value: '$ 30,000', priority: 3 }, + { id: '5', title: 'Office furniture setup', company: 'The Corner', value: '$ 15,000', priority: 2 }, + ] + }, + { + id: 'proposition', + name: 'Proposition', + count: 1, + total: '$ 8,000', + items: [ + { id: '6', title: 'Smart home automation', company: 'Lumiere', value: '$ 8,000', priority: 3 }, + ] + }, + { + id: 'won', + name: 'Won', + count: 0, + total: '$ 0', + items: [] + }, +]; + +export default function CRMPage() { + return ( + +
+ {kanbanColumns.map((column) => ( +
+
+
+ {column.name} + {column.count} +
+
{column.total}
+
+ +
+ {column.items.map((item) => ( +
+
+ {item.title} + +
+
+
{item.company}
+
+
{item.value}
+
+ {[...Array(3)].map((_, i) => ( + + ))} +
+
+
+
+ ))} + +
+
+ ))} +
+
+ ); +} diff --git a/src/app/dashboard/dashboard.module.css b/src/app/dashboard/dashboard.module.css new file mode 100644 index 0000000..56bb3d8 --- /dev/null +++ b/src/app/dashboard/dashboard.module.css @@ -0,0 +1,180 @@ +.dashboardGrid { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.kpiRow { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; +} + +.kpiCard { + background: white; + padding: 1.5rem; + border-radius: 16px; + border: 1px solid #e2e8f0; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); + transition: var(--transition); +} + +.kpiCard:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-lg); +} + +.kpiHeader { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 1rem; +} + +.kpiIcon { + width: 48px; + height: 48px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; +} + +.change { + display: flex; + align-items: center; + gap: 0.25rem; + font-size: 0.85rem; + font-weight: 700; + padding: 0.25rem 0.5rem; + border-radius: 6px; +} + +.up { + background: #dcfce7; + color: #15803d; +} + +.down { + background: #fee2e2; + color: #b91c1c; +} + +.kpiValue { + font-size: 2rem; + font-weight: 800; + color: #1e293b; + margin-bottom: 0.25rem; + font-family: var(--font-heading); +} + +.kpiLabel { + color: #64748b; + font-weight: 500; + font-size: 0.95rem; +} + +.contentRow { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 1.5rem; +} + +.sectionHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.sectionHeader h3 { + font-size: 1.1rem; + font-weight: 700; + color: #1e293b; +} + +.moreBtn { + background: none; + border: none; + color: #94a3b8; + cursor: pointer; +} + +.chartSection, +.activitySection { + background: white; + padding: 1.5rem; + border-radius: 16px; + border: 1px solid #e2e8f0; +} + +.chartPlaceholder { + height: 250px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.svgChart { + width: 100%; + height: 180px; +} + +.chartLabels { + display: flex; + justify-content: space-between; + color: #94a3b8; + font-size: 0.8rem; + font-weight: 500; + padding: 0 10px; +} + +.activityList { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.activityItem { + display: flex; + align-items: center; + gap: 1rem; +} + +.activityUser { + width: 36px; + height: 36px; + background: #f1f5f9; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + color: var(--pk-primary); + font-size: 0.8rem; +} + +.activityInfo { + flex: 1; +} + +.activityInfo p { + font-size: 0.9rem; + color: #1e293b; +} + +.activityInfo span { + font-size: 0.8rem; + color: #64748b; +} + +.activityTime { + font-size: 0.75rem; + color: #94a3b8; +} + +@media (max-width: 1024px) { + .contentRow { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx new file mode 100644 index 0000000..f17ef24 --- /dev/null +++ b/src/app/dashboard/page.tsx @@ -0,0 +1,116 @@ +"use client"; + +import React from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + TrendingUp, + Users, + ShoppingCart, + DollarSign, + ArrowUpRight, + ArrowDownRight, + Clock, + MoreVertical +} from 'lucide-react'; +import styles from './dashboard.module.css'; + +const sidebarItems = [ + { icon: , label: 'Overview', active: true }, + { icon: , label: 'Analytics' }, + { icon: , label: 'History' }, +]; + +const kpis = [ + { label: 'Total Revenue', value: '$ 124,500', change: '+12.5%', isUp: true, icon: , color: '#714B67' }, + { label: 'Sales Orders', value: '1,420', change: '+8.2%', isUp: true, icon: , color: '#017E84' }, + { label: 'New Customers', value: '384', change: '-2.4%', isUp: false, icon: , color: '#4B7BEC' }, +]; + +const activities = [ + { id: 1, user: 'James Doe', action: 'Confirmed Sales Order', detail: 'S00042', time: '2 mins ago' }, + { id: 2, user: 'Alice Smith', action: 'Created New Lead', detail: 'Azure Interior', time: '15 mins ago' }, + { id: 3, user: 'System', action: 'Inventory Alert', detail: 'Low stock on Office Chair', time: '1 hour ago' }, + { id: 4, user: 'Bob Wilson', action: 'Payment Received', detail: '$ 450.00 from Deco Addict', time: '3 hours ago' }, +]; + +export default function DashboardPage() { + return ( + +
+ {/* KPI Row */} +
+ {kpis.map((kpi, idx) => ( +
+
+
+ {kpi.icon} +
+
+ {kpi.isUp ? : } + {kpi.change} +
+
+
{kpi.value}
+
{kpi.label}
+
+ ))} +
+ + {/* Charts & Reports */} +
+
+
+

Revenue Growth

+ +
+
+ {/* Fake Chart SVG */} + + + + + + + + + + +
+ JanFebMarAprMayJun +
+
+
+ +
+
+

Recent Activity

+ +
+
+ {activities.map(activity => ( +
+
{activity.user[0]}
+
+

{activity.user} {activity.action}

+ {activity.detail} +
+
{activity.time}
+
+ ))} +
+
+
+
+
+ ); +} diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/src/app/favicon.ico differ diff --git a/src/app/financials/financials.module.css b/src/app/financials/financials.module.css new file mode 100644 index 0000000..3211d81 --- /dev/null +++ b/src/app/financials/financials.module.css @@ -0,0 +1,269 @@ +.container { + display: flex; + flex-direction: column; + gap: 2.5rem; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.titleArea h2 { + font-size: 1.75rem; + font-weight: 800; + color: #1e293b; +} + +.titleArea p { + color: #64748b; + font-size: 1rem; +} + +.headerActions { + display: flex; + gap: 1rem; +} + +.dateSelector, +.exportBtn { + padding: 0.75rem 1.25rem; + border-radius: 12px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.dateSelector { + background: white; + border: 1px solid #e2e8f0; + color: #1e293b; +} + +.exportBtn { + background: #1e293b; + color: white; + border: none; +} + +.metricsGrid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 1.5rem; +} + +.metricCard { + background: white; + padding: 1.5rem; + border-radius: 20px; + border: 1px solid #e2e8f0; + display: flex; + flex-direction: column; + gap: 0.75rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.metricLabel { + font-size: 0.85rem; + font-weight: 700; + color: #64748b; + text-transform: uppercase; + letter-spacing: 0.025em; +} + +.metricMain { + display: flex; + align-items: baseline; + justify-content: space-between; +} + +.metricValue { + font-size: 1.75rem; + font-weight: 800; + color: #1e293b; + font-family: var(--font-heading); +} + +.badge { + display: flex; + align-items: center; + gap: 0.25rem; + font-size: 0.75rem; + font-weight: 700; + padding: 4px 8px; + border-radius: 999px; +} + +.up { + background: #dcfce7; + color: #15803d; +} + +.down { + background: #fee2e2; + color: #b91c1c; +} + +.miniChart { + width: 100%; + height: 6px; + background: #f1f5f9; + border-radius: 10px; + overflow: hidden; + margin-top: 0.5rem; +} + +.progress { + height: 100%; + border-radius: 10px; +} + +.contentRow { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 2rem; +} + +.chartCard, +.topItemsCard { + background: white; + padding: 2rem; + border-radius: 24px; + border: 1px solid #e2e8f0; +} + +.sectionHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 2rem; +} + +.sectionHeader h3 { + font-size: 1.1rem; + font-weight: 800; + color: #1e293b; +} + +.legend { + display: flex; + gap: 1rem; + font-size: 0.8rem; + font-weight: 700; +} + +.revenueL::before { + content: ''; + display: inline-block; + width: 10px; + height: 10px; + background: #714b67; + border-radius: 50%; + margin-right: 6px; +} + +.costL::before { + content: ''; + display: inline-block; + width: 10px; + height: 10px; + background: #ef4444; + border-radius: 50%; + margin-right: 6px; +} + +.visualPlaceholder { + height: 250px; + display: flex; + flex-direction: column; +} + +.svgChart { + flex: 1; +} + +.chartLabels { + display: flex; + justify-content: space-between; + color: #94a3b8; + font-size: 0.75rem; + font-weight: 700; + padding: 1rem 0 0 0; +} + +.itemsList { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.itemRow { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 1rem; + border-bottom: 1px solid #f1f5f9; +} + +.itemInfo { + display: flex; + flex-direction: column; +} + +.itemInfo strong { + font-size: 0.95rem; + color: #1e293b; +} + +.itemInfo span { + font-size: 0.8rem; + color: #64748b; +} + +.itemStats { + display: flex; + flex-direction: column; + text-align: right; +} + +.itemRevenue { + font-weight: 800; + color: #1e293b; +} + +.itemMargin { + font-size: 0.75rem; + color: #10b981; + font-weight: 700; +} + +.viewDetailed { + margin-top: 2rem; + width: 100%; + padding: 1rem; + background: #f8fafc; + border: 1px solid #e2e8f0; + border-radius: 12px; + font-weight: 700; + color: var(--pk-primary); + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.viewDetailed:hover { + background: #f1f5f9; +} + +@media (max-width: 1024px) { + .contentRow { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/src/app/financials/page.tsx b/src/app/financials/page.tsx new file mode 100644 index 0000000..e1f59ea --- /dev/null +++ b/src/app/financials/page.tsx @@ -0,0 +1,119 @@ +"use client"; + +import React from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + DollarSign, + TrendingUp, + TrendingDown, + PieChart, + Calendar, + Filter, + Download, + ArrowUpRight, + ArrowDownRight, + ChevronRight, + LayoutDashboard, + Wallet +} from 'lucide-react'; +import styles from './financials.module.css'; + +const sidebarItems = [ + { icon: , label: 'Dashboard' }, + { icon: , label: 'Financial Reports', active: true }, +]; + +const metrics = [ + { label: 'Total Revenue', value: '$ 42,850', sub: '+18% vs last month', isUp: true, color: '#017e84' }, + { label: 'Ingredient Costs', value: '$ 12,400', sub: '+5% vs last month', isUp: false, color: '#ef4444' }, + { label: 'Net Profit', value: '$ 30,450', sub: '+24% vs last month', isUp: true, color: '#714b67' }, + { label: 'Avg. Check', value: '$ 64.20', sub: '-2% vs last week', isUp: false, color: '#f59e0b' }, +]; + +const topItems = [ + { name: 'Classic Burger', sales: 450, revenue: '$ 5,845', margin: '65%' }, + { name: 'Margherita Pizza', sales: 320, revenue: '$ 4,640', margin: '72%' }, + { name: 'Caesar Salad', sales: 210, revenue: '$ 1,680', margin: '80%' }, +]; + +export default function FinancialsPage() { + return ( + +
+
+
+

Profit & Loss Insights

+

Real-time financial performance and cost analysis

+
+
+ + +
+
+ + {/* Metrics Grid */} +
+ {metrics.map((m, idx) => ( +
+ {m.label} +
+ {m.value} +
+ {m.isUp ? : } + {m.sub.split(' ')[0]} +
+
+
+
+
+
+ ))} +
+ +
+ {/* Sales vs Cost Chart Placeholder */} +
+
+

Revenue vs. Ingredient Cost

+
+ Revenue + Cost +
+
+
+ + + + +
+ W1W2W3W4 +
+
+
+ + {/* Top Products Margin */} +
+
+

High Margin Items

+
+
+ {topItems.map((item, idx) => ( +
+
+ {item.name} + {item.sales} sold +
+
+ {item.revenue} + {item.margin} Margin +
+
+ ))} +
+ +
+
+
+
+ ); +} diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..a17e318 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,127 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@300;400;500;600;700;800&display=swap'); + +:root { + --font-sans: 'Inter', system-ui, -apple-system, sans-serif; + --font-heading: 'Outfit', sans-serif; + + /* Premium Palette */ + --pk-primary: #714b67; + --pk-primary-hover: #5d3d53; + --pk-secondary: #017e84; + --pk-accent: #e91e63; + + --bg-main: #f0f2f5; + --bg-card: rgba(255, 255, 255, 0.8); + --bg-sidebar: #2c3e50; + + --text-main: #1a1a1a; + --text-muted: #64748b; + --text-on-dark: #f8fafc; + + --border-radius: 12px; + --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + + /* Glassmorphism */ + --glass-bg: rgba(255, 255, 255, 0.7); + --glass-border: rgba(255, 255, 255, 0.3); + --glass-blur: blur(12px); +} + +[data-theme='dark'] { + --bg-main: #0f172a; + --bg-card: rgba(30, 41, 59, 0.7); + --text-main: #f8fafc; + --text-muted: #94a3b8; + --glass-bg: rgba(15, 23, 42, 0.7); + --glass-border: rgba(255, 255, 255, 0.1); +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +body { + font-family: var(--font-sans); + background: var(--bg-main); + color: var(--text-main); + -webkit-font-smoothing: antialiased; + overflow-x: hidden; + min-height: 100vh; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: var(--font-heading); + font-weight: 700; +} + +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: #cbd5e1; + border-radius: 10px; +} + +::-webkit-scrollbar-thumb:hover { + background: #94a3b8; +} + +/* Animations */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(1.05); + } + + 100% { + transform: scale(1); + } +} + +.animate-fade-in { + animation: fadeIn 0.5s ease-out forwards; +} + +/* Utility Classes */ +.glass { + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + border: 1px solid var(--glass-border); +} + +.gradient-text { + background: linear-gradient(135deg, var(--pk-primary), var(--pk-secondary)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} \ No newline at end of file diff --git a/src/app/inventory/inventory.module.css b/src/app/inventory/inventory.module.css new file mode 100644 index 0000000..4741f92 --- /dev/null +++ b/src/app/inventory/inventory.module.css @@ -0,0 +1,230 @@ +.inventoryContainer { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.statsRow { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} + +.statCard { + background: white; + padding: 1.5rem; + border-radius: 16px; + border: 1px solid #e2e8f0; + display: flex; + align-items: center; + gap: 1rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.statIcon { + width: 48px; + height: 48px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; +} + +.statInfo { + display: flex; + flex-direction: column; +} + +.statLabel { + font-size: 0.85rem; + color: #64748b; + font-weight: 600; +} + +.statValue { + font-size: 1.25rem; + font-weight: 800; + color: #1e293b; +} + +.toolbar { + display: flex; + justify-content: space-between; + align-items: center; + gap: 2rem; +} + +.searchWrapper { + flex: 1; + position: relative; + max-width: 500px; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; +} + +.searchWrapper input { + width: 100%; + padding: 0.75rem 1rem 0.75rem 2.5rem; + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: var(--transition); +} + +.searchWrapper input:focus { + border-color: var(--pk-primary); + box-shadow: 0 0 0 4px rgba(113, 75, 103, 0.1); +} + +.toolActions { + display: flex; + gap: 0.75rem; +} + +.filterBtn, +.addBtn { + padding: 0.75rem 1.25rem; + border-radius: 10px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.filterBtn { + background: white; + color: #475569; + border: 1px solid #e2e8f0; +} + +.addBtn { + background: var(--pk-primary); + color: white; + border: none; +} + +.stockList { + background: white; + border-radius: 20px; + border: 1px solid #e2e8f0; + overflow: hidden; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); +} + +.listHeader { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr 1fr 0.5fr; + padding: 1rem 1.5rem; + background: #f8fafc; + color: #64748b; + font-weight: 700; + font-size: 0.85rem; + border-bottom: 1px solid #e2e8f0; +} + +.listBody { + display: flex; + flex-direction: column; +} + +.listItem { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr 1fr 0.5fr; + padding: 1.25rem 1.5rem; + align-items: center; + border-bottom: 1px solid #f1f5f9; + transition: var(--transition); + cursor: pointer; +} + +.listItem:hover { + background: #f8fafc; +} + +.itemName { + display: flex; + align-items: center; + gap: 1rem; + font-weight: 700; + color: #1e293b; +} + +.itemIcon { + width: 32px; + height: 32px; + background: #f1f5f9; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + color: var(--pk-primary); + font-weight: 800; + font-size: 0.75rem; +} + +.itemCategory { + color: #64748b; + font-size: 0.9rem; +} + +.itemQty, +.itemMin { + font-weight: 600; + font-size: 0.9rem; +} + +.statusBadge { + padding: 0.25rem 0.75rem; + border-radius: 999px; + font-size: 0.75rem; + font-weight: 700; +} + +.instock { + background: #dcfce7; + color: #15803d; +} + +.lowstock { + background: #fef9c3; + color: #854d0e; +} + +.outofstock { + background: #fee2e2; + color: #b91c1c; +} + +.actions { + display: flex; + align-items: center; + gap: 1rem; + color: #94a3b8; +} + +.actionBtn { + background: none; + border: none; + color: inherit; + cursor: pointer; +} + +.arrow { + opacity: 0; + transition: var(--transition); + transform: translateX(-5px); +} + +.listItem:hover .arrow { + opacity: 1; + transform: translateX(0); +} \ No newline at end of file diff --git a/src/app/inventory/page.tsx b/src/app/inventory/page.tsx new file mode 100644 index 0000000..8b6b4c4 --- /dev/null +++ b/src/app/inventory/page.tsx @@ -0,0 +1,116 @@ +"use client"; + +import React, { useState } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Package, + AlertTriangle, + TrendingDown, + TrendingUp, + Plus, + Search, + Filter, + BarChart2, + RefreshCw, + MoreVertical, + ChevronRight +} from 'lucide-react'; +import styles from './inventory.module.css'; + +const sidebarItems = [ + { icon: , label: 'Stock Levels', active: true }, + { icon: , label: 'Incoming Orders' }, + { icon: , label: 'Forecast' }, + { icon: , label: 'Valuation' }, +]; + +const mockItems = [ + { id: 1, name: 'Burger Buns', category: 'Bread', quantity: 150, unit: 'pcs', minLevel: 50, status: 'In Stock' }, + { id: 2, name: 'Beef Patties', category: 'Meat', quantity: 24, unit: 'kg', minLevel: 30, status: 'Low Stock' }, + { id: 3, name: 'Cooking Oil', category: 'Pantry', quantity: 0, unit: 'L', minLevel: 10, status: 'Out of Stock' }, + { id: 4, name: 'Cheddar Cheese', category: 'Dairy', quantity: 45, unit: 'kg', minLevel: 20, status: 'In Stock' }, + { id: 5, name: 'Potatoes', category: 'Vegetables', quantity: 200, unit: 'kg', minLevel: 100, status: 'In Stock' }, + { id: 6, name: 'Ketchup', category: 'Pantry', quantity: 12, unit: 'L', minLevel: 15, status: 'Low Stock' }, +]; + +export default function InventoryPage() { + const [search, setSearch] = useState(''); + + const stats = [ + { label: 'Total Valuation', value: '$ 12,450', icon: , color: '#714B67' }, + { label: 'Low Stock Items', value: '4 Assets', icon: , color: '#f59e0b' }, + { label: 'Out of Stock', value: '2 Items', icon: , color: '#ef4444' }, + ]; + + return ( + +
+ {/* Stats Row */} +
+ {stats.map((stat, idx) => ( +
+
+ {stat.icon} +
+
+ {stat.label} + {stat.value} +
+
+ ))} +
+ + {/* Toolbar */} +
+
+ + setSearch(e.target.value)} + /> +
+
+ + +
+
+ + {/* Inventory List */} +
+
+ Item Name + Category + On Hand + Min. Level + Status + Action +
+
+ {mockItems.map(item => ( +
+
+
{item.name[0]}
+ {item.name} +
+ {item.category} + {item.quantity} {item.unit} + {item.minLevel} {item.unit} +
+ + {item.status} + +
+
+ + +
+
+ ))} +
+
+
+
+ ); +} diff --git a/src/app/kitchen/page.tsx b/src/app/kitchen/page.tsx new file mode 100644 index 0000000..ecb9ee0 --- /dev/null +++ b/src/app/kitchen/page.tsx @@ -0,0 +1,152 @@ +"use client"; + +import React, { useState, useEffect } from 'react'; +import { ChefHat, Clock, CheckCircle, Check, RotateCcw, Truck } from 'lucide-react'; + +interface OrderItem { + productId: number; + name: string; + qty: number; + modifiers: string[]; +} + +interface Order { + _id: string; + tableName: string; + items: OrderItem[]; + status: 'KITCHEN' | 'READY' | 'SERVED'; + createdAt: string; + elapsed?: string; +} + +export default function KitchenPage() { + const [orders, setOrders] = useState([]); + + const fetchOrders = async () => { + try { + const res = await fetch('http://localhost:5000/api/pos/orders/kitchen'); + if (res.ok) { + const data = await res.json(); + setOrders(data); + } + } catch (e) { + console.error("Fetch kitchen error", e); + } + }; + + useEffect(() => { + fetchOrders(); + const interval = setInterval(fetchOrders, 10000); // Poll every 10s + return () => clearInterval(interval); + }, []); + + const updateStatus = async (id: string, status: string) => { + try { + await fetch(`http://localhost:5000/api/pos/orders/${id}/status`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ status }) + }); + fetchOrders(); + } catch (error) { + console.error("Update status error", error); + } + }; + + const getStatusColor = (status: string) => { + switch (status) { + case 'KITCHEN': return '#f59e0b'; + case 'READY': return '#10b981'; + case 'SERVED': return '#3b82f6'; + default: return '#64748b'; + } + }; + + return ( +
+
+
+ +
+

KITCHEN DISPLAY SYSTEM

+ Live Orders +
+
+
+
+ {orders.filter(o => o.status === 'KITCHEN').length} + Pending +
+
+ {orders.filter(o => o.status === 'READY').length} + Ready +
+
+
+ +
+ {orders.length === 0 && ( +
+ +

No Active Orders

+

Waiting for new orders from POS...

+
+ )} + {orders.map(order => ( +
+
+ {order.tableName} +
+ + {new Date(order.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} +
+
+
+
+ {order.items.map((item, idx) => ( +
+
+ {item.qty}x +
+ {item.name} + {item.modifiers && item.modifiers.length > 0 && ( + {item.modifiers.join(', ')} + )} +
+
+
+ ))} +
+
+
+ {order.status === 'KITCHEN' && ( + + )} + {order.status === 'READY' && ( + + )} + {order.status === 'SERVED' && ( + + )} +
+
+ ))} +
+
+ ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..9232e86 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,23 @@ +import type { Metadata } from "next"; +import "./globals.css"; + +export const metadata: Metadata = { + title: "Dine360 - Premium ERP", + description: "Dine360 - Premium ERP", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + +
+ {children} +
+ + + ); +} diff --git a/src/app/page.module.css b/src/app/page.module.css new file mode 100644 index 0000000..3b4d5b7 --- /dev/null +++ b/src/app/page.module.css @@ -0,0 +1,288 @@ +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + padding: 2rem; + position: relative; + overflow: hidden; + background-color: var(--bg-main); +} + +.bgGlow1 { + position: absolute; + top: -10%; + left: -10%; + width: 40%; + height: 40%; + background: radial-gradient(circle, rgba(113, 75, 103, 0.1) 0%, transparent 70%); + filter: blur(80px); + pointer-events: none; +} + +.bgGlow2 { + position: absolute; + bottom: -10%; + right: -10%; + width: 40%; + height: 40%; + background: radial-gradient(circle, rgba(1, 126, 132, 0.1) 0%, transparent 70%); + filter: blur(80px); + pointer-events: none; +} + +.header { + width: 100%; + max-width: 1200px; + margin: 0 auto 3rem auto; + display: flex; + align-items: center; + justify-content: space-between; + animation: fadeIn 0.8s ease-out; +} + +.logoArea { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.logoIcon { + width: 42px; + height: 42px; + background: white; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + box-shadow: var(--shadow); + color: var(--pk-primary); + font-weight: 800; + font-size: 1.5rem; +} + +.logoTitle { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-main); +} + +.logoSubtitle { + font-weight: 400; + color: var(--text-muted); +} + +.searchWrapper { + flex: 1; + max-width: 400px; + margin: 0 2rem; + position: relative; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + width: 18px; + height: 18px; + color: var(--text-muted); +} + +.searchInput { + width: 100%; + padding: 0.75rem 1rem 0.75rem 2.5rem; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + border: 1px solid var(--glass-border); + border-radius: 14px; + outline: none; + transition: var(--transition); + color: var(--text-main); +} + +.searchInput:focus { + border-color: var(--pk-primary); + box-shadow: 0 0 0 4px rgba(113, 75, 103, 0.1); +} + +.actions { + display: flex; + align-items: center; + gap: 1rem; +} + +.iconBtn { + background: none; + border: none; + padding: 0.5rem; + color: var(--text-muted); + cursor: pointer; + border-radius: 50%; + transition: var(--transition); + position: relative; +} + +.iconBtn:hover { + background: rgba(0, 0, 0, 0.05); + color: var(--text-main); +} + +.badge { + position: absolute; + top: 6px; + right: 6px; + width: 8px; + height: 8px; + background: var(--pk-accent); + border-radius: 50%; + border: 2px solid var(--bg-main); +} + +.userSection { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.userAvatar { + width: 38px; + height: 38px; + border-radius: 50%; + background: linear-gradient(135deg, var(--pk-primary), var(--pk-secondary)); + color: white; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 600; + border: 2px solid white; + box-shadow: var(--shadow); + cursor: pointer; +} + +.logoutBtn { + background: none; + border: none; + padding: 0.5rem; + color: var(--text-muted); + cursor: pointer; + border-radius: 50%; + transition: var(--transition); + display: flex; + align-items: center; + justify-content: center; +} + +.logoutBtn:hover { + background: rgba(231, 76, 60, 0.1); + color: #e74c3c; +} + +.loginBtn { + padding: 0.6rem 1.2rem; + background: var(--pk-primary); + color: white; + border-radius: 10px; + text-decoration: none; + font-weight: 600; + font-size: 0.9rem; + transition: var(--transition); + box-shadow: var(--shadow); +} + +.loginBtn:hover { + transform: translateY(-2px); + filter: brightness(1.1); +} + +.mainGrid { + width: 100%; + max-width: 1200px; + margin: 0 auto; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + gap: 2.5rem; + padding: 1rem; +} + +.appItem { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.75rem; + text-decoration: none; + color: inherit; + cursor: pointer; + transition: var(--transition); +} + +.appIconWrapper { + width: 84px; + height: 84px; + border-radius: 22px; + display: flex; + align-items: center; + justify-content: center; + color: white; + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); + box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.1); +} + +.appItem:hover .appIconWrapper { + transform: translateY(-8px) scale(1.05) rotate(2deg); + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); +} + +.appName { + font-weight: 600; + color: var(--text-main); + font-size: 0.95rem; + text-align: center; +} + +.footerActions { + position: fixed; + bottom: 2rem; + right: 2rem; + display: flex; + gap: 0.5rem; + padding: 0.5rem; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + border: 1px solid var(--glass-border); + border-radius: 18px; + box-shadow: var(--shadow-lg); +} + +.footerBtn { + background: none; + border: none; + padding: 0.75rem; + border-radius: 12px; + color: var(--text-muted); + cursor: pointer; + transition: var(--transition); +} + +.footerBtn:hover { + background: rgba(0, 0, 0, 0.05); + color: var(--pk-primary); +} + +@media (max-width: 768px) { + .header { + flex-direction: column; + gap: 1.5rem; + } + + .searchWrapper { + max-width: 100%; + margin: 0; + } + + .mainGrid { + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; + } +} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..345e606 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,184 @@ +"use client"; + +import React, { useState, useEffect } from 'react'; +import { + BarChart3, + MessageSquare, + Users, + ShoppingCart, + Package, + Settings, + Search, + Grid, + Bell, + Calendar, + LayoutDashboard, + Wallet, + Building2, + Cpu, + Utensils, + LogOut +} from 'lucide-react'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { deleteCookie, getCookie } from 'cookies-next'; +import styles from './page.module.css'; + +// Restaurant-focused modules only +const apps = [ + { id: 'restaurant', name: 'Restaurant', icon: , color: '#F1C40F' }, + { id: 'pos', name: 'POS', icon: , color: '#27AE60' }, + { id: 'inventory', name: 'Inventory', icon: , color: '#786FA6' }, + { id: 'accounting', name: 'Accounting', icon: , color: '#546DE5' }, + { id: 'calendar', name: 'Calendar', icon: , color: '#017E84' }, + { id: 'settings', name: 'Settings', icon: , color: '#7F8C8D' }, +]; + +export default function Home() { + const [search, setSearch] = useState(''); + const [user, setUser] = useState<{ id: string; name: string; role: string; email: string } | null>(null); + const [loading, setLoading] = useState(true); + const router = useRouter(); + + useEffect(() => { + const checkAuth = async () => { + const token = getCookie('auth_token'); + if (!token) { + setUser(null); + setLoading(false); + return; + } + + try { + const res = await fetch('http://localhost:5000/api/auth/me', { + headers: { + 'Authorization': `Bearer ${token}` + } + }); + const data = await res.json(); + if (res.ok) { + setUser(data); + } else { + deleteCookie('auth_token'); + setUser(null); + } + } catch (err) { + setUser(null); + } finally { + setLoading(false); + } + }; + + checkAuth(); + }, []); + + const handleLogout = () => { + deleteCookie('auth_token'); + localStorage.removeItem('user'); + setUser(null); + router.push('/auth/login'); + }; + + const filteredApps = apps.filter(app => { + const matchesSearch = app.name.toLowerCase().includes(search.toLowerCase()); + if (!matchesSearch) return false; + if (loading) return true; + if (!user) return true; // Show all for guests (landing page feel) + if (user.role === 'admin') return true; + + const rolePermissions: Record = { + 'waiter': ['POS', 'Restaurant', 'Calendar'], + 'cashier': ['POS', 'Accounting', 'Calendar'], + 'manager': ['Restaurant', 'POS', 'Inventory', 'Accounting', 'Calendar', 'Settings'], + }; + + const allowedApps = rolePermissions[user.role as keyof typeof rolePermissions] || []; + return allowedApps.includes(app.name); + }); + + return ( +
+
+
+ +
+
+ {/*
O
*/} +

Dine360

+
+ +
+ + setSearch(e.target.value)} + /> +
+ +
+ + {user ? ( +
+
+ {user.name.substring(0, 2).toUpperCase()} +
+ +
+ ) : ( + Login + )} +
+
+ +
+ {filteredApps.map((app, index) => { + const content = ( +
+
+ {app.icon} +
+ {app.name} +
+ ); + + return ( + + {content} + + ); + })} +
+ +
+ + +
+
+ ); +} diff --git a/src/app/payroll/page.tsx b/src/app/payroll/page.tsx new file mode 100644 index 0000000..a998e9d --- /dev/null +++ b/src/app/payroll/page.tsx @@ -0,0 +1,117 @@ +"use client"; + +import React, { useState } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Users, + CreditCard, + Wallet, + Calendar, + FileCheck, + Plus, + Search, + TrendingUp, + Download, + AlertCircle, + LayoutDashboard, + Building2, + CheckCircle2 +} from 'lucide-react'; +import styles from './payroll.module.css'; + +const sidebarItems = [ + { icon: , label: 'Employee Dashboard' }, + { icon: , label: 'Payslips', active: true }, + { icon: , label: 'Salary Structures' }, + { icon: , label: 'Attendances' }, +]; + +const payslips = [ + { id: 'PSL/001', employee: 'Alice Johnson', period: 'January 2026', basic: '$ 3,500.00', allowance: '$ 450.00', deduction: '$ 200.00', net: '$ 3,750.00', status: 'Paid' }, + { id: 'PSL/002', employee: 'Bob Smith', period: 'January 2026', basic: '$ 2,800.00', allowance: '$ 200.00', deduction: '$ 150.00', net: '$ 2,850.00', status: 'Draft' }, + { id: 'PSL/003', employee: 'Charlie Dave', period: 'January 2026', basic: '$ 2,200.00', allowance: '$ 150.00', deduction: '$ 100.00', net: '$ 2,250.00', status: 'Waiting' }, + { id: 'PSL/004', employee: 'Diana Prince', period: 'January 2026', basic: '$ 4,200.00', allowance: '$ 600.00', deduction: '$ 350.00', net: '$ 4,450.00', status: 'Paid' }, +]; + +export default function PayrollPage() { + const [search, setSearch] = useState(''); + + return ( + +
+ {/* Payroll Summary */} +
+
+
+ Total Payroll (Jan) + $ 13,300.00 +
+
+
+
+
+ Pending Payments + 2 Batches +
+
+
+
+
+ Employees Paid + 24 / 26 +
+
+
+
+ + {/* Toolbar */} +
+
+ + setSearch(e.target.value)} /> +
+
+ + +
+
+ + {/* Payslip Table */} +
+ + + + + + + + + + + + + + + {payslips.map((slip) => ( + + + + + + + + + + + ))} + +
ReferenceEmployeePeriodBasic SalaryAllowancesDeductionsNet WageStatus
{slip.id}{slip.employee}{slip.period}{slip.basic}+ {slip.allowance}- {slip.deduction}{slip.net} + + {slip.status} + +
+
+
+
+ ); +} diff --git a/src/app/payroll/payroll.module.css b/src/app/payroll/payroll.module.css new file mode 100644 index 0000000..4268311 --- /dev/null +++ b/src/app/payroll/payroll.module.css @@ -0,0 +1,185 @@ +.container { + display: flex; + flex-direction: column; + gap: 2.5rem; +} + +.summaryRow { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} + +.summaryCard { + background: white; + padding: 1.5rem; + border-radius: 20px; + border: 1px solid #e2e8f0; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.cardInfo { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.clabel { + font-size: 0.85rem; + font-weight: 700; + color: #64748b; + text-transform: uppercase; +} + +.cvalue { + font-size: 1.5rem; + font-weight: 800; + color: #1e293b; + font-family: var(--font-heading); +} + +.cardIcon { + width: 50px; + height: 50px; + border-radius: 14px; + display: flex; + align-items: center; + justify-content: center; +} + +.toolbar { + display: flex; + justify-content: space-between; + align-items: center; + gap: 2rem; +} + +.searchWrapper { + flex: 1; + position: relative; + max-width: 500px; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; +} + +.searchWrapper input { + width: 100%; + padding: 0.75rem 1rem 0.75rem 2.5rem; + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: var(--transition); +} + +.actions { + display: flex; + gap: 0.75rem; +} + +.batchBtn { + background: var(--pk-primary); + color: white; + border: none; + padding: 0.75rem 1.25rem; + border-radius: 12px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.printBtn { + background: white; + border: 1px solid #e2e8f0; + padding: 0.75rem 1.25rem; + border-radius: 12px; + color: #64748b; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.tableWrapper { + background: white; + border-radius: 20px; + border: 1px solid #e2e8f0; + overflow: hidden; + box-shadow: var(--shadow); +} + +.payrollTable { + width: 100%; + border-collapse: collapse; + text-align: left; +} + +.payrollTable th { + padding: 1rem 1.5rem; + background: #f8fafc; + color: #64748b; + font-weight: 700; + font-size: 0.85rem; + border-bottom: 1px solid #e2e8f0; +} + +.payrollTable td { + padding: 1.25rem 1.5rem; + border-bottom: 1px solid #f1f5f9; + font-size: 0.9rem; + color: #1e293b; +} + +.row:hover { + background: #f8fafc; +} + +.ref { + font-weight: 700; + color: var(--pk-primary); +} + +.employeeName { + font-weight: 700; + color: #1e293b; +} + +.netWage { + font-weight: 800; + color: var(--pk-secondary); + font-family: var(--font-heading); +} + +.statusBadge { + padding: 0.25rem 0.75rem; + border-radius: 999px; + font-size: 0.75rem; + font-weight: 700; +} + +.paid { + background: #dcfce7; + color: #15803d; +} + +.draft { + background: #f1f5f9; + color: #64748b; +} + +.waiting { + background: #fef9c3; + color: #854d0e; +} \ No newline at end of file diff --git a/src/app/pos/PaymentCheckout.tsx b/src/app/pos/PaymentCheckout.tsx new file mode 100644 index 0000000..ed00cab --- /dev/null +++ b/src/app/pos/PaymentCheckout.tsx @@ -0,0 +1,89 @@ +import React, { useState, useEffect } from 'react'; +import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js'; + +interface PaymentCheckoutProps { + amount: number; + onSuccess: () => void; + onCancel: () => void; +} + +export default function PaymentCheckout({ amount, onSuccess, onCancel }: PaymentCheckoutProps) { + const stripe = useStripe(); + const elements = useElements(); + const [message, setMessage] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!stripe || !elements) { + return; + } + + setIsLoading(true); + + const { error, paymentIntent } = await stripe.confirmPayment({ + elements, + confirmParams: { + // Return URL is required for some payment methods, but we try to handle inline + return_url: window.location.origin + "/pos", + }, + redirect: 'if_required', + }); + + if (error) { + setMessage(error.message || "An unexpected error occurred."); + setIsLoading(false); + } else if (paymentIntent && paymentIntent.status === 'succeeded') { + onSuccess(); + // Do not setIsLoading(false) here to prevent flicker before modal closes + } else { + // Unexpected status + setMessage(`Payment Status: ${paymentIntent.status}`); + setIsLoading(false); + } + }; + + return ( +
+ + {message &&
{message}
} + +
+ + +
+ + ); +} diff --git a/src/app/pos/page.tsx b/src/app/pos/page.tsx new file mode 100644 index 0000000..4b69c2a --- /dev/null +++ b/src/app/pos/page.tsx @@ -0,0 +1,1198 @@ +"use client"; + +import React, { useState, useEffect } from 'react'; +import { + Search, + ShoppingCart, + User, + Plus, + Minus, + Trash2, + ChevronLeft, + LayoutGrid, + MoreVertical, + Settings, + Save, + Move, + Check, + Coffee, + ArrowRight, + Zap, + Printer, + History, + ChefHat, + Wallet, + X, + CreditCard, + Banknote, + QrCode +} from 'lucide-react'; +import Link from 'next/link'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { motion, AnimatePresence } from 'framer-motion'; +import styles from './pos.module.css'; +import { loadStripe } from '@stripe/stripe-js'; +import { Elements } from '@stripe/react-stripe-js'; +import PaymentCheckout from './PaymentCheckout'; + +const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || 'pk_test_placeholder'); + + +const categories = [ + { name: 'ALL', color: 'catAll', icon: }, + { name: 'BIRYANI', color: 'catBiryani', icon: }, + { name: 'TANDOOR', color: 'catTandoor', icon: }, + { name: 'CURRIES', color: 'catCurries', icon: } +]; + +const products = [ + { id: 1, name: 'Chicken Dum Biryani', price: 550.00, category: 'BIRYANI', image: 'https://images.unsplash.com/photo-1563379091339-03b21bc4a4f8?w=500&auto=format&fit=crop&q=60', badge: 'BIRYANI' }, + { id: 2, name: 'Butter Chicken', price: 450.00, category: 'CURRIES', image: 'https://images.unsplash.com/photo-1603894584373-5ac82b2ae398?w=500&auto=format&fit=crop&q=60', badge: 'CURRY' }, + { id: 3, name: 'Malabar Paratha', price: 60.00, category: 'TANDOOR', image: 'https://images.unsplash.com/photo-1626082927389-6cd097cdc6ec?w=500&auto=format&fit=crop&q=60', badge: 'BREAD' }, + { id: 4, name: 'Mutton Rogan Josh', price: 620.00, category: 'CURRIES', image: 'https://images.unsplash.com/photo-1545243191-2092cc7790b5?w=500&auto=format&fit=crop&q=60', badge: 'SOLD OUT', soldOut: true }, + { id: 5, name: 'Paneer Tikka', price: 320.00, category: 'TANDOOR', image: 'https://images.unsplash.com/photo-1599487488170-d11ec9c172f0?w=500&auto=format&fit=crop&q=60', badge: 'STARTER' }, + { id: 6, name: 'Mango Lassi', price: 120.00, category: 'ALL', image: 'https://images.unsplash.com/photo-1618067423528-9840243be7c5?w=500&auto=format&fit=crop&q=60', badge: 'DRINK' }, + { id: 7, name: 'Garlic Naan', price: 75.00, category: 'TANDOOR', image: 'https://images.unsplash.com/photo-1610192244261-3f33de3f55e4?w=500&auto=format&fit=crop&q=60', badge: 'BREAD' }, +]; + +const sessions = [ + { + id: 'restaurant', + name: 'Restaurant', + isRestaurant: true, + badges: [ + { text: 'Self Ordering Enabled', type: 'info' }, + { text: 'To Close', type: 'warn' } + ] + }, + { + id: 'shop', + name: 'Main Shop', + isRestaurant: false, + badges: [ + { text: 'Online', type: 'info' } + ] + } +]; + +const initialFloors = [ + { id: 1, name: 'First Floor' }, + { id: 2, name: 'Ground Floor' } +]; + +const initialTables = [ + { id: 1, floorId: 1, name: 'Table 1', seats: 8, x: 200, y: 150, status: 'available', pendingOrders: 0, shape: 'circle' }, + { id: 2, floorId: 1, name: 'Table 2', seats: 6, x: 450, y: 150, status: 'occupied', pendingOrders: 0, shape: 'circle' }, + { id: 3, floorId: 1, name: 'Table 3', seats: 4, x: 700, y: 150, status: 'occupied', pendingOrders: 0, shape: 'square' }, + { id: 4, floorId: 1, name: 'Table 4', seats: 8, x: 300, y: 400, status: 'available', pendingOrders: 0, shape: 'circle' }, + { id: 5, floorId: 1, name: 'Table 5', seats: 2, x: 600, y: 400, status: 'occupied', pendingOrders: 0, shape: 'circle' }, + { id: 6, floorId: 2, name: 'Table G1', seats: 4, x: 200, y: 200, status: 'available', pendingOrders: 0, shape: 'circle' }, +]; + +type CartItem = { + product: typeof products[0], + qty: number, + modifiers?: string[] +}; +type POSStep = 'DASHBOARD' | 'FLOOR' | 'ORDERING'; + +export default function POSPage() { + const router = useRouter(); + const searchParams = useSearchParams(); + const initialTableId = searchParams.get('table'); + + const [step, setStep] = useState('DASHBOARD'); + const [selectedSession, setSelectedSession] = useState(null); + + // Floor & Table States + const [floors, setFloors] = useState(initialFloors); + const [activeFloorId, setActiveFloorId] = useState(1); + const [editingFloorId, setEditingFloorId] = useState(null); + const [floorNameInput, setFloorNameInput] = useState(''); + const [isDesignMode, setIsDesignMode] = useState(false); + const [tables, setTables] = useState(initialTables); + const [selectedTable, setSelectedTable] = useState(null); + + // Initial Data Fetch + useEffect(() => { + const fetchData = async () => { + try { + const [floorsRes, tablesRes] = await Promise.all([ + fetch('http://localhost:5000/api/pos/floors'), + fetch('http://localhost:5000/api/pos/tables') + ]); + + if (floorsRes.ok) { + const floorsData = await floorsRes.json(); + if (Array.isArray(floorsData) && floorsData.length > 0) { + setFloors(floorsData); + setActiveFloorId(floorsData[0].id); + } + } + + if (tablesRes.ok) { + const tablesData = await tablesRes.json(); + if (Array.isArray(tablesData) && tablesData.length > 0) { + setTables(tablesData); + } + } + } catch (err) { + console.error("Error fetching POS data:", err); + } + }; + fetchData(); + }, []); + + + + // Multi-Cart State + const [tableCarts, setTableCarts] = useState>({}); + const [retailCart, setRetailCart] = useState([]); + + // Track tables that have active orders on the server + const [tablesWithActiveOrders, setTablesWithActiveOrders] = useState([]); + + useEffect(() => { + const fetchActiveTables = async () => { + try { + // Fetch all orders that are not PAID + const res = await fetch('http://localhost:5000/api/pos/orders?active=true'); + if (res.ok) { + const activeOrders = await res.json(); + if (Array.isArray(activeOrders)) { + const tableIds = Array.from(new Set(activeOrders.map((o: any) => o.tableId))).filter(id => id !== undefined) as number[]; + setTablesWithActiveOrders(tableIds); + } + } + } catch (err) { + console.error("Error fetching active tables:", err); + } + }; + + fetchActiveTables(); + const interval = setInterval(fetchActiveTables, 8000); // Check every 8 seconds + return () => clearInterval(interval); + }, []); + + + // Define currentCart here so it is available for useEffect + // Define currentCart here so it is available for useEffect + const currentCart = selectedTable ? (tableCarts[selectedTable.id] || []) : retailCart; + + // Active Table Orders (Server Side) + const [serverOrders, setServerOrders] = useState([]); + + const fetchSelectedTableOrders = async () => { + if (!selectedTable) return; + try { + const res = await fetch(`http://localhost:5000/api/pos/orders?tableId=${selectedTable.id}&active=true`); + if (res.ok) { + const data = await res.json(); + if (Array.isArray(data)) { + setServerOrders(data); + } + } + } catch (err) { + console.error(err); + } + }; + + useEffect(() => { + let timer: any; + // Always reset server orders when selected table changes to avoid cross-table data leak + setServerOrders([]); + + if (selectedTable) { + fetchSelectedTableOrders(); + timer = setInterval(fetchSelectedTableOrders, 5000); + } + return () => clearInterval(timer); + }, [selectedTable?.id]); // Use .id to be specific + + // Combined Display Items + // Client-side filter as a double-safety measure against backend filter failures + const serverItems = (Array.isArray(serverOrders) ? serverOrders : []) + .filter(order => order.tableId === selectedTable?.id) + .flatMap(order => + order.items.map((item: any) => ({ + product: { id: item.productId, name: item.name, price: item.price }, + qty: item.qty, + modifiers: item.modifiers, + status: order.status, + locked: true + })) + ); + + // Total calculation needs to include server items for payment + const displayCart = [...serverItems, ...currentCart]; + + + // Quick Stock + const [quickStock, setQuickStock] = useState({ + "Dum Biryani": true, + "Butter Chicken": true, + "Mutton Rogan": false, + "Garlic Naan": true, + "Mango Lassi": true + }); + + // Payment & Order State + const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); + const [paymentMethod, setPaymentMethod] = useState<'CASH' | 'CARD' | 'ONLINE'>('CASH'); + const [amountTendered, setAmountTendered] = useState(''); + const [isProcessingPayment, setIsProcessingPayment] = useState(false); + const [lastOrder, setLastOrder] = useState(null); // For receipt printing logic if needed after payment + const [clientSecret, setClientSecret] = useState(''); + + useEffect(() => { + if (isPaymentModalOpen && paymentMethod === 'CARD') { + // Use the global 'total' calculated at component level (line 690ish) + // Or re-calculate here to be safe + const subtotal = displayCart.reduce((sum, item) => sum + (item.product.price * item.qty), 0); + const totalToCharge = subtotal * 1.1; // sub + 5% tax + 5% svc + + fetch('http://localhost:5000/api/payment/create-payment-intent', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ amount: totalToCharge }) + }) + .then(res => res.json()) + .then(data => setClientSecret(data.clientSecret)) + .catch(err => console.error("Stripe Intent Error:", err)); + } + }, [isPaymentModalOpen, paymentMethod, displayCart]); + + const handleProceedToPay = () => { + if (displayCart.length === 0) return; + setIsPaymentModalOpen(true); + }; + + const processPayment = async () => { + setIsProcessingPayment(true); + // Use proper calculations from displayed items + const subtotal = displayCart.reduce((sum, item) => sum + (item.product.price * item.qty), 0); + const tax = subtotal * 0.05; + const svc = subtotal * 0.05; + const total = subtotal + tax + svc; + + if (selectedTable) { + // Settle Table Logic + const newItems = currentCart.map(item => ({ + productId: item.product.id, + name: item.product.name, + price: item.product.price, + qty: item.qty, + modifiers: item.modifiers + })); + + try { + const res = await fetch(`http://localhost:5000/api/pos/tables/${selectedTable.id}/settle`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + paymentMethod, + newItems, + subtotal, tax, serviceCharge: svc, total // Add detailed breakdown if needed by backend for the "new items order" + // Note: Backend settleTable currently creates an order only for new items. + // The existing orders are marked PAID. + // The 'amount' charged via Stripe should be the TOTAL. + }) + }); + + if (res.ok) { + setTableCarts(prev => { + const next = { ...prev }; + delete next[selectedTable.id]; + return next; + }); + setServerOrders([]); // Clear local view of server orders until refresh + setIsPaymentModalOpen(false); + setIsProcessingPayment(false); + alert("Table Settled Successfully!"); + } else { + alert("Settlement Failed"); + setIsProcessingPayment(false); + } + } catch (error) { + console.error("Settle Error", error); + setIsProcessingPayment(false); + } + } else { + // Retail Logic (Keep logic as is but use currentCart) + // ... existing retail logic ... + const orderData = { + tableName: 'Retail', + items: currentCart.map(item => ({ + productId: item.product.id, + name: item.product.name, + price: item.product.price, + qty: item.qty, + modifiers: item.modifiers + })), + subtotal, tax, serviceCharge: svc, total, + paymentMethod, + status: 'PAID' + }; + + try { + const res = await fetch('http://localhost:5000/api/pos/orders', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(orderData) + }); + if (res.ok) { + setRetailCart([]); + setIsPaymentModalOpen(false); + setIsProcessingPayment(false); + alert("Order Paid Successfully!"); + } else { + alert("Payment Failed"); + setIsProcessingPayment(false); + } + } catch (error) { + console.error("Payment Error", error); + setIsProcessingPayment(false); + } + } + }; + + const handleSendToKitchen = async () => { + if (currentCart.length === 0) return; + + const subtotal = currentCart.reduce((sum, item) => sum + (item.product.price * item.qty), 0); + const tax = subtotal * 0.05; + const svc = subtotal * 0.05; + const total = subtotal + tax + svc; + + const orderData = { + tableId: selectedTable?.id, + tableName: selectedTable?.name || 'Retail', + items: currentCart.map(item => ({ + productId: item.product.id, + name: item.product.name, + price: item.product.price, + qty: item.qty, + modifiers: item.modifiers + })), + subtotal, + tax, + serviceCharge: svc, + total, + paymentMethod: 'PENDING', + status: 'KITCHEN' + }; + + try { + const res = await fetch('http://localhost:5000/api/pos/orders', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(orderData) + }); + if (res.ok) { + // Clear Cart + if (selectedTable) { + setTableCarts(prev => { + const next = { ...prev }; + delete next[selectedTable.id]; + return next; + }); + // Immediately fetch updated server orders + fetchSelectedTableOrders(); + } else { + setRetailCart([]); + } + // Optional: success notification instead of alert for better UX + console.log("Order Sent to Kitchen!"); + } else { + alert("Failed to send order."); + } + } catch (error) { + console.error("Kitchen Order Error", error); + } + }; + + + const handlePrintBill = () => { + // Simple receipt generation for printing + const printWindow = window.open('', '', 'width=600,height=600'); + if (!printWindow) return; + + const cartToPrint = currentCart; + const subtotal = cartToPrint.reduce((sum, item) => sum + (item.product.price * item.qty), 0); + const tax = subtotal * 0.05; + const svc = subtotal * 0.05; + const total = subtotal + tax + svc; + + const date = new Date().toLocaleString(); + + printWindow.document.write(` + + + Print Receipt + + + +
+

CHENNORA

+

Fine Dining & Takeaway

+

${date}

+

${selectedTable ? selectedTable.name : 'Retail Order'}

+
+
+ ${cartToPrint.map(item => ` +
+ ${item.qty} x ${item.product.name} + ₹${(item.product.price * item.qty).toFixed(2)} +
+ `).join('')} +
+
Subtotal₹${subtotal.toFixed(2)}
+
Tax (5%)₹${tax.toFixed(2)}
+
Svc Chg (5%)₹${svc.toFixed(2)}
+
+
TOTAL₹${total.toFixed(2)}
+
+
Thank You! Visit Again.
+ + + + `); + printWindow.document.close(); + }; + + const [activeCategory, setActiveCategory] = useState('ALL'); + const [search, setSearch] = useState(''); + + useEffect(() => { + if (initialTableId) { + const table = tables.find(t => t.id === parseInt(initialTableId)); + if (table) { + setStep('ORDERING'); + setSelectedSession(sessions[0]); + setSelectedTable(table); + setActiveFloorId(table.floorId); + } + } + }, [initialTableId, tables]); + + + + const handleContinueSession = (session: typeof sessions[0]) => { + setSelectedSession(session); + if (session.isRestaurant) { + setStep('FLOOR'); + } else { + setStep('ORDERING'); + } + }; + + const handleTableAction = (table: any) => { + if (isDesignMode) { + setSelectedTable(table); + } else { + setSelectedTable(table); + setStep('ORDERING'); + } + }; + + const handleDragEnd = async (id: number, info: any) => { + const table = tables.find(t => t.id === id); + if (!table) return; + + const newX = table.x + info.offset.x; + const newY = table.y + info.offset.y; + + // Optimistic update + setTables(prev => prev.map(t => + t.id === id ? { ...t, x: newX, y: newY } : t + )); + + // API Call + try { + await fetch(`http://localhost:5000/api/pos/tables/${id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ x: newX, y: newY }) + }); + } catch (error) { + console.error("Failed to save table position", error); + } + }; + + // Floor Management + const addFloor = async () => { + const newId = floors.length > 0 ? Math.max(...floors.map(f => f.id)) + 1 : 1; + const newFloor = { id: newId, name: `New Floor ${newId}` }; + + // Optimistic + setFloors([...floors, newFloor]); + setActiveFloorId(newId); + setEditingFloorId(newId); + setFloorNameInput(newFloor.name); + + try { + await fetch('http://localhost:5000/api/pos/floors', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(newFloor) + }); + } catch (error) { + console.error("Failed to add floor", error); + } + }; + + const deleteFloor = async (id: number) => { + if (floors.length <= 1) return; + setFloors(floors.filter(f => f.id !== id)); + setTables(tables.filter(t => t.floorId !== id)); + if (activeFloorId === id) { + setActiveFloorId(floors.find(f => f.id !== id)?.id || 1); + } + + try { + await fetch(`http://localhost:5000/api/pos/floors/${id}`, { method: 'DELETE' }); + } catch (error) { + console.error("Failed to delete floor", error); + } + }; + + const saveFloorName = async () => { + if (editingFloorId) { + setFloors(floors.map(f => f.id === editingFloorId ? { ...f, name: floorNameInput } : f)); + const idToSave = editingFloorId; + setEditingFloorId(null); + + try { + await fetch(`http://localhost:5000/api/pos/floors/${idToSave}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: floorNameInput }) + }); + } catch (error) { + console.error("Failed to save floor name", error); + } + } + }; + + // Table Management + const addTable = async () => { + const newId = tables.length > 0 ? Math.max(...tables.map(t => t.id)) + 1 : 1; + const newTable = { + id: newId, + floorId: activeFloorId, + name: `Table ${newId}`, + seats: 4, + x: 100, + y: 100, + status: 'available', + pendingOrders: 0, + shape: 'circle' + }; + setTables([...tables, newTable]); + setSelectedTable(newTable); + + try { + await fetch('http://localhost:5000/api/pos/tables', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(newTable) + }); + } catch (error) { + console.error("Failed to add table", error); + } + }; + + const deleteTable = async (id: number) => { + setTables(tables.filter(t => t.id !== id)); + setSelectedTable(null); + setTableCarts(prev => { + const next = { ...prev }; + delete next[id]; + return next; + }); + + try { + await fetch(`http://localhost:5000/api/pos/tables/${id}`, { method: 'DELETE' }); + } catch (error) { + console.error("Failed to delete table", error); + } + }; + + const updateTable = async (id: number, updates: any) => { + setTables(tables.map(t => t.id === id ? { ...t, ...updates } : t)); + if (selectedTable && selectedTable.id === id) { + setSelectedTable({ ...selectedTable, ...updates }); + } + + try { + await fetch(`http://localhost:5000/api/pos/tables/${id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(updates) + }); + } catch (error) { + console.error("Failed to update table", error); + } + }; + + // Ordering Logic + const addToCart = (product: typeof products[0]) => { + if (product.soldOut) return; + if (selectedTable) { + setTableCarts(prev => { + const tableId = selectedTable.id; + const prevCart = prev[tableId] || []; + const existing = prevCart.find(item => item.product.id === product.id); + let nextCart; + if (existing) { + nextCart = prevCart.map(item => item.product.id === product.id ? { ...item, qty: item.qty + 1 } : item); + } else { + nextCart = [...prevCart, { product, qty: 1, modifiers: ['MEDIUM'] }]; + } + return { ...prev, [tableId]: nextCart }; + }); + } else { + setRetailCart(prev => { + const existing = prev.find(item => item.product.id === product.id); + if (existing) { + return prev.map(item => item.product.id === product.id ? { ...item, qty: item.qty + 1 } : item); + } + return [...prev, { product, qty: 1, modifiers: ['MEDIUM'] }]; + }); + } + }; + + const updateQty = (productId: number, delta: number) => { + if (selectedTable) { + setTableCarts(prev => { + const tableId = selectedTable.id; + const nextCart = prev[tableId].map(item => { + if (item.product.id === productId) { + return { ...item, qty: Math.max(1, item.qty + delta) }; + } + return item; + }); + return { ...prev, [tableId]: nextCart }; + }); + } else { + setRetailCart(prev => prev.map(item => { + if (item.product.id === productId) { + return { ...item, qty: Math.max(1, item.qty + delta) }; + } + return item; + })); + } + }; + + const removeFromCart = (productId: number) => { + if (selectedTable) { + setTableCarts(prev => { + const tableId = selectedTable.id; + const nextCart = prev[tableId].filter(item => item.product.id !== productId); + return { ...prev, [tableId]: nextCart }; + }); + } else { + setRetailCart(prev => prev.filter(item => item.product.id !== productId)); + } + }; + + + const subtotal = displayCart.reduce((sum, item) => sum + (item.product.price * item.qty), 0); + const tax = subtotal * 0.05; + const svc = subtotal * 0.05; + const total = subtotal + tax + svc; + + if (step === 'DASHBOARD') { + return ( +
+
+
+ + + Dashboard + + Point of Sale +
+
+ +
+
+

Welcome back, Admin

+

Select a session to start selling or manage your floor plan.

+
+ +
+ {sessions.map(session => ( +
+
+ {session.name} +
+ {session.isRestaurant ? : } +
+
+
+ {session.badges.map((b, i) => ( + + {b.text} + + ))} +
+ + { + session.isRestaurant && ( + + + + ) + } +
A
+
+ ))} +
+
+
+ ); + } + + if (step === 'FLOOR') { + return ( +
+
+
+ + Floor Layout +
+
+ {isDesignMode && ( + + )} + +
+
+ +
+
+ {(Array.isArray(floors) ? floors : []).map(floor => ( +
+ {editingFloorId === floor.id ? ( +
+ setFloorNameInput(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && saveFloorName()} + /> + +
+ ) : ( + + )} + {isDesignMode && activeFloorId === floor.id && ( + + )} +
+ ))} + {isDesignMode && ( + + )} +
+
+ +
+
+
+ {(Array.isArray(tables) ? tables : []).filter(t => t.floorId === activeFloorId).map(table => { + const itemCount = (tableCarts[table.id] || []).reduce((s, i) => s + i.qty, 0); + const hasServerOrder = tablesWithActiveOrders.includes(table.id); + const isOccupied = itemCount > 0 || hasServerOrder; + + return ( + handleDragEnd(table.id, info)} + className={` + ${styles.tableBox} + ${table.shape === 'square' ? styles.squareTable : ''} + ${isOccupied ? styles.occupiedTable : ''} + ${hasServerOrder && !isDesignMode ? styles.serverActiveTable : ''} + ${selectedTable?.id === table.id && isDesignMode ? styles.selectedTableBox : ''} + `} + onClick={() => handleTableAction(table)} + whileHover={{ scale: isDesignMode ? 1.02 : 1.05 }} + whileTap={{ scale: 0.95 }} + > + {table.name} + {table.seats} Seats + {itemCount > 0 && !isDesignMode && ( +
{itemCount}
+ )} + {isDesignMode && ( +
+ {Math.round(table.x)}, {Math.round(table.y)} +
+ )} +
+ ); + })} +
+
+ + +
+
+ ); + } + + return ( +
+
+
+
+
+

CHENNORA

+ RUSH MODE +
+
+ +
+
+ + setSearch(e.target.value)} /> +
+
INVENTORY
+
+ +
+
A
+ +
+
+ +
+ + +
+
+ {categories.map(cat => ( + + ))} +
+ +
+ {products.filter(p => activeCategory === 'ALL' || p.category === activeCategory).map(product => ( +
addToCart(product)}> + {product.name} + {product.badge &&
{product.badge}
} +
+ {product.name} + ₹{product.price} +
+ {product.soldOut &&
} +
+ ))} +
+
+ + +
// Ends mainLayout + + {/* Payment Modal */} + + {isPaymentModalOpen && ( + + +
+

Payment

+ +
+ +
+
+ Total Amount +

₹{total.toFixed(2)}

+
+ +
+ + + +
+ + {paymentMethod === 'CASH' && ( +
+ + setAmountTendered(e.target.value)} + placeholder="Enter amount..." + /> + {amountTendered && parseFloat(amountTendered) >= total && ( +
+ Change: ₹{(parseFloat(amountTendered) - total).toFixed(2)} +
+ )} +
+ )} +
+ + + + {paymentMethod === 'CARD' && clientSecret ? ( + + setIsPaymentModalOpen(false)} + /> + + ) : ( +
+ + +
+ )} +
+
+ )} +
+
+ ); +} diff --git a/src/app/pos/pos.module.css b/src/app/pos/pos.module.css new file mode 100644 index 0000000..4a28439 --- /dev/null +++ b/src/app/pos/pos.module.css @@ -0,0 +1,1296 @@ +:root { + --bg-dark: #0f172a; + --bg-sidebar: #0b0f19; + --accent-teal: #2dd4bf; + --accent-green: #10b981; + --text-primary: #f8fafc; + --text-muted: #94a3b8; + --card-bg: rgba(30, 41, 59, 0.7); + --border-color: rgba(255, 255, 255, 0.1); + --font-heading: 'Outfit', sans-serif; +} + +.posContainer { + height: 100vh; + display: flex; + flex-direction: column; + background-color: var(--bg-dark); + color: var(--text-primary); + overflow: hidden; + font-family: 'Inter', sans-serif; +} + +/* Header Styles */ +.header { + height: 80px; + background: #ffffff; + border-bottom: 2px solid #eef2f6; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2rem; + z-index: 100; +} + +.brandInfo { + display: flex; + align-items: center; + gap: 1rem; +} + +.logo { + width: 44px; + height: 44px; + background: var(--accent-teal); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + color: white; +} + +.brandText h1 { + font-size: 1.2rem; + font-weight: 800; + color: #0f172a; + margin: 0; + line-height: 1; +} + +.brandText span { + font-size: 0.75rem; + font-weight: 700; + color: #ef4444; + text-transform: uppercase; + letter-spacing: 1px; +} + +.headerCenter { + flex: 1; + max-width: 600px; + display: flex; + align-items: center; + gap: 1.5rem; +} + +.searchBar { + flex: 1; + position: relative; +} + +.searchIcon { + position: absolute; + left: 16px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; +} + +.searchBar input { + width: 100%; + padding: 0.85rem 1.5rem 0.85rem 3.5rem; + background: #f1f5f9; + border: 2px solid transparent; + border-radius: 16px; + color: #0f172a; + font-weight: 600; + font-size: 0.95rem; + outline: none; + transition: all 0.3s ease; +} + +.searchBar input:focus { + background: white; + border-color: var(--accent-teal); + box-shadow: 0 4px 20px rgba(45, 212, 191, 0.15); +} + +.modeBadge { + background: #0f172a; + color: #fbbf24; + padding: 0.75rem 1.25rem; + border-radius: 14px; + display: flex; + align-items: center; + gap: 0.75rem; + font-weight: 800; + font-size: 0.85rem; + text-transform: uppercase; + border: 2px solid transparent; +} + +/* Dashboard Upgrade */ +.dashboardContainer { + flex: 1; + padding: 3rem; + overflow-y: auto; + background: radial-gradient(circle at top right, #1e293b 0%, #0b0f19 100%); + display: flex; + flex-direction: column; + gap: 3rem; + position: relative; +} + +.dashboardHero { + z-index: 10; +} + +.dashboardTitle { + font-size: 2.5rem; + font-weight: 800; + background: linear-gradient(to right, #f8fafc, #2dd4bf); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 0.5rem; +} + +.dashboardSubtitle { + color: #94a3b8; + font-size: 1.1rem; +} + +.sessionGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); + gap: 2.5rem; + z-index: 10; +} + +.sessionCard { + background: rgba(30, 41, 59, 0.7); + backdrop-filter: blur(12px); + border-radius: 28px; + padding: 2.5rem; + position: relative; + border: 1px solid rgba(255, 255, 255, 0.08); + transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); + display: flex; + flex-direction: column; + min-height: 280px; +} + +.sessionCard:hover { + transform: translateY(-12px) scale(1.02); + border-color: rgba(45, 212, 191, 0.4); + box-shadow: 0 40px 60px -20px rgba(0, 0, 0, 0.6); +} + +.sessionName { + font-size: 1.8rem; + font-weight: 800; + color: #f8fafc; + letter-spacing: -0.5px; +} + +.sessionBadges { + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + margin-bottom: 2.5rem; +} + +.badge { + padding: 0.4rem 1rem; + border-radius: 12px; + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; +} + +.badgeInfo { + background: rgba(8, 145, 178, 0.2); + color: #22d3ee; +} + +.badgeWarn { + background: rgba(185, 28, 28, 0.2); + color: #f87171; +} + +.continueBtn { + margin-top: auto; + background: linear-gradient(135deg, #2dd4bf, #14b8a6); + color: #0f172a; + border: none; + padding: 1.2rem 2rem; + border-radius: 18px; + font-weight: 800; + font-size: 1.1rem; + cursor: pointer; + text-align: center; +} + +.userInitial { + position: absolute; + bottom: 1rem; + right: 1rem; + width: 36px; + height: 36px; + background: #f97316; + color: white; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 900; +} + +/* Floor Management Styles */ +.floorHeader { + height: 70px; + background: #ffffff; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2rem; + border-bottom: 2px solid #e5e7eb; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); +} + +.floorTabs { + display: flex; + gap: 1rem; + align-items: center; +} + +.floorTab { + padding: 0.6rem 1.2rem; + border-radius: 14px; + background: #f9fafb; + border: 2px solid #e5e7eb; + color: #6b7280; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; +} + +.floorTab:hover { + background: #ffffff; + border-color: #2dd4bf; + color: #2dd4bf; +} + +.activeFloorTab { + background: linear-gradient(135deg, #2dd4bf, #14b8a6); + border-color: #2dd4bf; + color: #ffffff; + box-shadow: 0 4px 12px rgba(45, 212, 191, 0.3); +} + +.designerActions { + display: flex; + gap: 1rem; +} + +.addTableBtn, +.designToggle { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.6rem 1.2rem; + border-radius: 14px; + font-weight: 700; + cursor: pointer; + border: none; + transition: all 0.3s ease; +} + +.addTableBtn { + background: linear-gradient(135deg, #2dd4bf, #14b8a6); + color: white; + box-shadow: 0 4px 12px rgba(45, 212, 191, 0.3); +} + +.addTableBtn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(45, 212, 191, 0.4); +} + +.designToggle { + background: #f9fafb; + color: #6b7280; + border: 2px solid #e5e7eb; +} + +.designToggle:hover { + border-color: #2dd4bf; + color: #2dd4bf; +} + +.activeDesignToggle { + background: linear-gradient(135deg, #14b8a6, #0d9488); + color: #ffffff; + border-color: #14b8a6; + box-shadow: 0 4px 12px rgba(20, 184, 166, 0.3); +} + +.floorAreaWrapper { + flex: 1; + display: flex; + overflow: hidden; + position: relative; +} + +.floorArea { + flex: 1; + background: linear-gradient(135deg, #f0fdfa 0%, #ecfeff 100%); + position: relative; + overflow: hidden; +} + +.canvas { + width: 100%; + height: 100%; + position: relative; + background-image: + linear-gradient(#e5e7eb 1px, transparent 1px), + linear-gradient(90deg, #e5e7eb 1px, transparent 1px); + background-size: 50px 50px; +} + +.tableBox { + position: absolute; + width: 120px; + height: 120px; + background: #ffffff; + backdrop-filter: blur(8px); + border: 3px solid #e5e7eb; + border-radius: 50%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.3s ease; + z-index: 5; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.tableBox:hover { + transform: scale(1.05); +} + +.squareTable { + border-radius: 24px; +} + +.occupiedTable { + border-color: #10b981; + background: linear-gradient(135deg, #d1fae5, #a7f3d0); + box-shadow: 0 4px 20px rgba(16, 185, 129, 0.3); +} + +.selectedTableBox { + border-color: #2dd4bf; + box-shadow: 0 0 0 4px rgba(45, 212, 191, 0.2), 0 8px 30px rgba(45, 212, 191, 0.4); +} + +.tableNameLabel { + font-weight: 800; + font-size: 1rem; + color: #111827; +} + +.seatsLabel { + font-size: 0.75rem; + color: #6b7280; + font-weight: 600; +} + +.orderBadge { + position: absolute; + top: -8px; + right: -8px; + background: linear-gradient(135deg, #ef4444, #dc2626); + color: white; + width: 24px; + height: 24px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + font-weight: 900; + border: 2px solid #ffffff; + animation: pulse 2s infinite; + box-shadow: 0 2px 8px rgba(239, 68, 68, 0.4); +} + +@keyframes pulse { + 0% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); + } + + 70% { + transform: scale(1.1); + box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); + } + + 100% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); + } +} + +.serverActiveTable { + border-color: #f59e0b !important; + background: linear-gradient(135deg, #fef3c7, #fde68a) !important; + animation: serverPulse 2.5s infinite ease-in-out; +} + +@keyframes serverPulse { + 0% { + box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4); + } + + 70% { + box-shadow: 0 0 0 15px rgba(245, 158, 11, 0); + } + + 100% { + box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); + } +} + + +.propSidebar { + width: 350px; + background: #ffffff; + backdrop-filter: blur(20px); + border-left: 2px solid #e5e7eb; + display: flex; + flex-direction: column; + padding: 2rem; + z-index: 20; + box-shadow: -4px 0 20px rgba(0, 0, 0, 0.05); +} + +.propHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 2rem; +} + +.propHeader h3 { + font-size: 1.25rem; + font-weight: 800; + color: #2dd4bf; +} + +.propGroup { + margin-bottom: 1.5rem; +} + +.propGroup label { + display: block; + font-size: 0.75rem; + font-weight: 800; + color: #6b7280; + text-transform: uppercase; + margin-bottom: 0.5rem; + letter-spacing: 0.5px; +} + +.propGroup input { + width: 100%; + background: #f9fafb; + border: 2px solid #e5e7eb; + border-radius: 12px; + padding: 0.8rem 1rem; + color: #111827; + font-weight: 600; + transition: all 0.3s ease; +} + +.propGroup input:focus { + outline: none; + border-color: #2dd4bf; + background: #ffffff; + box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.1); +} + +.shapeToggle { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.5rem; + background: #f3f4f6; + padding: 4px; + border-radius: 14px; +} + +.shapeBtn { + padding: 0.6rem; + border-radius: 10px; + border: none; + background: transparent; + color: #6b7280; + font-weight: 800; + cursor: pointer; + transition: all 0.3s ease; +} + +.shapeBtn:hover { + color: #2dd4bf; +} + +.activeShape { + background: #ffffff; + color: #2dd4bf; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); +} + +.deleteBtn { + background: #fee2e2; + color: #dc2626; + border: 2px solid #fecaca; + padding: 0.5rem; + border-radius: 10px; + cursor: pointer; + font-weight: 700; + transition: all 0.3s ease; +} + +.deleteBtn:hover { + background: #fecaca; + border-color: #dc2626; + transform: translateY(-1px); +} + +/* Main Layout */ +.mainLayout { + flex: 1; + display: flex; + overflow: hidden; + background: #f8fafc; +} + +/* Quick Stock Sidebar */ +.quickStockSidebar { + width: 280px; + background: #0f172a; + display: flex; + flex-direction: column; + padding: 1.5rem; + gap: 2rem; +} + +.sidebarTitle { + display: flex; + align-items: center; + gap: 0.75rem; + color: #fbbf24; + font-weight: 800; + font-size: 1rem; + text-transform: uppercase; +} + +.stockList { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.stockItem { + padding: 1rem; + background: rgba(255, 255, 255, 0.03); + border-radius: 14px; + display: flex; + justify-content: space-between; + align-items: center; + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.stockName { + font-weight: 700; + font-size: 0.9rem; + color: white; +} + +.toggleSwitch { + width: 44px; + height: 24px; + background: #1e293b; + border-radius: 12px; + position: relative; + cursor: pointer; + transition: background 0.3s ease; +} + +.toggleActive { + background: var(--accent-green); +} + +.toggleCircle { + width: 18px; + height: 18px; + background: white; + border-radius: 50%; + position: absolute; + top: 3px; + left: 3px; + transition: transform 0.3s ease; +} + +.toggleActive .toggleCircle { + transform: translateX(20px); +} + +/* Product Section */ +.productSection { + flex: 1; + display: flex; + flex-direction: column; + padding: 1.5rem; + gap: 1.5rem; + overflow-y: auto; +} + +.categoryGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1rem; +} + +.categoryCard { + height: 110px; + border-radius: 20px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.75rem; + cursor: pointer; + transition: all 0.3s ease; + border: none; + color: white; +} + +.catAll { + background: #0f172a; +} + +.catBiryani { + background: #f97316; +} + +.catTandoor { + background: #b45309; +} + +.catCurry { + background: #ef4444; +} + +.categoryCard:hover { + transform: translateY(-4px); + filter: brightness(1.1); + box-shadow: 0 12px 20px rgba(0, 0, 0, 0.15); +} + +.activeCatCard { + outline: 4px solid var(--accent-teal); + outline-offset: 4px; +} + +.catName { + font-weight: 900; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.productGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 1.5rem; +} + +.productCard { + background: white; + border-radius: 24px; + overflow: hidden; + position: relative; + aspect-ratio: 1; + cursor: pointer; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; +} + +.productCard:hover { + transform: translateY(-6px); + box-shadow: 0 20px 30px rgba(0, 0, 0, 0.1); +} + +.productImg { + width: 100%; + height: 100%; + object-fit: cover; + filter: brightness(0.9); +} + +.productOverlay { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 1.25rem; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.8)); + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.pName { + font-weight: 800; + font-size: 1.1rem; + color: white; +} + +.pPrice { + font-size: 1.2rem; + font-weight: 900; + color: var(--accent-teal); +} + +.pBadge { + position: absolute; + top: 12px; + right: 12px; + padding: 0.4rem 0.75rem; + background: var(--accent-teal); + color: var(--bg-dark); + border-radius: 8px; + font-size: 0.65rem; + font-weight: 800; + text-transform: uppercase; +} + +/* Order Section */ +.orderSidebar { + width: 420px; + background: white; + border-left: 2px solid #eef2f6; + display: flex; + flex-direction: column; +} + +.orderHeader { + padding: 1.5rem; + border-bottom: 2px solid #eef2f6; +} + +.orderTitleRow { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; +} + +.orderTitleRow h2 { + font-size: 1.4rem; + font-weight: 800; + color: #0f172a; + margin: 0; +} + +.orderMeta { + display: flex; + gap: 1rem; + align-items: center; +} + +.tableTag { + background: #ecfeff; + color: var(--accent-teal); + padding: 0.4rem 0.75rem; + border-radius: 8px; + font-weight: 800; + font-size: 0.8rem; +} + +.customerName { + font-size: 0.85rem; + color: #64748b; + font-weight: 600; +} + +.orderList { + flex: 1; + overflow-y: auto; + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.orderItem { + display: flex; + flex-direction: column; + gap: 0.75rem; + padding-bottom: 1.25rem; + border-bottom: 1px dashed #e2e8f0; +} + +.itemMain { + display: flex; + justify-content: space-between; + align-items: center; +} + +.itemInfo h4 { + margin: 0; + font-weight: 800; + color: #0f172a; + font-size: 1rem; +} + +.itemPrice { + color: #64748b; + font-weight: 700; + font-size: 0.85rem; + margin-top: 0.2rem; +} + +.qtyControl { + display: flex; + align-items: center; + background: #f1f5f9; + padding: 4px; + border-radius: 12px; + gap: 0.75rem; +} + +.qtyBtn { + width: 32px; + height: 32px; + border: none; + background: transparent; + color: #0f172a; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + font-weight: 800; +} + +.qtyValue { + font-weight: 800; + min-width: 20px; + text-align: center; + color: #0f172a; + /* Fix visibility */ +} + +.deleteItemBtn { + background: #fee2e2; + color: #ef4444; + border: none; + border-radius: 12px; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.2s; + margin-left: 0.5rem; +} + +.deleteItemBtn:hover { + background: #fecaca; + color: #dc2626; +} + +.modifierGrid { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.modifierTag { + padding: 0.4rem 0.8rem; + background: #f8fafc; + border: 1px solid #e2e8f0; + border-radius: 10px; + font-size: 0.7rem; + font-weight: 700; + color: #64748b; + text-transform: uppercase; + cursor: pointer; +} + +.modifierActive { + background: #ecfeff; + border-color: var(--accent-teal); + color: var(--accent-teal); +} + +.orderFooter { + padding: 1.5rem; + background: #f8fafc; + border-top: 2px solid #eef2f6; + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.totalRow { + display: flex; + justify-content: space-between; + align-items: center; +} + +.totalLabel { + font-size: 1.2rem; + font-weight: 800; + color: #0f172a; + text-transform: uppercase; +} + +.totalValue { + font-size: 2rem; + font-weight: 900; + color: var(--accent-green); +} + +.proceedBtn { + background: var(--accent-green); + color: white; + border: none; + padding: 1.25rem; + border-radius: 20px; + font-size: 1.2rem; + font-weight: 800; + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + cursor: pointer; + transition: all 0.3s ease; +} + +.proceedBtn:hover { + filter: brightness(1.1); + transform: translateY(-2px); + box-shadow: 0 10px 25px rgba(16, 185, 129, 0.3); +} + +.secondaryActions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; +} + +.secBtn { + padding: 1rem; + border: 2px solid #e2e8f0; + background: white; + border-radius: 16px; + font-weight: 800; + font-size: 0.85rem; + color: #64748b; + text-transform: uppercase; + cursor: pointer; + transition: all 0.3s ease; +} + +.secBtnPrint { + border-color: var(--accent-teal); + color: var(--accent-teal); +} + +.bottomNavBar { + height: 100px; + background: white; + border-top: 2px solid #eef2f6; + display: grid; + grid-template-columns: 1fr 1fr 1.5fr; + padding: 1rem 1.5rem; + gap: 1rem; +} + +.navBtn { + border: none; + border-radius: 18px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.4rem; + font-weight: 800; + font-size: 0.9rem; + cursor: pointer; + transition: all 0.3s ease; +} + +.navBtnCash { + background: #0f172a; + color: white; +} + +.navBtnRepeat { + background: #3b82f6; + color: white; +} + +.navBtnKitchen { + background: #f87171; + color: white; +} + +.navBtn:hover { + transform: translateY(-4px); + filter: brightness(1.1); +} + +.navBtnSpan { + font-size: 0.7rem; + opacity: 0.8; + font-weight: 600; +} + +.lockedItem { + opacity: 0.85; + background: rgba(248, 250, 252, 0.5); + border-left: 4px solid #f59e0b; +} + +.statusSmallBadge { + font-size: 0.6rem; + padding: 2px 6px; + border-radius: 6px; + font-weight: 800; + text-transform: uppercase; +} + +.statusKITCHEN { + background: #fef3c7; + color: #b45309; +} + +.statusREADY { + background: #d1fae5; + color: #065f46; +} + +.statusSERVED { + background: #dbeafe; + color: #1e40af; +} + +.qtyValueLocked { + font-size: 1.1rem; + font-weight: 900; + color: #1e293b; + width: 30px; + text-align: center; +} + + +/* Payment Modal */ +.modalOverlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(15, 23, 42, 0.85); + backdrop-filter: blur(8px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.paymentModal { + background: white; + width: 600px; + border-radius: 32px; + overflow: hidden; + box-shadow: 0 50px 100px -20px rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; +} + +.modalHeader { + padding: 2rem; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #eef2f6; +} + +.modalHeader h2 { + font-size: 1.8rem; + font-weight: 800; + color: #0f172a; + margin: 0; +} + +.modalHeader button { + background: #f1f5f9; + border: none; + padding: 0.8rem; + border-radius: 12px; + cursor: pointer; + color: #64748b; + transition: all 0.2s; +} + +.modalHeader button:hover { + background: #eef2f6; + color: #ef4444; +} + +.paymentContent { + padding: 2.5rem; + display: flex; + flex-direction: column; + gap: 2rem; +} + +.amountDisplay { + text-align: center; + margin-bottom: 1rem; +} + +.amountDisplay span { + font-size: 0.9rem; + color: #64748b; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 1px; +} + +.amountDisplay h1 { + font-size: 3.5rem; + font-weight: 900; + color: #0f172a; + margin: 0.5rem 0 0 0; + letter-spacing: -1px; +} + +.paymentMethods { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1rem; +} + +.payMethodBtn { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; + padding: 1.5rem; + background: #f8fafc; + border: 2px solid #e2e8f0; + border-radius: 20px; + cursor: pointer; + transition: all 0.3s; + color: #64748b; +} + +.payMethodBtn span { + font-weight: 700; +} + +.payMethodBtn:hover { + background: #ffffff; + border-color: #2dd4bf; + color: #2dd4bf; + transform: translateY(-4px); + box-shadow: 0 12px 24px rgba(45, 212, 191, 0.15); +} + +.activeMethod { + background: #f0fdfa; + border-color: #2dd4bf; + color: #0d9488; + box-shadow: 0 4px 0 #2dd4bf; +} + +.cashInputSection { + background: #f8fafc; + padding: 1.5rem; + border-radius: 16px; + display: flex; + flex-direction: column; + gap: 0.8rem; +} + +.cashInputSection label { + font-size: 0.8rem; + font-weight: 700; + color: #64748b; + text-transform: uppercase; +} + +.cashInputSection input { + width: 100%; + padding: 1rem; + font-size: 1.5rem; + font-weight: 700; + border: 2px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: 0.3s; +} + +.cashInputSection input:focus { + border-color: #2dd4bf; + background: white; +} + +.changeDisplay { + font-size: 1.2rem; + font-weight: 800; + color: #0f172a; + display: flex; + justify-content: space-between; +} + +.modalFooter { + padding: 2rem; + background: #f8fafc; + border-top: 1px solid #eef2f6; + display: flex; + justify-content: flex-end; + gap: 1rem; +} + +.cancelBtn { + padding: 1rem 2rem; + border: none; + background: transparent; + color: #64748b; + font-weight: 700; + font-size: 1rem; + cursor: pointer; +} + +.confirmPayBtn { + padding: 1rem 2.5rem; + background: #0f172a; + color: white; + border: none; + border-radius: 16px; + font-weight: 800; + font-size: 1rem; + cursor: pointer; + box-shadow: 0 12px 24px rgba(15, 23, 42, 0.3); + transition: all 0.3s; +} + +.confirmPayBtn:hover { + transform: translateY(-2px); + box-shadow: 0 20px 40px rgba(15, 23, 42, 0.4); +} + +.confirmPayBtn:disabled { + opacity: 0.7; + cursor: not-allowed; +} \ No newline at end of file diff --git a/src/app/restaurant/menu/menu.module.css b/src/app/restaurant/menu/menu.module.css new file mode 100644 index 0000000..6d315ec --- /dev/null +++ b/src/app/restaurant/menu/menu.module.css @@ -0,0 +1,253 @@ +.menuContainer { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + gap: 2rem; +} + +.searchWrapper { + flex: 1; + position: relative; + max-width: 500px; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; +} + +.searchWrapper input { + width: 100%; + padding: 0.75rem 1rem 0.75rem 2.5rem; + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + outline: none; + transition: var(--transition); +} + +.actions { + display: flex; + gap: 1rem; + align-items: center; +} + +.viewToggle { + display: flex; + background: #f1f5f9; + padding: 4px; + border-radius: 10px; +} + +.viewToggle button { + padding: 0.5rem; + border: none; + background: transparent; + color: #64748b; + cursor: pointer; + border-radius: 8px; + transition: var(--transition); +} + +.activeView { + background: white !important; + color: var(--pk-primary) !important; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); +} + +.filterBtn, +.addBtn { + padding: 0.75rem 1.25rem; + border-radius: 10px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.filterBtn { + background: white; + border: 1px solid #e2e8f0; + color: #475569; +} + +.addBtn { + background: var(--pk-primary); + color: white; + border: none; +} + +.menuGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 2rem; +} + +.menuCard { + background: white; + border-radius: 20px; + border: 1px solid #e2e8f0; + overflow: hidden; + transition: var(--transition); + cursor: pointer; +} + +.menuCard:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-lg); +} + +.imagePlaceholder { + height: 160px; + background: #f8fafc; + display: flex; + align-items: center; + justify-content: center; + font-size: 4rem; +} + +.cardInfo { + padding: 1.25rem; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.cardHeader { + display: flex; + justify-content: space-between; + align-items: center; +} + +.category { + font-size: 0.75rem; + font-weight: 700; + color: var(--pk-secondary); + text-transform: uppercase; +} + +.name { + font-size: 1.1rem; + font-weight: 800; + color: #1e293b; +} + +.cardFooter { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 0.5rem; +} + +.price { + font-weight: 800; + color: var(--pk-primary); + font-size: 1.25rem; +} + +.editBtn { + background: #f1f5f9; + border: none; + padding: 0.5rem; + border-radius: 8px; + color: #64748b; + cursor: pointer; +} + +.statusBadge { + padding: 0.2rem 0.6rem; + border-radius: 999px; + font-size: 0.7rem; + font-weight: 700; +} + +.available { + background: #dcfce7; + color: #15803d; +} + +.limited { + background: #fef9c3; + color: #854d0e; +} + +.soldout { + background: #fee2e2; + color: #b91c1c; +} + +.menuList { + background: white; + border-radius: 20px; + border: 1px solid #e2e8f0; + overflow: hidden; +} + +.menuListItem { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + padding: 1rem 1.5rem; + align-items: center; + border-bottom: 1px solid #f1f5f9; +} + +.itemMain { + display: flex; + align-items: center; + gap: 1rem; +} + +.listIcon { + width: 40px; + height: 40px; + background: #f8fafc; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; +} + +.itemDetail { + display: flex; + flex-direction: column; +} + +.itemDetail strong { + color: #1e293b; + font-size: 0.95rem; +} + +.itemDetail span { + color: #94a3b8; + font-size: 0.75rem; +} + +.listPrice { + font-weight: 700; + color: var(--pk-primary); +} + +.listActions { + display: flex; + gap: 0.5rem; + justify-content: flex-end; +} + +.listActions button { + background: none; + border: none; + color: #94a3b8; + cursor: pointer; + padding: 4px; +} \ No newline at end of file diff --git a/src/app/restaurant/menu/page.tsx b/src/app/restaurant/menu/page.tsx new file mode 100644 index 0000000..1c82f45 --- /dev/null +++ b/src/app/restaurant/menu/page.tsx @@ -0,0 +1,112 @@ +"use client"; + +import React, { useState } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Plus, + Search, + Image as ImageIcon, + Edit2, + Trash2, + ChevronRight, + Filter, + Grid, + List, + LayoutDashboard, + Utensils, + Monitor +} from 'lucide-react'; +import styles from './menu.module.css'; + +const sidebarItems = [ + { icon: , label: 'Floor Plan' }, + { icon: , label: 'Orders' }, + { icon: , label: 'KDS (Kitchen)' }, + { icon: , label: 'Menu Management', active: true }, +]; + +const mockMenu = [ + { id: 1, name: 'Classic Burger', category: 'Main Course', price: 12.99, image: '🍔', status: 'Available' }, + { id: 2, name: 'Margherita Pizza', category: 'Main Course', price: 14.50, image: '🍕', status: 'Available' }, + { id: 3, name: 'Caesar Salad', category: 'Appetizers', price: 8.00, image: '🥗', status: 'Available' }, + { id: 4, name: 'French Fries', category: 'Sides', price: 4.50, image: '🍟', status: 'Available' }, + { id: 5, name: 'Chocolate Cake', category: 'Desserts', price: 6.50, image: '🍰', status: 'Limited' }, + { id: 6, name: 'Fresh Orange Juice', category: 'Beverages', price: 3.50, image: '🥤', status: 'Available' }, +]; + +export default function MenuManagementPage() { + const [view, setView] = useState<'grid' | 'list'>('grid'); + const [search, setSearch] = useState(''); + + return ( + +
+ {/* Top Header */} +
+
+ + setSearch(e.target.value)} + /> +
+ +
+
+ + +
+ + +
+
+ + {/* Content */} + {view === 'grid' ? ( +
+ {mockMenu.map(item => ( +
+
{item.image}
+
+
+ {item.category} + {item.status} +
+

{item.name}

+
+ $ {item.price.toFixed(2)} +
+ +
+
+
+
+ ))} +
+ ) : ( +
+ {mockMenu.map(item => ( +
+
+
{item.image}
+
+ {item.name} + {item.category} +
+
+ $ {item.price.toFixed(2)} + {item.status} +
+ + +
+
+ ))} +
+ )} +
+
+ ); +} diff --git a/src/app/restaurant/page.tsx b/src/app/restaurant/page.tsx new file mode 100644 index 0000000..ab4e5f5 --- /dev/null +++ b/src/app/restaurant/page.tsx @@ -0,0 +1,236 @@ +"use client"; + +import React, { useState, useEffect } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Users, + LayoutDashboard, + Utensils, + Plus, + Settings, + Grid, + Monitor, + CheckCircle2, + Clock, + ArrowRight, + Move, + Trash2, + Save, + Maximize2 +} from 'lucide-react'; +import { motion } from 'framer-motion'; +import Link from 'next/link'; +import styles from './restaurant.module.css'; + +const sidebarItems = [ + { icon: , label: 'Floor Plan', active: true }, + { icon: , label: 'Orders' }, + { icon: , label: 'KDS (Kitchen)' }, + { icon: , label: 'Menu Management' }, +]; + +const initialTables = [ + { id: 1, name: 'T1', seats: 2, status: 'available', x: 100, y: 100, shape: 'rect' as const }, + { id: 2, name: 'T2', seats: 4, status: 'occupied', x: 250, y: 100, shape: 'rect' as const, orderTotal: '$ 45.00' }, + { id: 3, name: 'T3', seats: 6, status: 'available', x: 450, y: 100, shape: 'circle' as const }, + { id: 4, name: 'T4', seats: 4, status: 'reserved', x: 100, y: 300, shape: 'rect' as const }, + { id: 5, name: 'T5', seats: 2, status: 'occupied', x: 300, y: 300, shape: 'circle' as const, orderTotal: '$ 12.50' }, +]; + +export default function RestaurantPage() { + const [activeFloor, setActiveFloor] = useState('Main Floor'); + const [isEditing, setIsEditing] = useState(false); + const [tables, setTables] = useState(initialTables); + const [selectedTable, setSelectedTable] = useState(null); + const [user, setUser] = useState<{ name: string; role: string } | null>(null); + + useEffect(() => { + fetch('/api/auth/me') + .then(res => res.json()) + .then(data => { + if (data.user) { + setUser(data.user); + } + }); + }, []); + + const canEdit = user?.role === 'admin' || user?.role === 'manager'; + + const handleDrag = (id: number, info: any) => { + setTables(prev => prev.map(t => + t.id === id ? { ...t, x: t.x + info.delta.x, y: t.y + info.delta.y } : t + )); + }; + + const addTable = () => { + const newId = tables.length > 0 ? Math.max(...tables.map(t => t.id)) + 1 : 1; + setTables([...tables, { + id: newId, + name: `T${newId}`, + seats: 4, + status: 'available', + x: 50, + y: 50, + shape: 'rect' + }]); + setSelectedTable(newId); + }; + + const deleteTable = (id: number) => { + setTables(tables.filter(t => t.id !== id)); + setSelectedTable(null); + }; + + const updateTable = (id: number, updates: any) => { + setTables(tables.map(t => t.id === id ? { ...t, ...updates } : t)); + }; + + const currentTable = tables.find(t => t.id === selectedTable); + + return ( + +
+ {/* Floor Navigation */} +
+ {['Main Floor', 'Terrace', 'Bar'].map(floor => ( + + ))} + + + {canEdit && ( +
+ + {isEditing && ( + + )} +
+ )} +
+ + {/* Main Floor Area */} +
+ {!isEditing && ( +
+
Available
+
Occupied
+
Reserved
+
+ )} + +
+ {tables.map(table => ( + handleDrag(table.id, info)} + className={`${styles.table} ${styles[table.status]} ${styles[table.shape]} ${selectedTable === table.id && isEditing ? styles.selectedTable : ''}`} + style={{ left: table.x, top: table.y, position: 'absolute' }} + onClick={() => isEditing && setSelectedTable(table.id)} + > + {!isEditing ? ( + +
+ {table.name} + {table.seats} seats + {table.orderTotal && {table.orderTotal}} +
+ + ) : ( +
+
+ {table.name} +
+ )} +
+ ))} +
+
+ + {/* Designer Sidebar / KDS Sidebar */} +
+ {isEditing && selectedTable ? ( +
+
+

Table Properties

+ +
+
+ + updateTable(selectedTable, { name: e.target.value })} + /> +
+
+ + updateTable(selectedTable, { seats: parseInt(e.target.value) })} + /> +
+
+ +
+ + +
+
+
+ ) : ( +
+
+

Kitchen Status

+ 3 Ready +
+
+
+
+ Burger x2 + Table T2 +
+ +
+
+
+ Pizza x1 + Table T5 +
+ +
+
+ View Full KDS +
+ )} +
+
+
+ ); +} diff --git a/src/app/restaurant/restaurant.module.css b/src/app/restaurant/restaurant.module.css new file mode 100644 index 0000000..c3b3796 --- /dev/null +++ b/src/app/restaurant/restaurant.module.css @@ -0,0 +1,424 @@ +.restaurantContainer { + display: flex; + gap: 2rem; + height: calc(100vh - 160px); +} + +.floorNav { + display: flex; + flex-direction: column; + gap: 0.75rem; + width: 200px; +} + +.floorBtn { + padding: 0.75rem 1rem; + background: #ffffff; + border: 2px solid #e5e7eb; + border-radius: 14px; + text-align: left; + font-weight: 600; + color: #6b7280; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.floorBtn:hover { + background: #f9fafb; + color: #2dd4bf; + border-color: #2dd4bf; + transform: translateX(4px); +} + +.activeFloor { + background: linear-gradient(135deg, #2dd4bf, #14b8a6) !important; + color: white !important; + border-color: #2dd4bf; + box-shadow: 0 4px 12px rgba(45, 212, 191, 0.3); +} + +.addFloorBtn { + padding: 0.75rem; + background: #f9fafb; + border: 2px dashed #d1d5db; + border-radius: 14px; + color: #9ca3af; + cursor: pointer; + transition: all 0.3s ease; +} + +.addFloorBtn:hover { + background: #ffffff; + border-color: #2dd4bf; + color: #2dd4bf; +} + +.editToggleSection { + margin-top: 1.5rem; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.editToggle { + padding: 0.75rem; + border-radius: 14px; + font-weight: 700; + border: 2px solid #e5e7eb; + background: #ffffff; + color: #374151; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.editToggle:hover { + border-color: #2dd4bf; + color: #2dd4bf; +} + +.activeEdit { + background: linear-gradient(135deg, #14b8a6, #0d9488); + color: white; + border-color: #14b8a6; + box-shadow: 0 4px 12px rgba(20, 184, 166, 0.3); +} + +.addTableBtn { + padding: 0.75rem; + background: linear-gradient(135deg, #2dd4bf, #14b8a6); + color: white; + border: none; + border-radius: 14px; + font-weight: 700; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + transition: all 0.3s ease; + box-shadow: 0 4px 12px rgba(45, 212, 191, 0.3); +} + +.addTableBtn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(45, 212, 191, 0.4); +} + +.floorPlan { + flex: 1; + background: linear-gradient(135deg, #f0fdfa 0%, #ecfeff 100%); + border-radius: 24px; + position: relative; + overflow: hidden; + border: 2px solid #e5e7eb; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); +} + +.canvas { + width: 100%; + height: 100%; + background-image: + radial-gradient(circle, #d1d5db 1px, transparent 1px); + background-size: 30px 30px; + position: relative; +} + +.legend { + position: absolute; + top: 1.5rem; + right: 1.5rem; + display: flex; + gap: 1.5rem; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + padding: 0.75rem 1.25rem; + border-radius: 16px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(0, 0, 0, 0.05); + z-index: 10; +} + +.legendItem { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.85rem; + font-weight: 600; + color: #475569; +} + +.statusDot { + width: 10px; + height: 10px; + border-radius: 50%; +} + +.table { + width: 120px; + height: 120px; + cursor: pointer; + transition: all 0.3s ease; +} + +.table:hover { + transform: scale(1.05); +} + +.tableInnerLink { + text-decoration: none; + width: 100%; + height: 100%; + display: block; +} + +.tableInner { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.25rem; + transition: all 0.3s ease; + position: relative; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.rect .tableInner { + border-radius: 16px; +} + +.circle .tableInner { + border-radius: 50%; +} + +.available .tableInner { + background: linear-gradient(135deg, #ffffff, #f0fdf4); + border: 3px solid #10b981; + box-shadow: 0 6px 0 #059669, 0 8px 20px rgba(16, 185, 129, 0.2); +} + +.available:hover .tableInner { + box-shadow: 0 6px 0 #059669, 0 10px 25px rgba(16, 185, 129, 0.3); +} + +.occupied .tableInner { + background: linear-gradient(135deg, #fee2e2, #fecaca); + border: 3px solid #ef4444; + color: #991b1b; + box-shadow: 0 6px 0 #dc2626, 0 8px 20px rgba(239, 68, 68, 0.2); +} + +.occupied:hover .tableInner { + box-shadow: 0 6px 0 #dc2626, 0 10px 25px rgba(239, 68, 68, 0.3); +} + +.reserved .tableInner { + background: linear-gradient(135deg, #fef3c7, #fde68a); + border: 3px solid #f59e0b; + color: #92400e; + box-shadow: 0 6px 0 #d97706, 0 8px 20px rgba(245, 158, 11, 0.2); +} + +.reserved:hover .tableInner { + box-shadow: 0 6px 0 #d97706, 0 10px 25px rgba(245, 158, 11, 0.3); +} + +.selectedTable .tableInner { + border-color: #2dd4bf !important; + box-shadow: 0 0 0 4px rgba(45, 212, 191, 0.3), 0 8px 20px rgba(45, 212, 191, 0.4) !important; +} + +.dragHandle { + position: absolute; + top: -10px; + left: 50%; + transform: translateX(-50%); + background: var(--pk-primary); + color: white; + padding: 4px; + border-radius: 4px; + cursor: move; +} + +.tableName { + font-weight: 800; + font-size: 1.25rem; +} + +.seats { + font-size: 0.75rem; + opacity: 0.8; + font-weight: 600; +} + +.orderTotal { + font-weight: 700; + font-size: 0.85rem; + margin-top: 4px; +} + +.rightSidebar { + width: 300px; + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.propertyEditor, +.kdsPreview { + background: #ffffff; + border-radius: 20px; + padding: 1.5rem; + border: 2px solid #e5e7eb; + display: flex; + flex-direction: column; + gap: 1.5rem; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); +} + +.sidebarHeader { + display: flex; + justify-content: space-between; + align-items: center; +} + +.sidebarHeader h3 { + font-size: 1rem; + color: #111827; + font-weight: 800; +} + +.propGroup { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.propGroup label { + font-size: 0.8rem; + font-weight: 700; + color: #6b7280; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.propGroup input { + padding: 0.75rem; + border: 2px solid #e5e7eb; + border-radius: 12px; + outline: none; + transition: all 0.3s ease; + background: #f9fafb; + color: #111827; + font-weight: 600; +} + +.propGroup input:focus { + border-color: #2dd4bf; + background: #ffffff; + box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.1); +} + +.shapeToggle { + display: flex; + gap: 0.5rem; + background: #f3f4f6; + padding: 4px; + border-radius: 12px; +} + +.shapeToggle button { + flex: 1; + padding: 0.5rem; + border: none; + background: transparent; + border-radius: 10px; + font-size: 0.85rem; + font-weight: 700; + cursor: pointer; + color: #6b7280; + transition: all 0.3s ease; +} + +.shapeToggle button:hover { + color: #2dd4bf; +} + +.activeShape { + background: white !important; + color: #2dd4bf !important; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); +} + +.deleteBtn { + background: #fee2e2; + color: #dc2626; + border: 2px solid #fecaca; + padding: 0.5rem; + border-radius: 10px; + cursor: pointer; + font-weight: 700; + transition: all 0.3s ease; +} + +.deleteBtn:hover { + background: #fecaca; + border-color: #dc2626; + transform: translateY(-1px); +} + +.kdsCount { + font-size: 0.75rem; + background: #dcfce7; + color: #15803d; + padding: 0.2rem 0.5rem; + border-radius: 6px; + font-weight: 700; +} + +.kdsList { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.kdsItem { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem; + background: #f8fafc; + border-radius: 12px; + border: 1px solid #f1f5f9; +} + +.kdsItemInfo strong { + display: block; + font-size: 0.9rem; + color: #1e293b; +} + +.kdsItemInfo span { + font-size: 0.75rem; + color: #64748b; +} + +.viewFullKds { + margin-top: auto; + text-align: center; + font-size: 0.85rem; + color: var(--pk-primary); + text-decoration: none; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} \ No newline at end of file diff --git a/src/app/restaurant/waitstaff/page.tsx b/src/app/restaurant/waitstaff/page.tsx new file mode 100644 index 0000000..df6799c --- /dev/null +++ b/src/app/restaurant/waitstaff/page.tsx @@ -0,0 +1,88 @@ +"use client"; + +import React, { useState } from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + Users, + UserPlus, + Map, + CheckCircle2, + XCircle, + ChevronRight, + MoreVertical, + LayoutDashboard, + Utensils, + Monitor, + Plus +} from 'lucide-react'; +import styles from './waitstaff.module.css'; + +const sidebarItems = [ + { icon: , label: 'Floor Plan' }, + { icon: , label: 'Waitstaff Assignment', active: true }, + { icon: , label: 'Orders' }, + { icon: , label: 'KDS (Kitchen)' }, +]; + +const staffList = [ + { id: 1, name: 'Alice Johnson', role: 'Senior Waiter', tables: ['T1', 'T2', 'T3'], status: 'active', avatar: 'AJ' }, + { id: 2, name: 'Bob Smith', role: 'Waiter', tables: ['T4', 'T5'], status: 'active', avatar: 'BS' }, + { id: 3, name: 'Charlie Dave', role: 'Junior Waiter', tables: ['T6'], status: 'on_break', avatar: 'CD' }, + { id: 4, name: 'Diana Prince', role: 'Senior Waiter', tables: [], status: 'inactive', avatar: 'DP' }, +]; + +export default function WaitstaffPage() { + return ( + +
+
+
+

Team Assignment

+

Manage waitstaff table zones and current shifts

+
+ +
+ +
+ {staffList.map(staff => ( +
+
+
{staff.avatar}
+
+ {staff.status === 'active' ? : } + {staff.status.replace('_', ' ')} +
+
+ +
+

{staff.name}

+ {staff.role} +
+ +
+
+ Assigned Tables +
+
+ {staff.tables.length > 0 ? ( + staff.tables.map(table => ( + {table} + )) + ) : ( + No tables assigned + )} + +
+
+ +
+ + +
+
+ ))} +
+
+
+ ); +} diff --git a/src/app/restaurant/waitstaff/waitstaff.module.css b/src/app/restaurant/waitstaff/waitstaff.module.css new file mode 100644 index 0000000..a41996f --- /dev/null +++ b/src/app/restaurant/waitstaff/waitstaff.module.css @@ -0,0 +1,206 @@ +.container { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.titleArea h2 { + font-size: 1.5rem; + font-weight: 800; + color: #1e293b; +} + +.titleArea p { + color: #64748b; + font-size: 0.9rem; +} + +.addBtn { + background: var(--pk-primary); + color: white; + border: none; + padding: 0.75rem 1.25rem; + border-radius: 12px; + font-weight: 700; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.staffGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 2rem; +} + +.staffCard { + background: white; + border-radius: 24px; + border: 1px solid #e2e8f0; + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 1.5rem; + transition: var(--transition); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.staffCard:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-lg); + border-color: var(--pk-primary); +} + +.cardHeader { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.avatar { + width: 50px; + height: 50px; + background: #f1f5f9; + border: 2px solid white; + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + color: var(--pk-primary); + box-shadow: var(--shadow); +} + +.statusBadge { + display: flex; + align-items: center; + gap: 0.25rem; + background: #f8fafc; + padding: 4px 8px; + border-radius: 999px; + border: 1px solid #f1f5f9; +} + +.statusBadge span { + font-size: 0.75rem; + font-weight: 700; + text-transform: capitalize; +} + +.active { + color: #10b981; +} + +.on_break { + color: #f59e0b; +} + +.inactive { + color: #94a3b8; +} + +.staffInfo { + display: flex; + flex-direction: column; +} + +.staffName { + font-size: 1.1rem; + font-weight: 800; + color: #1e293b; +} + +.staffRole { + font-size: 0.85rem; + color: #64748b; + font-weight: 500; +} + +.assignmentSection { + background: #f8fafc; + padding: 1rem; + border-radius: 16px; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.sectionHeader { + font-size: 0.75rem; + font-weight: 700; + color: #94a3b8; + text-transform: uppercase; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.tableBadges { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + align-items: center; +} + +.tableBadge { + background: white; + color: #1e293b; + font-weight: 700; + font-size: 0.75rem; + padding: 4px 10px; + border-radius: 8px; + border: 1px solid #e2e8f0; +} + +.noTables { + font-size: 0.8rem; + color: #94a3b8; + font-style: italic; +} + +.assignMore { + width: 26px; + height: 26px; + border-radius: 6px; + border: 1px dashed #cbd5e1; + background: transparent; + color: #94a3b8; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; +} + +.viewPerf { + font-size: 0.85rem; + font-weight: 700; + color: var(--pk-primary); + background: none; + border: none; + cursor: pointer; + padding: 0; +} + +.viewPerf:hover { + text-decoration: underline; +} + +.moreIcon { + color: #94a3b8; + cursor: pointer; +} \ No newline at end of file diff --git a/src/app/sales/page.tsx b/src/app/sales/page.tsx new file mode 100644 index 0000000..89a1871 --- /dev/null +++ b/src/app/sales/page.tsx @@ -0,0 +1,70 @@ +"use client"; + +import React from 'react'; +import AppLayout from '@/components/AppLayout/AppLayout'; +import { + BarChart3, + Users, + ShoppingCart, + Package, + LayoutDashboard, + FileText, + CreditCard, + Truck +} from 'lucide-react'; +import styles from './sales.module.css'; + +const sidebarItems = [ + { icon: , label: 'Dashboard' }, + { icon: , label: 'Quotations', active: true }, + { icon: , label: 'Orders' }, + { icon: , label: 'Customers' }, + { icon: , label: 'Products' }, +]; + +const mockOrders = [ + { id: 'S0001', customer: 'Azure Interior', date: '2026-01-20', salesman: 'James Doe', total: '$ 1,250.00', status: 'Quotation' }, + { id: 'S0002', customer: 'Deco Addict', date: '2026-01-21', salesman: 'Alice Smith', total: '$ 4,500.00', status: 'Sales Order' }, + { id: 'S0003', customer: 'Ready Mat', date: '2026-01-21', salesman: 'James Doe', total: '$ 800.00', status: 'Sent' }, + { id: 'S0004', customer: 'Gemini Corp', date: '2026-01-22', salesman: 'James Doe', total: '$ 12,000.00', status: 'Sales Order' }, + { id: 'S0005', customer: 'The Corner', date: '2026-01-22', salesman: 'Bob Wilson', total: '$ 320.00', status: 'Cancelled' }, +]; + +export default function SalesPage() { + return ( + +
+ + + + + + + + + + + + + + {mockOrders.map((order) => ( + + + + + + + + + + ))} + +
NumberCustomerOrder DateSalespersonTotalStatus
{order.id}{order.customer}{order.date}{order.salesman}{order.total} + + {order.status} + +
+
+
+ ); +} diff --git a/src/app/sales/sales.module.css b/src/app/sales/sales.module.css new file mode 100644 index 0000000..539e1a1 --- /dev/null +++ b/src/app/sales/sales.module.css @@ -0,0 +1,70 @@ +.tableContainer { + background: white; + border-radius: 12px; + border: 1px solid #e2e8f0; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.table { + width: 100%; + border-collapse: collapse; + text-align: left; +} + +.table th { + padding: 1rem; + background: #f8fafc; + color: #64748b; + font-weight: 600; + font-size: 0.85rem; + border-bottom: 1px solid #e2e8f0; +} + +.table td { + padding: 1rem; + border-bottom: 1px solid #f1f5f9; + font-size: 0.9rem; + color: #1e293b; +} + +.row:hover { + background: #f8fafc; + cursor: pointer; +} + +.orderId { + font-weight: 600; + color: var(--pk-primary); +} + +.total { + font-weight: 600; +} + +.status { + padding: 0.25rem 0.75rem; + border-radius: 9999px; + font-size: 0.75rem; + font-weight: 600; +} + +.quotation { + background: #e0f2fe; + color: #0369a1; +} + +.salesorder { + background: #dcfce7; + color: #15803d; +} + +.sent { + background: #fef9c3; + color: #854d0e; +} + +.cancelled { + background: #fee2e2; + color: #b91c1c; +} \ No newline at end of file diff --git a/src/components/AppLayout/AppLayout.module.css b/src/components/AppLayout/AppLayout.module.css new file mode 100644 index 0000000..6568cba --- /dev/null +++ b/src/components/AppLayout/AppLayout.module.css @@ -0,0 +1,243 @@ +.appContainer { + display: flex; + height: 100vh; + background-color: #f8fafc; +} + +.sidebar { + width: 64px; + background-color: var(--bg-sidebar); + display: flex; + flex-direction: column; + align-items: center; + padding: 1rem 0; + gap: 1.5rem; + z-index: 50; +} + +.appSwitcher { + width: 44px; + height: 44px; + background: rgba(255, 255, 255, 0.1); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + transition: var(--transition); +} + +.appSwitcher:hover { + background: rgba(255, 255, 255, 0.2); +} + +.sidebarMenu { + flex: 1; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.sidebarItem { + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 12px; + color: #94a3b8; + cursor: pointer; + transition: var(--transition); +} + +.sidebarItem:hover { + background: rgba(255, 255, 255, 0.05); + color: white; +} + +.active { + background: rgba(255, 255, 255, 0.1); + color: white; +} + +.contentWrapper { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.navbar { + height: 56px; + background: white; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 1.5rem; +} + +.navLeft { + display: flex; + align-items: baseline; + gap: 1rem; +} + +.appTitle { + font-weight: 700; + font-size: 1.1rem; + color: var(--pk-primary); +} + +.breadcrumbs { + font-size: 0.9rem; + color: var(--text-muted); +} + +.current { + color: var(--text-main); + font-weight: 500; +} + +.navCenter { + flex: 1; + max-width: 500px; +} + +.searchBar { + position: relative; + width: 100%; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #94a3b8; +} + +.searchInput { + width: 100%; + padding: 0.5rem 1rem 0.5rem 2.5rem; + background: #f1f5f9; + border: 1px solid transparent; + border-radius: 8px; + outline: none; + transition: var(--transition); +} + +.searchInput:focus { + background: white; + border-color: var(--pk-primary); + box-shadow: 0 0 0 3px rgba(113, 75, 103, 0.1); +} + +.navRight { + display: flex; + align-items: center; + gap: 1rem; +} + +.navBtn { + background: none; + border: none; + color: #64748b; + cursor: pointer; + padding: 0.5rem; + border-radius: 50%; + transition: var(--transition); +} + +.navBtn:hover { + background: #f1f5f9; +} + +.avatar { + width: 32px; + height: 32px; + background: var(--pk-primary); + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.75rem; + font-weight: 600; +} + +.actionBar { + height: 56px; + background: white; + border-bottom: 1px solid #e2e8f0; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 1.5rem; +} + +.actionLeft { + display: flex; + gap: 0.75rem; +} + +.primaryBtn { + background: var(--pk-primary); + color: white; + border: none; + padding: 0.5rem 1rem; + border-radius: 6px; + font-weight: 600; + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + transition: var(--transition); +} + +.primaryBtn:hover { + background: var(--pk-primary-hover); +} + +.secondaryBtn { + background: white; + border: 1px solid #d1d5db; + padding: 0.5rem 1rem; + border-radius: 6px; + font-weight: 500; + cursor: pointer; + transition: var(--transition); +} + +.secondaryBtn:hover { + background: #f9fafb; +} + +.viewToggle { + display: flex; + background: #f1f5f9; + padding: 3px; + border-radius: 8px; +} + +.viewBtn { + background: none; + border: none; + padding: 0.4rem 0.8rem; + font-size: 0.8rem; + font-weight: 500; + border-radius: 6px; + cursor: pointer; + color: #64748b; +} + +.viewBtn:first-child { + background: white; + color: var(--text-main); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.mainContent { + flex: 1; + overflow-y: auto; + padding: 1.5rem; +} \ No newline at end of file diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx new file mode 100644 index 0000000..23d3236 --- /dev/null +++ b/src/components/AppLayout/AppLayout.tsx @@ -0,0 +1,135 @@ +"use client"; + +import React, { useState, useEffect } from 'react'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { + Grid, + Settings, + Search, + Bell, + Plus, + Filter, + ArrowUpDown, + MoreVertical +} from 'lucide-react'; +import styles from './AppLayout.module.css'; + +interface AppLayoutProps { + children: React.ReactNode; + title: string; + sidebarItems: { icon: React.ReactNode; label: string; active?: boolean }[]; +} + +export default function AppLayout({ children, title, sidebarItems }: AppLayoutProps) { + const [user, setUser] = useState<{ name: string; role: string } | null>(null); + const router = useRouter(); + + useEffect(() => { + fetch('/api/auth/me') + .then(res => res.json()) + .then(data => { + if (data.user) { + setUser(data.user); + } else { + router.push('/auth/login'); + } + }) + .catch(() => router.push('/auth/login')); + }, [router]); + + const filteredSidebarItems = sidebarItems.filter(item => { + if (!user) return false; + if (user.role === 'admin') return true; + + // Define restrictions + const restrictions: Record = { + 'waiter': ['Floor Plan', 'Orders', 'KDS (Kitchen)'], + 'cashier': ['Orders', 'POS Dashboard'], + 'manager': ['Floor Plan', 'Orders', 'KDS (Kitchen)', 'Menu Management', 'Waitstaff Assignment'], + }; + + const allowedItems = restrictions[user.role as keyof typeof restrictions] || []; + return allowedItems.includes(item.label); + }); + + return ( +
+ {/* Sidebar */} + + + {/* Main Content Area */} +
+ {/* Navbar */} + + + {/* Action Bar */} +
+
+ + +
+
+
+ + + +
+
+
+ + {/* Main Content */} +
+ {children} +
+
+
+ ); +} diff --git a/src/lib/mongodb.ts b/src/lib/mongodb.ts new file mode 100644 index 0000000..b50b070 --- /dev/null +++ b/src/lib/mongodb.ts @@ -0,0 +1,40 @@ +import mongoose from 'mongoose'; + +const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/odoo_next'; + +if (!MONGODB_URI) { + throw new Error('Please define the MONGODB_URI environment variable inside .env.local'); +} + +let cached = (global as any).mongoose; + +if (!cached) { + cached = (global as any).mongoose = { conn: null, promise: null }; +} + +async function dbConnect() { + if (cached.conn) { + return cached.conn; + } + + if (!cached.promise) { + const opts = { + bufferCommands: false, + }; + + cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => { + return mongoose; + }); + } + + try { + cached.conn = await cached.promise; + } catch (e) { + cached.promise = null; + throw e; + } + + return cached.conn; +} + +export default dbConnect; diff --git a/src/models/Restaurant.ts b/src/models/Restaurant.ts new file mode 100644 index 0000000..2c9d498 --- /dev/null +++ b/src/models/Restaurant.ts @@ -0,0 +1,56 @@ +import mongoose from 'mongoose'; + +// --- Category --- +const CategorySchema = new mongoose.Schema({ + name: { type: String, required: true }, + icon: String, + color: String, +}); + +export const Category = mongoose.models.Category || mongoose.model('Category', CategorySchema); + +// --- Product --- +const ProductSchema = new mongoose.Schema({ + name: { type: String, required: true }, + price: { type: Number, required: true }, + category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' }, + image: String, + available: { type: Boolean, default: true }, + isAddon: { type: Boolean, default: false }, +}); + +export const Product = mongoose.models.Product || mongoose.model('Product', ProductSchema); + +// --- Table --- +const TableSchema = new mongoose.Schema({ + name: { type: String, required: true }, + seats: { type: Number, default: 4 }, + status: { type: String, enum: ['available', 'occupied', 'reserved'], default: 'available' }, + x: Number, + y: Number, + width: Number, + height: Number, + shape: { type: String, enum: ['rect', 'circle'], default: 'rect' }, + currentOrderId: { type: mongoose.Schema.Types.ObjectId, ref: 'Order' }, +}); + +export const Table = mongoose.models.Table || mongoose.model('Table', TableSchema); + +// --- Order --- +const OrderSchema = new mongoose.Schema({ + tableId: { type: mongoose.Schema.Types.ObjectId, ref: 'Table' }, + waiterId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + items: [{ + productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' }, + quantity: { type: Number, default: 1 }, + price: Number, // snapshot price + note: String, + }], + status: { type: String, enum: ['draft', 'sent', 'paid', 'cancelled'], default: 'draft' }, + subtotal: Number, + tax: Number, + total: Number, + paymentMethod: String, +}, { timestamps: true }); + +export const Order = mongoose.models.Order || mongoose.model('Order', OrderSchema); diff --git a/src/models/User.ts b/src/models/User.ts new file mode 100644 index 0000000..bc8ae06 --- /dev/null +++ b/src/models/User.ts @@ -0,0 +1,13 @@ +import mongoose from 'mongoose'; + +const UserSchema = new mongoose.Schema({ + name: { type: String, required: true }, + email: { type: String, required: true, unique: true }, + password: { type: String, required: true }, + role: { type: String, enum: ['admin', 'manager', 'waiter', 'cashier'], default: 'admin' }, + avatar: String, + resetPasswordToken: String, + resetPasswordExpires: Date, +}, { timestamps: true }); + +export default mongoose.models.User || mongoose.model('User', UserSchema); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..cf9c65d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts" + ], + "exclude": ["node_modules"] +}