├── README.md ├── backend ├── .gitignore ├── db.js ├── index.js ├── middleware.js ├── package-lock.json ├── package.json ├── routes │ ├── account.js │ ├── index.js │ └── user.js └── vercel.json └── frontend ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── App.jsx ├── components │ ├── Appbar.jsx │ ├── Balance.jsx │ ├── BottomWarning.jsx │ ├── Button.jsx │ ├── Heading.jsx │ ├── InputBox.jsx │ ├── SubHeading.jsx │ └── Users.jsx ├── index.css ├── main.jsx └── pages │ ├── Dashboard.jsx │ ├── PaymentStatus.jsx │ ├── SendMoney.jsx │ ├── Signin.jsx │ └── Signup.jsx ├── tailwind.config.js ├── vercel.json └── vite.config.js /README.md: -------------------------------------------------------------------------------- 1 | # PayTM Clone 2 | 3 | Welcome to the PayTM Clone project! This project aims to replicate the basic functionality of PayTM, allowing users to perform transactions, view their account balance, and interact with other users. 4 | 5 | ## Features 6 | 7 | - User Authentication & Authorization using JWT 8 | - View Account Balance 9 | - Search and view other users 10 | - Send money to other users' accounts 11 | 12 | ## Technology Stack 13 | 14 | - **Frontend**: React.js, Tailwind CSS 15 | - **Backend**: Node.js, Express.js 16 | - **Database**: MongoDB 17 | 18 | ## Getting Started 19 | 20 | To get started with the PayTM Clone project, follow these steps: 21 | 22 | 1. **Clone the Repository**: Clone the repository from GitHub: 23 | 24 | ``` 25 | git clone https://github.com/HarshBatra/paytm-clone.git 26 | ``` 27 | 28 | 2. **Set Environment Variables**: Navigate to the `frontend` and `backend` folders and add necessary environment variables. You may need to create a `.env` file and configure it with required variables: 29 | In the backend/.env file: 30 | 31 | ``` 32 | MONGO_URL = your-mongo-url 33 | PORT = 3000 34 | JWT_SECRET = your-jwt-secret 35 | ``` 36 | 37 | In the frontend/.env file: 38 | 39 | ``` 40 | VITE_SERVER_URL = your-server-url 41 | ``` 42 | 43 | 3. **Install Dependencies**: Install dependencies in the `frontend` and `backend` folders using npm or yarn: 44 | 45 | ``` 46 | cd frontend 47 | npm install 48 | cd ../backend 49 | npm install 50 | ``` 51 | 52 | 4. **Start the Backend Server**: In the `backend` folder, start the development server using npm: 53 | 54 | ``` 55 | npm run dev 56 | ``` 57 | 58 | 5. **Start the Frontend**: In the `frontend` folder, start the frontend application: 59 | 60 | ``` 61 | npm run dev 62 | ``` 63 | 64 | ## Database Transactions 65 | 66 | The PayTM Clone project implements MongoDB Transactions to ensure data consistency and reliability. Transactions follow the ACID properties of databases, ensuring that transactions are either fully completed and committed or reverted back in case of issues, thus preventing inconsistencies in the database. 67 | 68 | ## Contributions 69 | 70 | Contributions to the PayTM Clone project are welcome! If you find any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request. 71 | 72 | Thank you for using PayTM Clone! Happy Coding! 🚀 73 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /backend/db.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const userSchema = new mongoose.Schema({ 4 | username: { 5 | type: String, 6 | required: true, 7 | unique: true, 8 | trim: true, 9 | lowercase: true, 10 | minLength: 3, 11 | maxLength: 30, 12 | }, 13 | password: { 14 | type: String, 15 | required: true, 16 | minLength: 6, 17 | }, 18 | firstName: { 19 | type: String, 20 | required: true, 21 | trim: true, 22 | maxLength: 50, 23 | }, 24 | lastName: { 25 | type: String, 26 | required: true, 27 | trim: true, 28 | maxLength: 50, 29 | }, 30 | }); 31 | 32 | const accountSchema = new mongoose.Schema({ 33 | userId: { 34 | type: mongoose.Schema.Types.ObjectId, // Reference to User model 35 | ref: "User", 36 | required: true, 37 | }, 38 | balance: { 39 | type: Number, 40 | required: true, 41 | }, 42 | }); 43 | 44 | const Account = mongoose.model("Account", accountSchema); 45 | const User = mongoose.model("User", userSchema); 46 | 47 | module.exports = { 48 | User, 49 | Account, 50 | }; 51 | -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const mongoose = require("mongoose"); 3 | const dotenv = require("dotenv"); 4 | const mainRouter = require("./routes/index"); 5 | const cors = require("cors"); 6 | 7 | const app = express(); 8 | dotenv.config(); 9 | 10 | app.use(express.json()); 11 | app.use(cors()); 12 | 13 | app.use("/api/v1", mainRouter); 14 | 15 | // /api/v1/user/signup 16 | // /api/v1/user/signin 17 | // /api/v1/user/changePassword..... 18 | 19 | // /api/v1/account/transferMoney 20 | // /api/v1/account/balance 21 | 22 | //database 23 | const connectDB = async () => { 24 | try { 25 | await mongoose.connect(process.env.MONGO_URL); 26 | console.log("database is connected successfully!"); 27 | } catch (err) { 28 | console.log(err); 29 | } 30 | }; 31 | 32 | app.get("/", (req, res) => { 33 | res.json("Server is up and running"); 34 | }); 35 | 36 | app.listen(process.env.PORT, () => { 37 | connectDB(); 38 | console.log("Server is running on port: " + process.env.PORT); 39 | }); 40 | -------------------------------------------------------------------------------- /backend/middleware.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | const authMiddleware = (req, res, next) => { 4 | const authHeader = req.headers.authorization; 5 | 6 | if (!authHeader || !authHeader.startsWith("Bearer ")) { 7 | return res.status(403).json({ 8 | message: "Invalid auth header", 9 | }); 10 | } 11 | 12 | const token = authHeader.split(" ")[1]; 13 | 14 | try { 15 | const decoded = jwt.verify(token, process.env.JWT_SECRET); 16 | 17 | if (decoded.userId) { 18 | req.userId = decoded.userId; 19 | next(); 20 | } else { 21 | return res.status(403).json({ 22 | message: "Invalid auth header", 23 | }); 24 | } 25 | } catch (err) { 26 | return res.status(403).json({ 27 | message: "Invalid auth header", 28 | }); 29 | } 30 | }; 31 | 32 | module.exports = { 33 | authMiddleware, 34 | }; 35 | -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "backend", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcrypt": "^5.1.1", 13 | "cors": "^2.8.5", 14 | "dotenv": "^16.4.4", 15 | "express": "^4.18.2", 16 | "jsonwebtoken": "^9.0.2", 17 | "mongoose": "^8.1.0", 18 | "zod": "^3.22.4" 19 | } 20 | }, 21 | "node_modules/@mapbox/node-pre-gyp": { 22 | "version": "1.0.11", 23 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", 24 | "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", 25 | "dependencies": { 26 | "detect-libc": "^2.0.0", 27 | "https-proxy-agent": "^5.0.0", 28 | "make-dir": "^3.1.0", 29 | "node-fetch": "^2.6.7", 30 | "nopt": "^5.0.0", 31 | "npmlog": "^5.0.1", 32 | "rimraf": "^3.0.2", 33 | "semver": "^7.3.5", 34 | "tar": "^6.1.11" 35 | }, 36 | "bin": { 37 | "node-pre-gyp": "bin/node-pre-gyp" 38 | } 39 | }, 40 | "node_modules/@mongodb-js/saslprep": { 41 | "version": "1.1.4", 42 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", 43 | "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", 44 | "dependencies": { 45 | "sparse-bitfield": "^3.0.3" 46 | } 47 | }, 48 | "node_modules/@types/webidl-conversions": { 49 | "version": "7.0.3", 50 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 51 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 52 | }, 53 | "node_modules/@types/whatwg-url": { 54 | "version": "11.0.4", 55 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", 56 | "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", 57 | "dependencies": { 58 | "@types/webidl-conversions": "*" 59 | } 60 | }, 61 | "node_modules/abbrev": { 62 | "version": "1.1.1", 63 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 64 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 65 | }, 66 | "node_modules/accepts": { 67 | "version": "1.3.8", 68 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 69 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 70 | "dependencies": { 71 | "mime-types": "~2.1.34", 72 | "negotiator": "0.6.3" 73 | }, 74 | "engines": { 75 | "node": ">= 0.6" 76 | } 77 | }, 78 | "node_modules/agent-base": { 79 | "version": "6.0.2", 80 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 81 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 82 | "dependencies": { 83 | "debug": "4" 84 | }, 85 | "engines": { 86 | "node": ">= 6.0.0" 87 | } 88 | }, 89 | "node_modules/agent-base/node_modules/debug": { 90 | "version": "4.3.4", 91 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 92 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 93 | "dependencies": { 94 | "ms": "2.1.2" 95 | }, 96 | "engines": { 97 | "node": ">=6.0" 98 | }, 99 | "peerDependenciesMeta": { 100 | "supports-color": { 101 | "optional": true 102 | } 103 | } 104 | }, 105 | "node_modules/agent-base/node_modules/ms": { 106 | "version": "2.1.2", 107 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 108 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 109 | }, 110 | "node_modules/ansi-regex": { 111 | "version": "5.0.1", 112 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 113 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 114 | "engines": { 115 | "node": ">=8" 116 | } 117 | }, 118 | "node_modules/aproba": { 119 | "version": "2.0.0", 120 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", 121 | "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" 122 | }, 123 | "node_modules/are-we-there-yet": { 124 | "version": "2.0.0", 125 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", 126 | "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", 127 | "dependencies": { 128 | "delegates": "^1.0.0", 129 | "readable-stream": "^3.6.0" 130 | }, 131 | "engines": { 132 | "node": ">=10" 133 | } 134 | }, 135 | "node_modules/array-flatten": { 136 | "version": "1.1.1", 137 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 138 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 139 | }, 140 | "node_modules/balanced-match": { 141 | "version": "1.0.2", 142 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 143 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 144 | }, 145 | "node_modules/bcrypt": { 146 | "version": "5.1.1", 147 | "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", 148 | "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", 149 | "hasInstallScript": true, 150 | "dependencies": { 151 | "@mapbox/node-pre-gyp": "^1.0.11", 152 | "node-addon-api": "^5.0.0" 153 | }, 154 | "engines": { 155 | "node": ">= 10.0.0" 156 | } 157 | }, 158 | "node_modules/body-parser": { 159 | "version": "1.20.1", 160 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 161 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 162 | "dependencies": { 163 | "bytes": "3.1.2", 164 | "content-type": "~1.0.4", 165 | "debug": "2.6.9", 166 | "depd": "2.0.0", 167 | "destroy": "1.2.0", 168 | "http-errors": "2.0.0", 169 | "iconv-lite": "0.4.24", 170 | "on-finished": "2.4.1", 171 | "qs": "6.11.0", 172 | "raw-body": "2.5.1", 173 | "type-is": "~1.6.18", 174 | "unpipe": "1.0.0" 175 | }, 176 | "engines": { 177 | "node": ">= 0.8", 178 | "npm": "1.2.8000 || >= 1.4.16" 179 | } 180 | }, 181 | "node_modules/brace-expansion": { 182 | "version": "1.1.11", 183 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 184 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 185 | "dependencies": { 186 | "balanced-match": "^1.0.0", 187 | "concat-map": "0.0.1" 188 | } 189 | }, 190 | "node_modules/bson": { 191 | "version": "6.2.0", 192 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", 193 | "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", 194 | "engines": { 195 | "node": ">=16.20.1" 196 | } 197 | }, 198 | "node_modules/buffer-equal-constant-time": { 199 | "version": "1.0.1", 200 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 201 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 202 | }, 203 | "node_modules/bytes": { 204 | "version": "3.1.2", 205 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 206 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 207 | "engines": { 208 | "node": ">= 0.8" 209 | } 210 | }, 211 | "node_modules/call-bind": { 212 | "version": "1.0.5", 213 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", 214 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", 215 | "dependencies": { 216 | "function-bind": "^1.1.2", 217 | "get-intrinsic": "^1.2.1", 218 | "set-function-length": "^1.1.1" 219 | }, 220 | "funding": { 221 | "url": "https://github.com/sponsors/ljharb" 222 | } 223 | }, 224 | "node_modules/chownr": { 225 | "version": "2.0.0", 226 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 227 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", 228 | "engines": { 229 | "node": ">=10" 230 | } 231 | }, 232 | "node_modules/color-support": { 233 | "version": "1.1.3", 234 | "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", 235 | "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", 236 | "bin": { 237 | "color-support": "bin.js" 238 | } 239 | }, 240 | "node_modules/concat-map": { 241 | "version": "0.0.1", 242 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 243 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 244 | }, 245 | "node_modules/console-control-strings": { 246 | "version": "1.1.0", 247 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 248 | "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" 249 | }, 250 | "node_modules/content-disposition": { 251 | "version": "0.5.4", 252 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 253 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 254 | "dependencies": { 255 | "safe-buffer": "5.2.1" 256 | }, 257 | "engines": { 258 | "node": ">= 0.6" 259 | } 260 | }, 261 | "node_modules/content-type": { 262 | "version": "1.0.5", 263 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 264 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 265 | "engines": { 266 | "node": ">= 0.6" 267 | } 268 | }, 269 | "node_modules/cookie": { 270 | "version": "0.5.0", 271 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 272 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 273 | "engines": { 274 | "node": ">= 0.6" 275 | } 276 | }, 277 | "node_modules/cookie-signature": { 278 | "version": "1.0.6", 279 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 280 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 281 | }, 282 | "node_modules/cors": { 283 | "version": "2.8.5", 284 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 285 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 286 | "dependencies": { 287 | "object-assign": "^4", 288 | "vary": "^1" 289 | }, 290 | "engines": { 291 | "node": ">= 0.10" 292 | } 293 | }, 294 | "node_modules/debug": { 295 | "version": "2.6.9", 296 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 297 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 298 | "dependencies": { 299 | "ms": "2.0.0" 300 | } 301 | }, 302 | "node_modules/define-data-property": { 303 | "version": "1.1.1", 304 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", 305 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", 306 | "dependencies": { 307 | "get-intrinsic": "^1.2.1", 308 | "gopd": "^1.0.1", 309 | "has-property-descriptors": "^1.0.0" 310 | }, 311 | "engines": { 312 | "node": ">= 0.4" 313 | } 314 | }, 315 | "node_modules/delegates": { 316 | "version": "1.0.0", 317 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 318 | "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" 319 | }, 320 | "node_modules/depd": { 321 | "version": "2.0.0", 322 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 323 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 324 | "engines": { 325 | "node": ">= 0.8" 326 | } 327 | }, 328 | "node_modules/destroy": { 329 | "version": "1.2.0", 330 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 331 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 332 | "engines": { 333 | "node": ">= 0.8", 334 | "npm": "1.2.8000 || >= 1.4.16" 335 | } 336 | }, 337 | "node_modules/detect-libc": { 338 | "version": "2.0.2", 339 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", 340 | "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", 341 | "engines": { 342 | "node": ">=8" 343 | } 344 | }, 345 | "node_modules/dotenv": { 346 | "version": "16.4.4", 347 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", 348 | "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", 349 | "engines": { 350 | "node": ">=12" 351 | }, 352 | "funding": { 353 | "url": "https://dotenvx.com" 354 | } 355 | }, 356 | "node_modules/ecdsa-sig-formatter": { 357 | "version": "1.0.11", 358 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 359 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 360 | "dependencies": { 361 | "safe-buffer": "^5.0.1" 362 | } 363 | }, 364 | "node_modules/ee-first": { 365 | "version": "1.1.1", 366 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 367 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 368 | }, 369 | "node_modules/emoji-regex": { 370 | "version": "8.0.0", 371 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 372 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 373 | }, 374 | "node_modules/encodeurl": { 375 | "version": "1.0.2", 376 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 377 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 378 | "engines": { 379 | "node": ">= 0.8" 380 | } 381 | }, 382 | "node_modules/escape-html": { 383 | "version": "1.0.3", 384 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 385 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 386 | }, 387 | "node_modules/etag": { 388 | "version": "1.8.1", 389 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 390 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 391 | "engines": { 392 | "node": ">= 0.6" 393 | } 394 | }, 395 | "node_modules/express": { 396 | "version": "4.18.2", 397 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 398 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 399 | "dependencies": { 400 | "accepts": "~1.3.8", 401 | "array-flatten": "1.1.1", 402 | "body-parser": "1.20.1", 403 | "content-disposition": "0.5.4", 404 | "content-type": "~1.0.4", 405 | "cookie": "0.5.0", 406 | "cookie-signature": "1.0.6", 407 | "debug": "2.6.9", 408 | "depd": "2.0.0", 409 | "encodeurl": "~1.0.2", 410 | "escape-html": "~1.0.3", 411 | "etag": "~1.8.1", 412 | "finalhandler": "1.2.0", 413 | "fresh": "0.5.2", 414 | "http-errors": "2.0.0", 415 | "merge-descriptors": "1.0.1", 416 | "methods": "~1.1.2", 417 | "on-finished": "2.4.1", 418 | "parseurl": "~1.3.3", 419 | "path-to-regexp": "0.1.7", 420 | "proxy-addr": "~2.0.7", 421 | "qs": "6.11.0", 422 | "range-parser": "~1.2.1", 423 | "safe-buffer": "5.2.1", 424 | "send": "0.18.0", 425 | "serve-static": "1.15.0", 426 | "setprototypeof": "1.2.0", 427 | "statuses": "2.0.1", 428 | "type-is": "~1.6.18", 429 | "utils-merge": "1.0.1", 430 | "vary": "~1.1.2" 431 | }, 432 | "engines": { 433 | "node": ">= 0.10.0" 434 | } 435 | }, 436 | "node_modules/finalhandler": { 437 | "version": "1.2.0", 438 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 439 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 440 | "dependencies": { 441 | "debug": "2.6.9", 442 | "encodeurl": "~1.0.2", 443 | "escape-html": "~1.0.3", 444 | "on-finished": "2.4.1", 445 | "parseurl": "~1.3.3", 446 | "statuses": "2.0.1", 447 | "unpipe": "~1.0.0" 448 | }, 449 | "engines": { 450 | "node": ">= 0.8" 451 | } 452 | }, 453 | "node_modules/forwarded": { 454 | "version": "0.2.0", 455 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 456 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 457 | "engines": { 458 | "node": ">= 0.6" 459 | } 460 | }, 461 | "node_modules/fresh": { 462 | "version": "0.5.2", 463 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 464 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 465 | "engines": { 466 | "node": ">= 0.6" 467 | } 468 | }, 469 | "node_modules/fs-minipass": { 470 | "version": "2.1.0", 471 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 472 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 473 | "dependencies": { 474 | "minipass": "^3.0.0" 475 | }, 476 | "engines": { 477 | "node": ">= 8" 478 | } 479 | }, 480 | "node_modules/fs-minipass/node_modules/minipass": { 481 | "version": "3.3.6", 482 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 483 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 484 | "dependencies": { 485 | "yallist": "^4.0.0" 486 | }, 487 | "engines": { 488 | "node": ">=8" 489 | } 490 | }, 491 | "node_modules/fs.realpath": { 492 | "version": "1.0.0", 493 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 494 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 495 | }, 496 | "node_modules/function-bind": { 497 | "version": "1.1.2", 498 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 499 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 500 | "funding": { 501 | "url": "https://github.com/sponsors/ljharb" 502 | } 503 | }, 504 | "node_modules/gauge": { 505 | "version": "3.0.2", 506 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", 507 | "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", 508 | "dependencies": { 509 | "aproba": "^1.0.3 || ^2.0.0", 510 | "color-support": "^1.1.2", 511 | "console-control-strings": "^1.0.0", 512 | "has-unicode": "^2.0.1", 513 | "object-assign": "^4.1.1", 514 | "signal-exit": "^3.0.0", 515 | "string-width": "^4.2.3", 516 | "strip-ansi": "^6.0.1", 517 | "wide-align": "^1.1.2" 518 | }, 519 | "engines": { 520 | "node": ">=10" 521 | } 522 | }, 523 | "node_modules/get-intrinsic": { 524 | "version": "1.2.2", 525 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", 526 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", 527 | "dependencies": { 528 | "function-bind": "^1.1.2", 529 | "has-proto": "^1.0.1", 530 | "has-symbols": "^1.0.3", 531 | "hasown": "^2.0.0" 532 | }, 533 | "funding": { 534 | "url": "https://github.com/sponsors/ljharb" 535 | } 536 | }, 537 | "node_modules/glob": { 538 | "version": "7.2.3", 539 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 540 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 541 | "dependencies": { 542 | "fs.realpath": "^1.0.0", 543 | "inflight": "^1.0.4", 544 | "inherits": "2", 545 | "minimatch": "^3.1.1", 546 | "once": "^1.3.0", 547 | "path-is-absolute": "^1.0.0" 548 | }, 549 | "engines": { 550 | "node": "*" 551 | }, 552 | "funding": { 553 | "url": "https://github.com/sponsors/isaacs" 554 | } 555 | }, 556 | "node_modules/gopd": { 557 | "version": "1.0.1", 558 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 559 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 560 | "dependencies": { 561 | "get-intrinsic": "^1.1.3" 562 | }, 563 | "funding": { 564 | "url": "https://github.com/sponsors/ljharb" 565 | } 566 | }, 567 | "node_modules/has-property-descriptors": { 568 | "version": "1.0.1", 569 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", 570 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", 571 | "dependencies": { 572 | "get-intrinsic": "^1.2.2" 573 | }, 574 | "funding": { 575 | "url": "https://github.com/sponsors/ljharb" 576 | } 577 | }, 578 | "node_modules/has-proto": { 579 | "version": "1.0.1", 580 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 581 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 582 | "engines": { 583 | "node": ">= 0.4" 584 | }, 585 | "funding": { 586 | "url": "https://github.com/sponsors/ljharb" 587 | } 588 | }, 589 | "node_modules/has-symbols": { 590 | "version": "1.0.3", 591 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 592 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 593 | "engines": { 594 | "node": ">= 0.4" 595 | }, 596 | "funding": { 597 | "url": "https://github.com/sponsors/ljharb" 598 | } 599 | }, 600 | "node_modules/has-unicode": { 601 | "version": "2.0.1", 602 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 603 | "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" 604 | }, 605 | "node_modules/hasown": { 606 | "version": "2.0.0", 607 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 608 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 609 | "dependencies": { 610 | "function-bind": "^1.1.2" 611 | }, 612 | "engines": { 613 | "node": ">= 0.4" 614 | } 615 | }, 616 | "node_modules/http-errors": { 617 | "version": "2.0.0", 618 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 619 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 620 | "dependencies": { 621 | "depd": "2.0.0", 622 | "inherits": "2.0.4", 623 | "setprototypeof": "1.2.0", 624 | "statuses": "2.0.1", 625 | "toidentifier": "1.0.1" 626 | }, 627 | "engines": { 628 | "node": ">= 0.8" 629 | } 630 | }, 631 | "node_modules/https-proxy-agent": { 632 | "version": "5.0.1", 633 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", 634 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", 635 | "dependencies": { 636 | "agent-base": "6", 637 | "debug": "4" 638 | }, 639 | "engines": { 640 | "node": ">= 6" 641 | } 642 | }, 643 | "node_modules/https-proxy-agent/node_modules/debug": { 644 | "version": "4.3.4", 645 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 646 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 647 | "dependencies": { 648 | "ms": "2.1.2" 649 | }, 650 | "engines": { 651 | "node": ">=6.0" 652 | }, 653 | "peerDependenciesMeta": { 654 | "supports-color": { 655 | "optional": true 656 | } 657 | } 658 | }, 659 | "node_modules/https-proxy-agent/node_modules/ms": { 660 | "version": "2.1.2", 661 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 662 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 663 | }, 664 | "node_modules/iconv-lite": { 665 | "version": "0.4.24", 666 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 667 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 668 | "dependencies": { 669 | "safer-buffer": ">= 2.1.2 < 3" 670 | }, 671 | "engines": { 672 | "node": ">=0.10.0" 673 | } 674 | }, 675 | "node_modules/inflight": { 676 | "version": "1.0.6", 677 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 678 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 679 | "dependencies": { 680 | "once": "^1.3.0", 681 | "wrappy": "1" 682 | } 683 | }, 684 | "node_modules/inherits": { 685 | "version": "2.0.4", 686 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 687 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 688 | }, 689 | "node_modules/ipaddr.js": { 690 | "version": "1.9.1", 691 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 692 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 693 | "engines": { 694 | "node": ">= 0.10" 695 | } 696 | }, 697 | "node_modules/is-fullwidth-code-point": { 698 | "version": "3.0.0", 699 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 700 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 701 | "engines": { 702 | "node": ">=8" 703 | } 704 | }, 705 | "node_modules/jsonwebtoken": { 706 | "version": "9.0.2", 707 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 708 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 709 | "dependencies": { 710 | "jws": "^3.2.2", 711 | "lodash.includes": "^4.3.0", 712 | "lodash.isboolean": "^3.0.3", 713 | "lodash.isinteger": "^4.0.4", 714 | "lodash.isnumber": "^3.0.3", 715 | "lodash.isplainobject": "^4.0.6", 716 | "lodash.isstring": "^4.0.1", 717 | "lodash.once": "^4.0.0", 718 | "ms": "^2.1.1", 719 | "semver": "^7.5.4" 720 | }, 721 | "engines": { 722 | "node": ">=12", 723 | "npm": ">=6" 724 | } 725 | }, 726 | "node_modules/jsonwebtoken/node_modules/ms": { 727 | "version": "2.1.3", 728 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 729 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 730 | }, 731 | "node_modules/jwa": { 732 | "version": "1.4.1", 733 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 734 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 735 | "dependencies": { 736 | "buffer-equal-constant-time": "1.0.1", 737 | "ecdsa-sig-formatter": "1.0.11", 738 | "safe-buffer": "^5.0.1" 739 | } 740 | }, 741 | "node_modules/jws": { 742 | "version": "3.2.2", 743 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 744 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 745 | "dependencies": { 746 | "jwa": "^1.4.1", 747 | "safe-buffer": "^5.0.1" 748 | } 749 | }, 750 | "node_modules/kareem": { 751 | "version": "2.5.1", 752 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", 753 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", 754 | "engines": { 755 | "node": ">=12.0.0" 756 | } 757 | }, 758 | "node_modules/lodash.includes": { 759 | "version": "4.3.0", 760 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 761 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 762 | }, 763 | "node_modules/lodash.isboolean": { 764 | "version": "3.0.3", 765 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 766 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 767 | }, 768 | "node_modules/lodash.isinteger": { 769 | "version": "4.0.4", 770 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 771 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 772 | }, 773 | "node_modules/lodash.isnumber": { 774 | "version": "3.0.3", 775 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 776 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 777 | }, 778 | "node_modules/lodash.isplainobject": { 779 | "version": "4.0.6", 780 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 781 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 782 | }, 783 | "node_modules/lodash.isstring": { 784 | "version": "4.0.1", 785 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 786 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 787 | }, 788 | "node_modules/lodash.once": { 789 | "version": "4.1.1", 790 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 791 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 792 | }, 793 | "node_modules/lru-cache": { 794 | "version": "6.0.0", 795 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 796 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 797 | "dependencies": { 798 | "yallist": "^4.0.0" 799 | }, 800 | "engines": { 801 | "node": ">=10" 802 | } 803 | }, 804 | "node_modules/make-dir": { 805 | "version": "3.1.0", 806 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 807 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 808 | "dependencies": { 809 | "semver": "^6.0.0" 810 | }, 811 | "engines": { 812 | "node": ">=8" 813 | }, 814 | "funding": { 815 | "url": "https://github.com/sponsors/sindresorhus" 816 | } 817 | }, 818 | "node_modules/make-dir/node_modules/semver": { 819 | "version": "6.3.1", 820 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 821 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 822 | "bin": { 823 | "semver": "bin/semver.js" 824 | } 825 | }, 826 | "node_modules/media-typer": { 827 | "version": "0.3.0", 828 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 829 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 830 | "engines": { 831 | "node": ">= 0.6" 832 | } 833 | }, 834 | "node_modules/memory-pager": { 835 | "version": "1.5.0", 836 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 837 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 838 | }, 839 | "node_modules/merge-descriptors": { 840 | "version": "1.0.1", 841 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 842 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 843 | }, 844 | "node_modules/methods": { 845 | "version": "1.1.2", 846 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 847 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 848 | "engines": { 849 | "node": ">= 0.6" 850 | } 851 | }, 852 | "node_modules/mime": { 853 | "version": "1.6.0", 854 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 855 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 856 | "bin": { 857 | "mime": "cli.js" 858 | }, 859 | "engines": { 860 | "node": ">=4" 861 | } 862 | }, 863 | "node_modules/mime-db": { 864 | "version": "1.52.0", 865 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 866 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 867 | "engines": { 868 | "node": ">= 0.6" 869 | } 870 | }, 871 | "node_modules/mime-types": { 872 | "version": "2.1.35", 873 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 874 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 875 | "dependencies": { 876 | "mime-db": "1.52.0" 877 | }, 878 | "engines": { 879 | "node": ">= 0.6" 880 | } 881 | }, 882 | "node_modules/minimatch": { 883 | "version": "3.1.2", 884 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 885 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 886 | "dependencies": { 887 | "brace-expansion": "^1.1.7" 888 | }, 889 | "engines": { 890 | "node": "*" 891 | } 892 | }, 893 | "node_modules/minipass": { 894 | "version": "5.0.0", 895 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", 896 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", 897 | "engines": { 898 | "node": ">=8" 899 | } 900 | }, 901 | "node_modules/minizlib": { 902 | "version": "2.1.2", 903 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 904 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 905 | "dependencies": { 906 | "minipass": "^3.0.0", 907 | "yallist": "^4.0.0" 908 | }, 909 | "engines": { 910 | "node": ">= 8" 911 | } 912 | }, 913 | "node_modules/minizlib/node_modules/minipass": { 914 | "version": "3.3.6", 915 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 916 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 917 | "dependencies": { 918 | "yallist": "^4.0.0" 919 | }, 920 | "engines": { 921 | "node": ">=8" 922 | } 923 | }, 924 | "node_modules/mkdirp": { 925 | "version": "1.0.4", 926 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 927 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 928 | "bin": { 929 | "mkdirp": "bin/cmd.js" 930 | }, 931 | "engines": { 932 | "node": ">=10" 933 | } 934 | }, 935 | "node_modules/mongodb": { 936 | "version": "6.3.0", 937 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", 938 | "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", 939 | "dependencies": { 940 | "@mongodb-js/saslprep": "^1.1.0", 941 | "bson": "^6.2.0", 942 | "mongodb-connection-string-url": "^3.0.0" 943 | }, 944 | "engines": { 945 | "node": ">=16.20.1" 946 | }, 947 | "peerDependencies": { 948 | "@aws-sdk/credential-providers": "^3.188.0", 949 | "@mongodb-js/zstd": "^1.1.0", 950 | "gcp-metadata": "^5.2.0", 951 | "kerberos": "^2.0.1", 952 | "mongodb-client-encryption": ">=6.0.0 <7", 953 | "snappy": "^7.2.2", 954 | "socks": "^2.7.1" 955 | }, 956 | "peerDependenciesMeta": { 957 | "@aws-sdk/credential-providers": { 958 | "optional": true 959 | }, 960 | "@mongodb-js/zstd": { 961 | "optional": true 962 | }, 963 | "gcp-metadata": { 964 | "optional": true 965 | }, 966 | "kerberos": { 967 | "optional": true 968 | }, 969 | "mongodb-client-encryption": { 970 | "optional": true 971 | }, 972 | "snappy": { 973 | "optional": true 974 | }, 975 | "socks": { 976 | "optional": true 977 | } 978 | } 979 | }, 980 | "node_modules/mongodb-connection-string-url": { 981 | "version": "3.0.0", 982 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", 983 | "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", 984 | "dependencies": { 985 | "@types/whatwg-url": "^11.0.2", 986 | "whatwg-url": "^13.0.0" 987 | } 988 | }, 989 | "node_modules/mongoose": { 990 | "version": "8.1.0", 991 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.1.0.tgz", 992 | "integrity": "sha512-kOA4Xnq2goqNpN9EmYElGNWfxA9H80fxcr7UdJKWi3UMflza0R7wpTihCpM67dE/0MNFljoa0sjQtlXVkkySAQ==", 993 | "dependencies": { 994 | "bson": "^6.2.0", 995 | "kareem": "2.5.1", 996 | "mongodb": "6.3.0", 997 | "mpath": "0.9.0", 998 | "mquery": "5.0.0", 999 | "ms": "2.1.3", 1000 | "sift": "16.0.1" 1001 | }, 1002 | "engines": { 1003 | "node": ">=16.20.1" 1004 | }, 1005 | "funding": { 1006 | "type": "opencollective", 1007 | "url": "https://opencollective.com/mongoose" 1008 | } 1009 | }, 1010 | "node_modules/mongoose/node_modules/ms": { 1011 | "version": "2.1.3", 1012 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1013 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1014 | }, 1015 | "node_modules/mpath": { 1016 | "version": "0.9.0", 1017 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", 1018 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", 1019 | "engines": { 1020 | "node": ">=4.0.0" 1021 | } 1022 | }, 1023 | "node_modules/mquery": { 1024 | "version": "5.0.0", 1025 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", 1026 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", 1027 | "dependencies": { 1028 | "debug": "4.x" 1029 | }, 1030 | "engines": { 1031 | "node": ">=14.0.0" 1032 | } 1033 | }, 1034 | "node_modules/mquery/node_modules/debug": { 1035 | "version": "4.3.4", 1036 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1037 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1038 | "dependencies": { 1039 | "ms": "2.1.2" 1040 | }, 1041 | "engines": { 1042 | "node": ">=6.0" 1043 | }, 1044 | "peerDependenciesMeta": { 1045 | "supports-color": { 1046 | "optional": true 1047 | } 1048 | } 1049 | }, 1050 | "node_modules/mquery/node_modules/ms": { 1051 | "version": "2.1.2", 1052 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1053 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1054 | }, 1055 | "node_modules/ms": { 1056 | "version": "2.0.0", 1057 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1058 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1059 | }, 1060 | "node_modules/negotiator": { 1061 | "version": "0.6.3", 1062 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1063 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1064 | "engines": { 1065 | "node": ">= 0.6" 1066 | } 1067 | }, 1068 | "node_modules/node-addon-api": { 1069 | "version": "5.1.0", 1070 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", 1071 | "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" 1072 | }, 1073 | "node_modules/node-fetch": { 1074 | "version": "2.7.0", 1075 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 1076 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 1077 | "dependencies": { 1078 | "whatwg-url": "^5.0.0" 1079 | }, 1080 | "engines": { 1081 | "node": "4.x || >=6.0.0" 1082 | }, 1083 | "peerDependencies": { 1084 | "encoding": "^0.1.0" 1085 | }, 1086 | "peerDependenciesMeta": { 1087 | "encoding": { 1088 | "optional": true 1089 | } 1090 | } 1091 | }, 1092 | "node_modules/node-fetch/node_modules/tr46": { 1093 | "version": "0.0.3", 1094 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1095 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 1096 | }, 1097 | "node_modules/node-fetch/node_modules/webidl-conversions": { 1098 | "version": "3.0.1", 1099 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1100 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 1101 | }, 1102 | "node_modules/node-fetch/node_modules/whatwg-url": { 1103 | "version": "5.0.0", 1104 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1105 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1106 | "dependencies": { 1107 | "tr46": "~0.0.3", 1108 | "webidl-conversions": "^3.0.0" 1109 | } 1110 | }, 1111 | "node_modules/nopt": { 1112 | "version": "5.0.0", 1113 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", 1114 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", 1115 | "dependencies": { 1116 | "abbrev": "1" 1117 | }, 1118 | "bin": { 1119 | "nopt": "bin/nopt.js" 1120 | }, 1121 | "engines": { 1122 | "node": ">=6" 1123 | } 1124 | }, 1125 | "node_modules/npmlog": { 1126 | "version": "5.0.1", 1127 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", 1128 | "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", 1129 | "dependencies": { 1130 | "are-we-there-yet": "^2.0.0", 1131 | "console-control-strings": "^1.1.0", 1132 | "gauge": "^3.0.0", 1133 | "set-blocking": "^2.0.0" 1134 | } 1135 | }, 1136 | "node_modules/object-assign": { 1137 | "version": "4.1.1", 1138 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1139 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1140 | "engines": { 1141 | "node": ">=0.10.0" 1142 | } 1143 | }, 1144 | "node_modules/object-inspect": { 1145 | "version": "1.13.1", 1146 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 1147 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 1148 | "funding": { 1149 | "url": "https://github.com/sponsors/ljharb" 1150 | } 1151 | }, 1152 | "node_modules/on-finished": { 1153 | "version": "2.4.1", 1154 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1155 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1156 | "dependencies": { 1157 | "ee-first": "1.1.1" 1158 | }, 1159 | "engines": { 1160 | "node": ">= 0.8" 1161 | } 1162 | }, 1163 | "node_modules/once": { 1164 | "version": "1.4.0", 1165 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1166 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1167 | "dependencies": { 1168 | "wrappy": "1" 1169 | } 1170 | }, 1171 | "node_modules/parseurl": { 1172 | "version": "1.3.3", 1173 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1174 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1175 | "engines": { 1176 | "node": ">= 0.8" 1177 | } 1178 | }, 1179 | "node_modules/path-is-absolute": { 1180 | "version": "1.0.1", 1181 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1182 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1183 | "engines": { 1184 | "node": ">=0.10.0" 1185 | } 1186 | }, 1187 | "node_modules/path-to-regexp": { 1188 | "version": "0.1.7", 1189 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1190 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1191 | }, 1192 | "node_modules/proxy-addr": { 1193 | "version": "2.0.7", 1194 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1195 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1196 | "dependencies": { 1197 | "forwarded": "0.2.0", 1198 | "ipaddr.js": "1.9.1" 1199 | }, 1200 | "engines": { 1201 | "node": ">= 0.10" 1202 | } 1203 | }, 1204 | "node_modules/punycode": { 1205 | "version": "2.3.1", 1206 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1207 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1208 | "engines": { 1209 | "node": ">=6" 1210 | } 1211 | }, 1212 | "node_modules/qs": { 1213 | "version": "6.11.0", 1214 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1215 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1216 | "dependencies": { 1217 | "side-channel": "^1.0.4" 1218 | }, 1219 | "engines": { 1220 | "node": ">=0.6" 1221 | }, 1222 | "funding": { 1223 | "url": "https://github.com/sponsors/ljharb" 1224 | } 1225 | }, 1226 | "node_modules/range-parser": { 1227 | "version": "1.2.1", 1228 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1229 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1230 | "engines": { 1231 | "node": ">= 0.6" 1232 | } 1233 | }, 1234 | "node_modules/raw-body": { 1235 | "version": "2.5.1", 1236 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1237 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1238 | "dependencies": { 1239 | "bytes": "3.1.2", 1240 | "http-errors": "2.0.0", 1241 | "iconv-lite": "0.4.24", 1242 | "unpipe": "1.0.0" 1243 | }, 1244 | "engines": { 1245 | "node": ">= 0.8" 1246 | } 1247 | }, 1248 | "node_modules/readable-stream": { 1249 | "version": "3.6.2", 1250 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1251 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1252 | "dependencies": { 1253 | "inherits": "^2.0.3", 1254 | "string_decoder": "^1.1.1", 1255 | "util-deprecate": "^1.0.1" 1256 | }, 1257 | "engines": { 1258 | "node": ">= 6" 1259 | } 1260 | }, 1261 | "node_modules/rimraf": { 1262 | "version": "3.0.2", 1263 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1264 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1265 | "dependencies": { 1266 | "glob": "^7.1.3" 1267 | }, 1268 | "bin": { 1269 | "rimraf": "bin.js" 1270 | }, 1271 | "funding": { 1272 | "url": "https://github.com/sponsors/isaacs" 1273 | } 1274 | }, 1275 | "node_modules/safe-buffer": { 1276 | "version": "5.2.1", 1277 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1278 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1279 | "funding": [ 1280 | { 1281 | "type": "github", 1282 | "url": "https://github.com/sponsors/feross" 1283 | }, 1284 | { 1285 | "type": "patreon", 1286 | "url": "https://www.patreon.com/feross" 1287 | }, 1288 | { 1289 | "type": "consulting", 1290 | "url": "https://feross.org/support" 1291 | } 1292 | ] 1293 | }, 1294 | "node_modules/safer-buffer": { 1295 | "version": "2.1.2", 1296 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1297 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1298 | }, 1299 | "node_modules/semver": { 1300 | "version": "7.6.0", 1301 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", 1302 | "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", 1303 | "dependencies": { 1304 | "lru-cache": "^6.0.0" 1305 | }, 1306 | "bin": { 1307 | "semver": "bin/semver.js" 1308 | }, 1309 | "engines": { 1310 | "node": ">=10" 1311 | } 1312 | }, 1313 | "node_modules/send": { 1314 | "version": "0.18.0", 1315 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1316 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1317 | "dependencies": { 1318 | "debug": "2.6.9", 1319 | "depd": "2.0.0", 1320 | "destroy": "1.2.0", 1321 | "encodeurl": "~1.0.2", 1322 | "escape-html": "~1.0.3", 1323 | "etag": "~1.8.1", 1324 | "fresh": "0.5.2", 1325 | "http-errors": "2.0.0", 1326 | "mime": "1.6.0", 1327 | "ms": "2.1.3", 1328 | "on-finished": "2.4.1", 1329 | "range-parser": "~1.2.1", 1330 | "statuses": "2.0.1" 1331 | }, 1332 | "engines": { 1333 | "node": ">= 0.8.0" 1334 | } 1335 | }, 1336 | "node_modules/send/node_modules/ms": { 1337 | "version": "2.1.3", 1338 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1339 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1340 | }, 1341 | "node_modules/serve-static": { 1342 | "version": "1.15.0", 1343 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1344 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1345 | "dependencies": { 1346 | "encodeurl": "~1.0.2", 1347 | "escape-html": "~1.0.3", 1348 | "parseurl": "~1.3.3", 1349 | "send": "0.18.0" 1350 | }, 1351 | "engines": { 1352 | "node": ">= 0.8.0" 1353 | } 1354 | }, 1355 | "node_modules/set-blocking": { 1356 | "version": "2.0.0", 1357 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1358 | "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" 1359 | }, 1360 | "node_modules/set-function-length": { 1361 | "version": "1.2.0", 1362 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", 1363 | "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", 1364 | "dependencies": { 1365 | "define-data-property": "^1.1.1", 1366 | "function-bind": "^1.1.2", 1367 | "get-intrinsic": "^1.2.2", 1368 | "gopd": "^1.0.1", 1369 | "has-property-descriptors": "^1.0.1" 1370 | }, 1371 | "engines": { 1372 | "node": ">= 0.4" 1373 | } 1374 | }, 1375 | "node_modules/setprototypeof": { 1376 | "version": "1.2.0", 1377 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1378 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1379 | }, 1380 | "node_modules/side-channel": { 1381 | "version": "1.0.4", 1382 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1383 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1384 | "dependencies": { 1385 | "call-bind": "^1.0.0", 1386 | "get-intrinsic": "^1.0.2", 1387 | "object-inspect": "^1.9.0" 1388 | }, 1389 | "funding": { 1390 | "url": "https://github.com/sponsors/ljharb" 1391 | } 1392 | }, 1393 | "node_modules/sift": { 1394 | "version": "16.0.1", 1395 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", 1396 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" 1397 | }, 1398 | "node_modules/signal-exit": { 1399 | "version": "3.0.7", 1400 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1401 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" 1402 | }, 1403 | "node_modules/sparse-bitfield": { 1404 | "version": "3.0.3", 1405 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 1406 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 1407 | "dependencies": { 1408 | "memory-pager": "^1.0.2" 1409 | } 1410 | }, 1411 | "node_modules/statuses": { 1412 | "version": "2.0.1", 1413 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1414 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1415 | "engines": { 1416 | "node": ">= 0.8" 1417 | } 1418 | }, 1419 | "node_modules/string_decoder": { 1420 | "version": "1.3.0", 1421 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1422 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1423 | "dependencies": { 1424 | "safe-buffer": "~5.2.0" 1425 | } 1426 | }, 1427 | "node_modules/string-width": { 1428 | "version": "4.2.3", 1429 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1430 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1431 | "dependencies": { 1432 | "emoji-regex": "^8.0.0", 1433 | "is-fullwidth-code-point": "^3.0.0", 1434 | "strip-ansi": "^6.0.1" 1435 | }, 1436 | "engines": { 1437 | "node": ">=8" 1438 | } 1439 | }, 1440 | "node_modules/strip-ansi": { 1441 | "version": "6.0.1", 1442 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1443 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1444 | "dependencies": { 1445 | "ansi-regex": "^5.0.1" 1446 | }, 1447 | "engines": { 1448 | "node": ">=8" 1449 | } 1450 | }, 1451 | "node_modules/tar": { 1452 | "version": "6.2.0", 1453 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", 1454 | "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", 1455 | "dependencies": { 1456 | "chownr": "^2.0.0", 1457 | "fs-minipass": "^2.0.0", 1458 | "minipass": "^5.0.0", 1459 | "minizlib": "^2.1.1", 1460 | "mkdirp": "^1.0.3", 1461 | "yallist": "^4.0.0" 1462 | }, 1463 | "engines": { 1464 | "node": ">=10" 1465 | } 1466 | }, 1467 | "node_modules/toidentifier": { 1468 | "version": "1.0.1", 1469 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1470 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1471 | "engines": { 1472 | "node": ">=0.6" 1473 | } 1474 | }, 1475 | "node_modules/tr46": { 1476 | "version": "4.1.1", 1477 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 1478 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 1479 | "dependencies": { 1480 | "punycode": "^2.3.0" 1481 | }, 1482 | "engines": { 1483 | "node": ">=14" 1484 | } 1485 | }, 1486 | "node_modules/type-is": { 1487 | "version": "1.6.18", 1488 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1489 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1490 | "dependencies": { 1491 | "media-typer": "0.3.0", 1492 | "mime-types": "~2.1.24" 1493 | }, 1494 | "engines": { 1495 | "node": ">= 0.6" 1496 | } 1497 | }, 1498 | "node_modules/unpipe": { 1499 | "version": "1.0.0", 1500 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1501 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1502 | "engines": { 1503 | "node": ">= 0.8" 1504 | } 1505 | }, 1506 | "node_modules/util-deprecate": { 1507 | "version": "1.0.2", 1508 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1509 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 1510 | }, 1511 | "node_modules/utils-merge": { 1512 | "version": "1.0.1", 1513 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1514 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1515 | "engines": { 1516 | "node": ">= 0.4.0" 1517 | } 1518 | }, 1519 | "node_modules/vary": { 1520 | "version": "1.1.2", 1521 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1522 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1523 | "engines": { 1524 | "node": ">= 0.8" 1525 | } 1526 | }, 1527 | "node_modules/webidl-conversions": { 1528 | "version": "7.0.0", 1529 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 1530 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 1531 | "engines": { 1532 | "node": ">=12" 1533 | } 1534 | }, 1535 | "node_modules/whatwg-url": { 1536 | "version": "13.0.0", 1537 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 1538 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 1539 | "dependencies": { 1540 | "tr46": "^4.1.1", 1541 | "webidl-conversions": "^7.0.0" 1542 | }, 1543 | "engines": { 1544 | "node": ">=16" 1545 | } 1546 | }, 1547 | "node_modules/wide-align": { 1548 | "version": "1.1.5", 1549 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", 1550 | "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", 1551 | "dependencies": { 1552 | "string-width": "^1.0.2 || 2 || 3 || 4" 1553 | } 1554 | }, 1555 | "node_modules/wrappy": { 1556 | "version": "1.0.2", 1557 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1558 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 1559 | }, 1560 | "node_modules/yallist": { 1561 | "version": "4.0.0", 1562 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1563 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 1564 | }, 1565 | "node_modules/zod": { 1566 | "version": "3.22.4", 1567 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 1568 | "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", 1569 | "funding": { 1570 | "url": "https://github.com/sponsors/colinhacks" 1571 | } 1572 | } 1573 | } 1574 | } 1575 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "dev": "nodemon index.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "bcrypt": "^5.1.1", 16 | "cors": "^2.8.5", 17 | "dotenv": "^16.4.4", 18 | "express": "^4.18.2", 19 | "jsonwebtoken": "^9.0.2", 20 | "mongoose": "^8.1.0", 21 | "zod": "^3.22.4" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /backend/routes/account.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { authMiddleware } = require("../middleware"); 3 | const { Account } = require("../db"); 4 | const mongoose = require("mongoose"); 5 | 6 | const router = express.Router(); 7 | 8 | router.get("/balance", authMiddleware, async (req, res) => { 9 | const account = await Account.findOne({ 10 | userId: req.userId, 11 | }); 12 | 13 | res.json({ 14 | balance: account.balance, 15 | }); 16 | }); 17 | 18 | router.post("/transfer", authMiddleware, async (req, res) => { 19 | const session = await mongoose.startSession(); 20 | session.startTransaction(); 21 | 22 | const { amount, to } = req.body; 23 | 24 | // Don't allow transfer to oneself 25 | if (to === req.userId) { 26 | await session.abortTransaction(); 27 | return res.json({ message: "Cannot Transfer to yourself!" }); 28 | } 29 | 30 | // Fetch the accounts within transaction 31 | const account = await Account.findOne({ 32 | userId: req.userId, 33 | }).session(session); 34 | 35 | if (!account || account.balance < amount) { 36 | await session.abortTransaction(); 37 | return res.status(400).json({ 38 | message: "Insufficient balance", 39 | }); 40 | } 41 | 42 | // Fetch the accounts within transaction 43 | const toAccount = await Account.findOne({ 44 | userId: to, 45 | }).session(session); 46 | 47 | if (!toAccount) { 48 | await session.abortTransaction(); 49 | return res.status(400).json({ 50 | message: "Invalid account", 51 | }); 52 | } 53 | 54 | // Perform the transfer within transaction 55 | await Account.updateOne( 56 | { userId: req.userId }, 57 | { $inc: { balance: -amount } } 58 | ).session(session); 59 | await Account.updateOne( 60 | { userId: to }, 61 | { $inc: { balance: amount } } 62 | ).session(session); 63 | 64 | // Commit Transaction 65 | await session.commitTransaction(); 66 | 67 | res.json({ 68 | message: "Transfer successful", 69 | }); 70 | }); 71 | 72 | module.exports = router; 73 | -------------------------------------------------------------------------------- /backend/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const userRouter = require("./user"); 3 | const accountRouter = require("./account"); 4 | 5 | const router = express.Router(); 6 | 7 | router.use("/user", userRouter); 8 | router.use("/account", accountRouter); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /backend/routes/user.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const zod = require("zod"); 3 | const { User, Account } = require("../db"); 4 | const jwt = require("jsonwebtoken"); 5 | const bcrypt = require("bcrypt"); 6 | const { authMiddleware } = require("../middleware"); 7 | 8 | const router = express.Router(); 9 | 10 | // USER SIGN UP 11 | 12 | const signupBody = zod.object({ 13 | username: zod.string().email(), 14 | firstName: zod.string(), 15 | lastName: zod.string(), 16 | password: zod.string(), 17 | }); 18 | 19 | router.post("/signup", async (req, res) => { 20 | const { success } = signupBody.safeParse(req.body); 21 | if (!success) { 22 | return res.status(411).json({ 23 | message: "Incorrect inputs", 24 | }); 25 | } 26 | 27 | const existingUser = await User.findOne({ 28 | username: req.body.username, 29 | }); 30 | 31 | if (existingUser) { 32 | return res.status(411).json({ 33 | message: "Email already taken", 34 | }); 35 | } 36 | 37 | const { username, firstName, lastName, password } = req.body; 38 | 39 | const salt = await bcrypt.genSalt(10); 40 | const hashedPassword = await bcrypt.hashSync(password, salt); 41 | const newUser = await User.create({ 42 | username, 43 | firstName, 44 | lastName, 45 | password: hashedPassword, 46 | }); 47 | const userId = newUser._id; 48 | 49 | // ----- Create new account ------ 50 | 51 | await Account.create({ 52 | userId, 53 | balance: parseInt(Math.random() * 10000), 54 | }); 55 | 56 | // ----- ----- 57 | 58 | const token = jwt.sign( 59 | { 60 | userId, 61 | }, 62 | process.env.JWT_SECRET 63 | ); 64 | 65 | res.status(200).json({ 66 | message: "User created successfully", 67 | token: token, 68 | }); 69 | }); 70 | 71 | // USER SIGN IN 72 | 73 | const signinBody = zod.object({ 74 | username: zod.string().email(), 75 | password: zod.string(), 76 | }); 77 | 78 | router.post("/signin", async (req, res) => { 79 | const { success } = signinBody.safeParse(req.body); 80 | if (!success) { 81 | return res.status(411).json({ 82 | message: "Incorrect inputs", 83 | }); 84 | } 85 | 86 | const user = await User.findOne({ 87 | username: req.body.username, 88 | }); 89 | 90 | if (!user) { 91 | return res.status(404).json("User not found!"); 92 | } 93 | 94 | if (user) { 95 | const match = await bcrypt.compare(req.body.password, user.password); 96 | if (!match) { 97 | return res.status(401).json("Wrong credentials!"); 98 | } 99 | 100 | const token = jwt.sign( 101 | { 102 | userId: user._id, 103 | }, 104 | process.env.JWT_SECRET 105 | ); 106 | 107 | res.status(200).json({ 108 | token: token, 109 | }); 110 | return; 111 | } 112 | }); 113 | 114 | // FOR UPDATING USER INFO 115 | 116 | const updateBody = zod.object({ 117 | password: zod.string().optional(), 118 | firstName: zod.string().optional(), 119 | lastName: zod.string().optional(), 120 | }); 121 | 122 | router.put("/", authMiddleware, async (req, res) => { 123 | const { success } = updateBody.safeParse(req.body); 124 | if (!success) { 125 | res.status(411).json({ 126 | message: "Error while updating information", 127 | }); 128 | } 129 | 130 | await User.updateOne({ _id: req.userId }, req.body); 131 | 132 | res.json({ 133 | message: "Updated successfully", 134 | }); 135 | }); 136 | 137 | // FOR GETTING USERS WITH FILTER QUERY 138 | 139 | router.get("/bulk", async (req, res) => { 140 | const filter = req.query.filter || ""; 141 | 142 | const users = await User.find({ 143 | $or: [ 144 | { 145 | firstName: { 146 | $regex: filter, 147 | }, 148 | }, 149 | { 150 | lastName: { 151 | $regex: filter, 152 | }, 153 | }, 154 | ], 155 | }); 156 | 157 | res.json({ 158 | user: users.map((user) => ({ 159 | username: user.username, 160 | firstName: user.firstName, 161 | lastName: user.lastName, 162 | _id: user._id, 163 | })), 164 | }); 165 | }); 166 | 167 | // FOR GETTING CURRENT USER INFO 168 | 169 | router.get("/getUser", authMiddleware, async (req, res) => { 170 | const user = await User.findOne({ 171 | _id: req.userId, 172 | }); 173 | res.json(user); 174 | }); 175 | 176 | module.exports = router; 177 | -------------------------------------------------------------------------------- /backend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "index.js", 6 | "use": "@vercel/node" 7 | } 8 | ], 9 | "routes": [ 10 | { 11 | "src": "/(.*)", 12 | "dest": "/index.js", 13 | "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"], 14 | "headers": { 15 | "Access-Control-Allow-Credentials": "true", 16 | "Access-Control-Allow-Origin": "*", 17 | "Access-Control-Allow-Methods": "GET,OPTIONS,PATCH,DELETE,POST,PUT", 18 | "Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | .env 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | PayTM Clone 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.6.7", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-router-dom": "^6.22.1" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.43", 20 | "@types/react-dom": "^18.2.17", 21 | "@vitejs/plugin-react": "^4.2.1", 22 | "autoprefixer": "^10.4.17", 23 | "eslint": "^8.55.0", 24 | "eslint-plugin-react": "^7.33.2", 25 | "eslint-plugin-react-hooks": "^4.6.0", 26 | "eslint-plugin-react-refresh": "^0.4.5", 27 | "postcss": "^8.4.35", 28 | "tailwindcss": "^3.4.1", 29 | "vite": "^5.0.8" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 2 | import { Signup } from "./pages/Signup"; 3 | import { Signin } from "./pages/Signin"; 4 | import { Dashboard } from "./pages/Dashboard"; 5 | import { SendMoney } from "./pages/SendMoney"; 6 | import { PaymentStatus } from "./pages/PaymentStatus.jsx"; 7 | 8 | function App() { 9 | return ( 10 | <> 11 | 12 | 13 | } /> 14 | } /> 15 | } /> 16 | } /> 17 | } /> 18 | } /> 19 | 20 | 21 | 22 | ); 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /frontend/src/components/Appbar.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import axios from "axios"; 3 | import { Button } from "./Button"; 4 | import { Link, useNavigate } from "react-router-dom"; 5 | 6 | export const Appbar = () => { 7 | const [user, setUser] = useState(null); 8 | const navigate = useNavigate(); 9 | 10 | useEffect(() => { 11 | const userToken = localStorage.getItem("token"); 12 | 13 | // Check if token exists in local storage 14 | if (!userToken) { 15 | navigate("/signin"); // Redirect to sign-in page if token doesn't exist 16 | } else { 17 | axios 18 | .get(import.meta.env.VITE_SERVER_URL + "/api/v1/user/getUser", { 19 | headers: { 20 | Authorization: "Bearer " + localStorage.getItem("token"), 21 | }, 22 | }) 23 | .then((response) => { 24 | setUser(response.data); 25 | }); 26 | } 27 | }, []); 28 | 29 | const signOutHandler = () => { 30 | localStorage.removeItem("token"); 31 | navigate("/signin"); 32 | }; 33 | 34 | return ( 35 |
36 | 37 |
38 | PayTM App 39 |
40 | 41 |
42 |
52 |
53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /frontend/src/components/Balance.jsx: -------------------------------------------------------------------------------- 1 | export const Balance = ({ value }) => { 2 | return ( 3 |
4 |
Your balance
5 |
Rs {value}
6 |
7 | ); 8 | }; 9 | -------------------------------------------------------------------------------- /frontend/src/components/BottomWarning.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | export function BottomWarning({ label, buttonText, to }) { 4 | return ( 5 |
6 |
{label}
7 | 8 | {buttonText} 9 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /frontend/src/components/Button.jsx: -------------------------------------------------------------------------------- 1 | export function Button({ label, onClick }) { 2 | return ( 3 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /frontend/src/components/Heading.jsx: -------------------------------------------------------------------------------- 1 | export function Heading({ label }) { 2 | return
{label}
; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/src/components/InputBox.jsx: -------------------------------------------------------------------------------- 1 | export function InputBox({ label, placeholder, onChange }) { 2 | return ( 3 |
4 |
{label}
5 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /frontend/src/components/SubHeading.jsx: -------------------------------------------------------------------------------- 1 | export function SubHeading({ label }) { 2 | return
{label}
; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/src/components/Users.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { Button } from "./Button"; 3 | import axios from "axios"; 4 | import { useNavigate } from "react-router-dom"; 5 | 6 | export const Users = () => { 7 | const [users, setUsers] = useState([]); 8 | const [filter, setFilter] = useState(""); 9 | 10 | useEffect(() => { 11 | axios 12 | .get( 13 | import.meta.env.VITE_SERVER_URL + "/api/v1/user/bulk?filter=" + filter 14 | ) 15 | .then((response) => { 16 | setUsers(response.data.user); 17 | }); 18 | }, [filter]); 19 | 20 | return ( 21 | <> 22 |
Users
23 |
24 | { 26 | setFilter(e.target.value); 27 | }} 28 | type="text" 29 | placeholder="Search users..." 30 | className="w-full px-2 py-1 border rounded border-slate-200" 31 | > 32 |
33 |
34 | {users.map((user) => ( 35 | 36 | ))} 37 |
38 | 39 | ); 40 | }; 41 | 42 | function User({ user }) { 43 | const navigate = useNavigate(); 44 | 45 | return ( 46 |
47 |
48 |
49 |
50 | {user.firstName[0].toUpperCase()} 51 |
52 |
53 |
54 |
55 | {user.firstName} {user.lastName} 56 |
57 |
58 |
59 | 60 |
61 |
68 |
69 | ); 70 | } 71 | -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /frontend/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App.jsx"; 4 | import "./index.css"; 5 | 6 | ReactDOM.createRoot(document.getElementById("root")).render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /frontend/src/pages/Dashboard.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { Appbar } from "../components/Appbar"; 3 | import { Balance } from "../components/Balance"; 4 | import { Users } from "../components/Users"; 5 | import axios from "axios"; 6 | import { useNavigate } from "react-router-dom"; 7 | 8 | export const Dashboard = () => { 9 | const [bal, setBal] = useState(0); 10 | const navigate = useNavigate(); 11 | 12 | useEffect(() => { 13 | const userToken = localStorage.getItem("token"); 14 | 15 | // Check if token exists in local storage 16 | if (!userToken) { 17 | navigate("/signin"); // Redirect to sign-in page if token doesn't exist 18 | } else { 19 | // Fetch balance if token exists 20 | axios 21 | .get(import.meta.env.VITE_SERVER_URL + "/api/v1/account/balance", { 22 | headers: { 23 | Authorization: "Bearer " + userToken, 24 | }, 25 | }) 26 | .then((response) => { 27 | setBal(response.data.balance); 28 | }) 29 | .catch((error) => { 30 | navigate("/signin"); 31 | }); 32 | } 33 | }, [navigate]); 34 | 35 | return ( 36 |
37 | 38 |
39 | 40 | 41 |
42 |
43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /frontend/src/pages/PaymentStatus.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { useNavigate, useSearchParams } from "react-router-dom"; 3 | 4 | export const PaymentStatus = () => { 5 | const [searchParams] = useSearchParams(); 6 | const message = searchParams.get("message"); 7 | const navigate = useNavigate(); 8 | 9 | useEffect(() => { 10 | const userToken = localStorage.getItem("token"); 11 | 12 | // Check if token exists in local storage 13 | if (!userToken) { 14 | navigate("/signin"); // Redirect to sign-in page if token doesn't exist 15 | } else { 16 | const t = setTimeout(() => { 17 | navigate("/dashboard"); 18 | }, 3000); 19 | return () => clearTimeout(t); 20 | } 21 | }, []); 22 | 23 | return ( 24 |
25 |
26 | {message} 27 |
28 | Redirecting to Dashboard in 3 seconds. 29 |
30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /frontend/src/pages/SendMoney.jsx: -------------------------------------------------------------------------------- 1 | import { useNavigate, useSearchParams } from "react-router-dom"; 2 | import axios from "axios"; 3 | import { useEffect, useState } from "react"; 4 | 5 | export const SendMoney = () => { 6 | const navigate = useNavigate(); 7 | 8 | useEffect(() => { 9 | const userToken = localStorage.getItem("token"); 10 | 11 | // Check if token exists in local storage 12 | if (!userToken) { 13 | navigate("/signin"); // Redirect to sign-in page if token doesn't exist 14 | } 15 | }, []); 16 | 17 | const [searchParams] = useSearchParams(); 18 | const id = searchParams.get("id"); 19 | const name = searchParams.get("name"); 20 | const [amount, setAmount] = useState(0); 21 | 22 | return ( 23 |
24 |
25 |
26 |
27 |

Send Money

28 |
29 |
30 |
31 |
32 | 33 | {name && name.length > 0 && name[0].toUpperCase()} 34 | 35 |
36 |

{name}

37 |
38 |
39 |
40 | 43 | { 45 | setAmount(e.target.value); 46 | }} 47 | type="number" 48 | className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm" 49 | id="amount" 50 | placeholder="Enter amount" 51 | /> 52 |
53 | 76 | 82 |
83 |
84 |
85 |
86 |
87 | ); 88 | }; 89 | -------------------------------------------------------------------------------- /frontend/src/pages/Signin.jsx: -------------------------------------------------------------------------------- 1 | import { useNavigate } from "react-router-dom"; 2 | import { BottomWarning } from "../components/BottomWarning"; 3 | import { Button } from "../components/Button"; 4 | import { Heading } from "../components/Heading"; 5 | import { InputBox } from "../components/InputBox"; 6 | import { SubHeading } from "../components/SubHeading"; 7 | import { useEffect, useState } from "react"; 8 | import axios from "axios"; 9 | 10 | export const Signin = () => { 11 | const [username, setUsername] = useState(""); 12 | const [password, setPassword] = useState(""); 13 | const navigate = useNavigate(); 14 | 15 | useEffect(() => { 16 | const userToken = localStorage.getItem("token"); 17 | 18 | // Check if token exists in local storage 19 | if (userToken) { 20 | navigate("/dashboard"); // Redirect to sign-in page if token doesn't exist 21 | } 22 | }, []); 23 | 24 | return ( 25 |
26 |
27 |
28 | 29 | 30 | { 32 | setUsername(e.target.value); 33 | }} 34 | placeholder="Email" 35 | label={"Email"} 36 | /> 37 | { 39 | setPassword(e.target.value); 40 | }} 41 | placeholder="Password" 42 | label={"Password"} 43 | /> 44 |
45 |
60 | 65 |
66 |
67 |
68 | ); 69 | }; 70 | -------------------------------------------------------------------------------- /frontend/src/pages/Signup.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { BottomWarning } from "../components/BottomWarning"; 3 | import { Button } from "../components/Button"; 4 | import { Heading } from "../components/Heading"; 5 | import { InputBox } from "../components/InputBox"; 6 | import { SubHeading } from "../components/SubHeading"; 7 | import axios from "axios"; 8 | import { useNavigate } from "react-router-dom"; 9 | 10 | export const Signup = () => { 11 | const [firstName, setFirstName] = useState(""); 12 | const [lastName, setLastName] = useState(""); 13 | const [username, setUsername] = useState(""); 14 | const [password, setPassword] = useState(""); 15 | const navigate = useNavigate(); 16 | 17 | useEffect(() => { 18 | const userToken = localStorage.getItem("token"); 19 | 20 | // Check if token exists in local storage 21 | if (userToken) { 22 | navigate("/dashboard"); // Redirect to sign-in page if token doesn't exist 23 | } 24 | }, []); 25 | 26 | return ( 27 |
28 |
29 |
30 | 31 | 32 | { 34 | setFirstName(e.target.value); 35 | }} 36 | placeholder="FirstName" 37 | label={"First Name"} 38 | /> 39 | { 41 | setLastName(e.target.value); 42 | }} 43 | placeholder="LastName" 44 | label={"Last Name"} 45 | /> 46 | { 48 | setUsername(e.target.value); 49 | }} 50 | placeholder="Email" 51 | label={"Email"} 52 | /> 53 | { 55 | setPassword(e.target.value); 56 | }} 57 | placeholder="Password" 58 | label={"Password"} 59 | /> 60 |
61 |
78 | 83 |
84 |
85 |
86 | ); 87 | }; 88 | -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /frontend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/" }] 3 | } 4 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------