├── README.md ├── notezz.png ├── project.png ├── react-app-vite ├── .env ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── ProtectedRoute.tsx │ ├── Routing.tsx │ ├── api │ │ └── ApiConstants.ts │ ├── assets │ │ ├── logo.png │ │ └── todo.jpg │ ├── axios │ │ └── AxiosSetup.ts │ ├── components │ │ ├── ActiveTodoList.tsx │ │ ├── CompletedTodoList.tsx │ │ └── NavBar.tsx │ ├── main.tsx │ ├── pages │ │ ├── ActiveTodos.tsx │ │ ├── CompletedTodos.tsx │ │ ├── Login.tsx │ │ ├── SignUp.tsx │ │ └── UsersPage.tsx │ ├── utils │ │ └── LoginInfo.ts │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts └── todo-backend ├── .eslintrc.js ├── .gitignore ├── .local.env ├── .prettierrc ├── nest-cli.json ├── package-lock.json ├── package.json ├── src ├── app.module.ts ├── auth │ ├── auth.controller.ts │ ├── auth.module.ts │ ├── dto │ │ └── login.dto.ts │ ├── guard │ │ ├── jwt.guard.ts │ │ └── role.guard.ts │ └── strategy │ │ ├── jwt.strategy.ts │ │ └── local.strategy.ts ├── main.ts ├── todo │ ├── dto │ │ ├── create-todo.dto.ts │ │ └── update-todo.dto.ts │ ├── entities │ │ └── todo.entity.ts │ ├── repo │ │ └── todo.repository.ts │ ├── todo.controller.ts │ ├── todo.module.ts │ └── todo.service.ts ├── user │ ├── dto │ │ └── create-user.dto.ts │ ├── entities │ │ └── user.entity.ts │ ├── repo │ │ └── user.repository.ts │ ├── user.controller.ts │ ├── user.module.ts │ └── user.service.ts └── utils │ └── constants.ts ├── test ├── app.e2e-spec.ts └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json /README.md: -------------------------------------------------------------------------------- 1 | ![myimage-alt-tag](./project.png) 2 | 3 |

A Todo App Written with NestJs And Integragted with React Front-End

4 |

5 | NPM Version 6 | Package License 7 | NPM Downloads 8 | CircleCI 9 | Coverage 10 | Discord 11 | Backers on Open Collective 12 | Sponsors on Open Collective 13 | 14 | Support us 15 | 16 |

17 | 19 | 20 | ## NestJs Configuration 21 | 22 | Live At https://todo.afaqjaved.com 23 | 24 | ``` 25 | Provide Postgres Parameters 26 | in .local.env file accordingly : 27 | 28 | DATABASE_HOST 29 | DATABASE_PORT 30 | DATABASE_USERNANE 31 | DATABASE_PASSWORD 32 | DATABASE_NAME 33 | ``` 34 | 35 | ## NestJs Install Dependencies 36 | 37 | ```bash 38 | $ npm install 39 | ``` 40 | 41 | ## Run NestJs (Default Port is 3000) 42 | 43 | ```bash 44 | # development 45 | $ npm run start 46 | 47 | # watch mode 48 | $ npm run start:dev 49 | 50 | # production mode 51 | $ npm run start:prod 52 | ``` 53 | 54 | ## React Install Dependencies 55 | 56 | ```bash 57 | $ npm install 58 | ``` 59 | 60 | ## Run React App (Default Port is 4000) 61 | 62 | ``` 63 | npm run dev 64 | ``` 65 | 66 | ![myimage-alt-tag](./notezz.png) 67 | 68 | # Support By Subscribing [Notezz](https://www.youtube.com/channel/UC8DETz-dfBr_xkotFcNu5tQ). 69 | 70 | ## Stay in touch 71 | 72 | - Author - Afaq Javed 73 | - Website - [https://afaqjaved.com] 74 | -------------------------------------------------------------------------------- /notezz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AfaqJaved/todo-app-nestjs-react/c873940fbc5bc566a78ade475079553f46ba7095/notezz.png -------------------------------------------------------------------------------- /project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AfaqJaved/todo-app-nestjs-react/c873940fbc5bc566a78ade475079553f46ba7095/project.png -------------------------------------------------------------------------------- /react-app-vite/.env: -------------------------------------------------------------------------------- 1 | VITE_BASE_URL=https://todo.backend.afaqjaved.com -------------------------------------------------------------------------------- /react-app-vite/.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 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /react-app-vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Todo App 8 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /react-app-vite/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-app-vite", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "react-app-vite", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "axios": "^0.27.2", 12 | "dotenv": "^16.0.1", 13 | "jwt-decode": "^3.1.2", 14 | "react": "^18.0.0", 15 | "react-dom": "^18.0.0", 16 | "react-router-dom": "^6.3.0", 17 | "react-toastify": "^9.0.3" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^18.0.0", 21 | "@types/react-dom": "^18.0.0", 22 | "@vitejs/plugin-react": "^1.3.0", 23 | "typescript": "^4.6.3", 24 | "vite": "^2.9.9" 25 | } 26 | }, 27 | "node_modules/@ampproject/remapping": { 28 | "version": "2.2.0", 29 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", 30 | "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", 31 | "dev": true, 32 | "dependencies": { 33 | "@jridgewell/gen-mapping": "^0.1.0", 34 | "@jridgewell/trace-mapping": "^0.3.9" 35 | }, 36 | "engines": { 37 | "node": ">=6.0.0" 38 | } 39 | }, 40 | "node_modules/@babel/code-frame": { 41 | "version": "7.16.7", 42 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", 43 | "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", 44 | "dev": true, 45 | "dependencies": { 46 | "@babel/highlight": "^7.16.7" 47 | }, 48 | "engines": { 49 | "node": ">=6.9.0" 50 | } 51 | }, 52 | "node_modules/@babel/compat-data": { 53 | "version": "7.17.10", 54 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", 55 | "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", 56 | "dev": true, 57 | "engines": { 58 | "node": ">=6.9.0" 59 | } 60 | }, 61 | "node_modules/@babel/core": { 62 | "version": "7.18.2", 63 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", 64 | "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", 65 | "dev": true, 66 | "dependencies": { 67 | "@ampproject/remapping": "^2.1.0", 68 | "@babel/code-frame": "^7.16.7", 69 | "@babel/generator": "^7.18.2", 70 | "@babel/helper-compilation-targets": "^7.18.2", 71 | "@babel/helper-module-transforms": "^7.18.0", 72 | "@babel/helpers": "^7.18.2", 73 | "@babel/parser": "^7.18.0", 74 | "@babel/template": "^7.16.7", 75 | "@babel/traverse": "^7.18.2", 76 | "@babel/types": "^7.18.2", 77 | "convert-source-map": "^1.7.0", 78 | "debug": "^4.1.0", 79 | "gensync": "^1.0.0-beta.2", 80 | "json5": "^2.2.1", 81 | "semver": "^6.3.0" 82 | }, 83 | "engines": { 84 | "node": ">=6.9.0" 85 | }, 86 | "funding": { 87 | "type": "opencollective", 88 | "url": "https://opencollective.com/babel" 89 | } 90 | }, 91 | "node_modules/@babel/generator": { 92 | "version": "7.18.2", 93 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", 94 | "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", 95 | "dev": true, 96 | "dependencies": { 97 | "@babel/types": "^7.18.2", 98 | "@jridgewell/gen-mapping": "^0.3.0", 99 | "jsesc": "^2.5.1" 100 | }, 101 | "engines": { 102 | "node": ">=6.9.0" 103 | } 104 | }, 105 | "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { 106 | "version": "0.3.1", 107 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", 108 | "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", 109 | "dev": true, 110 | "dependencies": { 111 | "@jridgewell/set-array": "^1.0.0", 112 | "@jridgewell/sourcemap-codec": "^1.4.10", 113 | "@jridgewell/trace-mapping": "^0.3.9" 114 | }, 115 | "engines": { 116 | "node": ">=6.0.0" 117 | } 118 | }, 119 | "node_modules/@babel/helper-annotate-as-pure": { 120 | "version": "7.16.7", 121 | "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", 122 | "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", 123 | "dev": true, 124 | "dependencies": { 125 | "@babel/types": "^7.16.7" 126 | }, 127 | "engines": { 128 | "node": ">=6.9.0" 129 | } 130 | }, 131 | "node_modules/@babel/helper-compilation-targets": { 132 | "version": "7.18.2", 133 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", 134 | "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", 135 | "dev": true, 136 | "dependencies": { 137 | "@babel/compat-data": "^7.17.10", 138 | "@babel/helper-validator-option": "^7.16.7", 139 | "browserslist": "^4.20.2", 140 | "semver": "^6.3.0" 141 | }, 142 | "engines": { 143 | "node": ">=6.9.0" 144 | }, 145 | "peerDependencies": { 146 | "@babel/core": "^7.0.0" 147 | } 148 | }, 149 | "node_modules/@babel/helper-environment-visitor": { 150 | "version": "7.18.2", 151 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", 152 | "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", 153 | "dev": true, 154 | "engines": { 155 | "node": ">=6.9.0" 156 | } 157 | }, 158 | "node_modules/@babel/helper-function-name": { 159 | "version": "7.17.9", 160 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", 161 | "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", 162 | "dev": true, 163 | "dependencies": { 164 | "@babel/template": "^7.16.7", 165 | "@babel/types": "^7.17.0" 166 | }, 167 | "engines": { 168 | "node": ">=6.9.0" 169 | } 170 | }, 171 | "node_modules/@babel/helper-hoist-variables": { 172 | "version": "7.16.7", 173 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", 174 | "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", 175 | "dev": true, 176 | "dependencies": { 177 | "@babel/types": "^7.16.7" 178 | }, 179 | "engines": { 180 | "node": ">=6.9.0" 181 | } 182 | }, 183 | "node_modules/@babel/helper-module-imports": { 184 | "version": "7.16.7", 185 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", 186 | "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", 187 | "dev": true, 188 | "dependencies": { 189 | "@babel/types": "^7.16.7" 190 | }, 191 | "engines": { 192 | "node": ">=6.9.0" 193 | } 194 | }, 195 | "node_modules/@babel/helper-module-transforms": { 196 | "version": "7.18.0", 197 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", 198 | "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", 199 | "dev": true, 200 | "dependencies": { 201 | "@babel/helper-environment-visitor": "^7.16.7", 202 | "@babel/helper-module-imports": "^7.16.7", 203 | "@babel/helper-simple-access": "^7.17.7", 204 | "@babel/helper-split-export-declaration": "^7.16.7", 205 | "@babel/helper-validator-identifier": "^7.16.7", 206 | "@babel/template": "^7.16.7", 207 | "@babel/traverse": "^7.18.0", 208 | "@babel/types": "^7.18.0" 209 | }, 210 | "engines": { 211 | "node": ">=6.9.0" 212 | } 213 | }, 214 | "node_modules/@babel/helper-plugin-utils": { 215 | "version": "7.17.12", 216 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", 217 | "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", 218 | "dev": true, 219 | "engines": { 220 | "node": ">=6.9.0" 221 | } 222 | }, 223 | "node_modules/@babel/helper-simple-access": { 224 | "version": "7.18.2", 225 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", 226 | "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", 227 | "dev": true, 228 | "dependencies": { 229 | "@babel/types": "^7.18.2" 230 | }, 231 | "engines": { 232 | "node": ">=6.9.0" 233 | } 234 | }, 235 | "node_modules/@babel/helper-split-export-declaration": { 236 | "version": "7.16.7", 237 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", 238 | "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", 239 | "dev": true, 240 | "dependencies": { 241 | "@babel/types": "^7.16.7" 242 | }, 243 | "engines": { 244 | "node": ">=6.9.0" 245 | } 246 | }, 247 | "node_modules/@babel/helper-validator-identifier": { 248 | "version": "7.16.7", 249 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", 250 | "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", 251 | "dev": true, 252 | "engines": { 253 | "node": ">=6.9.0" 254 | } 255 | }, 256 | "node_modules/@babel/helper-validator-option": { 257 | "version": "7.16.7", 258 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", 259 | "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", 260 | "dev": true, 261 | "engines": { 262 | "node": ">=6.9.0" 263 | } 264 | }, 265 | "node_modules/@babel/helpers": { 266 | "version": "7.18.2", 267 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", 268 | "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", 269 | "dev": true, 270 | "dependencies": { 271 | "@babel/template": "^7.16.7", 272 | "@babel/traverse": "^7.18.2", 273 | "@babel/types": "^7.18.2" 274 | }, 275 | "engines": { 276 | "node": ">=6.9.0" 277 | } 278 | }, 279 | "node_modules/@babel/highlight": { 280 | "version": "7.17.12", 281 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", 282 | "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", 283 | "dev": true, 284 | "dependencies": { 285 | "@babel/helper-validator-identifier": "^7.16.7", 286 | "chalk": "^2.0.0", 287 | "js-tokens": "^4.0.0" 288 | }, 289 | "engines": { 290 | "node": ">=6.9.0" 291 | } 292 | }, 293 | "node_modules/@babel/parser": { 294 | "version": "7.18.3", 295 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.3.tgz", 296 | "integrity": "sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==", 297 | "dev": true, 298 | "bin": { 299 | "parser": "bin/babel-parser.js" 300 | }, 301 | "engines": { 302 | "node": ">=6.0.0" 303 | } 304 | }, 305 | "node_modules/@babel/plugin-syntax-jsx": { 306 | "version": "7.17.12", 307 | "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz", 308 | "integrity": "sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==", 309 | "dev": true, 310 | "dependencies": { 311 | "@babel/helper-plugin-utils": "^7.17.12" 312 | }, 313 | "engines": { 314 | "node": ">=6.9.0" 315 | }, 316 | "peerDependencies": { 317 | "@babel/core": "^7.0.0-0" 318 | } 319 | }, 320 | "node_modules/@babel/plugin-transform-react-jsx": { 321 | "version": "7.17.12", 322 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", 323 | "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", 324 | "dev": true, 325 | "dependencies": { 326 | "@babel/helper-annotate-as-pure": "^7.16.7", 327 | "@babel/helper-module-imports": "^7.16.7", 328 | "@babel/helper-plugin-utils": "^7.17.12", 329 | "@babel/plugin-syntax-jsx": "^7.17.12", 330 | "@babel/types": "^7.17.12" 331 | }, 332 | "engines": { 333 | "node": ">=6.9.0" 334 | }, 335 | "peerDependencies": { 336 | "@babel/core": "^7.0.0-0" 337 | } 338 | }, 339 | "node_modules/@babel/plugin-transform-react-jsx-development": { 340 | "version": "7.16.7", 341 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz", 342 | "integrity": "sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==", 343 | "dev": true, 344 | "dependencies": { 345 | "@babel/plugin-transform-react-jsx": "^7.16.7" 346 | }, 347 | "engines": { 348 | "node": ">=6.9.0" 349 | }, 350 | "peerDependencies": { 351 | "@babel/core": "^7.0.0-0" 352 | } 353 | }, 354 | "node_modules/@babel/plugin-transform-react-jsx-self": { 355 | "version": "7.17.12", 356 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.17.12.tgz", 357 | "integrity": "sha512-7S9G2B44EnYOx74mue02t1uD8ckWZ/ee6Uz/qfdzc35uWHX5NgRy9i+iJSb2LFRgMd+QV9zNcStQaazzzZ3n3Q==", 358 | "dev": true, 359 | "dependencies": { 360 | "@babel/helper-plugin-utils": "^7.17.12" 361 | }, 362 | "engines": { 363 | "node": ">=6.9.0" 364 | }, 365 | "peerDependencies": { 366 | "@babel/core": "^7.0.0-0" 367 | } 368 | }, 369 | "node_modules/@babel/plugin-transform-react-jsx-source": { 370 | "version": "7.16.7", 371 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz", 372 | "integrity": "sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw==", 373 | "dev": true, 374 | "dependencies": { 375 | "@babel/helper-plugin-utils": "^7.16.7" 376 | }, 377 | "engines": { 378 | "node": ">=6.9.0" 379 | }, 380 | "peerDependencies": { 381 | "@babel/core": "^7.0.0-0" 382 | } 383 | }, 384 | "node_modules/@babel/runtime": { 385 | "version": "7.18.3", 386 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", 387 | "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", 388 | "dependencies": { 389 | "regenerator-runtime": "^0.13.4" 390 | }, 391 | "engines": { 392 | "node": ">=6.9.0" 393 | } 394 | }, 395 | "node_modules/@babel/template": { 396 | "version": "7.16.7", 397 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", 398 | "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", 399 | "dev": true, 400 | "dependencies": { 401 | "@babel/code-frame": "^7.16.7", 402 | "@babel/parser": "^7.16.7", 403 | "@babel/types": "^7.16.7" 404 | }, 405 | "engines": { 406 | "node": ">=6.9.0" 407 | } 408 | }, 409 | "node_modules/@babel/traverse": { 410 | "version": "7.18.2", 411 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", 412 | "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", 413 | "dev": true, 414 | "dependencies": { 415 | "@babel/code-frame": "^7.16.7", 416 | "@babel/generator": "^7.18.2", 417 | "@babel/helper-environment-visitor": "^7.18.2", 418 | "@babel/helper-function-name": "^7.17.9", 419 | "@babel/helper-hoist-variables": "^7.16.7", 420 | "@babel/helper-split-export-declaration": "^7.16.7", 421 | "@babel/parser": "^7.18.0", 422 | "@babel/types": "^7.18.2", 423 | "debug": "^4.1.0", 424 | "globals": "^11.1.0" 425 | }, 426 | "engines": { 427 | "node": ">=6.9.0" 428 | } 429 | }, 430 | "node_modules/@babel/types": { 431 | "version": "7.18.2", 432 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.2.tgz", 433 | "integrity": "sha512-0On6B8A4/+mFUto5WERt3EEuG1NznDirvwca1O8UwXQHVY8g3R7OzYgxXdOfMwLO08UrpUD/2+3Bclyq+/C94Q==", 434 | "dev": true, 435 | "dependencies": { 436 | "@babel/helper-validator-identifier": "^7.16.7", 437 | "to-fast-properties": "^2.0.0" 438 | }, 439 | "engines": { 440 | "node": ">=6.9.0" 441 | } 442 | }, 443 | "node_modules/@jridgewell/gen-mapping": { 444 | "version": "0.1.1", 445 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", 446 | "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", 447 | "dev": true, 448 | "dependencies": { 449 | "@jridgewell/set-array": "^1.0.0", 450 | "@jridgewell/sourcemap-codec": "^1.4.10" 451 | }, 452 | "engines": { 453 | "node": ">=6.0.0" 454 | } 455 | }, 456 | "node_modules/@jridgewell/resolve-uri": { 457 | "version": "3.0.7", 458 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", 459 | "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", 460 | "dev": true, 461 | "engines": { 462 | "node": ">=6.0.0" 463 | } 464 | }, 465 | "node_modules/@jridgewell/set-array": { 466 | "version": "1.1.1", 467 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", 468 | "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", 469 | "dev": true, 470 | "engines": { 471 | "node": ">=6.0.0" 472 | } 473 | }, 474 | "node_modules/@jridgewell/sourcemap-codec": { 475 | "version": "1.4.13", 476 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", 477 | "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", 478 | "dev": true 479 | }, 480 | "node_modules/@jridgewell/trace-mapping": { 481 | "version": "0.3.13", 482 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", 483 | "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", 484 | "dev": true, 485 | "dependencies": { 486 | "@jridgewell/resolve-uri": "^3.0.3", 487 | "@jridgewell/sourcemap-codec": "^1.4.10" 488 | } 489 | }, 490 | "node_modules/@rollup/pluginutils": { 491 | "version": "4.2.1", 492 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", 493 | "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", 494 | "dev": true, 495 | "dependencies": { 496 | "estree-walker": "^2.0.1", 497 | "picomatch": "^2.2.2" 498 | }, 499 | "engines": { 500 | "node": ">= 8.0.0" 501 | } 502 | }, 503 | "node_modules/@types/prop-types": { 504 | "version": "15.7.5", 505 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", 506 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", 507 | "dev": true 508 | }, 509 | "node_modules/@types/react": { 510 | "version": "18.0.9", 511 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.9.tgz", 512 | "integrity": "sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw==", 513 | "dev": true, 514 | "dependencies": { 515 | "@types/prop-types": "*", 516 | "@types/scheduler": "*", 517 | "csstype": "^3.0.2" 518 | } 519 | }, 520 | "node_modules/@types/react-dom": { 521 | "version": "18.0.5", 522 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.5.tgz", 523 | "integrity": "sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA==", 524 | "dev": true, 525 | "dependencies": { 526 | "@types/react": "*" 527 | } 528 | }, 529 | "node_modules/@types/scheduler": { 530 | "version": "0.16.2", 531 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 532 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 533 | "dev": true 534 | }, 535 | "node_modules/@vitejs/plugin-react": { 536 | "version": "1.3.2", 537 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz", 538 | "integrity": "sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==", 539 | "dev": true, 540 | "dependencies": { 541 | "@babel/core": "^7.17.10", 542 | "@babel/plugin-transform-react-jsx": "^7.17.3", 543 | "@babel/plugin-transform-react-jsx-development": "^7.16.7", 544 | "@babel/plugin-transform-react-jsx-self": "^7.16.7", 545 | "@babel/plugin-transform-react-jsx-source": "^7.16.7", 546 | "@rollup/pluginutils": "^4.2.1", 547 | "react-refresh": "^0.13.0", 548 | "resolve": "^1.22.0" 549 | }, 550 | "engines": { 551 | "node": ">=12.0.0" 552 | } 553 | }, 554 | "node_modules/ansi-styles": { 555 | "version": "3.2.1", 556 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 557 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 558 | "dev": true, 559 | "dependencies": { 560 | "color-convert": "^1.9.0" 561 | }, 562 | "engines": { 563 | "node": ">=4" 564 | } 565 | }, 566 | "node_modules/asynckit": { 567 | "version": "0.4.0", 568 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 569 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 570 | }, 571 | "node_modules/axios": { 572 | "version": "0.27.2", 573 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", 574 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", 575 | "dependencies": { 576 | "follow-redirects": "^1.14.9", 577 | "form-data": "^4.0.0" 578 | } 579 | }, 580 | "node_modules/browserslist": { 581 | "version": "4.20.3", 582 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", 583 | "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", 584 | "dev": true, 585 | "funding": [ 586 | { 587 | "type": "opencollective", 588 | "url": "https://opencollective.com/browserslist" 589 | }, 590 | { 591 | "type": "tidelift", 592 | "url": "https://tidelift.com/funding/github/npm/browserslist" 593 | } 594 | ], 595 | "dependencies": { 596 | "caniuse-lite": "^1.0.30001332", 597 | "electron-to-chromium": "^1.4.118", 598 | "escalade": "^3.1.1", 599 | "node-releases": "^2.0.3", 600 | "picocolors": "^1.0.0" 601 | }, 602 | "bin": { 603 | "browserslist": "cli.js" 604 | }, 605 | "engines": { 606 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 607 | } 608 | }, 609 | "node_modules/caniuse-lite": { 610 | "version": "1.0.30001344", 611 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz", 612 | "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==", 613 | "dev": true, 614 | "funding": [ 615 | { 616 | "type": "opencollective", 617 | "url": "https://opencollective.com/browserslist" 618 | }, 619 | { 620 | "type": "tidelift", 621 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 622 | } 623 | ] 624 | }, 625 | "node_modules/chalk": { 626 | "version": "2.4.2", 627 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 628 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 629 | "dev": true, 630 | "dependencies": { 631 | "ansi-styles": "^3.2.1", 632 | "escape-string-regexp": "^1.0.5", 633 | "supports-color": "^5.3.0" 634 | }, 635 | "engines": { 636 | "node": ">=4" 637 | } 638 | }, 639 | "node_modules/clsx": { 640 | "version": "1.1.1", 641 | "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", 642 | "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", 643 | "engines": { 644 | "node": ">=6" 645 | } 646 | }, 647 | "node_modules/color-convert": { 648 | "version": "1.9.3", 649 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 650 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 651 | "dev": true, 652 | "dependencies": { 653 | "color-name": "1.1.3" 654 | } 655 | }, 656 | "node_modules/color-name": { 657 | "version": "1.1.3", 658 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 659 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 660 | "dev": true 661 | }, 662 | "node_modules/combined-stream": { 663 | "version": "1.0.8", 664 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 665 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 666 | "dependencies": { 667 | "delayed-stream": "~1.0.0" 668 | }, 669 | "engines": { 670 | "node": ">= 0.8" 671 | } 672 | }, 673 | "node_modules/convert-source-map": { 674 | "version": "1.8.0", 675 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", 676 | "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", 677 | "dev": true, 678 | "dependencies": { 679 | "safe-buffer": "~5.1.1" 680 | } 681 | }, 682 | "node_modules/csstype": { 683 | "version": "3.1.0", 684 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", 685 | "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", 686 | "dev": true 687 | }, 688 | "node_modules/debug": { 689 | "version": "4.3.4", 690 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 691 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 692 | "dev": true, 693 | "dependencies": { 694 | "ms": "2.1.2" 695 | }, 696 | "engines": { 697 | "node": ">=6.0" 698 | }, 699 | "peerDependenciesMeta": { 700 | "supports-color": { 701 | "optional": true 702 | } 703 | } 704 | }, 705 | "node_modules/delayed-stream": { 706 | "version": "1.0.0", 707 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 708 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 709 | "engines": { 710 | "node": ">=0.4.0" 711 | } 712 | }, 713 | "node_modules/dotenv": { 714 | "version": "16.0.1", 715 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", 716 | "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", 717 | "engines": { 718 | "node": ">=12" 719 | } 720 | }, 721 | "node_modules/electron-to-chromium": { 722 | "version": "1.4.140", 723 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.140.tgz", 724 | "integrity": "sha512-NLz5va823QfJBYOO/hLV4AfU4Crmkl/6Hl2pH3qdJcmi0ySZ3YTWHxOlDm3uJOFBEPy3pIhu8gKQo6prQTWKKA==", 725 | "dev": true 726 | }, 727 | "node_modules/esbuild": { 728 | "version": "0.14.40", 729 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.40.tgz", 730 | "integrity": "sha512-toIoQk3ODEEIudsN74wXGdw1eiUN4aKRijOqiwEAqfUFlhORPYFJtACzRdRRlpUysRUUlvIUoGE1aw/MIVCWnA==", 731 | "dev": true, 732 | "hasInstallScript": true, 733 | "bin": { 734 | "esbuild": "bin/esbuild" 735 | }, 736 | "engines": { 737 | "node": ">=12" 738 | }, 739 | "optionalDependencies": { 740 | "esbuild-android-64": "0.14.40", 741 | "esbuild-android-arm64": "0.14.40", 742 | "esbuild-darwin-64": "0.14.40", 743 | "esbuild-darwin-arm64": "0.14.40", 744 | "esbuild-freebsd-64": "0.14.40", 745 | "esbuild-freebsd-arm64": "0.14.40", 746 | "esbuild-linux-32": "0.14.40", 747 | "esbuild-linux-64": "0.14.40", 748 | "esbuild-linux-arm": "0.14.40", 749 | "esbuild-linux-arm64": "0.14.40", 750 | "esbuild-linux-mips64le": "0.14.40", 751 | "esbuild-linux-ppc64le": "0.14.40", 752 | "esbuild-linux-riscv64": "0.14.40", 753 | "esbuild-linux-s390x": "0.14.40", 754 | "esbuild-netbsd-64": "0.14.40", 755 | "esbuild-openbsd-64": "0.14.40", 756 | "esbuild-sunos-64": "0.14.40", 757 | "esbuild-windows-32": "0.14.40", 758 | "esbuild-windows-64": "0.14.40", 759 | "esbuild-windows-arm64": "0.14.40" 760 | } 761 | }, 762 | "node_modules/esbuild-android-64": { 763 | "version": "0.14.40", 764 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.40.tgz", 765 | "integrity": "sha512-+69t+bmJWWhTyG8waJZcu4UGzM4NbDXAwssTEDYwonyz6L/Is11Y3csJhE16RM0a1GeDin0n810vNP+NVjttKA==", 766 | "cpu": [ 767 | "x64" 768 | ], 769 | "dev": true, 770 | "optional": true, 771 | "os": [ 772 | "android" 773 | ], 774 | "engines": { 775 | "node": ">=12" 776 | } 777 | }, 778 | "node_modules/esbuild-android-arm64": { 779 | "version": "0.14.40", 780 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.40.tgz", 781 | "integrity": "sha512-lVDn4d7/NL5Svrxuskmd/YcluI6uI4Ebp7A1/tWyLJJYbvfIy5l4Vy8GMhErGLePbRyJJiuBP9xusapK4u+6bg==", 782 | "cpu": [ 783 | "arm64" 784 | ], 785 | "dev": true, 786 | "optional": true, 787 | "os": [ 788 | "android" 789 | ], 790 | "engines": { 791 | "node": ">=12" 792 | } 793 | }, 794 | "node_modules/esbuild-darwin-64": { 795 | "version": "0.14.40", 796 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.40.tgz", 797 | "integrity": "sha512-b5u3IXCHhOjkRHIQTSxCN7ObUR5NTyJCP9LrnJ69dEEi1w1usI40T/VNyTTCs7n0UgEH7/zi27vBxbZU+sU4Ew==", 798 | "cpu": [ 799 | "x64" 800 | ], 801 | "dev": true, 802 | "optional": true, 803 | "os": [ 804 | "darwin" 805 | ], 806 | "engines": { 807 | "node": ">=12" 808 | } 809 | }, 810 | "node_modules/esbuild-darwin-arm64": { 811 | "version": "0.14.40", 812 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.40.tgz", 813 | "integrity": "sha512-Wn0C2nrZSANvzK9efcxjKpv9l8yUC4PtYMmnf775gUNwak7sqecuoelhbUTshhrwsfjCNfjsrUhsHY2OHUiEdw==", 814 | "cpu": [ 815 | "arm64" 816 | ], 817 | "dev": true, 818 | "optional": true, 819 | "os": [ 820 | "darwin" 821 | ], 822 | "engines": { 823 | "node": ">=12" 824 | } 825 | }, 826 | "node_modules/esbuild-freebsd-64": { 827 | "version": "0.14.40", 828 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.40.tgz", 829 | "integrity": "sha512-B9WZNUn7Y9f97xrQGBAQPKsebeFZzAd+JCdsLCexrVfTjB24b+/Iuq5O2z/q5Meg7Yz0S+j8AO6ncpvNkK2u0w==", 830 | "cpu": [ 831 | "x64" 832 | ], 833 | "dev": true, 834 | "optional": true, 835 | "os": [ 836 | "freebsd" 837 | ], 838 | "engines": { 839 | "node": ">=12" 840 | } 841 | }, 842 | "node_modules/esbuild-freebsd-arm64": { 843 | "version": "0.14.40", 844 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.40.tgz", 845 | "integrity": "sha512-3aB9uJv2/lmQNzwmieNyyOdxKi+3ERwrqf3snBu/oEng8b7nMBNrEN+p7jjkTYNYmo291KiH/5EIAXwpsZndFw==", 846 | "cpu": [ 847 | "arm64" 848 | ], 849 | "dev": true, 850 | "optional": true, 851 | "os": [ 852 | "freebsd" 853 | ], 854 | "engines": { 855 | "node": ">=12" 856 | } 857 | }, 858 | "node_modules/esbuild-linux-32": { 859 | "version": "0.14.40", 860 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.40.tgz", 861 | "integrity": "sha512-LMI9BMeuGf6NRS23LbyVarN3nf+JyNcfiVEnR9M8691kL5Ffp3e7oTYRH65XdTUirM9D6e5cppfWLjvrRbGnRw==", 862 | "cpu": [ 863 | "ia32" 864 | ], 865 | "dev": true, 866 | "optional": true, 867 | "os": [ 868 | "linux" 869 | ], 870 | "engines": { 871 | "node": ">=12" 872 | } 873 | }, 874 | "node_modules/esbuild-linux-64": { 875 | "version": "0.14.40", 876 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.40.tgz", 877 | "integrity": "sha512-D/NkZ9QR2KShJXNuRWANxJzPCrwJoAoWVetQiGIAepzXbNh+dBo5ZLmlh8Txs6tE600N67MF/ScHP1S4FxLaJg==", 878 | "cpu": [ 879 | "x64" 880 | ], 881 | "dev": true, 882 | "optional": true, 883 | "os": [ 884 | "linux" 885 | ], 886 | "engines": { 887 | "node": ">=12" 888 | } 889 | }, 890 | "node_modules/esbuild-linux-arm": { 891 | "version": "0.14.40", 892 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.40.tgz", 893 | "integrity": "sha512-2a0yZXbzr/s3iCgZ84jFTHf+NyyXQ/7/Sd28oQq5iyy7TbJNS973XUOwgdlHdRqBxvw0nIWTw2FuwyUJAFa6Qg==", 894 | "cpu": [ 895 | "arm" 896 | ], 897 | "dev": true, 898 | "optional": true, 899 | "os": [ 900 | "linux" 901 | ], 902 | "engines": { 903 | "node": ">=12" 904 | } 905 | }, 906 | "node_modules/esbuild-linux-arm64": { 907 | "version": "0.14.40", 908 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.40.tgz", 909 | "integrity": "sha512-TIoZWKjrMJxZujh2nSsrrLkLDLzD/oBpSiobdUGe2bqKZpT4m7fkR0tEDNyM6Xvzj9uTQ4iTfJr2ekmpg3DyTQ==", 910 | "cpu": [ 911 | "arm64" 912 | ], 913 | "dev": true, 914 | "optional": true, 915 | "os": [ 916 | "linux" 917 | ], 918 | "engines": { 919 | "node": ">=12" 920 | } 921 | }, 922 | "node_modules/esbuild-linux-mips64le": { 923 | "version": "0.14.40", 924 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.40.tgz", 925 | "integrity": "sha512-SP30CYYSDMwr6mPUbjvD4K2R03GQHIQGrkrbXt5NM6mFqzR+S+JKVv9juq/CjlM9V7iIPPPqe4mb4DWC3b8pBw==", 926 | "cpu": [ 927 | "mips64el" 928 | ], 929 | "dev": true, 930 | "optional": true, 931 | "os": [ 932 | "linux" 933 | ], 934 | "engines": { 935 | "node": ">=12" 936 | } 937 | }, 938 | "node_modules/esbuild-linux-ppc64le": { 939 | "version": "0.14.40", 940 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.40.tgz", 941 | "integrity": "sha512-HlU3dfIdwzm/zhbXvMa5yWIafBeI7v6BDaEuApAww5Av8ht7lXgD1fZ11iJVPjRWNLcCZUgZaJKFrosSPQO/Bw==", 942 | "cpu": [ 943 | "ppc64" 944 | ], 945 | "dev": true, 946 | "optional": true, 947 | "os": [ 948 | "linux" 949 | ], 950 | "engines": { 951 | "node": ">=12" 952 | } 953 | }, 954 | "node_modules/esbuild-linux-riscv64": { 955 | "version": "0.14.40", 956 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.40.tgz", 957 | "integrity": "sha512-4ImTBEUykhIcIq3c97dIXnsmAHb//cjHh4nxttLhwpTZ+b/KdM1IpttqFhB0AFLUsrjP4WOCMxAm5FOL7FC2uw==", 958 | "cpu": [ 959 | "riscv64" 960 | ], 961 | "dev": true, 962 | "optional": true, 963 | "os": [ 964 | "linux" 965 | ], 966 | "engines": { 967 | "node": ">=12" 968 | } 969 | }, 970 | "node_modules/esbuild-linux-s390x": { 971 | "version": "0.14.40", 972 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.40.tgz", 973 | "integrity": "sha512-kFCPKictYjpt5rt0bFdbSmb8AWut75sIh1fZUTCVkujWMcpdL8ADuYMfVrN7R0CSQvkF1nQtrIBfp+ZU7R7KNQ==", 974 | "cpu": [ 975 | "s390x" 976 | ], 977 | "dev": true, 978 | "optional": true, 979 | "os": [ 980 | "linux" 981 | ], 982 | "engines": { 983 | "node": ">=12" 984 | } 985 | }, 986 | "node_modules/esbuild-netbsd-64": { 987 | "version": "0.14.40", 988 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.40.tgz", 989 | "integrity": "sha512-Hwzw2cSI6+p03TUjugzec54W6uW4tA1J/WovmlHl96Icjy73eWnAyCQwgG6ZLirXpt2aDfTEVShNaC2fE4KVhQ==", 990 | "cpu": [ 991 | "x64" 992 | ], 993 | "dev": true, 994 | "optional": true, 995 | "os": [ 996 | "netbsd" 997 | ], 998 | "engines": { 999 | "node": ">=12" 1000 | } 1001 | }, 1002 | "node_modules/esbuild-openbsd-64": { 1003 | "version": "0.14.40", 1004 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.40.tgz", 1005 | "integrity": "sha512-L4Pix+N2Sb0HvLl8zyn1Aq2aYD5Jt8rk9zwW3NUx19yafJqAFsnUN7L/XbbWSv5/XMqnY4hpAvIP2pyeV9+Bjw==", 1006 | "cpu": [ 1007 | "x64" 1008 | ], 1009 | "dev": true, 1010 | "optional": true, 1011 | "os": [ 1012 | "openbsd" 1013 | ], 1014 | "engines": { 1015 | "node": ">=12" 1016 | } 1017 | }, 1018 | "node_modules/esbuild-sunos-64": { 1019 | "version": "0.14.40", 1020 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.40.tgz", 1021 | "integrity": "sha512-iEITaelmmCO43ewk0bOYRGrewu2i2h2V0gKHQ/rz1MRqif8ohY/FNLn4WnThGUlrEgA1nTL1tc57PL12QbOo2Q==", 1022 | "cpu": [ 1023 | "x64" 1024 | ], 1025 | "dev": true, 1026 | "optional": true, 1027 | "os": [ 1028 | "sunos" 1029 | ], 1030 | "engines": { 1031 | "node": ">=12" 1032 | } 1033 | }, 1034 | "node_modules/esbuild-windows-32": { 1035 | "version": "0.14.40", 1036 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.40.tgz", 1037 | "integrity": "sha512-uXHmKl4RtCkK1v6QQK4hsP8Xiku6CwUM/W7Yv2rGtfylSOrrWKcpqwlDWx6bIm1Hav1uBC8hbgJ1hY6pWFNhNA==", 1038 | "cpu": [ 1039 | "ia32" 1040 | ], 1041 | "dev": true, 1042 | "optional": true, 1043 | "os": [ 1044 | "win32" 1045 | ], 1046 | "engines": { 1047 | "node": ">=12" 1048 | } 1049 | }, 1050 | "node_modules/esbuild-windows-64": { 1051 | "version": "0.14.40", 1052 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.40.tgz", 1053 | "integrity": "sha512-dvgQLVYnJzqce97AeHvxWtV9lHRDxIPatOikmrh1vt/SCE4tyVo5nAT/2SiZBJ6DzYmZT3BcJTV24bBLyu4ZUA==", 1054 | "cpu": [ 1055 | "x64" 1056 | ], 1057 | "dev": true, 1058 | "optional": true, 1059 | "os": [ 1060 | "win32" 1061 | ], 1062 | "engines": { 1063 | "node": ">=12" 1064 | } 1065 | }, 1066 | "node_modules/esbuild-windows-arm64": { 1067 | "version": "0.14.40", 1068 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.40.tgz", 1069 | "integrity": "sha512-c8ohQSFtRq78pZ/LQcpMft2xuR2IEitQkW07f9K7iN4EBdJMrCpOoXrZCfmX9lAC8yYOU7xHoLFYVln3n6fK1Q==", 1070 | "cpu": [ 1071 | "arm64" 1072 | ], 1073 | "dev": true, 1074 | "optional": true, 1075 | "os": [ 1076 | "win32" 1077 | ], 1078 | "engines": { 1079 | "node": ">=12" 1080 | } 1081 | }, 1082 | "node_modules/escalade": { 1083 | "version": "3.1.1", 1084 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1085 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1086 | "dev": true, 1087 | "engines": { 1088 | "node": ">=6" 1089 | } 1090 | }, 1091 | "node_modules/escape-string-regexp": { 1092 | "version": "1.0.5", 1093 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1094 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1095 | "dev": true, 1096 | "engines": { 1097 | "node": ">=0.8.0" 1098 | } 1099 | }, 1100 | "node_modules/estree-walker": { 1101 | "version": "2.0.2", 1102 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1103 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1104 | "dev": true 1105 | }, 1106 | "node_modules/follow-redirects": { 1107 | "version": "1.15.1", 1108 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", 1109 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", 1110 | "funding": [ 1111 | { 1112 | "type": "individual", 1113 | "url": "https://github.com/sponsors/RubenVerborgh" 1114 | } 1115 | ], 1116 | "engines": { 1117 | "node": ">=4.0" 1118 | }, 1119 | "peerDependenciesMeta": { 1120 | "debug": { 1121 | "optional": true 1122 | } 1123 | } 1124 | }, 1125 | "node_modules/form-data": { 1126 | "version": "4.0.0", 1127 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 1128 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 1129 | "dependencies": { 1130 | "asynckit": "^0.4.0", 1131 | "combined-stream": "^1.0.8", 1132 | "mime-types": "^2.1.12" 1133 | }, 1134 | "engines": { 1135 | "node": ">= 6" 1136 | } 1137 | }, 1138 | "node_modules/fsevents": { 1139 | "version": "2.3.2", 1140 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1141 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1142 | "dev": true, 1143 | "hasInstallScript": true, 1144 | "optional": true, 1145 | "os": [ 1146 | "darwin" 1147 | ], 1148 | "engines": { 1149 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1150 | } 1151 | }, 1152 | "node_modules/function-bind": { 1153 | "version": "1.1.1", 1154 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1155 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1156 | "dev": true 1157 | }, 1158 | "node_modules/gensync": { 1159 | "version": "1.0.0-beta.2", 1160 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 1161 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 1162 | "dev": true, 1163 | "engines": { 1164 | "node": ">=6.9.0" 1165 | } 1166 | }, 1167 | "node_modules/globals": { 1168 | "version": "11.12.0", 1169 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1170 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1171 | "dev": true, 1172 | "engines": { 1173 | "node": ">=4" 1174 | } 1175 | }, 1176 | "node_modules/has": { 1177 | "version": "1.0.3", 1178 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1179 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1180 | "dev": true, 1181 | "dependencies": { 1182 | "function-bind": "^1.1.1" 1183 | }, 1184 | "engines": { 1185 | "node": ">= 0.4.0" 1186 | } 1187 | }, 1188 | "node_modules/has-flag": { 1189 | "version": "3.0.0", 1190 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1191 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1192 | "dev": true, 1193 | "engines": { 1194 | "node": ">=4" 1195 | } 1196 | }, 1197 | "node_modules/history": { 1198 | "version": "5.3.0", 1199 | "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", 1200 | "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", 1201 | "dependencies": { 1202 | "@babel/runtime": "^7.7.6" 1203 | } 1204 | }, 1205 | "node_modules/is-core-module": { 1206 | "version": "2.9.0", 1207 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", 1208 | "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", 1209 | "dev": true, 1210 | "dependencies": { 1211 | "has": "^1.0.3" 1212 | }, 1213 | "funding": { 1214 | "url": "https://github.com/sponsors/ljharb" 1215 | } 1216 | }, 1217 | "node_modules/js-tokens": { 1218 | "version": "4.0.0", 1219 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1220 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 1221 | }, 1222 | "node_modules/jsesc": { 1223 | "version": "2.5.2", 1224 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1225 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1226 | "dev": true, 1227 | "bin": { 1228 | "jsesc": "bin/jsesc" 1229 | }, 1230 | "engines": { 1231 | "node": ">=4" 1232 | } 1233 | }, 1234 | "node_modules/json5": { 1235 | "version": "2.2.1", 1236 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", 1237 | "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", 1238 | "dev": true, 1239 | "bin": { 1240 | "json5": "lib/cli.js" 1241 | }, 1242 | "engines": { 1243 | "node": ">=6" 1244 | } 1245 | }, 1246 | "node_modules/jwt-decode": { 1247 | "version": "3.1.2", 1248 | "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", 1249 | "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" 1250 | }, 1251 | "node_modules/loose-envify": { 1252 | "version": "1.4.0", 1253 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 1254 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 1255 | "dependencies": { 1256 | "js-tokens": "^3.0.0 || ^4.0.0" 1257 | }, 1258 | "bin": { 1259 | "loose-envify": "cli.js" 1260 | } 1261 | }, 1262 | "node_modules/mime-db": { 1263 | "version": "1.52.0", 1264 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1265 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1266 | "engines": { 1267 | "node": ">= 0.6" 1268 | } 1269 | }, 1270 | "node_modules/mime-types": { 1271 | "version": "2.1.35", 1272 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1273 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1274 | "dependencies": { 1275 | "mime-db": "1.52.0" 1276 | }, 1277 | "engines": { 1278 | "node": ">= 0.6" 1279 | } 1280 | }, 1281 | "node_modules/ms": { 1282 | "version": "2.1.2", 1283 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1284 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1285 | "dev": true 1286 | }, 1287 | "node_modules/nanoid": { 1288 | "version": "3.3.4", 1289 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 1290 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", 1291 | "dev": true, 1292 | "bin": { 1293 | "nanoid": "bin/nanoid.cjs" 1294 | }, 1295 | "engines": { 1296 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1297 | } 1298 | }, 1299 | "node_modules/node-releases": { 1300 | "version": "2.0.5", 1301 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", 1302 | "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", 1303 | "dev": true 1304 | }, 1305 | "node_modules/path-parse": { 1306 | "version": "1.0.7", 1307 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1308 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1309 | "dev": true 1310 | }, 1311 | "node_modules/picocolors": { 1312 | "version": "1.0.0", 1313 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1314 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1315 | "dev": true 1316 | }, 1317 | "node_modules/picomatch": { 1318 | "version": "2.3.1", 1319 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1320 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1321 | "dev": true, 1322 | "engines": { 1323 | "node": ">=8.6" 1324 | }, 1325 | "funding": { 1326 | "url": "https://github.com/sponsors/jonschlinkert" 1327 | } 1328 | }, 1329 | "node_modules/postcss": { 1330 | "version": "8.4.14", 1331 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 1332 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 1333 | "dev": true, 1334 | "funding": [ 1335 | { 1336 | "type": "opencollective", 1337 | "url": "https://opencollective.com/postcss/" 1338 | }, 1339 | { 1340 | "type": "tidelift", 1341 | "url": "https://tidelift.com/funding/github/npm/postcss" 1342 | } 1343 | ], 1344 | "dependencies": { 1345 | "nanoid": "^3.3.4", 1346 | "picocolors": "^1.0.0", 1347 | "source-map-js": "^1.0.2" 1348 | }, 1349 | "engines": { 1350 | "node": "^10 || ^12 || >=14" 1351 | } 1352 | }, 1353 | "node_modules/react": { 1354 | "version": "18.1.0", 1355 | "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", 1356 | "integrity": "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==", 1357 | "dependencies": { 1358 | "loose-envify": "^1.1.0" 1359 | }, 1360 | "engines": { 1361 | "node": ">=0.10.0" 1362 | } 1363 | }, 1364 | "node_modules/react-dom": { 1365 | "version": "18.1.0", 1366 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", 1367 | "integrity": "sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==", 1368 | "dependencies": { 1369 | "loose-envify": "^1.1.0", 1370 | "scheduler": "^0.22.0" 1371 | }, 1372 | "peerDependencies": { 1373 | "react": "^18.1.0" 1374 | } 1375 | }, 1376 | "node_modules/react-refresh": { 1377 | "version": "0.13.0", 1378 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.13.0.tgz", 1379 | "integrity": "sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg==", 1380 | "dev": true, 1381 | "engines": { 1382 | "node": ">=0.10.0" 1383 | } 1384 | }, 1385 | "node_modules/react-router": { 1386 | "version": "6.3.0", 1387 | "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", 1388 | "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", 1389 | "dependencies": { 1390 | "history": "^5.2.0" 1391 | }, 1392 | "peerDependencies": { 1393 | "react": ">=16.8" 1394 | } 1395 | }, 1396 | "node_modules/react-router-dom": { 1397 | "version": "6.3.0", 1398 | "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", 1399 | "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", 1400 | "dependencies": { 1401 | "history": "^5.2.0", 1402 | "react-router": "6.3.0" 1403 | }, 1404 | "peerDependencies": { 1405 | "react": ">=16.8", 1406 | "react-dom": ">=16.8" 1407 | } 1408 | }, 1409 | "node_modules/react-toastify": { 1410 | "version": "9.0.3", 1411 | "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz", 1412 | "integrity": "sha512-0QZJk0SqYBxouRBGCFU3ymvjlwimRRhVH7SzqGRiVrQ001KSoUNbGKx9Yq42aoPv18n45yJzEFG82zqv3HnASg==", 1413 | "dependencies": { 1414 | "clsx": "^1.1.1" 1415 | }, 1416 | "peerDependencies": { 1417 | "react": ">=16", 1418 | "react-dom": ">=16" 1419 | } 1420 | }, 1421 | "node_modules/regenerator-runtime": { 1422 | "version": "0.13.9", 1423 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", 1424 | "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" 1425 | }, 1426 | "node_modules/resolve": { 1427 | "version": "1.22.0", 1428 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", 1429 | "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", 1430 | "dev": true, 1431 | "dependencies": { 1432 | "is-core-module": "^2.8.1", 1433 | "path-parse": "^1.0.7", 1434 | "supports-preserve-symlinks-flag": "^1.0.0" 1435 | }, 1436 | "bin": { 1437 | "resolve": "bin/resolve" 1438 | }, 1439 | "funding": { 1440 | "url": "https://github.com/sponsors/ljharb" 1441 | } 1442 | }, 1443 | "node_modules/rollup": { 1444 | "version": "2.75.0", 1445 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.0.tgz", 1446 | "integrity": "sha512-1/wxtweHJ7YwI2AIK3ZgCBU3nbW8sLnBIFwN46cwOTnVzt8f1o6J8zPKjwoiuADvzSjmnLqJce31p0q2vQ+dqw==", 1447 | "dev": true, 1448 | "bin": { 1449 | "rollup": "dist/bin/rollup" 1450 | }, 1451 | "engines": { 1452 | "node": ">=10.0.0" 1453 | }, 1454 | "optionalDependencies": { 1455 | "fsevents": "~2.3.2" 1456 | } 1457 | }, 1458 | "node_modules/safe-buffer": { 1459 | "version": "5.1.2", 1460 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1461 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1462 | "dev": true 1463 | }, 1464 | "node_modules/scheduler": { 1465 | "version": "0.22.0", 1466 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz", 1467 | "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==", 1468 | "dependencies": { 1469 | "loose-envify": "^1.1.0" 1470 | } 1471 | }, 1472 | "node_modules/semver": { 1473 | "version": "6.3.0", 1474 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1475 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1476 | "dev": true, 1477 | "bin": { 1478 | "semver": "bin/semver.js" 1479 | } 1480 | }, 1481 | "node_modules/source-map-js": { 1482 | "version": "1.0.2", 1483 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1484 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 1485 | "dev": true, 1486 | "engines": { 1487 | "node": ">=0.10.0" 1488 | } 1489 | }, 1490 | "node_modules/supports-color": { 1491 | "version": "5.5.0", 1492 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1493 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1494 | "dev": true, 1495 | "dependencies": { 1496 | "has-flag": "^3.0.0" 1497 | }, 1498 | "engines": { 1499 | "node": ">=4" 1500 | } 1501 | }, 1502 | "node_modules/supports-preserve-symlinks-flag": { 1503 | "version": "1.0.0", 1504 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1505 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1506 | "dev": true, 1507 | "engines": { 1508 | "node": ">= 0.4" 1509 | }, 1510 | "funding": { 1511 | "url": "https://github.com/sponsors/ljharb" 1512 | } 1513 | }, 1514 | "node_modules/to-fast-properties": { 1515 | "version": "2.0.0", 1516 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1517 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 1518 | "dev": true, 1519 | "engines": { 1520 | "node": ">=4" 1521 | } 1522 | }, 1523 | "node_modules/typescript": { 1524 | "version": "4.7.2", 1525 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", 1526 | "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", 1527 | "dev": true, 1528 | "bin": { 1529 | "tsc": "bin/tsc", 1530 | "tsserver": "bin/tsserver" 1531 | }, 1532 | "engines": { 1533 | "node": ">=4.2.0" 1534 | } 1535 | }, 1536 | "node_modules/vite": { 1537 | "version": "2.9.9", 1538 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz", 1539 | "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==", 1540 | "dev": true, 1541 | "dependencies": { 1542 | "esbuild": "^0.14.27", 1543 | "postcss": "^8.4.13", 1544 | "resolve": "^1.22.0", 1545 | "rollup": "^2.59.0" 1546 | }, 1547 | "bin": { 1548 | "vite": "bin/vite.js" 1549 | }, 1550 | "engines": { 1551 | "node": ">=12.2.0" 1552 | }, 1553 | "optionalDependencies": { 1554 | "fsevents": "~2.3.2" 1555 | }, 1556 | "peerDependencies": { 1557 | "less": "*", 1558 | "sass": "*", 1559 | "stylus": "*" 1560 | }, 1561 | "peerDependenciesMeta": { 1562 | "less": { 1563 | "optional": true 1564 | }, 1565 | "sass": { 1566 | "optional": true 1567 | }, 1568 | "stylus": { 1569 | "optional": true 1570 | } 1571 | } 1572 | } 1573 | }, 1574 | "dependencies": { 1575 | "@ampproject/remapping": { 1576 | "version": "2.2.0", 1577 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", 1578 | "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", 1579 | "dev": true, 1580 | "requires": { 1581 | "@jridgewell/gen-mapping": "^0.1.0", 1582 | "@jridgewell/trace-mapping": "^0.3.9" 1583 | } 1584 | }, 1585 | "@babel/code-frame": { 1586 | "version": "7.16.7", 1587 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", 1588 | "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", 1589 | "dev": true, 1590 | "requires": { 1591 | "@babel/highlight": "^7.16.7" 1592 | } 1593 | }, 1594 | "@babel/compat-data": { 1595 | "version": "7.17.10", 1596 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", 1597 | "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", 1598 | "dev": true 1599 | }, 1600 | "@babel/core": { 1601 | "version": "7.18.2", 1602 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", 1603 | "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", 1604 | "dev": true, 1605 | "requires": { 1606 | "@ampproject/remapping": "^2.1.0", 1607 | "@babel/code-frame": "^7.16.7", 1608 | "@babel/generator": "^7.18.2", 1609 | "@babel/helper-compilation-targets": "^7.18.2", 1610 | "@babel/helper-module-transforms": "^7.18.0", 1611 | "@babel/helpers": "^7.18.2", 1612 | "@babel/parser": "^7.18.0", 1613 | "@babel/template": "^7.16.7", 1614 | "@babel/traverse": "^7.18.2", 1615 | "@babel/types": "^7.18.2", 1616 | "convert-source-map": "^1.7.0", 1617 | "debug": "^4.1.0", 1618 | "gensync": "^1.0.0-beta.2", 1619 | "json5": "^2.2.1", 1620 | "semver": "^6.3.0" 1621 | } 1622 | }, 1623 | "@babel/generator": { 1624 | "version": "7.18.2", 1625 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", 1626 | "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", 1627 | "dev": true, 1628 | "requires": { 1629 | "@babel/types": "^7.18.2", 1630 | "@jridgewell/gen-mapping": "^0.3.0", 1631 | "jsesc": "^2.5.1" 1632 | }, 1633 | "dependencies": { 1634 | "@jridgewell/gen-mapping": { 1635 | "version": "0.3.1", 1636 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", 1637 | "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", 1638 | "dev": true, 1639 | "requires": { 1640 | "@jridgewell/set-array": "^1.0.0", 1641 | "@jridgewell/sourcemap-codec": "^1.4.10", 1642 | "@jridgewell/trace-mapping": "^0.3.9" 1643 | } 1644 | } 1645 | } 1646 | }, 1647 | "@babel/helper-annotate-as-pure": { 1648 | "version": "7.16.7", 1649 | "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", 1650 | "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", 1651 | "dev": true, 1652 | "requires": { 1653 | "@babel/types": "^7.16.7" 1654 | } 1655 | }, 1656 | "@babel/helper-compilation-targets": { 1657 | "version": "7.18.2", 1658 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", 1659 | "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", 1660 | "dev": true, 1661 | "requires": { 1662 | "@babel/compat-data": "^7.17.10", 1663 | "@babel/helper-validator-option": "^7.16.7", 1664 | "browserslist": "^4.20.2", 1665 | "semver": "^6.3.0" 1666 | } 1667 | }, 1668 | "@babel/helper-environment-visitor": { 1669 | "version": "7.18.2", 1670 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", 1671 | "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", 1672 | "dev": true 1673 | }, 1674 | "@babel/helper-function-name": { 1675 | "version": "7.17.9", 1676 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", 1677 | "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", 1678 | "dev": true, 1679 | "requires": { 1680 | "@babel/template": "^7.16.7", 1681 | "@babel/types": "^7.17.0" 1682 | } 1683 | }, 1684 | "@babel/helper-hoist-variables": { 1685 | "version": "7.16.7", 1686 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", 1687 | "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", 1688 | "dev": true, 1689 | "requires": { 1690 | "@babel/types": "^7.16.7" 1691 | } 1692 | }, 1693 | "@babel/helper-module-imports": { 1694 | "version": "7.16.7", 1695 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", 1696 | "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", 1697 | "dev": true, 1698 | "requires": { 1699 | "@babel/types": "^7.16.7" 1700 | } 1701 | }, 1702 | "@babel/helper-module-transforms": { 1703 | "version": "7.18.0", 1704 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", 1705 | "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", 1706 | "dev": true, 1707 | "requires": { 1708 | "@babel/helper-environment-visitor": "^7.16.7", 1709 | "@babel/helper-module-imports": "^7.16.7", 1710 | "@babel/helper-simple-access": "^7.17.7", 1711 | "@babel/helper-split-export-declaration": "^7.16.7", 1712 | "@babel/helper-validator-identifier": "^7.16.7", 1713 | "@babel/template": "^7.16.7", 1714 | "@babel/traverse": "^7.18.0", 1715 | "@babel/types": "^7.18.0" 1716 | } 1717 | }, 1718 | "@babel/helper-plugin-utils": { 1719 | "version": "7.17.12", 1720 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", 1721 | "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", 1722 | "dev": true 1723 | }, 1724 | "@babel/helper-simple-access": { 1725 | "version": "7.18.2", 1726 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", 1727 | "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", 1728 | "dev": true, 1729 | "requires": { 1730 | "@babel/types": "^7.18.2" 1731 | } 1732 | }, 1733 | "@babel/helper-split-export-declaration": { 1734 | "version": "7.16.7", 1735 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", 1736 | "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", 1737 | "dev": true, 1738 | "requires": { 1739 | "@babel/types": "^7.16.7" 1740 | } 1741 | }, 1742 | "@babel/helper-validator-identifier": { 1743 | "version": "7.16.7", 1744 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", 1745 | "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", 1746 | "dev": true 1747 | }, 1748 | "@babel/helper-validator-option": { 1749 | "version": "7.16.7", 1750 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", 1751 | "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", 1752 | "dev": true 1753 | }, 1754 | "@babel/helpers": { 1755 | "version": "7.18.2", 1756 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", 1757 | "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", 1758 | "dev": true, 1759 | "requires": { 1760 | "@babel/template": "^7.16.7", 1761 | "@babel/traverse": "^7.18.2", 1762 | "@babel/types": "^7.18.2" 1763 | } 1764 | }, 1765 | "@babel/highlight": { 1766 | "version": "7.17.12", 1767 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", 1768 | "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", 1769 | "dev": true, 1770 | "requires": { 1771 | "@babel/helper-validator-identifier": "^7.16.7", 1772 | "chalk": "^2.0.0", 1773 | "js-tokens": "^4.0.0" 1774 | } 1775 | }, 1776 | "@babel/parser": { 1777 | "version": "7.18.3", 1778 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.3.tgz", 1779 | "integrity": "sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==", 1780 | "dev": true 1781 | }, 1782 | "@babel/plugin-syntax-jsx": { 1783 | "version": "7.17.12", 1784 | "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz", 1785 | "integrity": "sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==", 1786 | "dev": true, 1787 | "requires": { 1788 | "@babel/helper-plugin-utils": "^7.17.12" 1789 | } 1790 | }, 1791 | "@babel/plugin-transform-react-jsx": { 1792 | "version": "7.17.12", 1793 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", 1794 | "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", 1795 | "dev": true, 1796 | "requires": { 1797 | "@babel/helper-annotate-as-pure": "^7.16.7", 1798 | "@babel/helper-module-imports": "^7.16.7", 1799 | "@babel/helper-plugin-utils": "^7.17.12", 1800 | "@babel/plugin-syntax-jsx": "^7.17.12", 1801 | "@babel/types": "^7.17.12" 1802 | } 1803 | }, 1804 | "@babel/plugin-transform-react-jsx-development": { 1805 | "version": "7.16.7", 1806 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz", 1807 | "integrity": "sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==", 1808 | "dev": true, 1809 | "requires": { 1810 | "@babel/plugin-transform-react-jsx": "^7.16.7" 1811 | } 1812 | }, 1813 | "@babel/plugin-transform-react-jsx-self": { 1814 | "version": "7.17.12", 1815 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.17.12.tgz", 1816 | "integrity": "sha512-7S9G2B44EnYOx74mue02t1uD8ckWZ/ee6Uz/qfdzc35uWHX5NgRy9i+iJSb2LFRgMd+QV9zNcStQaazzzZ3n3Q==", 1817 | "dev": true, 1818 | "requires": { 1819 | "@babel/helper-plugin-utils": "^7.17.12" 1820 | } 1821 | }, 1822 | "@babel/plugin-transform-react-jsx-source": { 1823 | "version": "7.16.7", 1824 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz", 1825 | "integrity": "sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw==", 1826 | "dev": true, 1827 | "requires": { 1828 | "@babel/helper-plugin-utils": "^7.16.7" 1829 | } 1830 | }, 1831 | "@babel/runtime": { 1832 | "version": "7.18.3", 1833 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", 1834 | "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", 1835 | "requires": { 1836 | "regenerator-runtime": "^0.13.4" 1837 | } 1838 | }, 1839 | "@babel/template": { 1840 | "version": "7.16.7", 1841 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", 1842 | "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", 1843 | "dev": true, 1844 | "requires": { 1845 | "@babel/code-frame": "^7.16.7", 1846 | "@babel/parser": "^7.16.7", 1847 | "@babel/types": "^7.16.7" 1848 | } 1849 | }, 1850 | "@babel/traverse": { 1851 | "version": "7.18.2", 1852 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", 1853 | "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", 1854 | "dev": true, 1855 | "requires": { 1856 | "@babel/code-frame": "^7.16.7", 1857 | "@babel/generator": "^7.18.2", 1858 | "@babel/helper-environment-visitor": "^7.18.2", 1859 | "@babel/helper-function-name": "^7.17.9", 1860 | "@babel/helper-hoist-variables": "^7.16.7", 1861 | "@babel/helper-split-export-declaration": "^7.16.7", 1862 | "@babel/parser": "^7.18.0", 1863 | "@babel/types": "^7.18.2", 1864 | "debug": "^4.1.0", 1865 | "globals": "^11.1.0" 1866 | } 1867 | }, 1868 | "@babel/types": { 1869 | "version": "7.18.2", 1870 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.2.tgz", 1871 | "integrity": "sha512-0On6B8A4/+mFUto5WERt3EEuG1NznDirvwca1O8UwXQHVY8g3R7OzYgxXdOfMwLO08UrpUD/2+3Bclyq+/C94Q==", 1872 | "dev": true, 1873 | "requires": { 1874 | "@babel/helper-validator-identifier": "^7.16.7", 1875 | "to-fast-properties": "^2.0.0" 1876 | } 1877 | }, 1878 | "@jridgewell/gen-mapping": { 1879 | "version": "0.1.1", 1880 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", 1881 | "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", 1882 | "dev": true, 1883 | "requires": { 1884 | "@jridgewell/set-array": "^1.0.0", 1885 | "@jridgewell/sourcemap-codec": "^1.4.10" 1886 | } 1887 | }, 1888 | "@jridgewell/resolve-uri": { 1889 | "version": "3.0.7", 1890 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", 1891 | "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", 1892 | "dev": true 1893 | }, 1894 | "@jridgewell/set-array": { 1895 | "version": "1.1.1", 1896 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", 1897 | "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", 1898 | "dev": true 1899 | }, 1900 | "@jridgewell/sourcemap-codec": { 1901 | "version": "1.4.13", 1902 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", 1903 | "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", 1904 | "dev": true 1905 | }, 1906 | "@jridgewell/trace-mapping": { 1907 | "version": "0.3.13", 1908 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", 1909 | "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", 1910 | "dev": true, 1911 | "requires": { 1912 | "@jridgewell/resolve-uri": "^3.0.3", 1913 | "@jridgewell/sourcemap-codec": "^1.4.10" 1914 | } 1915 | }, 1916 | "@rollup/pluginutils": { 1917 | "version": "4.2.1", 1918 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", 1919 | "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", 1920 | "dev": true, 1921 | "requires": { 1922 | "estree-walker": "^2.0.1", 1923 | "picomatch": "^2.2.2" 1924 | } 1925 | }, 1926 | "@types/prop-types": { 1927 | "version": "15.7.5", 1928 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", 1929 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", 1930 | "dev": true 1931 | }, 1932 | "@types/react": { 1933 | "version": "18.0.9", 1934 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.9.tgz", 1935 | "integrity": "sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw==", 1936 | "dev": true, 1937 | "requires": { 1938 | "@types/prop-types": "*", 1939 | "@types/scheduler": "*", 1940 | "csstype": "^3.0.2" 1941 | } 1942 | }, 1943 | "@types/react-dom": { 1944 | "version": "18.0.5", 1945 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.5.tgz", 1946 | "integrity": "sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA==", 1947 | "dev": true, 1948 | "requires": { 1949 | "@types/react": "*" 1950 | } 1951 | }, 1952 | "@types/scheduler": { 1953 | "version": "0.16.2", 1954 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 1955 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 1956 | "dev": true 1957 | }, 1958 | "@vitejs/plugin-react": { 1959 | "version": "1.3.2", 1960 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz", 1961 | "integrity": "sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==", 1962 | "dev": true, 1963 | "requires": { 1964 | "@babel/core": "^7.17.10", 1965 | "@babel/plugin-transform-react-jsx": "^7.17.3", 1966 | "@babel/plugin-transform-react-jsx-development": "^7.16.7", 1967 | "@babel/plugin-transform-react-jsx-self": "^7.16.7", 1968 | "@babel/plugin-transform-react-jsx-source": "^7.16.7", 1969 | "@rollup/pluginutils": "^4.2.1", 1970 | "react-refresh": "^0.13.0", 1971 | "resolve": "^1.22.0" 1972 | } 1973 | }, 1974 | "ansi-styles": { 1975 | "version": "3.2.1", 1976 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1977 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1978 | "dev": true, 1979 | "requires": { 1980 | "color-convert": "^1.9.0" 1981 | } 1982 | }, 1983 | "asynckit": { 1984 | "version": "0.4.0", 1985 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 1986 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 1987 | }, 1988 | "axios": { 1989 | "version": "0.27.2", 1990 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", 1991 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", 1992 | "requires": { 1993 | "follow-redirects": "^1.14.9", 1994 | "form-data": "^4.0.0" 1995 | } 1996 | }, 1997 | "browserslist": { 1998 | "version": "4.20.3", 1999 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", 2000 | "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", 2001 | "dev": true, 2002 | "requires": { 2003 | "caniuse-lite": "^1.0.30001332", 2004 | "electron-to-chromium": "^1.4.118", 2005 | "escalade": "^3.1.1", 2006 | "node-releases": "^2.0.3", 2007 | "picocolors": "^1.0.0" 2008 | } 2009 | }, 2010 | "caniuse-lite": { 2011 | "version": "1.0.30001344", 2012 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz", 2013 | "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==", 2014 | "dev": true 2015 | }, 2016 | "chalk": { 2017 | "version": "2.4.2", 2018 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 2019 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 2020 | "dev": true, 2021 | "requires": { 2022 | "ansi-styles": "^3.2.1", 2023 | "escape-string-regexp": "^1.0.5", 2024 | "supports-color": "^5.3.0" 2025 | } 2026 | }, 2027 | "clsx": { 2028 | "version": "1.1.1", 2029 | "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", 2030 | "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" 2031 | }, 2032 | "color-convert": { 2033 | "version": "1.9.3", 2034 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 2035 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 2036 | "dev": true, 2037 | "requires": { 2038 | "color-name": "1.1.3" 2039 | } 2040 | }, 2041 | "color-name": { 2042 | "version": "1.1.3", 2043 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 2044 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 2045 | "dev": true 2046 | }, 2047 | "combined-stream": { 2048 | "version": "1.0.8", 2049 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 2050 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 2051 | "requires": { 2052 | "delayed-stream": "~1.0.0" 2053 | } 2054 | }, 2055 | "convert-source-map": { 2056 | "version": "1.8.0", 2057 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", 2058 | "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", 2059 | "dev": true, 2060 | "requires": { 2061 | "safe-buffer": "~5.1.1" 2062 | } 2063 | }, 2064 | "csstype": { 2065 | "version": "3.1.0", 2066 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", 2067 | "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", 2068 | "dev": true 2069 | }, 2070 | "debug": { 2071 | "version": "4.3.4", 2072 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2073 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2074 | "dev": true, 2075 | "requires": { 2076 | "ms": "2.1.2" 2077 | } 2078 | }, 2079 | "delayed-stream": { 2080 | "version": "1.0.0", 2081 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 2082 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" 2083 | }, 2084 | "dotenv": { 2085 | "version": "16.0.1", 2086 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", 2087 | "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" 2088 | }, 2089 | "electron-to-chromium": { 2090 | "version": "1.4.140", 2091 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.140.tgz", 2092 | "integrity": "sha512-NLz5va823QfJBYOO/hLV4AfU4Crmkl/6Hl2pH3qdJcmi0ySZ3YTWHxOlDm3uJOFBEPy3pIhu8gKQo6prQTWKKA==", 2093 | "dev": true 2094 | }, 2095 | "esbuild": { 2096 | "version": "0.14.40", 2097 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.40.tgz", 2098 | "integrity": "sha512-toIoQk3ODEEIudsN74wXGdw1eiUN4aKRijOqiwEAqfUFlhORPYFJtACzRdRRlpUysRUUlvIUoGE1aw/MIVCWnA==", 2099 | "dev": true, 2100 | "requires": { 2101 | "esbuild-android-64": "0.14.40", 2102 | "esbuild-android-arm64": "0.14.40", 2103 | "esbuild-darwin-64": "0.14.40", 2104 | "esbuild-darwin-arm64": "0.14.40", 2105 | "esbuild-freebsd-64": "0.14.40", 2106 | "esbuild-freebsd-arm64": "0.14.40", 2107 | "esbuild-linux-32": "0.14.40", 2108 | "esbuild-linux-64": "0.14.40", 2109 | "esbuild-linux-arm": "0.14.40", 2110 | "esbuild-linux-arm64": "0.14.40", 2111 | "esbuild-linux-mips64le": "0.14.40", 2112 | "esbuild-linux-ppc64le": "0.14.40", 2113 | "esbuild-linux-riscv64": "0.14.40", 2114 | "esbuild-linux-s390x": "0.14.40", 2115 | "esbuild-netbsd-64": "0.14.40", 2116 | "esbuild-openbsd-64": "0.14.40", 2117 | "esbuild-sunos-64": "0.14.40", 2118 | "esbuild-windows-32": "0.14.40", 2119 | "esbuild-windows-64": "0.14.40", 2120 | "esbuild-windows-arm64": "0.14.40" 2121 | } 2122 | }, 2123 | "esbuild-android-64": { 2124 | "version": "0.14.40", 2125 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.40.tgz", 2126 | "integrity": "sha512-+69t+bmJWWhTyG8waJZcu4UGzM4NbDXAwssTEDYwonyz6L/Is11Y3csJhE16RM0a1GeDin0n810vNP+NVjttKA==", 2127 | "dev": true, 2128 | "optional": true 2129 | }, 2130 | "esbuild-android-arm64": { 2131 | "version": "0.14.40", 2132 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.40.tgz", 2133 | "integrity": "sha512-lVDn4d7/NL5Svrxuskmd/YcluI6uI4Ebp7A1/tWyLJJYbvfIy5l4Vy8GMhErGLePbRyJJiuBP9xusapK4u+6bg==", 2134 | "dev": true, 2135 | "optional": true 2136 | }, 2137 | "esbuild-darwin-64": { 2138 | "version": "0.14.40", 2139 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.40.tgz", 2140 | "integrity": "sha512-b5u3IXCHhOjkRHIQTSxCN7ObUR5NTyJCP9LrnJ69dEEi1w1usI40T/VNyTTCs7n0UgEH7/zi27vBxbZU+sU4Ew==", 2141 | "dev": true, 2142 | "optional": true 2143 | }, 2144 | "esbuild-darwin-arm64": { 2145 | "version": "0.14.40", 2146 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.40.tgz", 2147 | "integrity": "sha512-Wn0C2nrZSANvzK9efcxjKpv9l8yUC4PtYMmnf775gUNwak7sqecuoelhbUTshhrwsfjCNfjsrUhsHY2OHUiEdw==", 2148 | "dev": true, 2149 | "optional": true 2150 | }, 2151 | "esbuild-freebsd-64": { 2152 | "version": "0.14.40", 2153 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.40.tgz", 2154 | "integrity": "sha512-B9WZNUn7Y9f97xrQGBAQPKsebeFZzAd+JCdsLCexrVfTjB24b+/Iuq5O2z/q5Meg7Yz0S+j8AO6ncpvNkK2u0w==", 2155 | "dev": true, 2156 | "optional": true 2157 | }, 2158 | "esbuild-freebsd-arm64": { 2159 | "version": "0.14.40", 2160 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.40.tgz", 2161 | "integrity": "sha512-3aB9uJv2/lmQNzwmieNyyOdxKi+3ERwrqf3snBu/oEng8b7nMBNrEN+p7jjkTYNYmo291KiH/5EIAXwpsZndFw==", 2162 | "dev": true, 2163 | "optional": true 2164 | }, 2165 | "esbuild-linux-32": { 2166 | "version": "0.14.40", 2167 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.40.tgz", 2168 | "integrity": "sha512-LMI9BMeuGf6NRS23LbyVarN3nf+JyNcfiVEnR9M8691kL5Ffp3e7oTYRH65XdTUirM9D6e5cppfWLjvrRbGnRw==", 2169 | "dev": true, 2170 | "optional": true 2171 | }, 2172 | "esbuild-linux-64": { 2173 | "version": "0.14.40", 2174 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.40.tgz", 2175 | "integrity": "sha512-D/NkZ9QR2KShJXNuRWANxJzPCrwJoAoWVetQiGIAepzXbNh+dBo5ZLmlh8Txs6tE600N67MF/ScHP1S4FxLaJg==", 2176 | "dev": true, 2177 | "optional": true 2178 | }, 2179 | "esbuild-linux-arm": { 2180 | "version": "0.14.40", 2181 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.40.tgz", 2182 | "integrity": "sha512-2a0yZXbzr/s3iCgZ84jFTHf+NyyXQ/7/Sd28oQq5iyy7TbJNS973XUOwgdlHdRqBxvw0nIWTw2FuwyUJAFa6Qg==", 2183 | "dev": true, 2184 | "optional": true 2185 | }, 2186 | "esbuild-linux-arm64": { 2187 | "version": "0.14.40", 2188 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.40.tgz", 2189 | "integrity": "sha512-TIoZWKjrMJxZujh2nSsrrLkLDLzD/oBpSiobdUGe2bqKZpT4m7fkR0tEDNyM6Xvzj9uTQ4iTfJr2ekmpg3DyTQ==", 2190 | "dev": true, 2191 | "optional": true 2192 | }, 2193 | "esbuild-linux-mips64le": { 2194 | "version": "0.14.40", 2195 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.40.tgz", 2196 | "integrity": "sha512-SP30CYYSDMwr6mPUbjvD4K2R03GQHIQGrkrbXt5NM6mFqzR+S+JKVv9juq/CjlM9V7iIPPPqe4mb4DWC3b8pBw==", 2197 | "dev": true, 2198 | "optional": true 2199 | }, 2200 | "esbuild-linux-ppc64le": { 2201 | "version": "0.14.40", 2202 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.40.tgz", 2203 | "integrity": "sha512-HlU3dfIdwzm/zhbXvMa5yWIafBeI7v6BDaEuApAww5Av8ht7lXgD1fZ11iJVPjRWNLcCZUgZaJKFrosSPQO/Bw==", 2204 | "dev": true, 2205 | "optional": true 2206 | }, 2207 | "esbuild-linux-riscv64": { 2208 | "version": "0.14.40", 2209 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.40.tgz", 2210 | "integrity": "sha512-4ImTBEUykhIcIq3c97dIXnsmAHb//cjHh4nxttLhwpTZ+b/KdM1IpttqFhB0AFLUsrjP4WOCMxAm5FOL7FC2uw==", 2211 | "dev": true, 2212 | "optional": true 2213 | }, 2214 | "esbuild-linux-s390x": { 2215 | "version": "0.14.40", 2216 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.40.tgz", 2217 | "integrity": "sha512-kFCPKictYjpt5rt0bFdbSmb8AWut75sIh1fZUTCVkujWMcpdL8ADuYMfVrN7R0CSQvkF1nQtrIBfp+ZU7R7KNQ==", 2218 | "dev": true, 2219 | "optional": true 2220 | }, 2221 | "esbuild-netbsd-64": { 2222 | "version": "0.14.40", 2223 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.40.tgz", 2224 | "integrity": "sha512-Hwzw2cSI6+p03TUjugzec54W6uW4tA1J/WovmlHl96Icjy73eWnAyCQwgG6ZLirXpt2aDfTEVShNaC2fE4KVhQ==", 2225 | "dev": true, 2226 | "optional": true 2227 | }, 2228 | "esbuild-openbsd-64": { 2229 | "version": "0.14.40", 2230 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.40.tgz", 2231 | "integrity": "sha512-L4Pix+N2Sb0HvLl8zyn1Aq2aYD5Jt8rk9zwW3NUx19yafJqAFsnUN7L/XbbWSv5/XMqnY4hpAvIP2pyeV9+Bjw==", 2232 | "dev": true, 2233 | "optional": true 2234 | }, 2235 | "esbuild-sunos-64": { 2236 | "version": "0.14.40", 2237 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.40.tgz", 2238 | "integrity": "sha512-iEITaelmmCO43ewk0bOYRGrewu2i2h2V0gKHQ/rz1MRqif8ohY/FNLn4WnThGUlrEgA1nTL1tc57PL12QbOo2Q==", 2239 | "dev": true, 2240 | "optional": true 2241 | }, 2242 | "esbuild-windows-32": { 2243 | "version": "0.14.40", 2244 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.40.tgz", 2245 | "integrity": "sha512-uXHmKl4RtCkK1v6QQK4hsP8Xiku6CwUM/W7Yv2rGtfylSOrrWKcpqwlDWx6bIm1Hav1uBC8hbgJ1hY6pWFNhNA==", 2246 | "dev": true, 2247 | "optional": true 2248 | }, 2249 | "esbuild-windows-64": { 2250 | "version": "0.14.40", 2251 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.40.tgz", 2252 | "integrity": "sha512-dvgQLVYnJzqce97AeHvxWtV9lHRDxIPatOikmrh1vt/SCE4tyVo5nAT/2SiZBJ6DzYmZT3BcJTV24bBLyu4ZUA==", 2253 | "dev": true, 2254 | "optional": true 2255 | }, 2256 | "esbuild-windows-arm64": { 2257 | "version": "0.14.40", 2258 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.40.tgz", 2259 | "integrity": "sha512-c8ohQSFtRq78pZ/LQcpMft2xuR2IEitQkW07f9K7iN4EBdJMrCpOoXrZCfmX9lAC8yYOU7xHoLFYVln3n6fK1Q==", 2260 | "dev": true, 2261 | "optional": true 2262 | }, 2263 | "escalade": { 2264 | "version": "3.1.1", 2265 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 2266 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 2267 | "dev": true 2268 | }, 2269 | "escape-string-regexp": { 2270 | "version": "1.0.5", 2271 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 2272 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 2273 | "dev": true 2274 | }, 2275 | "estree-walker": { 2276 | "version": "2.0.2", 2277 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 2278 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 2279 | "dev": true 2280 | }, 2281 | "follow-redirects": { 2282 | "version": "1.15.1", 2283 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", 2284 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" 2285 | }, 2286 | "form-data": { 2287 | "version": "4.0.0", 2288 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 2289 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 2290 | "requires": { 2291 | "asynckit": "^0.4.0", 2292 | "combined-stream": "^1.0.8", 2293 | "mime-types": "^2.1.12" 2294 | } 2295 | }, 2296 | "fsevents": { 2297 | "version": "2.3.2", 2298 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 2299 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 2300 | "dev": true, 2301 | "optional": true 2302 | }, 2303 | "function-bind": { 2304 | "version": "1.1.1", 2305 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 2306 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 2307 | "dev": true 2308 | }, 2309 | "gensync": { 2310 | "version": "1.0.0-beta.2", 2311 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 2312 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 2313 | "dev": true 2314 | }, 2315 | "globals": { 2316 | "version": "11.12.0", 2317 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 2318 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 2319 | "dev": true 2320 | }, 2321 | "has": { 2322 | "version": "1.0.3", 2323 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 2324 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 2325 | "dev": true, 2326 | "requires": { 2327 | "function-bind": "^1.1.1" 2328 | } 2329 | }, 2330 | "has-flag": { 2331 | "version": "3.0.0", 2332 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 2333 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 2334 | "dev": true 2335 | }, 2336 | "history": { 2337 | "version": "5.3.0", 2338 | "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", 2339 | "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", 2340 | "requires": { 2341 | "@babel/runtime": "^7.7.6" 2342 | } 2343 | }, 2344 | "is-core-module": { 2345 | "version": "2.9.0", 2346 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", 2347 | "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", 2348 | "dev": true, 2349 | "requires": { 2350 | "has": "^1.0.3" 2351 | } 2352 | }, 2353 | "js-tokens": { 2354 | "version": "4.0.0", 2355 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 2356 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 2357 | }, 2358 | "jsesc": { 2359 | "version": "2.5.2", 2360 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 2361 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 2362 | "dev": true 2363 | }, 2364 | "json5": { 2365 | "version": "2.2.1", 2366 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", 2367 | "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", 2368 | "dev": true 2369 | }, 2370 | "jwt-decode": { 2371 | "version": "3.1.2", 2372 | "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", 2373 | "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" 2374 | }, 2375 | "loose-envify": { 2376 | "version": "1.4.0", 2377 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 2378 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 2379 | "requires": { 2380 | "js-tokens": "^3.0.0 || ^4.0.0" 2381 | } 2382 | }, 2383 | "mime-db": { 2384 | "version": "1.52.0", 2385 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 2386 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 2387 | }, 2388 | "mime-types": { 2389 | "version": "2.1.35", 2390 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 2391 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 2392 | "requires": { 2393 | "mime-db": "1.52.0" 2394 | } 2395 | }, 2396 | "ms": { 2397 | "version": "2.1.2", 2398 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2399 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2400 | "dev": true 2401 | }, 2402 | "nanoid": { 2403 | "version": "3.3.4", 2404 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 2405 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", 2406 | "dev": true 2407 | }, 2408 | "node-releases": { 2409 | "version": "2.0.5", 2410 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", 2411 | "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", 2412 | "dev": true 2413 | }, 2414 | "path-parse": { 2415 | "version": "1.0.7", 2416 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 2417 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 2418 | "dev": true 2419 | }, 2420 | "picocolors": { 2421 | "version": "1.0.0", 2422 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 2423 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 2424 | "dev": true 2425 | }, 2426 | "picomatch": { 2427 | "version": "2.3.1", 2428 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2429 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2430 | "dev": true 2431 | }, 2432 | "postcss": { 2433 | "version": "8.4.14", 2434 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 2435 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 2436 | "dev": true, 2437 | "requires": { 2438 | "nanoid": "^3.3.4", 2439 | "picocolors": "^1.0.0", 2440 | "source-map-js": "^1.0.2" 2441 | } 2442 | }, 2443 | "react": { 2444 | "version": "18.1.0", 2445 | "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", 2446 | "integrity": "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==", 2447 | "requires": { 2448 | "loose-envify": "^1.1.0" 2449 | } 2450 | }, 2451 | "react-dom": { 2452 | "version": "18.1.0", 2453 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", 2454 | "integrity": "sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==", 2455 | "requires": { 2456 | "loose-envify": "^1.1.0", 2457 | "scheduler": "^0.22.0" 2458 | } 2459 | }, 2460 | "react-refresh": { 2461 | "version": "0.13.0", 2462 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.13.0.tgz", 2463 | "integrity": "sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg==", 2464 | "dev": true 2465 | }, 2466 | "react-router": { 2467 | "version": "6.3.0", 2468 | "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", 2469 | "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", 2470 | "requires": { 2471 | "history": "^5.2.0" 2472 | } 2473 | }, 2474 | "react-router-dom": { 2475 | "version": "6.3.0", 2476 | "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", 2477 | "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", 2478 | "requires": { 2479 | "history": "^5.2.0", 2480 | "react-router": "6.3.0" 2481 | } 2482 | }, 2483 | "react-toastify": { 2484 | "version": "9.0.3", 2485 | "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz", 2486 | "integrity": "sha512-0QZJk0SqYBxouRBGCFU3ymvjlwimRRhVH7SzqGRiVrQ001KSoUNbGKx9Yq42aoPv18n45yJzEFG82zqv3HnASg==", 2487 | "requires": { 2488 | "clsx": "^1.1.1" 2489 | } 2490 | }, 2491 | "regenerator-runtime": { 2492 | "version": "0.13.9", 2493 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", 2494 | "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" 2495 | }, 2496 | "resolve": { 2497 | "version": "1.22.0", 2498 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", 2499 | "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", 2500 | "dev": true, 2501 | "requires": { 2502 | "is-core-module": "^2.8.1", 2503 | "path-parse": "^1.0.7", 2504 | "supports-preserve-symlinks-flag": "^1.0.0" 2505 | } 2506 | }, 2507 | "rollup": { 2508 | "version": "2.75.0", 2509 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.0.tgz", 2510 | "integrity": "sha512-1/wxtweHJ7YwI2AIK3ZgCBU3nbW8sLnBIFwN46cwOTnVzt8f1o6J8zPKjwoiuADvzSjmnLqJce31p0q2vQ+dqw==", 2511 | "dev": true, 2512 | "requires": { 2513 | "fsevents": "~2.3.2" 2514 | } 2515 | }, 2516 | "safe-buffer": { 2517 | "version": "5.1.2", 2518 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2519 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 2520 | "dev": true 2521 | }, 2522 | "scheduler": { 2523 | "version": "0.22.0", 2524 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz", 2525 | "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==", 2526 | "requires": { 2527 | "loose-envify": "^1.1.0" 2528 | } 2529 | }, 2530 | "semver": { 2531 | "version": "6.3.0", 2532 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2533 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 2534 | "dev": true 2535 | }, 2536 | "source-map-js": { 2537 | "version": "1.0.2", 2538 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 2539 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 2540 | "dev": true 2541 | }, 2542 | "supports-color": { 2543 | "version": "5.5.0", 2544 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2545 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2546 | "dev": true, 2547 | "requires": { 2548 | "has-flag": "^3.0.0" 2549 | } 2550 | }, 2551 | "supports-preserve-symlinks-flag": { 2552 | "version": "1.0.0", 2553 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2554 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2555 | "dev": true 2556 | }, 2557 | "to-fast-properties": { 2558 | "version": "2.0.0", 2559 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 2560 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 2561 | "dev": true 2562 | }, 2563 | "typescript": { 2564 | "version": "4.7.2", 2565 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", 2566 | "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", 2567 | "dev": true 2568 | }, 2569 | "vite": { 2570 | "version": "2.9.9", 2571 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz", 2572 | "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==", 2573 | "dev": true, 2574 | "requires": { 2575 | "esbuild": "^0.14.27", 2576 | "fsevents": "~2.3.2", 2577 | "postcss": "^8.4.13", 2578 | "resolve": "^1.22.0", 2579 | "rollup": "^2.59.0" 2580 | } 2581 | } 2582 | } 2583 | } 2584 | -------------------------------------------------------------------------------- /react-app-vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-app-vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite --port 4000 ", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.27.2", 12 | "dotenv": "^16.0.1", 13 | "jwt-decode": "^3.1.2", 14 | "react": "^18.0.0", 15 | "react-dom": "^18.0.0", 16 | "react-router-dom": "^6.3.0", 17 | "react-toastify": "^9.0.3" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^18.0.0", 21 | "@types/react-dom": "^18.0.0", 22 | "@vitejs/plugin-react": "^1.3.0", 23 | "typescript": "^4.6.3", 24 | "vite": "^2.9.9" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /react-app-vite/src/ProtectedRoute.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Navigate } from "react-router-dom"; 3 | 4 | const ProtectedRoute = (props: any) => { 5 | const token = localStorage.getItem("token"); 6 | if (token == undefined) { 7 | return ; 8 | } 9 | 10 | return props.children; 11 | }; 12 | 13 | export default ProtectedRoute; 14 | -------------------------------------------------------------------------------- /react-app-vite/src/Routing.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { BrowserRouter, Routes, Route } from "react-router-dom"; 3 | import ActiveTodos from "./pages/ActiveTodos"; 4 | import CompeletedTodos from "./pages/CompletedTodos"; 5 | import Login from "./pages/Login"; 6 | import SignUp from "./pages/SignUp"; 7 | import UsersPage from "./pages/UsersPage"; 8 | import { ToastContainer } from "react-toastify"; 9 | import "react-toastify/dist/ReactToastify.css"; 10 | import ProtectedRoute from "./ProtectedRoute"; 11 | 12 | const Routing = () => { 13 | return ( 14 |
15 | 16 | 17 | 18 | } /> 19 | } /> 20 | 21 | 25 | 26 | 27 | } 28 | /> 29 | 33 | 34 | 35 | } 36 | /> 37 | 41 | 42 | 43 | } 44 | /> 45 | 46 | {/* Default Page Active Todos */} 47 | 51 | 52 | 53 | } 54 | /> 55 | 56 | 57 |
58 | ); 59 | }; 60 | 61 | export default Routing; 62 | -------------------------------------------------------------------------------- /react-app-vite/src/api/ApiConstants.ts: -------------------------------------------------------------------------------- 1 | export const ApiConstants = { 2 | TODO: { 3 | ADD: (userId: number) => { 4 | return "/todo/" + userId; 5 | }, 6 | FIND_NOT_COMPLETED: (userId: number) => { 7 | return "/todo/findAllNotCompleted/" + userId; 8 | }, 9 | FIND_COMPLETED: (userId: number) => { 10 | return "/todo/findAllCompleted/" + userId; 11 | }, 12 | MARK_COMPLETE: (todoId: number) => { 13 | return "/todo/" + todoId; 14 | }, 15 | DELETE: (todoId: number) => { 16 | return "/todo/" + todoId; 17 | }, 18 | }, 19 | USER: { 20 | SIGN_UP: "/user/signUp", 21 | FIND_ALL: "/user", 22 | DELETE: (userId: number) => { 23 | return "/user/" + userId; 24 | }, 25 | }, 26 | LOGIN: "/auth/login", 27 | }; 28 | -------------------------------------------------------------------------------- /react-app-vite/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AfaqJaved/todo-app-nestjs-react/c873940fbc5bc566a78ade475079553f46ba7095/react-app-vite/src/assets/logo.png -------------------------------------------------------------------------------- /react-app-vite/src/assets/todo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AfaqJaved/todo-app-nestjs-react/c873940fbc5bc566a78ade475079553f46ba7095/react-app-vite/src/assets/todo.jpg -------------------------------------------------------------------------------- /react-app-vite/src/axios/AxiosSetup.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | let custom_axios = axios.create({ 4 | baseURL: import.meta.env.VITE_BASE_URL, 5 | headers: { 6 | Accept: "*/*", 7 | "Content-Type": "application/json", 8 | }, 9 | timeout: 5000, 10 | }); 11 | 12 | export default custom_axios; 13 | -------------------------------------------------------------------------------- /react-app-vite/src/components/ActiveTodoList.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface ActiveTodoListProps { 4 | id: number; 5 | todo: string; 6 | dateTime: string; 7 | markCompelte: (id: number) => void; 8 | deleteTodo: (id: number) => void; 9 | } 10 | 11 | const ActiveTodoList = (props: ActiveTodoListProps) => { 12 | return ( 13 |
  • 14 |
    15 |
    16 |
    {props.todo}
    17 |
    {props.dateTime}
    18 |
    19 | 22 | 25 |
    26 |
  • 27 | ); 28 | }; 29 | 30 | export default ActiveTodoList; 31 | -------------------------------------------------------------------------------- /react-app-vite/src/components/CompletedTodoList.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface CompeletedTodosProps { 4 | id: number; 5 | todo: string; 6 | dateTime: string; 7 | deleteTodo: (id: number) => void; 8 | } 9 | 10 | const CompletedTodoList = (props: CompeletedTodosProps) => { 11 | return ( 12 |
  • 13 |
    14 |
    15 |
    {props.todo}
    16 |
    {props.dateTime}
    17 |
    18 | 21 |
    22 |
  • 23 | ); 24 | }; 25 | 26 | export default CompletedTodoList; 27 | -------------------------------------------------------------------------------- /react-app-vite/src/components/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import Logo from "../assets/logo.png"; 3 | import { useNavigate } from "react-router-dom"; 4 | import { getLoginInfo } from "../utils/LoginInfo"; 5 | 6 | const NavBar = () => { 7 | let navigate = useNavigate(); 8 | const role = getLoginInfo()?.role; 9 | 10 | return ( 11 | 49 | ); 50 | }; 51 | 52 | export default NavBar; 53 | -------------------------------------------------------------------------------- /react-app-vite/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import Routing from "./Routing"; 4 | 5 | ReactDOM.createRoot(document.getElementById("root")!).render( 6 | 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /react-app-vite/src/pages/ActiveTodos.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import NavBar from "../components/NavBar"; 3 | import ActiveTodoList from "../components/ActiveTodoList"; 4 | import custom_axios from "../axios/AxiosSetup"; 5 | import { getLoginInfo } from "../utils/LoginInfo"; 6 | import { toast } from "react-toastify"; 7 | import { ApiConstants } from "../api/ApiConstants"; 8 | interface TodoModel { 9 | title: string; 10 | date: string; 11 | id: number; 12 | } 13 | function ActiveTodos() { 14 | const [todos, setTodos] = React.useState([]); 15 | const title: any = React.useRef(); 16 | 17 | // get all todos not completed with respect to userid 18 | const getAllNotCompletedTodos = async () => { 19 | const userId = getLoginInfo()?.userId; 20 | if (userId != null) { 21 | const response = await custom_axios.get(ApiConstants.TODO.FIND_NOT_COMPLETED(userId), { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 22 | setTodos(response.data); 23 | } else { 24 | toast.info("Sorry you are not authenticated"); 25 | } 26 | }; 27 | 28 | const saveTodo = async () => { 29 | if (title.current.value == "") { 30 | toast.info("Please Provide Title"); 31 | return; 32 | } 33 | const userId = getLoginInfo()?.userId; 34 | if (userId != null) { 35 | const response = await custom_axios.post( 36 | ApiConstants.TODO.ADD(userId), 37 | { 38 | title: title.current.value, 39 | }, 40 | { headers: { Authorization: "Bearer " + localStorage.getItem("token") } } 41 | ); 42 | getAllNotCompletedTodos(); 43 | title.current.value = ""; 44 | toast.success("Todo Added Scuessfully!!"); 45 | } else { 46 | toast.info("Sorry you are not authenticated"); 47 | } 48 | }; 49 | 50 | React.useEffect(() => { 51 | if (todos.length == 0) getAllNotCompletedTodos(); 52 | }, []); 53 | return ( 54 |
    55 | 56 |
    57 |
      58 | Enter Todo : 59 | 60 | 63 | 64 | {todos.map((todo) => { 65 | return ( 66 | { 70 | const response = await custom_axios.delete(ApiConstants.TODO.DELETE(todo.id), { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 71 | getAllNotCompletedTodos(); 72 | toast.success("Todo Deleted Sucessfully!!"); 73 | }} 74 | markCompelte={async () => { 75 | const response = await custom_axios.patch(ApiConstants.TODO.MARK_COMPLETE(todo.id), {}, { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 76 | getAllNotCompletedTodos(); 77 | toast.success("Todo Marked Completed"); 78 | }} 79 | id={todo.id} 80 | todo={todo.title} 81 | > 82 | ); 83 | })} 84 |
    85 |
    86 |
    87 | ); 88 | } 89 | 90 | export default ActiveTodos; 91 | -------------------------------------------------------------------------------- /react-app-vite/src/pages/CompletedTodos.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import NavBar from "../components/NavBar"; 3 | import TodoList from "../components/ActiveTodoList"; 4 | import CompletedTodoList from "../components/CompletedTodoList"; 5 | import { getLoginInfo } from "../utils/LoginInfo"; 6 | import custom_axios from "../axios/AxiosSetup"; 7 | import { ApiConstants } from "../api/ApiConstants"; 8 | import { toast } from "react-toastify"; 9 | 10 | interface TodoModel { 11 | title: string; 12 | date: string; 13 | id: number; 14 | } 15 | 16 | const CompeletedTodos = () => { 17 | const [todos, setTodos] = React.useState([]); 18 | 19 | const getAllCompletedTodos = async () => { 20 | const userId = getLoginInfo()?.userId; 21 | if (userId != null) { 22 | const response = await custom_axios.get(ApiConstants.TODO.FIND_COMPLETED(userId), { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 23 | setTodos(response.data); 24 | } else { 25 | toast.info("Sorry you are not authenticated"); 26 | } 27 | }; 28 | 29 | React.useEffect(() => { 30 | if (todos.length == 0) getAllCompletedTodos(); 31 | }, []); 32 | 33 | return ( 34 |
    35 | 36 |

    Completed Todos

    37 |
    38 |
      39 | {todos.map((todo) => { 40 | return ( 41 | { 45 | const response = await custom_axios.delete(ApiConstants.TODO.DELETE(todo.id), { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 46 | getAllCompletedTodos(); 47 | toast.success("Todo Deleted Sucessfully!!"); 48 | }} 49 | id={todo.id} 50 | todo={todo.title} 51 | > 52 | ); 53 | })} 54 |
    55 |
    56 |
    57 | ); 58 | }; 59 | 60 | export default CompeletedTodos; 61 | -------------------------------------------------------------------------------- /react-app-vite/src/pages/Login.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import { ApiConstants } from "../api/ApiConstants"; 4 | import Logo from "../assets/logo.png"; 5 | import custom_axios from "../axios/AxiosSetup"; 6 | import { toast } from "react-toastify"; 7 | 8 | const Login = () => { 9 | let navigate = useNavigate(); 10 | let email: any = React.useRef(); 11 | let password: any = React.useRef(); 12 | 13 | const loginApp = async () => { 14 | if (email.current.value == "" || password.current.value == "") { 15 | toast.info("Please fill the information"); 16 | return; 17 | } 18 | try { 19 | const response = await custom_axios.post(ApiConstants.LOGIN, { 20 | email: email.current.value, 21 | password: password.current.value, 22 | }); 23 | localStorage.setItem("token", response.data.token); 24 | dispatchEvent(new Event("storage")); 25 | navigate("/"); 26 | } catch (error: any) { 27 | if (error.response.status == 401) toast.warn(error.response.data.message); 28 | } 29 | 30 | // navigate("/"); 31 | }; 32 | 33 | return ( 34 |
    35 |
    36 |
    37 |
    38 | 39 | Todo App 40 | 41 |
    42 |
    43 |
    44 | {/* @csrf */} 45 | 46 |
    47 | 50 | 58 |
    59 |
    60 | 63 | 72 |
    73 | 81 |
    82 |

    ©2022 Notez. All rights reserved.

    83 |
    84 |
    85 | ); 86 | }; 87 | 88 | export default Login; 89 | -------------------------------------------------------------------------------- /react-app-vite/src/pages/SignUp.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import { ApiConstants } from "../api/ApiConstants"; 4 | import Todo from "../assets/logo.png"; 5 | import custom_axios from "../axios/AxiosSetup"; 6 | import { toast } from "react-toastify"; 7 | 8 | const SignUp = () => { 9 | let navigate = useNavigate(); 10 | let firstName: any = React.useRef(); 11 | let lastName: any = React.useRef(); 12 | let password: any = React.useRef(); 13 | let confirmPassword: any = React.useRef(); 14 | let email: any = React.useRef(); 15 | 16 | const register = async () => { 17 | if (password.current.value != confirmPassword.current.value) { 18 | toast.info("Password does not match!!!"); 19 | return; 20 | } 21 | 22 | const response = await custom_axios.post(ApiConstants.USER.SIGN_UP, { 23 | firstName: firstName.current.value, 24 | lastName: lastName.current.value, 25 | email: email.current.value, 26 | password: password.current.value, 27 | }); 28 | console.log(response.data); 29 | toast.success("Account Created Sucessfully!!!"); 30 | navigate("/login"); 31 | }; 32 | 33 | return ( 34 |
    35 | {/* Container */} 36 |
    37 |
    38 | {/* Row */} 39 |
    40 | {/* Col */} 41 |
    42 | 43 |
    44 | {/* Col */} 45 |
    46 |

    Create an Account!

    47 |
    48 |
    49 |
    50 | 53 | 60 |
    61 |
    62 | 65 | 72 |
    73 |
    74 |
    75 | 78 | 85 |
    86 |
    87 |
    88 | 91 | 98 | {/*

    Please choose a password.

    */} 99 |
    100 |
    101 | 104 | 111 |
    112 |
    113 |
    114 | 117 |
    118 |
    119 |
    120 | 130 |
    131 |
    132 |
    133 |
    134 |
    135 |
    136 | ); 137 | }; 138 | 139 | export default SignUp; 140 | -------------------------------------------------------------------------------- /react-app-vite/src/pages/UsersPage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ApiConstants } from "../api/ApiConstants"; 3 | import custom_axios from "../axios/AxiosSetup"; 4 | import NavBar from "../components/NavBar"; 5 | import { getLoginInfo } from "../utils/LoginInfo"; 6 | import { toast } from "react-toastify"; 7 | 8 | interface UserModel { 9 | firstName: string; 10 | lastName: string; 11 | email: string; 12 | id: number; 13 | role: string; 14 | } 15 | 16 | const UsersPage = () => { 17 | const [users, setUsers] = React.useState([]); 18 | 19 | const getAllUsers = async () => { 20 | const role = getLoginInfo()?.role; 21 | if (role != null && role == "ADMIN") { 22 | const response = await custom_axios.get(ApiConstants.USER.FIND_ALL, { headers: { Authorization: "Bearer " + localStorage.getItem("token") } }); 23 | setUsers(response.data); 24 | } else { 25 | toast.info("Forbidden Resource"); 26 | } 27 | }; 28 | 29 | React.useEffect(() => { 30 | if (users.length == 0) getAllUsers(); 31 | }, []); 32 | return ( 33 |
    34 | 35 |

    Users

    36 | {/* This is an example component */} 37 |
    38 |
    39 |
    40 |
    41 |
    42 | 43 | 44 | 45 | 48 | 51 | 54 | 57 | 58 | 59 | 60 | {users.map((user) => { 61 | return ( 62 | 63 | 64 | 65 | 66 | 79 | 80 | ); 81 | })} 82 | 83 |
    46 | First Name 47 | 49 | Last Name 50 | 52 | Email 53 | 55 | Active 56 |
    {user.firstName}{user.lastName}{user.email} 67 | 78 |
    84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 | ); 91 | }; 92 | 93 | export default UsersPage; 94 | -------------------------------------------------------------------------------- /react-app-vite/src/utils/LoginInfo.ts: -------------------------------------------------------------------------------- 1 | import jwt_decode from "jwt-decode"; 2 | interface UserInfo { 3 | userId: number; 4 | firstName: string; 5 | lastName: string; 6 | email: string; 7 | role: string; 8 | } 9 | export const getLoginInfo = (): UserInfo | null => { 10 | const token = localStorage.getItem("token"); 11 | if (token != null) { 12 | const userInfo: UserInfo = jwt_decode(token); 13 | return userInfo; 14 | } else { 15 | return null; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /react-app-vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /react-app-vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /react-app-vite/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /react-app-vite/vite.config.ts: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /todo-backend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir : __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /todo-backend/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /todo-backend/.local.env: -------------------------------------------------------------------------------- 1 | 2 | DATABASE_NAME=todo_db 3 | DATABASE_HOST=localhost 4 | DATABASE_PORT=5432 5 | DATABASE_USERNAME=postgres 6 | DATABASE_PASSWORD= 7 | DATABASE_SYNC=true 8 | DATABASE_LOGGING=true 9 | 10 | # JWT 11 | JWT_KEY=Thisisthemossddsafsadfewacewf23423fdsrtewf 12 | JWT_EXPIRE=3600 -------------------------------------------------------------------------------- /todo-backend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /todo-backend/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src" 5 | } 6 | -------------------------------------------------------------------------------- /todo-backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-backend", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "nest start", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "node dist/main", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@nestjs/common": "^8.0.0", 25 | "@nestjs/config": "^2.0.1", 26 | "@nestjs/core": "^8.0.0", 27 | "@nestjs/jwt": "^8.0.1", 28 | "@nestjs/mapped-types": "*", 29 | "@nestjs/passport": "^8.2.1", 30 | "@nestjs/platform-express": "^8.0.0", 31 | "@nestjs/swagger": "^5.2.1", 32 | "@nestjs/typeorm": "^8.0.4", 33 | "class-transformer": "^0.5.1", 34 | "class-validator": "^0.13.2", 35 | "passport": "^0.5.3", 36 | "passport-jwt": "^4.0.0", 37 | "passport-local": "^1.0.0", 38 | "pg": "^8.7.3", 39 | "reflect-metadata": "^0.1.13", 40 | "rimraf": "^3.0.2", 41 | "rxjs": "^7.2.0", 42 | "swagger-ui-express": "^4.4.0", 43 | "typeorm": "^0.2.45" 44 | }, 45 | "devDependencies": { 46 | "@nestjs/cli": "^8.0.0", 47 | "@nestjs/schematics": "^8.0.0", 48 | "@nestjs/testing": "^8.0.0", 49 | "@types/express": "^4.17.13", 50 | "@types/jest": "27.4.1", 51 | "@types/node": "^16.0.0", 52 | "@types/passport-jwt": "^3.0.6", 53 | "@types/passport-local": "^1.0.34", 54 | "@types/supertest": "^2.0.11", 55 | "@typescript-eslint/eslint-plugin": "^5.0.0", 56 | "@typescript-eslint/parser": "^5.0.0", 57 | "eslint": "^8.0.1", 58 | "eslint-config-prettier": "^8.3.0", 59 | "eslint-plugin-prettier": "^4.0.0", 60 | "jest": "^27.2.5", 61 | "prettier": "^2.3.2", 62 | "source-map-support": "^0.5.20", 63 | "supertest": "^6.1.3", 64 | "ts-jest": "^27.0.3", 65 | "ts-loader": "^9.2.3", 66 | "ts-node": "^10.0.0", 67 | "tsconfig-paths": "^3.10.1", 68 | "typescript": "^4.3.5" 69 | }, 70 | "jest": { 71 | "moduleFileExtensions": [ 72 | "js", 73 | "json", 74 | "ts" 75 | ], 76 | "rootDir": "src", 77 | "testRegex": ".*\\.spec\\.ts$", 78 | "transform": { 79 | "^.+\\.(t|j)s$": "ts-jest" 80 | }, 81 | "collectCoverageFrom": [ 82 | "**/*.(t|j)s" 83 | ], 84 | "coverageDirectory": "../coverage", 85 | "testEnvironment": "node" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /todo-backend/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ConfigModule, ConfigService } from '@nestjs/config'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { UserModule } from './user/user.module'; 5 | import { TodoModule } from './todo/todo.module'; 6 | import { AuthModule } from './auth/auth.module'; 7 | 8 | // FIND ALL USERS 9 | // ADD USER 10 | // DELETE USER 11 | 12 | // ADD TODO BASED ON USER ID 13 | // FIND ALL TODOS BASED ON USER ID (NOT COMPLETED) 14 | // FIND ALL COMPLETED TODOS BASED ON USER ID (COMPLETED) 15 | // MARK TODO AS COMPLETED BASED ON TODO ID 16 | // DELETE TODO BASED ON TODO ID 17 | 18 | @Module({ 19 | imports: [ 20 | ConfigModule.forRoot({ isGlobal: true, envFilePath: ['.local.env'] }), 21 | TypeOrmModule.forRootAsync({ 22 | imports: [ConfigModule], 23 | inject: [ConfigService], 24 | useFactory: (configService: ConfigService) => ({ 25 | type: 'postgres', 26 | host: configService.get('DATABASE_HOST'), 27 | port: configService.get('DATABASE_PORT'), 28 | username: configService.get('DATABASE_USERNAME'), 29 | password: configService.get('DATABASE_PASSWORD') || "", 30 | synchronize: configService.get('DATABASE_SYNC'), 31 | logging: configService.get('DATABASE_LOGGING'), 32 | database: configService.get('DATABASE_NAME'), 33 | entities: [__dirname + '/**/*.entity{.ts,.js}'], 34 | }), 35 | }), 36 | TodoModule, 37 | UserModule, 38 | AuthModule, 39 | ], 40 | 41 | controllers: [], 42 | providers: [], 43 | }) 44 | export class AppModule {} 45 | -------------------------------------------------------------------------------- /todo-backend/src/auth/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Post, Req, UseGuards } from '@nestjs/common'; 2 | import { JwtService } from '@nestjs/jwt'; 3 | import { AuthGuard } from '@nestjs/passport'; 4 | import { ApiTags } from '@nestjs/swagger'; 5 | import { User } from 'src/user/entities/user.entity'; 6 | import { LoginDto } from './dto/login.dto'; 7 | 8 | @Controller('auth') 9 | @ApiTags('Login') 10 | export class AuthController { 11 | constructor(private jwtService: JwtService) {} 12 | 13 | @Post('/login') 14 | @UseGuards(AuthGuard('local')) 15 | login(@Req() req, @Body() loginDto: LoginDto) { 16 | // jwt token 17 | const user: User = req.user; 18 | const payload = { 19 | userId: user.id, 20 | firstName: user.firstName, 21 | lastName: user.lastName, 22 | email: user.email, 23 | role: user.role, 24 | }; 25 | 26 | return { token: this.jwtService.sign(payload) }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /todo-backend/src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ConfigModule, ConfigService } from '@nestjs/config'; 3 | import { JwtModule } from '@nestjs/jwt'; 4 | import { PassportModule } from '@nestjs/passport'; 5 | import { UserModule } from 'src/user/user.module'; 6 | import { AuthController } from './auth.controller'; 7 | import { JwtStrategy } from './strategy/jwt.strategy'; 8 | import { LocalStrategy } from './strategy/local.strategy'; 9 | 10 | @Module({ 11 | imports: [ 12 | PassportModule, 13 | UserModule, 14 | JwtModule.registerAsync({ 15 | imports: [ConfigModule], 16 | inject: [ConfigService], 17 | useFactory: (configService: ConfigService) => ({ 18 | secret: configService.get('JWT_KEY'), 19 | signOptions: { 20 | expiresIn: configService.get('JWT_EXPIRE') + 's', // "60s" 21 | }, 22 | }), 23 | }), 24 | ], 25 | controllers: [AuthController], 26 | providers: [LocalStrategy, JwtStrategy], 27 | }) 28 | export class AuthModule {} 29 | -------------------------------------------------------------------------------- /todo-backend/src/auth/dto/login.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | export class LoginDto { 3 | @ApiProperty() 4 | email: string; 5 | 6 | @ApiProperty() 7 | password: string; 8 | } 9 | -------------------------------------------------------------------------------- /todo-backend/src/auth/guard/jwt.guard.ts: -------------------------------------------------------------------------------- 1 | import { ExecutionContext, Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | import { Constants } from 'src/utils/constants'; 4 | 5 | @Injectable() 6 | export class JwtAuthGuard extends AuthGuard('jwt') { 7 | canActivate(context: ExecutionContext) { 8 | const ctx = context.switchToHttp(); 9 | const request = ctx.getRequest(); 10 | 11 | for (let x = 0; x < Constants.BY_PASS_URLS.length; x++) { 12 | if (request.url == Constants.BY_PASS_URLS[x]) return true; 13 | } 14 | 15 | return super.canActivate(context); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /todo-backend/src/auth/guard/role.guard.ts: -------------------------------------------------------------------------------- 1 | import { CanActivate, ExecutionContext } from '@nestjs/common/interfaces'; 2 | import { Request } from 'express'; 3 | 4 | export class RoleGuard implements CanActivate { 5 | private role: string; 6 | 7 | constructor(role: string) { 8 | this.role = role; 9 | } 10 | 11 | canActivate(context: ExecutionContext): boolean { 12 | const ctx = context.switchToHttp(); 13 | const request: any = ctx.getRequest(); 14 | if (this.role == request.user.role) return true; 15 | 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /todo-backend/src/auth/strategy/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { PassportStrategy } from '@nestjs/passport'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { ExtractJwt, Strategy } from 'passport-jwt'; 4 | import { UserService } from 'src/user/user.service'; 5 | import { User } from '../../user/entities/user.entity'; 6 | import { UnauthorizedException } from '@nestjs/common'; 7 | import { ConfigService } from '@nestjs/config'; 8 | 9 | @Injectable() 10 | export class JwtStrategy extends PassportStrategy(Strategy) { 11 | constructor(public configService: ConfigService) { 12 | super({ 13 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 14 | ignoreExpiration: false, 15 | secretOrKey: configService.get('JWT_KEY'), 16 | }); 17 | } 18 | 19 | async validate(payload: any) { 20 | return { 21 | userId: payload.userId, 22 | firstName: payload.firstName, 23 | lastName: payload.lastName, 24 | email: payload.email, 25 | role: payload.role, 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /todo-backend/src/auth/strategy/local.strategy.ts: -------------------------------------------------------------------------------- 1 | import { PassportStrategy } from '@nestjs/passport'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { Strategy } from 'passport-local'; 4 | import { UserService } from 'src/user/user.service'; 5 | import { User } from '../../user/entities/user.entity'; 6 | import { UnauthorizedException } from '@nestjs/common'; 7 | 8 | @Injectable() 9 | export class LocalStrategy extends PassportStrategy(Strategy) { 10 | constructor(private userService: UserService) { 11 | super({ 12 | usernameField: 'email', 13 | passwordField: 'password', 14 | }); 15 | } 16 | 17 | async validate(email: string, password: string): Promise { 18 | const user: User = await this.userService.findUserByEmail(email); 19 | if (user && user.password == password) return user; 20 | if (user == undefined) 21 | throw new UnauthorizedException('User Not Found : ' + email); 22 | if (user.password != password) 23 | throw new UnauthorizedException('Invalid Password'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /todo-backend/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | import { JwtAuthGuard } from './auth/guard/jwt.guard'; 4 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 5 | async function bootstrap() { 6 | const app = await NestFactory.create(AppModule); 7 | app.useGlobalGuards(new JwtAuthGuard()); 8 | app.enableCors(); 9 | 10 | const options = new DocumentBuilder() 11 | .setTitle('TodoApp') 12 | .setDescription('Todo NestApp Rest Api Docs') 13 | .setVersion('1.0') 14 | .addBearerAuth( 15 | { 16 | type: 'http', 17 | scheme: 'bearer', 18 | bearerFormat: 'JWT', 19 | name: 'JWT', 20 | description: 'Enter JWT Token', 21 | in: 'header', 22 | }, 23 | 'JWT-auth', 24 | ) 25 | .build(); 26 | 27 | const document = SwaggerModule.createDocument(app, options); 28 | SwaggerModule.setup('api', app, document); 29 | await app.listen(3000); 30 | } 31 | bootstrap(); 32 | -------------------------------------------------------------------------------- /todo-backend/src/todo/dto/create-todo.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsString } from 'class-validator'; 3 | 4 | export class CreateTodoDto { 5 | @ApiProperty() 6 | @IsString() 7 | title: string; 8 | } 9 | -------------------------------------------------------------------------------- /todo-backend/src/todo/dto/update-todo.dto.ts: -------------------------------------------------------------------------------- 1 | import { PartialType } from '@nestjs/mapped-types'; 2 | import { CreateTodoDto } from './create-todo.dto'; 3 | 4 | export class UpdateTodoDto extends PartialType(CreateTodoDto) {} 5 | -------------------------------------------------------------------------------- /todo-backend/src/todo/entities/todo.entity.ts: -------------------------------------------------------------------------------- 1 | import { User } from 'src/user/entities/user.entity'; 2 | import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; 3 | 4 | @Entity() 5 | export class Todo { 6 | @PrimaryGeneratedColumn() 7 | id: number; 8 | 9 | @Column() 10 | title: string; 11 | 12 | @Column() 13 | date: string; 14 | 15 | @Column() 16 | completed: boolean; 17 | 18 | // many todos can belong to single user 19 | @ManyToOne(() => User, (user) => user.todos) 20 | user: User; 21 | } 22 | -------------------------------------------------------------------------------- /todo-backend/src/todo/repo/todo.repository.ts: -------------------------------------------------------------------------------- 1 | import { EntityRepository, Repository } from 'typeorm'; 2 | import { Todo } from '../entities/todo.entity'; 3 | 4 | @EntityRepository(Todo) 5 | export class TodoRepository extends Repository {} 6 | -------------------------------------------------------------------------------- /todo-backend/src/todo/todo.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Post, 5 | Body, 6 | Patch, 7 | Param, 8 | Delete, 9 | ValidationPipe, 10 | } from '@nestjs/common'; 11 | import { TodoService } from './todo.service'; 12 | import { CreateTodoDto } from './dto/create-todo.dto'; 13 | import { ApiSecurity, ApiTags } from '@nestjs/swagger'; 14 | 15 | @Controller('todo') 16 | @ApiTags('Todo') 17 | @ApiSecurity('JWT-auth') 18 | export class TodoController { 19 | constructor(private readonly todoService: TodoService) {} 20 | 21 | @Post(':userId') 22 | create( 23 | @Body(ValidationPipe) createTodoDto: CreateTodoDto, 24 | @Param('userId') userId: number, 25 | ) { 26 | return this.todoService.create(createTodoDto, Number(userId)); 27 | } 28 | 29 | @Get('/findAllNotCompleted/:userId') 30 | findAllTodosByUserIdNotCompleted(@Param('userId') userId: number) { 31 | return this.todoService.findAllTodoByUserNotCompleted(Number(userId)); 32 | } 33 | 34 | @Get('/findAllCompleted/:userId') 35 | findAllTodosByUserIdCompleted(@Param('userId') userId: number) { 36 | return this.todoService.findAllTodoByUserCompleted(Number(userId)); 37 | } 38 | 39 | @Patch(':id') 40 | update(@Param('id') id: number) { 41 | return this.todoService.update(Number(id)); 42 | } 43 | 44 | @Delete(':id') 45 | remove(@Param('id') id: string) { 46 | return this.todoService.remove(Number(id)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /todo-backend/src/todo/todo.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TodoService } from './todo.service'; 3 | import { TodoController } from './todo.controller'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { TodoRepository } from './repo/todo.repository'; 6 | import { UserModule } from 'src/user/user.module'; 7 | 8 | @Module({ 9 | imports: [TypeOrmModule.forFeature([TodoRepository]), UserModule], 10 | controllers: [TodoController], 11 | providers: [TodoService], 12 | }) 13 | export class TodoModule {} 14 | -------------------------------------------------------------------------------- /todo-backend/src/todo/todo.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { CreateTodoDto } from './dto/create-todo.dto'; 3 | import { UpdateTodoDto } from './dto/update-todo.dto'; 4 | import { TodoRepository } from './repo/todo.repository'; 5 | import { Todo } from './entities/todo.entity'; 6 | import { UserService } from 'src/user/user.service'; 7 | 8 | // ADD TODO BASED ON USER ID 9 | // FIND ALL TODOS BASED ON USER ID (NOT COMPLETED) 10 | // FIND ALL COMPLETED TODOS BASED ON USER ID (COMPLETED) 11 | // MARK TODO AS COMPLETED BASED ON TODO ID 12 | // DELETE TODO BASED ON TODO ID 13 | 14 | @Injectable() 15 | export class TodoService { 16 | constructor( 17 | private todoRepository: TodoRepository, 18 | private userService: UserService, 19 | ) {} 20 | 21 | async create(createTodoDto: CreateTodoDto, userId: number) { 22 | let todo: Todo = new Todo(); 23 | todo.title = createTodoDto.title; 24 | todo.date = new Date().toLocaleString(); 25 | todo.completed = false; 26 | todo.user = await this.userService.findUserById(userId); 27 | return this.todoRepository.save(todo); 28 | } 29 | 30 | findAllTodoByUserNotCompleted(userId: number) { 31 | // userid not completed 32 | return this.todoRepository.find({ 33 | relations: ['user'], 34 | where: { user: { id: userId }, completed: false }, 35 | }); 36 | } 37 | 38 | findAllTodoByUserCompleted(userId: number) { 39 | // userid not completed 40 | return this.todoRepository.find({ 41 | relations: ['user'], 42 | where: { user: { id: userId }, completed: true }, 43 | }); 44 | } 45 | 46 | update(todoId: number) { 47 | return this.todoRepository.update(todoId, { completed: true }); 48 | } 49 | 50 | remove(todoId: number) { 51 | return this.todoRepository.delete(todoId); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /todo-backend/src/user/dto/create-user.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsEmail, IsString } from 'class-validator'; 3 | 4 | export class CreateUserDto { 5 | @ApiProperty() 6 | @IsString() 7 | firstName: string; 8 | 9 | @ApiProperty() 10 | @IsString() 11 | lastName: string; 12 | 13 | @ApiProperty() 14 | @IsEmail() 15 | email: string; 16 | 17 | @ApiProperty() 18 | @IsString() 19 | password: string; 20 | } 21 | -------------------------------------------------------------------------------- /todo-backend/src/user/entities/user.entity.ts: -------------------------------------------------------------------------------- 1 | import { Todo } from 'src/todo/entities/todo.entity'; 2 | import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; 3 | 4 | @Entity() 5 | export class User { 6 | @PrimaryGeneratedColumn() 7 | id: number; 8 | 9 | @Column() 10 | firstName: string; 11 | 12 | @Column() 13 | lastName: string; 14 | 15 | @Column() 16 | email: string; 17 | 18 | @Column() 19 | password: string; 20 | 21 | @Column() 22 | role: string; 23 | 24 | // one user can have multipe todos 25 | @OneToMany(() => Todo, (todo) => todo.user) 26 | todos: Todo[]; 27 | } 28 | -------------------------------------------------------------------------------- /todo-backend/src/user/repo/user.repository.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { EntityRepository, Repository } from 'typeorm'; 3 | import { User } from '../entities/user.entity'; 4 | 5 | @EntityRepository(User) 6 | @Injectable() 7 | export class UserRepository extends Repository {} 8 | -------------------------------------------------------------------------------- /todo-backend/src/user/user.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Post, 5 | Body, 6 | Patch, 7 | Param, 8 | Delete, 9 | ValidationPipe, 10 | Req, 11 | UseGuards, 12 | } from '@nestjs/common'; 13 | import { UserService } from './user.service'; 14 | import { CreateUserDto } from './dto/create-user.dto'; 15 | import { RoleGuard } from 'src/auth/guard/role.guard'; 16 | import { Constants } from 'src/utils/constants'; 17 | import { ApiSecurity, ApiTags } from '@nestjs/swagger'; 18 | 19 | @Controller('user') 20 | @ApiTags('User') 21 | export class UserController { 22 | constructor(private readonly userService: UserService) {} 23 | 24 | @Post('/signUp') 25 | create(@Body(ValidationPipe) createUserDto: CreateUserDto) { 26 | return this.userService.create(createUserDto); 27 | } 28 | 29 | @ApiSecurity('JWT-auth') 30 | @Get() 31 | @UseGuards(new RoleGuard(Constants.ROLES.ADMIN_ROLE)) 32 | findAll(@Req() req) { 33 | console.log(req.user); 34 | return this.userService.findAll(); 35 | } 36 | 37 | @ApiSecurity('JWT-auth') 38 | @Delete(':id') 39 | @UseGuards(new RoleGuard(Constants.ROLES.ADMIN_ROLE)) 40 | remove(@Param('id') id: string, @Req() req) { 41 | console.log(req.user); 42 | return this.userService.remove(+id); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /todo-backend/src/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { UserService } from './user.service'; 3 | import { UserController } from './user.controller'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { UserRepository } from './repo/user.repository'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([UserRepository])], 9 | controllers: [UserController], 10 | providers: [UserService], 11 | exports: [UserService], 12 | }) 13 | export class UserModule {} 14 | -------------------------------------------------------------------------------- /todo-backend/src/user/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Constants } from 'src/utils/constants'; 3 | import { CreateUserDto } from './dto/create-user.dto'; 4 | import { User } from './entities/user.entity'; 5 | import { UserRepository } from './repo/user.repository'; 6 | 7 | @Injectable() 8 | export class UserService { 9 | constructor(private userRepository: UserRepository) {} 10 | 11 | create(createUserDto: CreateUserDto) { 12 | let user: User = new User(); 13 | user.email = createUserDto.email; 14 | user.firstName = createUserDto.firstName; 15 | user.lastName = createUserDto.lastName; 16 | user.password = createUserDto.password; 17 | user.role = Constants.ROLES.NORMAL_ROLE; 18 | return this.userRepository.save(user); 19 | } 20 | 21 | findUserById(id: number) { 22 | return this.userRepository.findOneOrFail({ where: { id: id } }); 23 | } 24 | 25 | findAll() { 26 | return this.userRepository.find(); 27 | } 28 | 29 | findUserByEmail(email: string) { 30 | return this.userRepository.findOne({ where: { email: email } }); 31 | } 32 | 33 | remove(id: number) { 34 | return this.userRepository.delete(id); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /todo-backend/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const Constants = { 2 | ROLES: { 3 | ADMIN_ROLE: 'ADMIN', 4 | NORMAL_ROLE: 'NORMAL_USER_ROLE', 5 | }, 6 | BY_PASS_URLS: ['/auth/login', '/user/signUp'], 7 | }; 8 | -------------------------------------------------------------------------------- /todo-backend/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /todo-backend/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /todo-backend/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /todo-backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | --------------------------------------------------------------------------------