diff --git a/jsconfig.json b/jsconfig.json
index b8d6842d7fad0a64e5ffa846e104342233782852..879f8fc5b7d23204d856dd09d330085ff8d61e9a 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,7 +1,9 @@
{
"compilerOptions": {
"paths": {
- "@/*": ["./src/*"]
+ "@/*": [
+ "./src/*"
+ ]
}
}
-}
+}
\ No newline at end of file
diff --git a/next.config.mjs b/next.config.mjs
index 4678774e6d606704bce1897a5dab960cd798bf66..2a39b71d075e0197440120491bcfa37f29d4eb57 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,4 +1,28 @@
/** @type {import('next').NextConfig} */
-const nextConfig = {};
+const nextConfig = {
+ images: {
+ domains: ['https://res.cloudinary.com'],
+ },
+ webpack(config) {
+ const fileLoaderRule = config.module.rules.find((rule) =>
+ rule.test?.test?.('.svg'),
+ )
+ config.module.rules.push(
+ {
+ ...fileLoaderRule,
+ test: /\.svg$/i,
+ resourceQuery: /url/, // *.svg?url
+ },
+ {
+ test: /\.svg$/i,
+ issuer: fileLoaderRule.issuer,
+ resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url
+ use: ['@svgr/webpack'],
+ },
+ )
+ fileLoaderRule.exclude = /\.svg$/i
+ return config
+ },
+};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index d4a9662c58821d09ebebe2ef995bf80407e9b29d..617d640ddc81ce717bb379227f12b644b4c8b435 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"react-dom": "^18"
},
"devDependencies": {
+ "@svgr/webpack": "^8.1.0",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
@@ -33,6 +34,1942 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+ "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.24.2",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz",
+ "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz",
+ "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.24.2",
+ "@babel/generator": "^7.24.5",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.24.5",
+ "@babel/helpers": "^7.24.5",
+ "@babel/parser": "^7.24.5",
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.5",
+ "@babel/types": "^7.24.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/core/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,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/core/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz",
+ "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.5",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+ "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz",
+ "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/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,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz",
+ "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-member-expression-to-functions": "^7.24.5",
+ "@babel/helper-optimise-call-expression": "^7.22.5",
+ "@babel/helper-replace-supers": "^7.24.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.24.5",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz",
+ "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "regexpu-core": "^5.3.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
+ "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.22.6",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz",
+ "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.24.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
+ "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz",
+ "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.24.3",
+ "@babel/helper-simple-access": "^7.24.5",
+ "@babel/helper-split-export-declaration": "^7.24.5",
+ "@babel/helper-validator-identifier": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
+ "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz",
+ "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz",
+ "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-wrap-function": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz",
+ "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-member-expression-to-functions": "^7.23.0",
+ "@babel/helper-optimise-call-expression": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz",
+ "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
+ "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz",
+ "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+ "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz",
+ "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz",
+ "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/template": "^7.24.0",
+ "@babel/types": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz",
+ "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.5",
+ "@babel/types": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz",
+ "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.24.5",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
+ "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz",
+ "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-plugin-utils": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz",
+ "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz",
+ "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/plugin-transform-optional-chaining": "^7.24.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz",
+ "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz",
+ "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz",
+ "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz",
+ "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz",
+ "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz",
+ "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.24.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz",
+ "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-remap-async-to-generator": "^7.22.20",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz",
+ "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-remap-async-to-generator": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz",
+ "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz",
+ "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz",
+ "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz",
+ "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.24.4",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz",
+ "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/helper-replace-supers": "^7.24.1",
+ "@babel/helper-split-export-declaration": "^7.24.5",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz",
+ "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/template": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz",
+ "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz",
+ "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz",
+ "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz",
+ "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz",
+ "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz",
+ "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz",
+ "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz",
+ "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz",
+ "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz",
+ "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz",
+ "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz",
+ "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz",
+ "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz",
+ "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-simple-access": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz",
+ "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz",
+ "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
+ "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz",
+ "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz",
+ "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz",
+ "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz",
+ "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz",
+ "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-replace-supers": "^7.24.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz",
+ "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz",
+ "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz",
+ "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz",
+ "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.24.1",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz",
+ "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.24.5",
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz",
+ "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-constant-elements": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.1.tgz",
+ "integrity": "sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-display-name": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz",
+ "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz",
+ "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-jsx": "^7.23.3",
+ "@babel/types": "^7.23.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
+ "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz",
+ "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz",
+ "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "regenerator-transform": "^0.15.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz",
+ "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz",
+ "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz",
+ "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz",
+ "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz",
+ "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz",
+ "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz",
+ "integrity": "sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.24.5",
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/plugin-syntax-typescript": "^7.24.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz",
+ "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz",
+ "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz",
+ "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz",
+ "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz",
+ "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.24.4",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-plugin-utils": "^7.24.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-import-assertions": "^7.24.1",
+ "@babel/plugin-syntax-import-attributes": "^7.24.1",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.24.1",
+ "@babel/plugin-transform-async-generator-functions": "^7.24.3",
+ "@babel/plugin-transform-async-to-generator": "^7.24.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.24.1",
+ "@babel/plugin-transform-block-scoping": "^7.24.5",
+ "@babel/plugin-transform-class-properties": "^7.24.1",
+ "@babel/plugin-transform-class-static-block": "^7.24.4",
+ "@babel/plugin-transform-classes": "^7.24.5",
+ "@babel/plugin-transform-computed-properties": "^7.24.1",
+ "@babel/plugin-transform-destructuring": "^7.24.5",
+ "@babel/plugin-transform-dotall-regex": "^7.24.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.24.1",
+ "@babel/plugin-transform-dynamic-import": "^7.24.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.24.1",
+ "@babel/plugin-transform-export-namespace-from": "^7.24.1",
+ "@babel/plugin-transform-for-of": "^7.24.1",
+ "@babel/plugin-transform-function-name": "^7.24.1",
+ "@babel/plugin-transform-json-strings": "^7.24.1",
+ "@babel/plugin-transform-literals": "^7.24.1",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.24.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.24.1",
+ "@babel/plugin-transform-modules-amd": "^7.24.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.24.1",
+ "@babel/plugin-transform-modules-umd": "^7.24.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
+ "@babel/plugin-transform-new-target": "^7.24.1",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1",
+ "@babel/plugin-transform-numeric-separator": "^7.24.1",
+ "@babel/plugin-transform-object-rest-spread": "^7.24.5",
+ "@babel/plugin-transform-object-super": "^7.24.1",
+ "@babel/plugin-transform-optional-catch-binding": "^7.24.1",
+ "@babel/plugin-transform-optional-chaining": "^7.24.5",
+ "@babel/plugin-transform-parameters": "^7.24.5",
+ "@babel/plugin-transform-private-methods": "^7.24.1",
+ "@babel/plugin-transform-private-property-in-object": "^7.24.5",
+ "@babel/plugin-transform-property-literals": "^7.24.1",
+ "@babel/plugin-transform-regenerator": "^7.24.1",
+ "@babel/plugin-transform-reserved-words": "^7.24.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.24.1",
+ "@babel/plugin-transform-spread": "^7.24.1",
+ "@babel/plugin-transform-sticky-regex": "^7.24.1",
+ "@babel/plugin-transform-template-literals": "^7.24.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.24.5",
+ "@babel/plugin-transform-unicode-escapes": "^7.24.1",
+ "@babel/plugin-transform-unicode-property-regex": "^7.24.1",
+ "@babel/plugin-transform-unicode-regex": "^7.24.1",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.24.1",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.10.4",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.31.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/preset-react": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz",
+ "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-validator-option": "^7.23.5",
+ "@babel/plugin-transform-react-display-name": "^7.24.1",
+ "@babel/plugin-transform-react-jsx": "^7.23.4",
+ "@babel/plugin-transform-react-jsx-development": "^7.22.5",
+ "@babel/plugin-transform-react-pure-annotations": "^7.24.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-typescript": {
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz",
+ "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.0",
+ "@babel/helper-validator-option": "^7.23.5",
+ "@babel/plugin-syntax-jsx": "^7.24.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.1",
+ "@babel/plugin-transform-typescript": "^7.24.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
+ "dev": true
+ },
"node_modules/@babel/runtime": {
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
@@ -45,6 +1982,64 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/template": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+ "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz",
+ "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.24.2",
+ "@babel/generator": "^7.24.5",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.24.5",
+ "@babel/parser": "^7.24.5",
+ "@babel/types": "^7.24.5",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz",
+ "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.24.1",
+ "@babel/helper-validator-identifier": "^7.24.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -307,112 +2302,369 @@
"node": ">= 10"
}
},
- "node_modules/@next/swc-linux-x64-musl": {
- "version": "14.2.3",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
- "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
+ "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
+ "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-ia32-msvc": {
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
+ "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
+ "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
+ "cpu": [
+ "x64"
+ ],
+ "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==",
+ "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==",
+ "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==",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
+ "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==",
+ "dev": true
+ },
+ "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
+ "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
+ "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-dynamic-title": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
+ "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-em-dimensions": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
+ "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
+ "dev": true,
"engines": {
- "node": ">= 10"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@next/swc-win32-arm64-msvc": {
- "version": "14.2.3",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
- "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
+ "node_modules/@svgr/babel-plugin-transform-react-native-svg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
+ "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
+ "dev": true,
"engines": {
- "node": ">= 10"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@next/swc-win32-ia32-msvc": {
- "version": "14.2.3",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
- "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
- "cpu": [
- "ia32"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
+ "node_modules/@svgr/babel-plugin-transform-svg-component": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
+ "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
+ "dev": true,
"engines": {
- "node": ">= 10"
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "node_modules/@next/swc-win32-x64-msvc": {
- "version": "14.2.3",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
- "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
+ "node_modules/@svgr/babel-preset": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
+ "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
+ "dev": true,
+ "dependencies": {
+ "@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
+ "@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
+ "@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
+ "@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
+ "@svgr/babel-plugin-transform-svg-component": "8.0.0"
+ },
"engines": {
- "node": ">= 10"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "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==",
+ "node_modules/@svgr/core": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
+ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
+ "dev": true,
"dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "camelcase": "^6.2.0",
+ "cosmiconfig": "^8.1.3",
+ "snake-case": "^3.0.4"
},
"engines": {
- "node": ">= 8"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
}
},
- "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==",
+ "node_modules/@svgr/hast-util-to-babel-ast": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
+ "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.21.3",
+ "entities": "^4.4.0"
+ },
"engines": {
- "node": ">= 8"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
}
},
- "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==",
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
"dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
},
"engines": {
- "node": ">= 8"
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
}
},
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "optional": true,
+ "node_modules/@svgr/plugin-svgo": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz",
+ "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==",
+ "dev": true,
+ "dependencies": {
+ "cosmiconfig": "^8.1.3",
+ "deepmerge": "^4.3.1",
+ "svgo": "^3.0.2"
+ },
"engines": {
"node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
}
},
- "node_modules/@rushstack/eslint-patch": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
- "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==",
- "dev": true
+ "node_modules/@svgr/webpack": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz",
+ "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@babel/plugin-transform-react-constant-elements": "^7.21.3",
+ "@babel/preset-env": "^7.20.2",
+ "@babel/preset-react": "^7.18.6",
+ "@babel/preset-typescript": "^7.21.0",
+ "@svgr/core": "8.1.0",
+ "@svgr/plugin-jsx": "8.1.0",
+ "@svgr/plugin-svgo": "8.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
},
"node_modules/@swc/counter": {
"version": "0.1.3",
@@ -436,6 +2688,15 @@
"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
}
},
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -878,6 +3139,54 @@
"dequal": "^2.0.3"
}
},
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.11",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
+ "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.22.6",
+ "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2/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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz",
+ "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.1",
+ "core-js-compat": "^3.36.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
+ "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -894,6 +3203,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -915,6 +3230,38 @@
"node": ">=8"
}
},
+ "node_modules/browserslist": {
+ "version": "4.23.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+ "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001587",
+ "electron-to-chromium": "^1.4.668",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -954,6 +3301,18 @@
"node": ">=6"
}
},
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@@ -1066,17 +3425,103 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
+ "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
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.37.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
+ "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.23.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+ "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
},
"engines": {
- "node": ">= 8"
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
}
},
"node_modules/cssesc": {
@@ -1090,6 +3535,39 @@
"node": ">=4"
}
},
+ "node_modules/csso": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+ "dev": true,
+ "dependencies": {
+ "css-tree": "~2.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.28",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
+ "dev": true
+ },
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -1170,6 +3648,15 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -1247,11 +3734,82 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.779",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.779.tgz",
+ "integrity": "sha512-oaTiIcszNfySXVJzKcjxd2YjPxziAd+GmXyb2HbidCeFo6Z88ygOT7EimlrEQhM2U08VhSrbKhLOXP0kKUCZ6g==",
+ "dev": true
+ },
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -1270,6 +3828,27 @@
"node": ">=10.13.0"
}
},
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.23.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
@@ -1428,6 +4007,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/escalade": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+ "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
+ "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",
@@ -2041,6 +4629,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
@@ -2377,6 +4974,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
"node_modules/is-async-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
@@ -2804,12 +5407,30 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"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
},
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2917,6 +5538,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -2934,6 +5561,15 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/lru-cache": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
@@ -2942,6 +5578,12 @@
"node": "14 || >=16.14"
}
},
+ "node_modules/mdn-data": {
+ "version": "2.0.30",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "dev": true
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -3106,6 +5748,22 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -3114,6 +5772,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3314,6 +5984,24 @@
"node": ">=6"
}
},
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -3668,12 +6356,39 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz",
+ "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true
},
+ "node_modules/regenerator-transform": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
+ "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
@@ -3692,6 +6407,44 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/regexpu-core": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
+ "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/regjsgen": "^0.8.0",
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.1.0",
+ "regjsparser": "^0.9.1",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsparser": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
+ "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "dev": true,
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -3936,6 +6689,16 @@
"node": ">=8"
}
},
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dev": true,
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
@@ -4197,6 +6960,46 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svg-parser": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
+ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
+ "dev": true
+ },
+ "node_modules/svgo": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
+ "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
+ "dev": true,
+ "dependencies": {
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
+ "css-select": "^5.1.0",
+ "css-tree": "^2.3.1",
+ "css-what": "^6.1.0",
+ "csso": "^5.0.5",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
+ "node_modules/svgo/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/tailwindcss": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
@@ -4267,6 +7070,15 @@
"node": ">=0.8"
}
},
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -4438,6 +7250,76 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dev": true,
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
+ "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.2",
+ "picocolors": "^1.0.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",
@@ -4647,6 +7529,12 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
"node_modules/yaml": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
diff --git a/package.json b/package.json
index c2cd5f90454007cef6ac16c790d9977ed069a82e..b38ca7e8db3e257f576e9c2638eb9c6d7b2ceb96 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"react-dom": "^18"
},
"devDependencies": {
+ "@svgr/webpack": "^8.1.0",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
diff --git a/src/app/auth/change-password/page.jsx b/src/app/auth/change-password/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..6bc46caa9f1a0aa71d39d43d249f2fb50b0bbafd
--- /dev/null
+++ b/src/app/auth/change-password/page.jsx
@@ -0,0 +1,126 @@
+"use client"
+import fetchRequest from '@/app/lib/fetchRequest'
+import Image from 'next/image'
+import Link from 'next/link'
+import React, { useEffect, useState } from 'react'
+import { useSearchParams } from 'next/navigation'
+import Loader from '@/components/Loader/Loader'
+import { PASSWORD_REGEX } from '@/app/lib/constants'
+import { useNotification } from '@/context/NotificationContext'
+
+const ChangePassword = () => {
+ const [isSuccess, setIsSuccess] = useState(false)
+ const [formErrors, setFormErrors] = useState([])
+ const [password, setPassword] = useState("")
+ const [confirmPassword, setConfirmPassword] = useState("")
+ const [isLoading, setIsLoading] = useState(false)
+ const params = useSearchParams();
+ const { toggleNotification } = useNotification()
+ const handleChangePassword = async (event) => {
+ event.preventDefault()
+ setIsLoading(true)
+ const { isSuccess, data, errors } = await fetchRequest(`/password_reset/confirm/?token=${params.get("token")}`, {
+ method: "POST",
+ body: JSON.stringify({
+ password,
+ token: params.get("token")
+ })
+ })
+ if (isSuccess) {
+ setIsSuccess(true)
+ }
+ else {
+ console.log(errors)
+ setIsLoading(false)
+ if (errors.type === "ValidationError") {
+ if (errors.detail.token) {
+ setFormErrors(["Le lien que vous avez utilisé pour réinitialiser votre mot de passe est invalide"])
+ }
+ else {
+ setFormErrors(["Le Mot de passe est invalide"])
+ }
+ } else if (errors?.detail?.detail?.startsWith("The OTP password entered is not valid")) {
+ setFormErrors(["Le lien que vous avez utilisé pour réinitialiser votre mot de passe est déja utilisé"])
+ }
+ else {
+ toggleNotification({
+ type: "error",
+ message: "Internal Server Error",
+ visible: true
+ })
+ }
+ }
+ }
+ const isEmptyFields = !password && !confirmPassword
+ useEffect(() => {
+ var currentErrors = []
+ if (password !== confirmPassword) {
+ currentErrors.push("Les mots de passe ne sont pas identiques.")
+ }
+ if (password.length < 8) {
+ currentErrors.push("Le mot de passe doit comporter au moins 8 caractères.")
+ }
+ if (!PASSWORD_REGEX.test(password)) {
+ currentErrors.push("Le mot de passe doit contenir au moins une lettre, un chiffre et un caractère spécial.")
+ }
+ setFormErrors(currentErrors)
+ }, [password, confirmPassword])
+ return (
+
+
+
+
+
+
+ {(!isSuccess) &&
+
Change your password.
+
+
+
+ - Le mot de passe doit contenir au moins 8 caractères
+ - Le mot de passe doit contenir au moins un chiffre
+ - Le mot de passe doit contenir au moins un caractère spécial
+
+
+
+
}
+ {(isSuccess) && (
+
+
The password has been changed!
+ log in again?
+
+ )}
+
+
+
+ )
+}
+
+export default ChangePassword
\ No newline at end of file
diff --git a/src/app/auth/forgot-password/page.jsx b/src/app/auth/forgot-password/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..d74d5db9ab4b3f3bd45be27257ce6fead4b790b3
--- /dev/null
+++ b/src/app/auth/forgot-password/page.jsx
@@ -0,0 +1,105 @@
+'use client'
+import fetchRequest from '@/app/lib/fetchRequest'
+import Loader from '@/components/Loader/Loader'
+import { useNotification } from '@/context/NotificationContext'
+import Image from 'next/image'
+import Link from 'next/link'
+import React, { useState } from 'react'
+
+const ForgotPassword = () => {
+ const [email, setEmail] = useState("")
+ const [isSuccess, setIsSuccess] = useState(false)
+ const [isLoading, setIsLoading] = useState(false)
+ const [requestErrors, setRequestErrors] = useState([])
+ const { toggleNotification } = useNotification()
+ const handleForgetPassword = async (event) => {
+ event.preventDefault()
+ setIsLoading(true)
+ const { isSuccess, errors, data } = await fetchRequest("/password_reset/", {
+ body: JSON.stringify({ email }),
+ method: "POST"
+ })
+ if (isSuccess) {
+ setIsSuccess(true)
+ }
+ else {
+ setIsLoading(false)
+ if (errors.type === "ValidationError") {
+ // setRequestErrors(Object.keys(errors.detail).reduce((prev, current) => {
+ // return [...prev, ...errors.detail[current]]
+ // }, []))
+ toggleNotification
+ setRequestErrors(["Nous n'avons pas pu trouver de compte associé à cet e-mail. Veuillez essayer une autre adresse e-mail."])
+ } else {
+ console.log(errors)
+ toggleNotification({
+ type: "error",
+ message: "Internal Server Error"
+ })
+ }
+ }
+ }
+ return (
+
+
+
+
+ {(!isSuccess) &&
+
+
Forgot your password!! No Problem
+ Reset it here
+
+
+
+
}
+ {(isSuccess) &&
+
+
+
Email Sent!
+
Check your email and open the link we sent to continue
+
+
}
+
+
+
+ )
+}
+
+export default ForgotPassword
\ No newline at end of file
diff --git a/src/app/auth/login/page.jsx b/src/app/auth/login/page.jsx
index 33b3f092806c43146c129778fdef8fa71449bd18..e94f196d34238d6f6324f5d3754292a44943a1b0 100644
--- a/src/app/auth/login/page.jsx
+++ b/src/app/auth/login/page.jsx
@@ -3,7 +3,7 @@
import { useState } from 'react';
import Link from 'next/link';
import Cookies from 'js-cookie';
-import {createSession} from "@/app/lib/session";
+import { createSession } from "@/app/lib/session";
const LoginPage = () => {
const [username, setUsername] = useState('');
@@ -18,45 +18,10 @@ const LoginPage = () => {
// Add your form submission logic here
};
- const secretKey = process.env.NEXT_PUBLIC_SESSION_SECRET;
- console.log(secretKey);
-
- // send login request to the server
const login = async (event) => {
event.preventDefault();
try {
- const response = await fetch('http://localhost:8000/login/', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ username, password }),
- });
- const data = await response.json();
- if (data.error) {
- setMessages(data.error);
- } else {
- setMessages('Login successful');
- // Set the cookie
- const expiresAt = new Date(new Date().getTime() + 60 * 60 * 1000); // Set cookie to expire in 1 hour
- // const session = json strigify it
- Cookies.set('session', data.token, {
- expires: expiresAt,
- secure: true,
- sameSite: 'Lax',
- });
- // Redirect to the dashboard
- // window.location.href = '/auth/verif';
- }
- } catch (error) {
- setMessages('An error occurred');
- }
- };
-
- const loginn = async (event) => {
- event.preventDefault();
- try {
- const response = await fetch('http://localhost:8000/login/', {
+ const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/login/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -64,16 +29,11 @@ const LoginPage = () => {
body: JSON.stringify({ username, password }),
});
const data = await response.json();
- if (data.error) {
- setMessages(data.error);
+ if (data.non_field_errors) {
+ setMessages(data.non_field_errors[0]);
} else {
- setMessages('Login successful');
- // Set the cookie
- const expiresAt = new Date(new Date().getTime() + 60 * 60 * 1000); // Set cookie to expire in 1 hour
- // const session = json strigify it
await createSession(data);
- // Redirect to the dashboard
- // window.location.href = '/auth/verif';
+ window.location.href = '/auth/verif';
}
} catch (error) {
setMessages('An error occurred');
@@ -91,7 +51,7 @@ const LoginPage = () => {
{
{
/>
-
-
Mot de passe oublié?
+
+
Mot de passe oublié?
{messages && (
@@ -124,7 +84,7 @@ const LoginPage = () => {
)}
diff --git a/src/app/auth/verif/page.jsx b/src/app/auth/verif/page.jsx
index cfea4df1253203ecab55cdbcb6d5644d8980cac5..15d3d4083be7e343e184e71bde68c51c9ab26e99 100644
--- a/src/app/auth/verif/page.jsx
+++ b/src/app/auth/verif/page.jsx
@@ -5,7 +5,7 @@ const Verif = () => {
// fetch data from the server /example
const fetchExampleData = async () => {
try {
- const data = await fetchRequest('http://localhost:8000/example/',
+ const data = await fetchRequest(`/example/`,
{method: 'POST',
body: JSON.stringify({
"name": "jhon",
@@ -20,18 +20,18 @@ const Verif = () => {
}
};
const isAuth = async () => {
- isAuthenticated();
+ await isAuthenticated();
}
return (
- <>
+
user is redirected to this page after successful login
{/*test fetchExampleData */}
- >
+
);
}
export default Verif;
\ No newline at end of file
diff --git a/src/app/etage/AddEtageComponent.jsx b/src/app/etage/AddEtageComponent.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..d84ae41ffbd070751b3decbd867a59fd8fd87ee1
--- /dev/null
+++ b/src/app/etage/AddEtageComponent.jsx
@@ -0,0 +1,58 @@
+'use client'
+import Loader from '@/components/Loader/Loader'
+import React, { useState, useRef } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+
+
+
+const AddEtageComponent = ({ etagesState })=> {
+ const [ numeroEtage, setNumeroEtage ] = useState("")
+ const [isLoading, setIsLoading] = useState(false)
+ const [errorMessage, setErrorMessage] = useState(null)
+ const inputRef = useRef(null)
+
+
+ const handleNewEtage = (e) => {
+ setErrorMessage(null)
+ setNumeroEtage(e.target.value)
+ }
+
+ const handleAddNewEtage = async () => {
+ setIsLoading(true)
+ const { data, errors, isSuccess } = await fetchRequest("/zoaning/etages/", {
+ method: "POST",
+ body: JSON.stringify({ numero: numeroEtage })
+ })
+ if (isSuccess) {
+ setIsLoading(false)
+ inputRef.current.value = ""
+ console.log(data)
+ etagesState((prevEtagesState) => [...prevEtagesState, data]);
+ } else {
+ setIsLoading(false)
+ if(errors.type == "ValidationError")
+ {setErrorMessage(errors.detail.numero)}
+ else{
+ setErrorMessage(errorMessage.type)
+ }
+ console.log(errors)
+ }
+
+ }
+
+ return(
+
+
+
Nouveau étage:
+
+
+
+
+
+ {errorMessage &&
{errorMessage}}
+
+
+ )
+}
+
+export default(AddEtageComponent)
\ No newline at end of file
diff --git a/src/app/etage/page.jsx b/src/app/etage/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..5177625933b1d8af927834ac9068aa67da4c722f
--- /dev/null
+++ b/src/app/etage/page.jsx
@@ -0,0 +1,83 @@
+"use client"
+import React from 'react'
+import AddEtageComponent from './AddEtageComponent'
+import fetchRequest from '../lib/fetchRequest'
+import { useState, useEffect } from 'react';
+import Loader from '@/components/Loader/Loader'
+
+
+
+const Etage = ()=> {
+ const [etages, setEtages] = useState([])
+ const [ isLoadingData, setIsLoadingData ] = useState(true)
+ // Fetch data from external API
+ useEffect(() => {
+ const getAllEtages = async () => {
+ try{
+ const {isSuccess, errors, data} = await fetchRequest('/zoaning/etages/', {method: 'GET'})
+ setIsLoadingData(false)
+ if(isSuccess){
+ setEtages(data)
+ }else{
+ setEtages([])
+ }
+ }catch(error){
+ setIsLoadingData(false)
+ console.log(error)
+ }
+ }
+ getAllEtages()
+ }, [])
+ const handleDeleteEtage = async (etage) => {
+ try{
+ console.log(etage)
+ const {isSuccess, errors, data} = await fetchRequest(`/zoaning/etages/${etage.id}/`, {method: "DELETE"})
+ console.log(isSuccess)
+ console.log(errors)
+ console.log(data)
+ if(isSuccess){
+ console.log(etages)
+ console.log("etage: ", etage)
+ setEtages((prevEtages) => prevEtages.filter((e) => e.id !== etage.id));
+ }
+ }catch(error){
+ console.log(error)
+ }
+ }
+ return(
+
+
+
+
Liste des étages
+
+
+ {(!isLoadingData) ? etages && etages?.length ?
+ {etages?.map((etage, index) =>
+ (
+ -
+ Etage numéro: {etage.numero}
+
{handleDeleteEtage(etage)}}>
+
+ )
+ )}
+
:
+
+ Aucun étage n'a été ajouté
+
+ :
+
+
+
+ }
+
+
+
+
+
+
+ )
+}
+
+export default Etage
\ No newline at end of file
diff --git a/src/app/globals.css b/src/app/globals.css
index 6c139df80533021db2ee61f9f06c23be2eb0a57f..b6ba7d37334c09788aa0026af48f37b048eed1d8 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -2,29 +2,6 @@
@tailwind components;
@tailwind utilities;
-:root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
-}
-
-body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
-}
@layer utilities {
.text-balance {
@@ -34,18 +11,23 @@ body {
/* Customize the scrollbar */
::-webkit-scrollbar {
- width: 6px; /* Set the width of the scrollbar */
+ width: 6px;
+ /* Set the width of the scrollbar */
}
::-webkit-scrollbar-thumb {
- background-color: rgba(0, 0, 0, 0.3); /* Color of the thumb */
- border-radius: 3px; /* Rounded corners of the thumb */
+ background-color: rgba(0, 0, 0, 0.3);
+ /* Color of the thumb */
+ border-radius: 3px;
+ /* Rounded corners of the thumb */
}
::-webkit-scrollbar-thumb:hover {
- background-color: rgba(0, 0, 0, 0.5); /* Color of the thumb on hover */
+ background-color: rgba(0, 0, 0, 0.5);
+ /* Color of the thumb on hover */
}
::-webkit-scrollbar-track {
- background-color: rgba(0, 0, 0, 0.1); /* Color of the track */
-}
+ background-color: rgba(0, 0, 0, 0.1);
+ /* Color of the track */
+}
\ No newline at end of file
diff --git a/src/app/layout.js b/src/app/layout.js
index 9aef1df7d6c3d50515ab62f578c5cc963a1243a7..45c21613310f3980d4975a0ebb436337cd7e5b89 100644
--- a/src/app/layout.js
+++ b/src/app/layout.js
@@ -1,17 +1,24 @@
import { Inter } from "next/font/google";
import "./globals.css";
+import Header from "@/app/ui/Header";
+import { NotificationProvider } from "@/context/NotificationContext";
const inter = Inter({ subsets: ["latin"] });
export const metadata = {
- title: "Create Next App",
+ title: "TeamBook",
description: "Generated by create next app",
};
export default function RootLayout({ children }) {
return (
- {children}
+
+
+
+ {children}
+
+
);
}
diff --git a/src/app/lib/TypesHelper.js b/src/app/lib/TypesHelper.js
new file mode 100644
index 0000000000000000000000000000000000000000..8077bc8cdb962a8c84c120e94ded330e19f02a38
--- /dev/null
+++ b/src/app/lib/TypesHelper.js
@@ -0,0 +1,3 @@
+export const isArray = (arg) => {
+ return Array.isArray(arg)
+}
\ No newline at end of file
diff --git a/src/app/lib/constants.js b/src/app/lib/constants.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d34296b9316dac3c714bc0476dcfa97e05dda4d
--- /dev/null
+++ b/src/app/lib/constants.js
@@ -0,0 +1,3 @@
+export const PASSWORD_REGEX = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[^a-zA-Z\d\s]).*$/;
+export const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@teamwillgroup\.com$/
+export const PAGINATION_SIZE = 3
\ No newline at end of file
diff --git a/src/app/lib/dal.js b/src/app/lib/dal.js
deleted file mode 100644
index 74c6293b78f5f50dac5fc7d8a9b11ed8f1b15fbe..0000000000000000000000000000000000000000
--- a/src/app/lib/dal.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'server-only'
-
-import Cookies from 'js-cookie';
-import { decrypt } from '@/app/lib/session'
-import {redirect} from "next/navigation";
-
-export const verifySession = cache(async () => {
- const cookie = Cookies.get('session').value
- const session = await decrypt(cookie)
-
- if (!session.token) {
- redirect('/login')
- }
-
- return { isAuth: true, userName: session.username }
-})
\ No newline at end of file
diff --git a/src/app/lib/fetchRequest.js b/src/app/lib/fetchRequest.js
index 3afb1c3072b662f2ba0461e36390f1f9e0700eed..a47d118550b459a157d8b8878de6a0cb8a859cd5 100644
--- a/src/app/lib/fetchRequest.js
+++ b/src/app/lib/fetchRequest.js
@@ -1,29 +1,52 @@
-//custom fetch tha have the token in header
-
import Cookies from 'js-cookie';
import {decrypt} from "@/app/lib/session";
+const BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"
const fetchRequest = async (url, options = {}) => {
- const token = Cookies.get('session');
- console.log('token', token)
- const jwtDecrypted = decrypt(token);
- console.log('jwtDecrypted', jwtDecrypted)
+ const jwtCookie = Cookies.get('session');
+ console.log('jwtCookie', jwtCookie)
+ const jwtDecrypted = await decrypt(jwtCookie);
+ console.log('jwtDecrypted', jwtDecrypted.sessionData.token)
const headers = {
...options.headers,
- 'Authorization': `Token ${token}`,
+ // add authorization header with token if there is jwtDecrypted.sessionData.token
+ Authorization: jwtDecrypted?.sessionData.token ? `Token ${jwtDecrypted.sessionData.token}` : undefined,
'Content-Type': 'application/json',
};
- const response = await fetch(url, {
+ const response = await fetch(`${BASE_URL}${url}`, {
...options,
headers,
});
-
+ console.log(response.status)
if (!response.ok) {
- throw new Error('Network response was not ok');
+ try {
+ const errorData = await response.json();
+ return {isSuccess: false, errors: errorData, data: null, status: response.status}
+ } catch (error) {
+ return {isSuccess: false, errors: error, data: null, status: response.status}
+ }
}
-
- return response.json();
+ console.log('response', response)
+ // Check if the response has content before parsing it as JSON
+ const contentType = response.headers.get('content-type');
+ if (contentType && contentType.includes('application/json')) {
+ const data = await response.json();
+ return {isSuccess: true, errors: null, data: data, status: response.status};
+ }
+ // If no JSON content, return null for data
+ return {isSuccess: true, errors: null, data: data, status: response.status};
};
export default fetchRequest;
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/lib/fetchRequestServer.js b/src/app/lib/fetchRequestServer.js
new file mode 100644
index 0000000000000000000000000000000000000000..16aafe94dd8d3c9fe65996005f25770a3231b70e
--- /dev/null
+++ b/src/app/lib/fetchRequestServer.js
@@ -0,0 +1,48 @@
+// src/app/lib/fetchRequestServer.js
+import {cookies as nextCookies} from 'next/headers';
+import {decrypt} from "@/app/lib/session";
+
+const BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
+
+const fetchRequestServer = async (url, options = {}) => {
+ const cookieStore = nextCookies();
+ const jwtCookie = cookieStore.get('session')?.value;
+
+ if (!jwtCookie) {
+ return {isSuccess: false, errors: "No session cookie found", data: null};
+ }
+
+ const jwtDecrypted = await decrypt(jwtCookie);
+
+ const headers = {
+ ...options.headers,
+ Authorization: jwtDecrypted?.sessionData.token ? `Token ${jwtDecrypted.sessionData.token}` : undefined,
+ 'Content-Type': 'application/json',
+ };
+
+ const response = await fetch(`${BASE_URL}${url}`, {
+ ...options,
+ headers,
+ });
+
+ if (!response.ok) {
+ try {
+ const errorData = await response.json();
+ return {isSuccess: false, errors: errorData, data: null};
+ } catch (error) {
+ return {isSuccess: false, errors: error, data: null};
+ }
+ }
+
+ // Check if the response has content before parsing it as JSON
+ const contentType = response.headers.get('content-type');
+ if (contentType && contentType.includes('application/json')) {
+ const data = await response.json();
+ return {isSuccess: true, errors: null, data: data};
+ }
+ // If no JSON content, return null for data
+ return {isSuccess: true, errors: null, data: null};
+
+};
+
+export default fetchRequestServer;
diff --git a/src/app/lib/isAuthenticated.js b/src/app/lib/isAuthenticated.js
index 0a880acf5d8ce15ae58da3d0295208ff7a4ca3f6..7c77a5e9fe0c6cb8dff56ea1052bd1b27e4b6f6b 100644
--- a/src/app/lib/isAuthenticated.js
+++ b/src/app/lib/isAuthenticated.js
@@ -1,16 +1,20 @@
//verify if the user is authenticated
import Cookies from "js-cookie";
+import {decrypt} from "@/app/lib/session";
-export default function isAuthenticated() {
+export default async function isAuthenticated() {
if (!Cookies.get('session')) {
console.log('user is not authenticated');
// redirect to auth/login page
- window.location.href = '/auth/login';
-
+ // window.location.href = '/auth/login';
return false;
}
- else console.log('user is authenticated');
- return true;
+
+ console.log('user is authenticated');
+ const session = Cookies.get('session')
+ const cookieDecoded = await decrypt(session)
+ return { isAuth: true, sessionData: cookieDecoded.sessionData }
+
}
diff --git a/src/app/lib/isAuthenticatedSSR.js b/src/app/lib/isAuthenticatedSSR.js
new file mode 100644
index 0000000000000000000000000000000000000000..b06881511928d746e1963011e32bac21034e96b9
--- /dev/null
+++ b/src/app/lib/isAuthenticatedSSR.js
@@ -0,0 +1,20 @@
+//verify if the user is authenticated
+import { cookies } from 'next/headers'
+
+import {decrypt} from "@/app/lib/session";
+
+export default async function isAuthenticatedSSR() {
+ if (!cookies().get('session')) {
+ console.log('user is not authenticated');
+ // redirect to auth/login page
+ // window.location.href = '/auth/login';
+ return false;
+ }
+
+ console.log('user is authenticated');
+ const cookie = cookies().get('session')?.value
+ const session = await decrypt(cookie)
+ return { isAuth: true, sessionData: session.sessionData }
+
+}
+
diff --git a/src/app/lib/session.js b/src/app/lib/session.js
index 850ed748db48de63bae014a7fe245ff3a84f3278..1eb509a2e30326ef4e345033f9811c8dc0688513 100644
--- a/src/app/lib/session.js
+++ b/src/app/lib/session.js
@@ -2,7 +2,8 @@
import Cookies from 'js-cookie';
import { SignJWT, jwtVerify } from 'jose'
-const secretKey = "password1234"
+const secretKey = process.env.NEXT_PUBLIC_SESSION_SECRET;
+console.log(secretKey);
const encodedKey = new TextEncoder().encode(secretKey)
export async function encrypt(payload) {
diff --git a/src/app/page.js b/src/app/page.js
index ecfca6f8e5034eb7f60a623d3db202433f6b96b9..87ce7aa74a17bf1ba51f0e9979b2d955634bf8ca 100644
--- a/src/app/page.js
+++ b/src/app/page.js
@@ -1,149 +1,8 @@
-import Image from "next/image";
export default function Home() {
return (
-
-
- Get started by editing
- src/app/page.js
-
-
-
-
-
-
-
-
-
+ Home Page
);
}
diff --git a/src/app/privilege/CreatePrivilegeForm.jsx b/src/app/privilege/CreatePrivilegeForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..d124e2edfbefad535461e370dcba8910952705f8
--- /dev/null
+++ b/src/app/privilege/CreatePrivilegeForm.jsx
@@ -0,0 +1,78 @@
+'use client'
+import Loader from '@/components/Loader/Loader'
+import React, { useRef, useState } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import {useNotification} from "@/context/NotificationContext";
+
+const CreatePrivilegeForm = ({ appendPrivilege }) => {
+ const [isLoading, setIsLoading] = useState(false)
+ const [error, setError] = useState(null)
+ const [privilegeName, setPrivilegeName] = useState("");
+ const { toggleNotification } = useNotification()
+ const handlePrivilegeNameChange = (event) => {
+ setError("")
+ setPrivilegeName(event.target.value)
+ }
+ const inputRef = useRef(null)
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setIsLoading(true)
+ const { data, errors, isSuccess } = await fetchRequest("/privileges/", {
+ method: "POST",
+ body: JSON.stringify({ name: privilegeName })
+ })
+ if (isSuccess) {
+ setIsLoading(false)
+ appendPrivilege(data)
+ inputRef.current.value = ""
+ setPrivilegeName("")
+ toggleNotification({
+ visible: true,
+ message: "L'habilitation a été créé avec succès",
+ type: "success"
+ })
+ } else {
+ setIsLoading(false)
+ if (errors.type === "ValidationError") {
+ if (errors.detail.name) {
+ toggleNotification({
+ type: "warning",
+ message: "Le nom de l'habilitation existe déjà",
+ visible: true,
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de l'habilitation",
+ type: "warning"
+ })
+ }
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ console.log(errors)
+ }
+ }
+ return (
+
+ )
+}
+
+export default CreatePrivilegeForm
\ No newline at end of file
diff --git a/src/app/privilege/PrivilegeTableRow.jsx b/src/app/privilege/PrivilegeTableRow.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7537e45773778a694de9fbe0655fdb37d9a04980
--- /dev/null
+++ b/src/app/privilege/PrivilegeTableRow.jsx
@@ -0,0 +1,174 @@
+'use client'
+import React, { useEffect, useRef, useState } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import Loader from '@/components/Loader/Loader'
+import DeleteIcon from "@/static/image/svg/delete.svg"
+import EditIcon from "@/static/image/svg/edit.svg"
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import CheckIcon from "@/static/image/svg/check.svg"
+import { useNotification } from '@/context/NotificationContext'
+import ConfirmationModal from '../ui/ConfirmationModal'
+const PrivilegeTableRow = ({ id, name, setPrivileges }) => {
+ const [isUpdating, setIsUpdating] = useState(false)
+ const [privilegeName, setPrivilegeName] = useState(name)
+ const [loadingStatus, setLoadingStatus] = useState(false)
+ const { toggleNotification } = useNotification()
+ const [isModalOpen, setModalOpen] = useState(false)
+ const showDeletePopup = () => {
+ setModalOpen(true);
+ }
+ useEffect(() => {
+ setPrivilegeName(name)
+ inputRef.current.value = name
+ }, [name])
+ const handleUpdatePrivilege = async () => {
+ setLoadingStatus(true)
+ const { isSuccess, errors, data, status } = await fetchRequest(`/privileges/${id}/`, {
+ method: "PATCH",
+ body: JSON.stringify({ name: privilegeName })
+ })
+ setLoadingStatus(false)
+ if (isSuccess) {
+ setPrivileges((privileges) => privileges.map((element) => element.id === id ? data.data : element))
+ setIsUpdating(false)
+ toggleNotification({
+ visible: true,
+ message: "L'habilitation a été modifiée avec succès.",
+ type: "success"
+ })
+ } else {
+ if (errors.type === "ValidationError") {
+ if (errors.detail.name) {
+ toggleNotification({
+ type: "warning",
+ message: "Le nom de l'habilitation existe déjà",
+ visible: true,
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de l'habilitation",
+ type: "warning"
+ })
+ }
+ } else if (status === 404) {
+ toggleNotification({
+ visible: true,
+ message: "L'habilitation n'a pas été trouvé",
+ type: "warning"
+ })
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ console.log(errors)
+ }
+
+ }
+ const handleDelete = async () => {
+ const { isSuccess, errors, status } = await fetchRequest(`/privileges/${id}/`, { method: "DELETE" })
+ if (isSuccess) {
+ setPrivileges((privileges) => privileges.filter((element) => element.id !== id))
+ toggleNotification({
+ visible: true,
+ message: "L'habilitation a été supprimée avec succès",
+ type: "success"
+ })
+ } else if (status == 404) {
+ toggleNotification({
+ visible: true,
+ message: "L'habilitation n'a pas été trouvé",
+ type: "warning"
+ })
+ } else {
+ console.log(errors)
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ setModalOpen(false)
+ }
+ const cancelUpdate = () => {
+ setIsUpdating(false)
+ setPrivilegeName(name)
+ inputRef.current.value = name
+ }
+ const inputRef = useRef(null)
+ const rowRef = useRef(null)
+ const handleUpdateBlur = (event) => {
+ const eventTarget = event.target
+ let isInsideRowRef = false;
+ let element = eventTarget;
+ while (element !== null) {
+ if (element === rowRef.current) {
+ isInsideRowRef = true;
+ break;
+ }
+ if (element.parentElement === null) {
+ isInsideRowRef = false;
+ break;
+ }
+ element = element.parentElement;
+ }
+ if (!isInsideRowRef && element?.classList.contains("privilegeRowSVG")) return;
+ if (!isInsideRowRef) {
+ cancelUpdate();
+ document.removeEventListener("click", handleUpdateBlur);
+ }
+ }
+ useEffect(() => {
+ if (isUpdating && inputRef?.current) {
+ inputRef.current.focus()
+ document.addEventListener("click", handleUpdateBlur)
+ }
+ return () => {
+ document.removeEventListener("click", handleUpdateBlur)
+ }
+ }, [isUpdating])
+ return (
+ <>
+
+ |
+ setPrivilegeName(event.target.value)} defaultValue={name} type='text' className='disabled:bg-white w-full border-0 rounded-md px-2 enabled:drop-shadow border-none enabled:bg-gray-100 duration-100 h-10 outline-none' />
+ |
+
+ {!isUpdating
+ ?
+
+
+
+ :
+
+
+
+ }
+ |
+
+
setModalOpen(false)}
+ onConfirm={handleDelete}
+ message={`Voulez-vous vraiment supprimer l'habilitation ?`}
+ />
+ >
+ )
+
+}
+
+export default PrivilegeTableRow
\ No newline at end of file
diff --git a/src/app/privilege/page.jsx b/src/app/privilege/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..46c9515f8523b64d56f4b60cedc04afaffeaf2fb
--- /dev/null
+++ b/src/app/privilege/page.jsx
@@ -0,0 +1,55 @@
+'use client'
+import React, { useEffect, useState } from 'react'
+import CreatePrivilegeForm from './CreatePrivilegeForm'
+import fetchRequest from '../lib/fetchRequest'
+import { isArray } from '../lib/TypesHelper'
+import PrivilegeTableRows from './PrivilegeTableRow'
+import Loader from '@/components/Loader/Loader'
+const Privilege = () => {
+ const [privileges, setPrivileges] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
+ useEffect(() => {
+ const getPrivileges = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/privileges")
+ setIsLoading(false)
+ if (isSuccess) {
+ setPrivileges(data)
+ } else {
+ console.log(errors)
+ }
+ }
+ getPrivileges()
+ }, [])
+ const appendPrivilege = (privilege) => {
+ setPrivileges((data) => [privilege, ...data])
+ }
+ return (
+
+
+
+
+
List des habilitations
+ {isLoading &&
}
+ {!isLoading && <> {(!isArray(privileges) || privileges?.length === 0)
+ ?
+
Pas encore des habilitations
+
+ :
+
+
+ | Habilitation |
+ Action |
+
+ {privileges.map((element) => {
+ return
+ })}
+
+
+ }>}
+
+
+
+ )
+}
+
+export default Privilege
\ No newline at end of file
diff --git a/src/app/projects/ProjectForm.jsx b/src/app/projects/ProjectForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..e8a184e425f1a48ab632b2c13242421776ed4318
--- /dev/null
+++ b/src/app/projects/ProjectForm.jsx
@@ -0,0 +1,188 @@
+import { useState, useEffect } from 'react';
+import fetchRequest from '@/app/lib/fetchRequest';
+
+const ProjectForm = ({ onAddProject, onEditProject, editingProject }) => {
+ const [projectName, setProjectName] = useState('');
+ const [clientName, setClientName] = useState('');
+ const [dateDebut, setDateDebut] = useState('');
+ const [dateFin, setDateFin] = useState('');
+ const [userIds, setUserIds] = useState([]);
+ const [searchQuery, setSearchQuery] = useState('');
+ const [userSuggestions, setUserSuggestions] = useState([]);
+ const [errors, setErrors] = useState({});
+
+ useEffect(() => {
+ if (editingProject) {
+ setProjectName(editingProject.nom);
+ setClientName(editingProject.nomClient);
+ setDateDebut(editingProject.dateDebut);
+ setDateFin(editingProject.dateFin);
+ setUserIds(editingProject.users || []);
+ } else {
+ setProjectName('');
+ setClientName('');
+ setDateDebut('');
+ setDateFin('');
+ setUserIds([]);
+ }
+ }, [editingProject]);
+
+ useEffect(() => {
+ if (searchQuery.length > 1) {
+ const fetchUsers = async () => {
+ const { isSuccess, data } = await fetchRequest(`/search-users/?q=${searchQuery}`);
+ if (isSuccess) {
+ setUserSuggestions(data);
+ }
+ };
+ fetchUsers();
+ } else {
+ setUserSuggestions([]);
+ }
+ }, [searchQuery]);
+
+ const handleUserSelect = (user) => {
+ setUserIds([...userIds, user]);
+ setSearchQuery('');
+ setUserSuggestions([]);
+ };
+
+ const handleRemoveUserId = (index) => {
+ setUserIds(userIds.filter((_, i) => i !== index));
+ };
+
+ const validateForm = () => {
+ const newErrors = {};
+ if (!projectName) newErrors.projectName = "Project name is required";
+ if (!clientName) newErrors.clientName = "Client name is required";
+ if (!dateDebut) newErrors.dateDebut = "Start date is required";
+ if (!userIds.length) newErrors.userIds = "At least one user is required";
+
+ setErrors(newErrors);
+ return Object.keys(newErrors).length === 0;
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ if (!validateForm()) return;
+
+ const project = {
+ nom: projectName,
+ nomClient: clientName,
+ dateDebut,
+ dateFin,
+ user_ids: userIds.map(user => user.id),
+ };
+
+ if (editingProject) {
+ onEditProject(editingProject.id, project);
+ } else {
+ onAddProject(project);
+ }
+ };
+
+ const isUserChosen = (user) => {
+ return userIds.some(chosenUser => chosenUser.id === user.id);
+ };
+
+ return (
+
+ );
+};
+
+export default ProjectForm;
diff --git a/src/app/projects/ProjectList.jsx b/src/app/projects/ProjectList.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..16d3fe3579cd7a07d7b7f1a293c3d0bed6afca85
--- /dev/null
+++ b/src/app/projects/ProjectList.jsx
@@ -0,0 +1,117 @@
+import ConfirmationModal from "@/app/ui/ConfirmationModal";
+import { useState } from "react";
+
+const ProjectList = ({ projects, onEdit, onDelete, onHandlePageUrl }) => {
+ const [isModalOpen, setModalOpen] = useState(false);
+ const [projectToDelete, setProjectToDelete] = useState(null);
+ const handleDeleteClick = (project) => {
+ setProjectToDelete(project);
+ setModalOpen(true);
+ };
+
+ const handleConfirmDelete = () => {
+ onDelete(projectToDelete);
+ setModalOpen(false);
+ setProjectToDelete(null);
+ };
+ return (
+ <>
+
+
+
+ | Projet |
+ Membres de léquipe |
+ Nom du client |
+ Actions |
+
+
+
+ {projects
+ .sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))
+ .map((project, index) => (
+
+ | {project.nom} |
+ {project.users.length} |
+ {project.nomClient} |
+
+
+
+ |
+
+ ))}
+
+
+ {/* Pagination */}
+ {projects.count &&
+
+
+ -
+
+
+ -
+ 1
+
+ -
+
+
+
+
+ }
+ {/* Confirmation Modal */}
+ setModalOpen(false)}
+ onConfirm={handleConfirmDelete}
+ message={`Are you sure you want to delete the project "${projectToDelete?.nom}"?`}
+ />
+ >
+ );
+};
+
+export default ProjectList;
diff --git a/src/app/projects/SideBar.jsx b/src/app/projects/SideBar.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..35e67e9ef9c957caba4dd59c0a72c688a2920c34
--- /dev/null
+++ b/src/app/projects/SideBar.jsx
@@ -0,0 +1,183 @@
+const SideBar = () => {
+ return (
+
+
+ );
+}
+export default SideBar;
\ No newline at end of file
diff --git a/src/app/projects/page.jsx b/src/app/projects/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..14a694adcd27d49a78664cb97ceb91bbab1580bd
--- /dev/null
+++ b/src/app/projects/page.jsx
@@ -0,0 +1,141 @@
+'use client';
+
+import SideBar from "@/app/projects/SideBar";
+import { useEffect, useState } from 'react';
+import ProjectForm from "@/app/projects/ProjectForm";
+import ProjectList from "@/app/projects/ProjectList";
+import fetchRequest from "@/app/lib/fetchRequest";
+
+const Projects = () => {
+ const [pageUrl, setPageUrl] = useState('/projects/');
+ const [projects, setProjects] = useState([]);
+ const [editingProject, setEditingProject] = useState(null);
+ {/* errors from request*/ }
+ const [errors, setErrors] = useState();
+ const [loading, setLoading] = useState(false);
+ const fetchProjects = async () => {
+ const { isSuccess, errors, data } = await fetchRequest(pageUrl);
+ if (isSuccess) {
+ setProjects(data);
+ setErrors(null);
+ } else {
+ console.error("Failed to fetch projects");
+ setErrors(errors)
+ }
+ };
+ useEffect(() => {
+
+ fetchProjects();
+ }, [pageUrl]);
+
+ // pageURL
+
+ const handleAddProject = async (project) => {
+ setLoading(true);
+ const { isSuccess, errors, data } = await fetchRequest('/projects/', {
+ method: 'POST',
+ body: JSON.stringify(project),
+ });
+
+ if (isSuccess) {
+ setProjects([...projects, data]);
+ setEditingProject(null);
+ setErrors(null);
+ } else {
+ console.log(errors);
+ console.error("Failed to add project");
+ setErrors(errors)
+ }
+ setLoading(false);
+ };
+
+ const handleEditProject = async (id, updatedProject) => {
+ setLoading(true);
+ const { isSuccess, errors, data } = await fetchRequest(`/projects/${id}/`, {
+ method: 'PUT',
+ body: JSON.stringify(updatedProject),
+ });
+
+ if (isSuccess) {
+ const updatedProjects = projects.map((project) =>
+ project.id === id ? data : project
+ );
+ setProjects(updatedProjects);
+ setEditingProject(null);
+ setErrors(null);
+ } else {
+ console.error("Failed to edit project");
+ setErrors(errors)
+ }
+ setLoading(false);
+ };
+
+ const handleEditClick = (project) => {
+ setEditingProject(project);
+ };
+
+ const handleDeleteProject = async (project) => {
+ setLoading(true)
+ const { isSuccess, errors } = await fetchRequest(`/projects/${project.id}/`, {
+ method: 'DELETE',
+ });
+
+ if (isSuccess) {
+ // setProjects(projects.filter((p) => p.id !== project.id));
+ await fetchProjects();
+ setEditingProject(null);
+ setErrors(null);
+ } else {
+ console.error("Failed to delete project");
+ setErrors(errors)
+ }
+ setLoading(false);
+ };
+
+ return (
+
+
+
+
+
+
+
+
Projets
+ {loading ? ... : null}
+
+ {/*errors from request*/}
+ {errors && errors.detail && Object.keys(errors.detail).map((key) => (
+
+
+
+
Something went wrong
+
+
+ {errors.detail[key]}
+
+
+ ))}
+
+
+
+
+
+ );
+}
+export default Projects;
+
diff --git a/src/app/role/CreateRoleForm.jsx b/src/app/role/CreateRoleForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..d7c479d0ba974ae82aebbaddb6c4d8f8ae95cfa8
--- /dev/null
+++ b/src/app/role/CreateRoleForm.jsx
@@ -0,0 +1,144 @@
+import Loader from '@/components/Loader/Loader'
+import React, { useState, useRef, useEffect, useMemo } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import { useNotification } from '@/context/NotificationContext'
+import CancelIcon from "@/static/image/svg/cancel.svg"
+const CreateRoleForm = ({ appendRole, setIsOpen }) => {
+ const [isLoading, setIsLoading] = useState(false)
+ const [roleName, setRoleName] = useState("")
+ const [privileges, setPrivileges] = useState(null)
+ const [selectedPrivileges, setSelectedPrivileges] = useState([])
+ const { toggleNotification } = useNotification()
+ useEffect(() => {
+ const getPrivileges = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/privileges")
+ if (isSuccess) {
+ setPrivileges(data)
+ } else {
+ setPrivileges([])
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ getPrivileges()
+ }, [])
+ const handleRoleNameChange = (event) => {
+ setRoleName(event.target.value)
+ }
+ const inputRef = useRef(null)
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setIsLoading(true)
+ const { data, errors, isSuccess, status } = await fetchRequest("/roles/", {
+ method: "POST",
+ body: JSON.stringify({ name: roleName, privileges: selectedPrivileges.map((element) => element.id) })
+ })
+ if (isSuccess) {
+ setIsLoading(false)
+ inputRef.current.value = ""
+ setSelectedPrivileges([])
+ setRoleName("")
+ appendRole(data)
+ toggleNotification({
+ visible: true,
+ message: "Le rôle a été créé avec succès",
+ type: "success"
+ })
+ setIsOpen(false)
+ } else {
+ setIsLoading(false)
+ if (errors.type === "ValidationError") {
+ if (errors.detail.name) {
+ toggleNotification({
+ visible: true,
+ message: "Le rôle existe déjà",
+ type: "warning"
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de rôle",
+ type: "warning"
+ })
+ setIsOpen(false)
+ }
+ }
+ else if (status === 409) {
+ toggleNotification({
+ visible: true,
+ message: "Roles created with 2 or more same privileges",
+ type: "error"
+ })
+ setIsOpen(false)
+ } else if (errors.detail === "Privilege matching query does not exist.") {
+ toggleNotification({
+ visible: true,
+ message: "Des privilèges que vous avez utilisés ont été supprimés.",
+ type: "warning"
+ })
+ setIsOpen(false)
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ setIsOpen(false)
+ }
+ console.log(errors)
+ }
+ }
+ const handlePrivilegeClick = (privilege) => {
+ if (selectedPrivileges.find((element) => element.id === privilege.id)) {
+ setSelectedPrivileges(selectedPrivileges.filter((element) => element.id !== privilege.id))
+ } else {
+ setSelectedPrivileges([...selectedPrivileges, privilege])
+ }
+ }
+ const selectAll = () => {
+ if (privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)))
+ setSelectedPrivileges([])
+ else setSelectedPrivileges(privileges)
+ }
+ var isAllSelected = useMemo(() => privileges ? privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)) : false, [selectedPrivileges, privileges])
+ return (
+
+
+
setIsOpen(false)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" />
+ {(privileges) ? :
}
+
+
+ )
+}
+
+export default CreateRoleForm
\ No newline at end of file
diff --git a/src/app/role/RoleTableRows.jsx b/src/app/role/RoleTableRows.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..c937dc003abaa06eb94bcdebe535b758c83843a7
--- /dev/null
+++ b/src/app/role/RoleTableRows.jsx
@@ -0,0 +1,84 @@
+import React, { useState } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import DeleteIcon from "@/static/image/svg/delete.svg"
+import EditIcon from "@/static/image/svg/edit.svg"
+import { useNotification } from '@/context/NotificationContext'
+import ConfirmationModal from '../ui/ConfirmationModal'
+
+const RoleTableRows = ({ name, setRoles, id, privileges, setRoleToUpdate }) => {
+ const { toggleNotification } = useNotification()
+ const [isModalOpen, setModalOpen] = useState(false);
+
+ const showDeletePopup = () => {
+ setModalOpen(true);
+ }
+ const handleDelete = async () => {
+ const { isSuccess, errors, status } = await fetchRequest(`/roles/${id}/`, { method: "DELETE" })
+ if (isSuccess) {
+ setRoles((roles) => roles.filter((element) => element.id !== id))
+ toggleNotification({
+ visible: true,
+ message: "Le rôle a été supprimée avec succès",
+ type: "success"
+ })
+ } else if (status == 404) {
+ toggleNotification({
+ visible: true,
+ message: "Le rôle n'a pas été trouvé",
+ type: "warning"
+ })
+ } else if (errors.detail?.indexOf("Cannot delete some instances of model 'Role'") !== -1) {
+ toggleNotification({
+ visible: true,
+ message: "Impossible de supprimer ce rôle car il est attribué à des utilisateurs",
+ type: "warning"
+ })
+ }
+ else {
+ console.log(errors)
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ setModalOpen(false)
+ console.log(errors)
+ }
+
+ return (
+ <>
+
+ |
+ {name}
+ |
+
+
+ {privileges?.map((element, index) => {
+ return {element.name}
+ })}
+
+ |
+
+
+
+
+
+ |
+
+ setModalOpen(false)}
+ onConfirm={handleDelete}
+ message={`Voulez-vous vraiment supprimer le rôle ?`}
+ />
+ >
+
+ )
+}
+
+export default RoleTableRows
\ No newline at end of file
diff --git a/src/app/role/UpdateRoleForm.jsx b/src/app/role/UpdateRoleForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..348ebfce5dc70d57d41f4157b2bb2579c29dafca
--- /dev/null
+++ b/src/app/role/UpdateRoleForm.jsx
@@ -0,0 +1,143 @@
+import { useNotification } from '@/context/NotificationContext'
+import React, { useState, useRef, useEffect, useMemo } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import Loader from '@/components/Loader/Loader'
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import { isArray } from '../lib/TypesHelper'
+const UpdateRoleForm = ({ setRoleToUpdate, setRoles, roles, privileges: rolePrivileges, name, id }) => {
+ const { toggleNotification } = useNotification()
+ const [loadingStatus, setLoadingStatus] = useState(false)
+ const [roleName, setRoleName] = useState(name)
+ const [privileges, setPrivileges] = useState(null)
+ const [selectedPrivileges, setSelectedPrivileges] = useState(isArray(rolePrivileges) ? rolePrivileges : [])
+ const inputRef = useRef(null)
+ console.log("les priv de role ", rolePrivileges)
+ useEffect(() => {
+ const getPrivileges = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/privileges")
+ if (isSuccess) {
+ setPrivileges(data)
+ } else {
+ setPrivileges([])
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ getPrivileges()
+ }, [])
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ setLoadingStatus(true)
+ const { isSuccess, errors, data, status } = await fetchRequest(`/roles/${id}/`, {
+ method: "PATCH",
+ body: JSON.stringify({ name: roleName, privileges: selectedPrivileges.filter((element) => privileges.find((prvElement) => prvElement.id === element.id)).map((element) => element.id) })
+ })
+ console.log(data)
+ setLoadingStatus(false)
+ if (isSuccess) {
+ setRoles((roles) => roles.map((element) => element.id === id ? data : element))
+ toggleNotification({
+ visible: true,
+ message: "Le rôle a été modifé avec succès",
+ type: "success"
+ })
+ setRoleToUpdate(null)
+ } else {
+ if (errors.type === "ValidationError") {
+ if (errors.detail.name) {
+ toggleNotification({
+ type: "warning",
+ message: "Le nom de rôle existe déjà",
+ visible: true,
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de rôle",
+ type: "warning"
+ })
+ setRoleToUpdate(null)
+ }
+ } else if (status === 404) {
+ toggleNotification({
+ visible: true,
+ message: "Le rôle n'a pas été trouvé",
+ type: "warning"
+ })
+ setRoleToUpdate(null)
+ } else if (errors.detail === "Privilege matching query does not exist.") {
+ toggleNotification({
+ visible: true,
+ message: "Des privilèges que vous avez utilisés ont été supprimés.",
+ type: "warning"
+ })
+ setRoleToUpdate(null)
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ setRoleToUpdate(null)
+ }
+ console.log(errors)
+ }
+ }
+ const handleRoleNameChange = (event) => {
+ setRoleName(event.target.value)
+ }
+ const handlePrivilegeClick = (privilege) => {
+ if (selectedPrivileges.find((element) => element.id === privilege.id)) {
+ setSelectedPrivileges(selectedPrivileges.filter((element) => element.id !== privilege.id))
+ } else {
+ setSelectedPrivileges([...selectedPrivileges, privilege])
+ }
+ }
+ const selectAll = () => {
+ if (privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)))
+ setSelectedPrivileges([])
+ else setSelectedPrivileges(privileges)
+ }
+ var isAllSelected = useMemo(() => privileges ? privileges.every((element) => selectedPrivileges.find((priv) => priv.id === element.id)) : false, [selectedPrivileges, privileges])
+ return (
+
+
+
setRoleToUpdate(null)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" />
+ {(privileges) ? :
}
+
+
+ )
+}
+
+export default UpdateRoleForm
\ No newline at end of file
diff --git a/src/app/role/page.jsx b/src/app/role/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..411c32f224b7080f45d8f933a48805edd67ee899
--- /dev/null
+++ b/src/app/role/page.jsx
@@ -0,0 +1,75 @@
+'use client'
+import React, { useState, useEffect } from 'react'
+import CreateRoleForm from './CreateRoleForm'
+import Loader from '@/components/Loader/Loader'
+import RoleTableRows from './RoleTableRows'
+import fetchRequest from '../lib/fetchRequest'
+import { isArray } from '../lib/TypesHelper'
+import AddIcon from "@/static/image/svg/add.svg"
+import UpdateRoleForm from './UpdateRoleForm'
+import { useNotification } from '@/context/NotificationContext'
+const Role = () => {
+ const [roles, setRoles] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
+ const [openCreatePopup, setOpenCreatePopup] = useState(null)
+ const [roleToUpdate, setRoleToUpdate] = useState(null)
+ const { toggleNotification } = useNotification()
+ useEffect(() => {
+ const getRoles = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/roles")
+ setIsLoading(false)
+ if (isSuccess) {
+ console.log(data)
+ setRoles(data)
+ } else {
+ console.log(errors)
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ }
+ getRoles()
+ }, [])
+ const appendRole = (newRole) => {
+ setRoles([newRole, ...roles])
+ }
+ return (
+
+
+
+ {openCreatePopup &&
}
+ {roleToUpdate &&
}
+
+
List des Roles
+
+
+ {isLoading &&
}
+ {!isLoading && <> {(!isArray(roles) || roles?.length === 0)
+ ?
+ :
+
+
+ | Rôle |
+ Habilitations |
+ Action |
+
+ {roles?.map((element) => {
+ return
+ })}
+
+
+ }>}
+
+
+
+ )
+}
+
+export default Role
\ No newline at end of file
diff --git a/src/app/ui/ConfirmationModal.jsx b/src/app/ui/ConfirmationModal.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1c667ac3e0990319217a3c6136941e21731b095b
--- /dev/null
+++ b/src/app/ui/ConfirmationModal.jsx
@@ -0,0 +1,30 @@
+import React from 'react';
+
+const ConfirmationModal = ({ isOpen, onClose, onConfirm, message }) => {
+ if (!isOpen) return null;
+
+ return (
+
+
+
Confirmation
+
{message}
+
+
+
+
+
+
+ );
+};
+
+export default ConfirmationModal;
diff --git a/src/app/ui/Header.jsx b/src/app/ui/Header.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1137e74f45a87cdbf0d69bd65b5a15668ad8219c
--- /dev/null
+++ b/src/app/ui/Header.jsx
@@ -0,0 +1,54 @@
+// 'use client';
+
+// import { useState, useEffect } from 'react';
+import Link from 'next/link';
+// import isAuthenticated from "@/app/lib/isAuthenticated";
+import isAuthenticatedSSR from "@/app/lib/isAuthenticatedSSR";
+import LogoutButton from "@/app/ui/LogoutButton";
+// import fetchRequest from "@/app/lib/fetchRequest";
+// import Cookies from "js-cookie";
+
+const Header = async () => {
+
+ const {isAuth, sessionData} = await isAuthenticatedSSR()
+ console.log('isAuth', isAuth)
+ console.log('sessionData', sessionData)
+ return (
+
+
+
+
+ );
+};
+
+export default Header;
\ No newline at end of file
diff --git a/src/app/ui/LogoutButton.js b/src/app/ui/LogoutButton.js
new file mode 100644
index 0000000000000000000000000000000000000000..b219fc4381e545d6cd4e3facfe37c20696fbe65b
--- /dev/null
+++ b/src/app/ui/LogoutButton.js
@@ -0,0 +1,26 @@
+'use client';
+
+import Cookies from 'js-cookie';
+import fetchRequest from "@/app/lib/fetchRequest";
+
+const LogoutButton = () => {
+ const logout = async () => {
+ const response = await fetchRequest(`/logout`, {
+ method: 'GET'});
+ console.log(response);
+ if (response.isSuccess) {
+ console.log('logout successful');
+ Cookies.remove('session');
+ window.location.href = '/';
+ }
+
+ };
+
+ return (
+
+ );
+};
+
+export default LogoutButton;
diff --git a/src/app/user/CreateUserForm.jsx b/src/app/user/CreateUserForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1b4540dded96560ea804cbd0e84475a0e820fc27
--- /dev/null
+++ b/src/app/user/CreateUserForm.jsx
@@ -0,0 +1,236 @@
+import React, { useState, useEffect } from 'react'
+import Loader from '@/components/Loader/Loader'
+import fetchRequest from '../lib/fetchRequest'
+import { useNotification } from '@/context/NotificationContext'
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import { EMAIL_REGEX } from '../lib/constants'
+
+
+
+
+function generateRandomPassword() {
+ const length = Math.floor(Math.random() * 3) + 8; // Length between 8 and 10
+ const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ const lowercase = 'abcdefghijklmnopqrstuvwxyz';
+ const numbers = '0123456789';
+ const symbols = '!@#$%^&*()_+[]{}|;:,.<>?';
+
+ let password = '';
+
+ password += uppercase[Math.floor(Math.random() * uppercase.length)];
+ password += numbers[Math.floor(Math.random() * numbers.length)];
+ password += symbols[Math.floor(Math.random() * symbols.length)];
+
+ const allCharacters = uppercase + lowercase + numbers + symbols;
+
+ for (let i = 3; i < length; i++) {
+ const randomIndex = Math.floor(Math.random() * allCharacters.length);
+ password += allCharacters[randomIndex];
+ }
+
+ password = password.split('').sort(() => 0.5 - Math.random()).join('');
+
+ return password;
+}
+const CreateUserForm = ({ setIsOpen, appendUser }) => {
+ const [isLoading, setIsLoading] = useState(false)
+ const [selectedRole, setSelectedRole] = useState(null)
+ const { toggleNotification } = useNotification()
+ const [selectedProject, setSelectedProject] = useState([])
+
+ const [roles, setRoles] = useState(null)
+ const [projects, setProjects] = useState(null)
+ useEffect(() => {
+ const getRoles = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/roles/")
+ if (isSuccess) {
+ setRoles(data)
+ } else {
+ setRoles([])
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ const getProjects = async () => {
+ const { isSuccess, errors, data } = await fetchRequest("/projects/");
+ if (isSuccess) {
+ setProjects(data);
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ getRoles()
+ getProjects()
+ }, [])
+ const handleFieldChange = (event) => {
+ setUserData({ ...userData, [event.target.name]: event.target.value })
+ setErrors({ ...errors, [event.target.name]: "" })
+ }
+ const [errors, setErrors] = useState({ first_name: "", last_name: "", email: "", role: "" })
+ const [userData, setUserData] = useState({ email: "", password: generateRandomPassword(), first_name: "", last_name: "" })
+
+ const isValidFields = () => {
+ const localErrors = { first_name: "", last_name: "", email: "", role: "" }
+ if (userData.first_name === "") localErrors.first_name = "Le prénom doit être spécifier."
+ if (userData.last_name === "") localErrors.last_name = "Le nom doit être spécifier."
+ if (!selectedRole) localErrors.role = "Le rôle doit être spécifier."
+ if (!userData.email) localErrors.email = "L'email doit être spécifier."
+ else if (!EMAIL_REGEX.test(userData.email)) localErrors.email = "Votre adresse email n'est pas valide."
+ setErrors({ ...localErrors })
+ return Object.values(localErrors).find((element) => element !== "") === undefined
+ }
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ if (isValidFields()) {
+ setIsLoading(true)
+ const { data, errors: requestErrors, isSuccess, status } = await fetchRequest("/users/", {
+ method: "POST",
+ body: JSON.stringify({ ...userData, username: userData.email, role: selectedRole, projects: selectedProject })
+ })
+ if (isSuccess) {
+ setIsLoading(false)
+ setSelectedRole(null)
+ appendUser(data)
+ toggleNotification({
+ visible: true,
+ message: "L'utilisateur a été créé avec succès",
+ type: "success"
+ })
+ setIsOpen(false)
+ } else {
+ setIsLoading(false)
+ if (requestErrors.type === "ValidationError") {
+ if (requestErrors.detail.email) {
+ setErrors({ ...errors, email: "Cette adresse email est déjà utilisée." })
+ }
+ else if (requestErrors.detail.role) {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de rôle (le rôle peut être supprimé)",
+ type: "warning"
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de utilisateur",
+ type: "warning"
+ })
+ setIsOpen(false)
+ }
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ setIsOpen(false)
+ }
+ console.log(requestErrors)
+ }
+ }
+
+ }
+ const handleRoleChange = (event) => {
+ setErrors({ ...errors, role: "" })
+ if (event.target.value)
+ setSelectedRole(event.target.value)
+ else setSelectedRole(null)
+ }
+ const handleProjectChange = (event) => {
+ if (event.target.value)
+ setSelectedProject([event.target.value])
+ else setSelectedProject([])
+ }
+ return (
+
+
+
setIsOpen(false)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" />
+ {(roles && projects) ? :
}
+
+
+ )
+}
+
+export default CreateUserForm
\ No newline at end of file
diff --git a/src/app/user/UpdateUserForm.jsx b/src/app/user/UpdateUserForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1e62cce821677d104112efa6e1185d54b24774b0
--- /dev/null
+++ b/src/app/user/UpdateUserForm.jsx
@@ -0,0 +1,206 @@
+import React, { useState, useEffect } from 'react'
+import Loader from '@/components/Loader/Loader'
+import fetchRequest from '../lib/fetchRequest'
+import { useNotification } from '@/context/NotificationContext'
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import { EMAIL_REGEX } from '../lib/constants'
+
+
+const UpdateUserForm = ({ setUserToUpdate, userToUpdate, setUsers }) => {
+ const [isLoading, setIsLoading] = useState(false)
+ const [selectedRole, setSelectedRole] = useState(userToUpdate.role?.id || null)
+ const { toggleNotification } = useNotification()
+ const [selectedProject, setSelectedProject] = useState(userToUpdate.projects?.length ? [userToUpdate.projects[0].id] : [])
+
+ const [roles, setRoles] = useState(null)
+ const [projects, setProjects] = useState(null)
+ useEffect(() => {
+ const getRoles = async () => {
+ const { data, errors, isSuccess } = await fetchRequest("/roles/")
+ if (isSuccess) {
+ setRoles(data)
+ } else {
+ setRoles([])
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ const getProjects = async () => {
+ const { isSuccess, errors, data } = await fetchRequest("/projects/");
+ if (isSuccess) {
+ setProjects(data);
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ console.log(errors)
+ }
+ }
+ getRoles()
+ getProjects()
+ }, [])
+ const handleFieldChange = (event) => {
+ setUserData({ ...userData, [event.target.name]: event.target.value })
+ setErrors({ ...errors, [event.target.name]: "" })
+ }
+ const [errors, setErrors] = useState({ first_name: "", last_name: "", email: "", role: "" })
+ const [userData, setUserData] = useState({ email: userToUpdate.email, first_name: userToUpdate.first_name, last_name: userToUpdate.last_name })
+
+ const isValidFields = () => {
+ const localErrors = { first_name: "", last_name: "", email: "", role: "" }
+ if (userData.first_name === "") localErrors.first_name = "Le prénom doit être spécifier."
+ if (userData.last_name === "") localErrors.last_name = "Le nom doit être spécifier."
+ if (!selectedRole) localErrors.role = "Le rôle doit être spécifier."
+ if (!userData.email) localErrors.email = "L'email doit être spécifier."
+ else if (!EMAIL_REGEX.test(userData.email)) localErrors.email = "Votre adresse email n'est pas valide."
+ setErrors({ ...localErrors })
+ return Object.values(localErrors).find((element) => element !== "") === undefined
+ }
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ if (isValidFields()) {
+ setIsLoading(true)
+ const { data, errors: requestErrors, isSuccess, status } = await fetchRequest(`/users/${userToUpdate.id}/`, {
+ method: "PATCH",
+ body: JSON.stringify({ ...userData, username: userData.email, role: selectedRole, projects: selectedProject })
+ })
+ if (isSuccess) {
+ setUsers((users) => users.map((element) => element.id === userToUpdate.id ? data : element))
+ setIsLoading(false)
+ setSelectedRole(null)
+ toggleNotification({
+ visible: true,
+ message: "L'utilisateur a été modifié avec succès",
+ type: "success"
+ })
+ setUserToUpdate(null)
+ } else {
+ setIsLoading(false)
+ if (requestErrors.type === "ValidationError") {
+ if (requestErrors.detail.email) {
+ setErrors({ ...errors, email: "Cette adresse email est déjà utilisée." })
+ }
+ else if (requestErrors.detail.role) {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de rôle (le rôle peut être supprimé)",
+ type: "warning"
+ })
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Erreur de validation de utilisateur",
+ type: "warning"
+ })
+ setUserToUpdate(null)
+ }
+ }
+ else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ setUserToUpdate(null)
+ }
+ console.log(requestErrors)
+ }
+ }
+
+ }
+ const handleRoleChange = (event) => {
+ setErrors({ ...errors, role: "" })
+ if (event.target.value)
+ setSelectedRole(event.target.value)
+ else setSelectedRole(null)
+ }
+ const handleProjectChange = (event) => {
+ if (event.target.value)
+ setSelectedProject([event.target.value])
+ else setSelectedProject([])
+ }
+ return (
+
+
+
setUserToUpdate(null)} className="h-8 w-8 cursor-pointer absolute top-2 right-2 fill-neutral-600" />
+ {(roles && projects) ? :
}
+
+
+ )
+}
+
+export default UpdateUserForm
\ No newline at end of file
diff --git a/src/app/user/UserTableRow.jsx b/src/app/user/UserTableRow.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..e0575321e03509d921e81fa70d03b2846fa3073a
--- /dev/null
+++ b/src/app/user/UserTableRow.jsx
@@ -0,0 +1,88 @@
+import React, { useState } from 'react'
+import DeleteIcon from "@/static/image/svg/delete.svg"
+import EditIcon from "@/static/image/svg/edit.svg"
+import ConfirmationModal from '../ui/ConfirmationModal'
+import { useNotification } from '@/context/NotificationContext'
+import fetchRequest from '../lib/fetchRequest'
+
+const UserTableRow = ({ email, last_name, first_name, id, setUsers, role, projects, setUserToUpdate }) => {
+ const { toggleNotification } = useNotification()
+ const [isModalOpen, setModalOpen] = useState(false);
+ const showDeletePopup = () => {
+ setModalOpen(true);
+ }
+ const handleDelete = async () => {
+ const { isSuccess, errors, status } = await fetchRequest(`/users/${id}/`, { method: "DELETE" })
+ if (isSuccess) {
+ setUsers((users) => users.filter((element) => element.id !== id))
+ toggleNotification({
+ visible: true,
+ message: "L'utilisateur a été supprimé avec succès",
+ type: "success"
+ })
+ } else if (status == 404) {
+ toggleNotification({
+ visible: true,
+ message: "L'utilisateur n'a pas été trouvé",
+ type: "warning"
+ })
+ } else if (errors.detail?.indexOf("Cannot delete some instances of model") !== -1) {
+ toggleNotification({
+ visible: true,
+ message: "Impossible de supprimer cet utilisateur car il est attribué à d'autre objets",
+ type: "warning"
+ })
+ }
+ else {
+ console.log(errors)
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ setModalOpen(false)
+ console.log(errors)
+ }
+ return (
+ <>
+
+ |
+ {first_name} {last_name}
+ |
+
+ {email}
+ |
+
+ {role?.name || ""}
+ |
+
+
+ {(!projects || projects.length === 0) && - }
+ {projects?.map((project) => {
+ return - {project.nom}
+ })}
+
+ |
+
+
+
+
+
+ |
+
+ setModalOpen(false)}
+ onConfirm={handleDelete}
+ message={`Voulez-vous vraiment supprimer le rôle ?`}
+ />
+ >
+ )
+}
+
+export default UserTableRow
\ No newline at end of file
diff --git a/src/app/user/page.jsx b/src/app/user/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..de82ec7b2e39c034cebdb294b46644b769a81f0a
--- /dev/null
+++ b/src/app/user/page.jsx
@@ -0,0 +1,119 @@
+'use client';
+import React, { useEffect, useState, useDeferredValue } from 'react'
+import CreateUserForm from './CreateUserForm'
+import UpdateUserForm from './UpdateUserForm'
+import AddIcon from "@/static/image/svg/add.svg"
+import Loader from '@/components/Loader/Loader'
+import fetchRequest from '../lib/fetchRequest';
+import { isArray } from '../lib/TypesHelper';
+import { useNotification } from '@/context/NotificationContext';
+import UserTableRow from './UserTableRow';
+import { PAGINATION_SIZE } from '../lib/constants';
+import ArrowRightIcon from "@/static/image/svg/chevron-right.svg"
+import ArrowLeftIcon from "@/static/image/svg/chevron-left.svg"
+const UserPage = () => {
+ const [users, setUsers] = useState([])
+ const [paginationData, setPaginationData] = useState(null)
+ const [isLoading, setIsLoading] = useState(true)
+ const [openCreatePopup, setOpenCreatePopup] = useState(null)
+ const [userToUpdate, setUserToUpdate] = useState(null)
+ const { toggleNotification } = useNotification()
+ const [query, setQuery] = useState('');
+ const getUsers = async (pageNumber = 1, signal) => {
+ setIsLoading(true)
+ if (search) var { data, errors, isSuccess } = await fetchRequest(`/users/?page=${pageNumber}&search=${query}`, { signal: signal })
+ else var { data, errors, isSuccess } = await fetchRequest(`/users/?page=${pageNumber}`)
+ setIsLoading(false)
+ if (isSuccess) {
+ console.log(data)
+ setUsers(data.results)
+ setPaginationData({ pagesNumber: Math.ceil((data.count || 0) / PAGINATION_SIZE), currentPage: pageNumber })
+ } else {
+ toggleNotification({
+ visible: true,
+ message: "Internal Server Error",
+ type: "error"
+ })
+ }
+ }
+ useEffect(() => {
+ const controller = new AbortController()
+ const signal = controller.signal
+ getUsers(1, signal)
+ return () => {
+ controller.abort("fetching another users")
+ }
+ }, [query])
+ const appendUser = (newUser) => {
+ setUsers([newUser, ...users])
+ }
+
+ const handleSearchChange = (event) => {
+ setQuery(event.target.value)
+ }
+ return (
+
+
+ {openCreatePopup &&
}
+ {userToUpdate &&
}
+
+
List des Utilisateurs
+
+
+
+
+
+ {(isLoading) &&
}
+ {(!isLoading) && <> {(!isArray(users) || users?.length === 0)
+ ?
+
Pas encore des utilisateurs
+
+ :
+
+
+
+ | Nom |
+ Email |
+ Rôle |
+ Projects |
+ Action |
+
+ {users?.map((element) => {
+ return
+ })}
+
+
}
+
+ >}
+
+ {(paginationData) &&
+ {(paginationData.currentPage > 1) &&
getUsers(paginationData.currentPage - 1)} className='flex cursor-pointer hover:bg-neutral-200 duration-150 delay-75 h-8 w-9 items-center justify-center'>
+
+
}
+ {paginationData && Array.from({ length: paginationData.pagesNumber }, (_, index) => index).map((element, index) => {
+ if (element + 1 === paginationData.currentPage + 3) return
+ ...
+
+ else if (paginationData.currentPage === element + 1) return
+ {element + 1}
+
+ else if (paginationData.currentPage < element + 3 && element - paginationData.currentPage < 3) return
getUsers(element + 1)} key={element} className='h-8 w-9 hover:bg-neutral-200 cursor-pointer duration-150 delay-75 font-bold text-neutral-700 text-sm flex items-center justify-center' >
+ {element + 1}
+
+ else return <>>
+ })}
+ {(paginationData.currentPage !== paginationData.pagesNumber) &&
getUsers(paginationData.currentPage + 1)} className='flex h-8 w-9 items-center hover:bg-neutral-200 duration-150 delay-75 cursor-pointer justify-center'>
+
+
}
+
}
+
+
+
+
+ )
+}
+
+export default UserPage
\ No newline at end of file
diff --git a/src/app/zone/CreateNewZone.jsx b/src/app/zone/CreateNewZone.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..cdfb8cb47bc60185bfd6a5f51a28aac26f481075
--- /dev/null
+++ b/src/app/zone/CreateNewZone.jsx
@@ -0,0 +1,103 @@
+"use client"
+import React, { useState, useEffect, useRef } from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import Loader from '@/components/Loader/Loader'
+import { Island_Moments } from 'next/font/google'
+
+const CreateNewZone = () => {
+ const [etages, setEtages] = useState([])
+ const [error, setError] = useState(null)
+ const [isLoadingEtages, setIsLoadingEtages] = useState(true)
+ const [isLoadingAction, setIsLoadingAction] = useState(false)
+ const [nomZone, setNomZone] = useState("")
+ const [selectedEtage, setSelectedEtage] = useState(null)
+
+ const inputRef = useRef(null)
+ const selectRef = useRef(null)
+
+ useEffect(() => {
+ const getAllEtages = async () => {
+ try{
+ const {isSuccess, errors, data} = await fetchRequest('/zoaning/etages/', {method: 'GET'})
+ setIsLoadingEtages(false)
+ if(isSuccess){
+ setEtages(data)
+ }else{
+ setEtages([])
+ }
+ }catch(error){
+ setIsLoadingEtages(false)
+ console.log(error)
+ }
+ }
+ getAllEtages()
+ }, [])
+
+ const handleSubmit = async (event) => {
+ event.preventDefault()
+ isLoadingAction(true)
+ const { data, errors, isSuccess } = await fetchRequest("/zoning/zones/", {
+ method: "POST",
+ body: JSON.stringify({ name: nomZone })
+ })
+ if (isSuccess) {
+ isLoadingAction(false)
+ appendPrivilege(data)
+ inputRef.current.value = ""
+ setPrivilegeName("")
+ } else {
+ isLoadingAction(false)
+ if (errors.type === "ValidationError") {
+ if (errors.detail.name) {
+ setError("Le privilège existe déjà")
+ }
+ }
+ console.log(errors)
+ }
+ }
+
+ // Handle the name of zone change
+ const handleChangeZone = (event) => {
+ setError("")
+ setNomZone(event.target.value)
+ }
+
+ const handleChangeEtage = (event) => {
+ setError("")
+ setSelectedEtage(event.target.value)
+ }
+
+
+
+ return(
+
+ )
+}
+
+
+export default CreateNewZone
\ No newline at end of file
diff --git a/src/app/zone/RowZone.jsx b/src/app/zone/RowZone.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1d71ca2b41bd1fb68e5dda4303226ade197b38c9
--- /dev/null
+++ b/src/app/zone/RowZone.jsx
@@ -0,0 +1,50 @@
+"use client"
+import React from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import { useState, useEffect } from 'react';
+import Loader from '@/components/Loader/Loader'
+import CreateNewZone from './CreateNewZone'
+import DeleteIcon from "@/static/image/svg/delete.svg"
+import EditIcon from "@/static/image/svg/edit.svg"
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import CheckIcon from "@/static/image/svg/check.svg"
+
+
+const RowZone = ({ id, nom, etage }) => {
+ return(
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+ |
+
+ )
+}
+
+
+export default RowZone
\ No newline at end of file
diff --git a/src/app/zone/page.jsx b/src/app/zone/page.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..a1c067effa3ea3e661e1e37ec94322ca0c992fd8
--- /dev/null
+++ b/src/app/zone/page.jsx
@@ -0,0 +1,66 @@
+"use client"
+import React from 'react'
+import fetchRequest from '../lib/fetchRequest'
+import { useState, useEffect } from 'react';
+import Loader from '@/components/Loader/Loader'
+import CreateNewZone from './CreateNewZone'
+import DeleteIcon from "@/static/image/svg/delete.svg"
+import EditIcon from "@/static/image/svg/edit.svg"
+import CancelIcon from "@/static/image/svg/cancel.svg"
+import CheckIcon from "@/static/image/svg/check.svg"
+import RowZone from './RowZone'
+
+
+const Zone = ()=> {
+ const [zones, setZones] = useState([])
+ const [ isLoadingData, setIsLoadingData ] = useState(true)
+ // Fetch data from external API
+ useEffect(() => {
+ const getAllZones = async () => {
+ try{
+ const {isSuccess, errors, data} = await fetchRequest('/zoaning/zones/', {method: 'GET'})
+ setIsLoadingData(false)
+ if(isSuccess){
+ setZones(data)
+ }else{
+ setZones([])
+ }
+ }catch(error){
+ setIsLoadingData(false)
+ console.log(error)
+ }
+ }
+ getAllZones()
+ }, [])
+ return(
+
+
+
+
+
List des Zones
+ {zones ?
+
+
Pas encore des habilitations
+
+ :
+
+
+
+ | Zone |
+ Etage |
+ Action |
+
+ {zones.map((element) => {
+ return
+ })}
+
+
+ }
+
+
+
+
+ )
+}
+
+export default Zone
\ No newline at end of file
diff --git a/src/components/Loader/Loader.css b/src/components/Loader/Loader.css
new file mode 100644
index 0000000000000000000000000000000000000000..1e1ca65608312aa3c0c9ecfbed194e5cee0cbf75
--- /dev/null
+++ b/src/components/Loader/Loader.css
@@ -0,0 +1,46 @@
+@keyframes ldio-gcsicpsikdq {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.ldio-gcsicpsikdq div {
+ width: 50px;
+ height: 50px;
+ border-top-color: transparent;
+ border: 5px solid transparent;
+ border-radius: 50%;
+}
+
+.ldio-gcsicpsikdq div {
+ animation: ldio-gcsicpsikdq 1s linear infinite;
+}
+
+.loadingio-spinner-rolling-daoiuzlm498 {
+ width: min-content;
+ height: 70px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: transparent;
+}
+
+.ldio-gcsicpsikdq {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ transform: translateZ(0) scale(1);
+ backface-visibility: hidden;
+ transform-origin: 0 0;
+ /* see note above */
+}
+
+.ldio-gcsicpsikdq div {
+ box-sizing: content-box;
+}
\ No newline at end of file
diff --git a/src/components/Loader/Loader.jsx b/src/components/Loader/Loader.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..2430f19a7bd30aade3569d38228bdc38b43b5288
--- /dev/null
+++ b/src/components/Loader/Loader.jsx
@@ -0,0 +1,13 @@
+import React from 'react'
+import "./Loader.css"
+const Loader = ({ size, border, className, color }) => {
+ return (
+
+ )
+}
+
+export default Loader
\ No newline at end of file
diff --git a/src/components/Notification/Error.jsx b/src/components/Notification/Error.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..6329a934072ae8e2b30be32c6703019794afd7f4
--- /dev/null
+++ b/src/components/Notification/Error.jsx
@@ -0,0 +1,39 @@
+import React, { useEffect, useRef } from 'react'
+import WarningIcon from "@/static/image/svg/WarningIcon.svg"
+import CrossIcon from "@/static/image/svg/cross.svg"
+import "./Notification.css"
+
+const Error = ({ displayNotification, message, closeNotification }) => {
+ const container = useRef(null)
+ useEffect(() => {
+ if (!displayNotification) {
+ container.current.style.transform = "translateX(110%)"
+ }
+ }, [displayNotification])
+ const hideNotification = () => {
+ container.current.style.transform = "translateX(110%)"
+ setTimeout(() => {
+ closeNotification()
+ }, 800)
+ }
+ return (
+
+ )
+}
+export default Error
\ No newline at end of file
diff --git a/src/components/Notification/Notification.css b/src/components/Notification/Notification.css
new file mode 100644
index 0000000000000000000000000000000000000000..6f8e680fdc982b32ba35c4305423d202660d0f24
--- /dev/null
+++ b/src/components/Notification/Notification.css
@@ -0,0 +1,277 @@
+@keyframes timerAnimation {
+ 0% {
+ width: 0%;
+ }
+
+ 100% {
+ width: 100%;
+ }
+}
+
+@keyframes notificationPopupContainerAnimation {
+ 0% {
+ transform: translateX(110%);
+ }
+
+ 30% {
+ transform: translateX(-11%);
+ }
+
+ 40% {
+ transform: translateX(-1%);
+ }
+
+ 45% {
+ transform: translateX(-8%);
+ }
+
+ 50% {
+ transform: translateX(-2%);
+ }
+
+ 100%,
+ 60% {
+ transform: translateX(-5%);
+ }
+}
+
+.notificationPopup {
+ z-index: 5000000;
+ position: fixed;
+ bottom: 10px;
+ right: 10px;
+ transform: translateX(-5%);
+ transition: 800ms;
+ animation-name: notificationPopupContainerAnimation;
+ animation-duration: 1700ms;
+ background-color: white;
+ height: 70px;
+ max-width: 450px;
+ border-radius: 7px;
+ width: 83.33%;
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-color: #d4d4d4;
+}
+
+@media screen and (min-width: 768px) {
+ .notificationPopup {
+ width: 66.66%;
+ }
+}
+
+@media screen and (min-width: 1024px) {
+ .notificationPopup {
+ width: 33.33%;
+ }
+}
+
+@media screen and (min-width: 1280px) {
+ .notificationPopup {
+ width: 30%;
+ }
+}
+
+.notificationPopup>div {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ position: relative;
+}
+
+.notificationPopup .part1 {
+ width: 20%;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ border-bottom-left-radius: 7px;
+ border-top-left-radius: 7px;
+ background-color: rgb(34 197 94);
+ justify-content: center;
+}
+
+.notificationPopup .part1Warning {
+ width: 20%;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ border-bottom-left-radius: 7px;
+ border-top-left-radius: 7px;
+ background-color: #facc15;
+ justify-content: center;
+}
+
+.notificationPopup .part1Error {
+ width: 20%;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ border-bottom-left-radius: 7px;
+ border-top-left-radius: 7px;
+ background-color: #ef4444;
+ justify-content: center;
+}
+
+.notificationPopup .part1 .icon {
+ height: 40px;
+ width: 40px;
+ fill: white;
+ stroke-width: 10px;
+}
+
+.notificationPopup .part1Warning .icon {
+ height: 40px;
+ width: 40px;
+ fill: white;
+ stroke-width: 10px;
+}
+
+.notificationPopup .part1Error .icon {
+ height: 40px;
+ width: 40px;
+ fill: white;
+ stroke-width: 10px;
+}
+
+.notificationPopup .part2 {
+ position: absolute;
+ z-index: 50;
+ right: 4px;
+ top: 4px;
+ cursor: pointer;
+}
+
+.notificationPopup .part2 .icon {
+ height: 12px;
+ width: 12px;
+ fill: rgb(23 23 23);
+}
+
+.notificationPopup .part3 {
+ position: relative;
+ height: 100%;
+ flex: 1;
+}
+
+.notificationPopup .part3:nth-child(1) {
+ display: flex;
+ justify-content: center;
+ height: 98%;
+ flex-direction: column;
+ display: flex;
+ margin-left: 8px;
+}
+
+.notificationPopup .part3 h2 {
+ line-height: 20px;
+ font-size: 18px;
+ margin-left: 5px;
+ position: relative;
+ top: 4px;
+}
+
+.notificationPopup .part3 p {
+ line-height: 20px;
+ font-size: 16px;
+ width: 91.6%;
+ line-height: 16px;
+ color: #78716c;
+ margin-left: 5px;
+ margin-top: 7px;
+}
+
+.timerSuccess {
+ position: absolute;
+ bottom: 0;
+ height: 4px;
+ width: 100%;
+ background-color: transparent;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
+
+.timerWarning {
+ position: absolute;
+ bottom: 0;
+ height: 4px;
+ width: 100%;
+ background-color: transparent;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
+
+.timerSuccess::before {
+ height: 4px;
+ background-color: rgb(34 197 94);
+}
+
+.timerSuccess::before {
+ height: 4px;
+ background-color: rgb(34 197 94);
+}
+
+.timerSuccess::before {
+ content: "";
+ position: absolute;
+ width: 0%;
+ animation-name: timerAnimation;
+ animation-duration: 4000ms;
+ animation-delay: 1700ms;
+ animation-timing-function: linear;
+ left: 0;
+ top: 0;
+}
+
+.timerWarning::before {
+ height: 4px;
+ background-color: #facc15;
+}
+
+.timerWarning::before {
+ height: 4px;
+ background-color: #facc15;
+}
+
+.timerWarning::before {
+ content: "";
+ position: absolute;
+ width: 0%;
+ animation-name: timerAnimation;
+ animation-duration: 4000ms;
+ animation-delay: 1700ms;
+ animation-timing-function: linear;
+ left: 0;
+ top: 0;
+}
+
+
+.timerError::before {
+ height: 4px;
+ background-color: #ef4444;
+}
+
+.timerError::before {
+ height: 4px;
+ background-color: #ef4444;
+}
+
+.timerError::before {
+ content: "";
+ position: absolute;
+ width: 0%;
+ animation-name: timerAnimation;
+ animation-duration: 4000ms;
+ animation-delay: 1700ms;
+ animation-timing-function: linear;
+ left: 0;
+ top: 0;
+}
+
+.timerError {
+ position: absolute;
+ bottom: 0;
+ height: 4px;
+ width: 100%;
+ background-color: transparent;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
\ No newline at end of file
diff --git a/src/components/Notification/Notification.jsx b/src/components/Notification/Notification.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4dc60386df416d364c670005ab5fca321f6d45d2
--- /dev/null
+++ b/src/components/Notification/Notification.jsx
@@ -0,0 +1,66 @@
+import React, { useCallback, useEffect, useState } from 'react'
+import Success from './Success'
+import Warning from './Warning'
+import { useNotification } from '@/context/NotificationContext'
+import Error from './Error'
+const Notification = () => {
+ const { toggleNotification, notification } = useNotification()
+ const [displayNotification, setDisplayNotification] = useState(true)
+
+ var timeOutForwordPropagation
+ var timeOutBackPropagation
+
+ const closeNotification = useCallback(() => {
+ clearTimeout(timeOutForwordPropagation)
+ clearTimeout(timeOutBackPropagation)
+ toggleNotification({
+ visible: false,
+ type: null,
+ message: ""
+ })
+ setDisplayNotification(true)
+ }, [timeOutForwordPropagation, timeOutBackPropagation])
+
+
+ useEffect(() => {
+ if (notification?.type) {
+ new Promise((resolve, reject) => {
+ try {
+ timeOutForwordPropagation = setTimeout(() => {
+ setDisplayNotification(false)
+ resolve()
+ }, 5700)
+ } catch (e) {
+ reject(e)
+ }
+ }).then(() => {
+ timeOutBackPropagation = setTimeout(() => {
+ toggleNotification({
+ visible: false,
+ type: null,
+ message: ""
+ })
+ setDisplayNotification(true)
+ }, 800)
+ }).catch((error) => {
+ console.log(error)
+ })
+
+ return () => {
+ clearTimeout(timeOutForwordPropagation)
+ clearTimeout(timeOutBackPropagation)
+ }
+ }
+ }, [notification?.type])
+
+ if (notification?.type === "error")
+ return
+ if (notification?.type === "success")
+ return
+ else if (notification?.type === "warning")
+ return
+ else
+ return
+}
+
+export default Notification
\ No newline at end of file
diff --git a/src/components/Notification/Success.jsx b/src/components/Notification/Success.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..943570acd9bd6dbab70f4dd9793cb5a0a670f3d9
--- /dev/null
+++ b/src/components/Notification/Success.jsx
@@ -0,0 +1,39 @@
+import React, { useEffect, useRef } from 'react'
+import SuccessIcon from "@/static/image/svg/successIcon.svg"
+import CrossIcon from "@/static/image/svg/cross.svg"
+import "./Notification.css"
+
+const Success = ({ displayNotification, message, closeNotification }) => {
+ const container = useRef(null)
+ useEffect(() => {
+ if (!displayNotification) {
+ container.current.style.transform = "translateX(110%)"
+ }
+ }, [displayNotification])
+ const hideNotification = () => {
+ container.current.style.transform = "translateX(110%)"
+ setTimeout(() => {
+ closeNotification()
+ }, 800)
+ }
+ return (
+
+ )
+}
+export default Success
\ No newline at end of file
diff --git a/src/components/Notification/Warning.jsx b/src/components/Notification/Warning.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..31eff42865f46e461f28dab4e06a9e6e846b8906
--- /dev/null
+++ b/src/components/Notification/Warning.jsx
@@ -0,0 +1,39 @@
+import React, { useEffect, useRef } from 'react'
+import CrossIcon from "@/static/image/svg/cross.svg"
+import WarningIcon from "@/static/image/svg/warningIcon.svg"
+
+const Warning = ({ displayNotification, message, closeNotification }) => {
+ const container = useRef(null)
+ useEffect(() => {
+ if (!displayNotification) {
+ container.current.style.transform = "translateX(110%)"
+ }
+ }, [displayNotification])
+ const hideNotification = () => {
+ container.current.style.transform = "translateX(110%)"
+ setTimeout(() => {
+ closeNotification()
+ }, 800)
+ }
+ return (
+
+
+
+
+
+
+
+
+
+
+
Avertissement
+
{message}
+
+
+
+
+
+ )
+}
+
+export default Warning
\ No newline at end of file
diff --git a/src/context/NotificationContext.js b/src/context/NotificationContext.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d2bb5c823324be91c19741af43e47b6478d1b40
--- /dev/null
+++ b/src/context/NotificationContext.js
@@ -0,0 +1,25 @@
+"use client"
+import Notification from '@/components/Notification/Notification';
+import React, { createContext, useState, useContext } from 'react';
+
+const NotificationContext = createContext();
+
+export const useNotification = () => {
+ return useContext(NotificationContext);
+};
+
+
+export const NotificationProvider = ({ children }) => {
+ const [notification, setNotification] = useState(null);
+
+ const toggleNotification = (payload) => {
+ setNotification(payload)
+ }
+
+ return (
+
+ {children}
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/middleware.js b/src/middleware.js
index 1308f827736c79a423734acb70d0051515d7d5b1..9c10ccd053ceab928edd7da6ffa5da999c49578b 100644
--- a/src/middleware.js
+++ b/src/middleware.js
@@ -1,12 +1,10 @@
-"use client";
-
import { NextResponse } from 'next/server'
import { decrypt } from '@/app/lib/session'
-import Cookies from 'js-cookie';
+import { cookies } from 'next/headers'
// 1. Specify protected and public routes
-const protectedRoutes = ['/dashboard']
-const publicRoutes = ['/login', '/signup', '/']
+const protectedRoutes = ['/dashboard', '/auth/verif']
+const publicRoutes = ['/auth/login', '/auth/signup']
export default async function middleware(req) {
// 2. Check if the current route is protected or public
@@ -15,22 +13,21 @@ export default async function middleware(req) {
const isPublicRoute = publicRoutes.includes(path)
// 3. Decrypt the session from the cookie
- const cookie = Cookies.get('session');
- console.log('cookie', cookie)
+ const cookie = cookies().get('session')?.value
const session = await decrypt(cookie)
-
+ // console.log('session dfdf', session)
// 5. Redirect to /login if the user is not authenticated
- if (isProtectedRoute && !session?.token) {
- return NextResponse.redirect(new URL('/login', req.nextUrl))
+ if (isProtectedRoute && !session?.sessionData.token) {
+ return NextResponse.redirect(new URL('/auth/login', req.nextUrl))
}
// 6. Redirect to /dashboard if the user is authenticated
if (
isPublicRoute &&
- session?.token &&
- !req.nextUrl.pathname.startsWith('/auth')
+ session?.sessionData.token &&
+ !req.nextUrl.pathname.startsWith('/auth/verif')
) {
- return NextResponse.redirect(new URL('/auth', req.nextUrl))
+ return NextResponse.redirect(new URL('/auth/verif', req.nextUrl))
}
return NextResponse.next()
diff --git a/src/static/image/svg/add.svg b/src/static/image/svg/add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..37eaf783c6b70ff9297a84dfff632105ad288efe
--- /dev/null
+++ b/src/static/image/svg/add.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/cancel.svg b/src/static/image/svg/cancel.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1a52a76615e2ee52c46822777d48a7b04b1f8113
--- /dev/null
+++ b/src/static/image/svg/cancel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/check.svg b/src/static/image/svg/check.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f169344e257f6f1c7aacb4d33fc3fb1f790d3119
--- /dev/null
+++ b/src/static/image/svg/check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/chevron-left.svg b/src/static/image/svg/chevron-left.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bfbeddaec4e6e4a0ae5f8210efcc1f2044fca927
--- /dev/null
+++ b/src/static/image/svg/chevron-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/chevron-right.svg b/src/static/image/svg/chevron-right.svg
new file mode 100644
index 0000000000000000000000000000000000000000..49c8a53fcd0352ccbec6886ee77927dd10244b18
--- /dev/null
+++ b/src/static/image/svg/chevron-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/cross.svg b/src/static/image/svg/cross.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f0c90d5047732e14d0693dfab195fb9d352cf075
--- /dev/null
+++ b/src/static/image/svg/cross.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/delete.svg b/src/static/image/svg/delete.svg
new file mode 100644
index 0000000000000000000000000000000000000000..37a3374c3a00ed9249b891340e143a0304ef189f
--- /dev/null
+++ b/src/static/image/svg/delete.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/static/image/svg/edit.svg b/src/static/image/svg/edit.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9f6730fd01232372fc31d62cf49a68627c09ccb3
--- /dev/null
+++ b/src/static/image/svg/edit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/successIcon.svg b/src/static/image/svg/successIcon.svg
new file mode 100644
index 0000000000000000000000000000000000000000..57199b67460a6e381793e902fa51c699449090b1
--- /dev/null
+++ b/src/static/image/svg/successIcon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/static/image/svg/warningIcon.svg b/src/static/image/svg/warningIcon.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8fdac5d1bf288ebf1fb6cb63992ec1488da89d64
--- /dev/null
+++ b/src/static/image/svg/warningIcon.svg
@@ -0,0 +1,17 @@
+
+
+
\ No newline at end of file