├── LISCENCE
├── README.md
├── client
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── _redirects
│ ├── buymeacoffee.png
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ ├── Avatar.jsx
│ ├── BotResponse.jsx
│ ├── Button.jsx
│ ├── BuyMeACoffeeButton.jsx
│ ├── Error.jsx
│ ├── IntroSection.jsx
│ ├── Loading.jsx
│ ├── NavContent.jsx
│ ├── NavLink.jsx
│ ├── NavLinksContainer.jsx
│ ├── NavPrompt.jsx
│ ├── NewChat.jsx
│ ├── SvgComponent.jsx
│ ├── login
│ │ └── LoginForm.jsx
│ └── signup
│ │ ├── SignUpForm.jsx
│ │ └── signupform.css
│ ├── context
│ ├── AuthContext.js
│ └── AuthReducer.js
│ ├── firebase.config.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── normal.css
│ ├── pages
│ ├── Home.jsx
│ └── Login.jsx
│ ├── reportWebVitals.js
│ └── setupTests.js
└── server
├── .gitignore
├── index.js
├── package-lock.json
└── package.json
/LISCENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Sushant Dhimal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | 1. Creative Commons Attribution (CC BY) License: This work is licensed under the Creative Commons Attribution (CC BY) 4.0 International License. To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
8 |
9 | Under the terms of this license, you are free to:
10 |
11 | - Share - copy and redistribute the material in any medium or format
12 | - Adapt - remix, transform, and build upon the material
13 | - Use - for any purpose, even commercially
14 |
15 | Under the following conditions:
16 |
17 | - Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
18 | - No Warranty - The licensor provides no warranty whatsoever with this work and shall not be liable for any damages whatsoever, including without limitation any damages relating to the use of this work.
19 |
20 | 2. OpenAI API License Agreement: If you are using the OpenAI API key in this project, you are also subject to the OpenAI API License Agreement, which can be found at https://beta.openai.com/docs/api-reference/license-agreement. You must comply with the terms of the OpenAI API License Agreement in addition to the terms of the CC BY license.
21 |
22 | By using or distributing this work, you agree to be bound by the terms and conditions of both licenses. If you do not agree to the terms and conditions of both licenses, do not use or distribute this work.
23 |
24 | For more information about the CC BY license, please visit: https://creativecommons.org/licenses/by/4.0/legalcode
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Talkbot App
2 |
3 | A conversational AI app inspired by OpenAI's GPT-3 language model, built with Create React App.
4 |
5 | ## Features
6 |
7 | - Natural language processing and understanding
8 | - Context-aware responses
9 | - Ability to converse on a variety of topics
10 | - React-based front-end for easy user interaction
11 | - Node.js back-end for communication with the OpenAI API
12 |
13 | ## Requirements
14 |
15 | - Node JS
16 | - npm
17 | - [Create Open AI account](https://beta.openai.com/signup/)
18 |
19 | ## Setup
20 |
21 | 1. Clone the repository
22 |
23 | ```
24 | git clone https://github.com/dhiant/react-chatGPT-clone.git
25 | ```
26 |
27 | 2. Install client dependencies
28 |
29 | ```
30 | cd client
31 | npm install
32 | ```
33 |
34 | 3. Install server dependencies
35 |
36 | ```
37 | cd server
38 | npm install
39 | ```
40 |
41 | 4. Get your Open AI API key from [Open AI API Key](https://platform.openai.com/account/api-keys)
42 |
43 | 5. Environment Variable Setup
44 |
45 | - Go to server folder and create .env file in root of server folder and create a variable REACT_APP_OPENAI_API_KEY = [ Your Open AI key here ] insise .env file as
46 |
47 | ```
48 | REACT_APP_OPENAI_API_KEY = [Your Open AI key here]
49 |
50 | ```
51 | 6. Configure Firebase
52 | - Go to [firbase console](https://console.firebase.google.com/) & click on add project, follow the guidelines to create new firebase project
53 | - Once project is created you'll see the config file generated for you. If you do not find the config file, see the Project Overview section on the left panel. Just click the gear icon which is at the right of Project Overview, there you'll see the Project Setting.
54 | - Click on the Project Setting, scroll to the bottom there you'll see "Your apps" section. You need to select web with > symbols. Click on the icon and follow along to add firebase to your web app. Once you'll have your config file update your firebase.config file in the client/src folder.
55 |
56 | ## Usage
57 |
58 | 1. Start the client
59 |
60 | ```
61 | cd client
62 | npm start
63 | ```
64 |
65 | 2. Start the server
66 |
67 | ```
68 | cd server
69 | node index.js
70 | ```
71 |
72 | - Check if your client application run on port 3000 with the development environment configuration, so in your browser just go to http://localhost:3000
73 |
74 | - Check if your server application run on port 4000
75 |
76 | ## Contribution
77 |
78 | All contributions are welcome. Feel free to open an issue or create a pull request. And I will be more than happy for sponsors.
79 |
80 |
81 |
82 | ## Liscence
83 |
84 | This project is licensed under the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license.
85 |
86 | This means that you can use, copy, and modify the code as long as you give credit to the original author (attribution), don't use it for commercial purposes (non-commercial), and distribute any modifications under the same license (share alike).
87 |
88 | Please note that this license applies to the code in this repository only, and does not apply to the OpenAI API, which is subject to its own license agreement.
89 |
90 | [Liscence](LISCENCE)
91 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clone-chatgpt-client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "firebase": "^9.17.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-router-dom": "^6.3.0",
13 | "react-scripts": "5.0.1",
14 | "react-spinners": "^0.13.7",
15 | "web-vitals": "^2.1.4"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject"
22 | },
23 | "eslintConfig": {
24 | "extends": [
25 | "react-app",
26 | "react-app/jest"
27 | ]
28 | },
29 | "browserslist": {
30 | "production": [
31 | ">0.2%",
32 | "not dead",
33 | "not op_mini all"
34 | ],
35 | "development": [
36 | "last 1 chrome version",
37 | "last 1 firefox version",
38 | "last 1 safari version"
39 | ]
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/client/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/client/public/buymeacoffee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhiant/react-chatGPT-clone/aa753329da46f46369578f0910be9aed1fc160d2/client/public/buymeacoffee.png
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhiant/react-chatGPT-clone/aa753329da46f46369578f0910be9aed1fc160d2/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 | Talk-Bot
15 |
16 |
17 | You need to enable JavaScript to run this app.
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhiant/react-chatGPT-clone/aa753329da46f46369578f0910be9aed1fc160d2/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhiant/react-chatGPT-clone/aa753329da46f46369578f0910be9aed1fc160d2/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --text-font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
3 | Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
4 | --primary-bg-color: #282c34;
5 | --secondary-bg-color: #575969;
6 | }
7 |
8 | .App {
9 | font-family: var(--text-font);
10 | text-align: center;
11 | background-color: var(--primary-bg-color);
12 | color: #fff;
13 | display: flex;
14 | position: absolute;
15 | top: 0;
16 | right: 0;
17 | bottom: 0;
18 | left: 0;
19 | }
20 | header {
21 | display: none;
22 | }
23 | header h1 {
24 | font-weight: 400;
25 | font-size: 16px;
26 | line-height: 24px;
27 | color: #d9d9e3;
28 | margin: auto;
29 | }
30 | .menu button {
31 | background: none;
32 | border: none;
33 | }
34 | nav {
35 | display: none;
36 | background-color: #4c4f5f;
37 | position: fixed;
38 | top: 0;
39 | right: 0;
40 | bottom: 0;
41 | left: 0;
42 | z-index: 999;
43 | height: 100vh;
44 | }
45 | .navItems {
46 | padding: 8px;
47 | background-color: #212122;
48 | width: 100%;
49 | max-width: 340px;
50 | }
51 | .navPromptWrapper {
52 | border-bottom: 1px solid #ffffff33;
53 | padding: 10px;
54 | height: calc(100vh - 330px);
55 | overflow-y: auto;
56 | }
57 | .navPrompt {
58 | display: flex;
59 | align-items: center;
60 | padding: 10px;
61 | column-gap: 20px;
62 | margin: 5px 0;
63 | text-align: left;
64 | }
65 | .navPrompt a {
66 | display: flex;
67 | align-items: center;
68 | column-gap: 20px;
69 | text-decoration: none;
70 | }
71 | .navPrompt p {
72 | font-size: 14px;
73 | line-height: 20px;
74 | color: #ececf1;
75 | overflow: hidden;
76 | white-space: nowrap;
77 | text-overflow: ellipsis;
78 | width: 150px;
79 | margin: 0;
80 | }
81 |
82 | .navPrompt span {
83 | animation: fadeInChar 1s ease-in forwards;
84 | opacity: 0;
85 | }
86 | #botMessage pre {
87 | margin: 0;
88 | padding: 0;
89 | text-indent: 0;
90 | white-space: pre-wrap;
91 | position: relative;
92 | top: -45px;
93 | }
94 | pre {
95 | font-family: var(--text-font);
96 | }
97 | @keyframes fadeInChar {
98 | 0% {
99 | opacity: 0;
100 | }
101 | 100% {
102 | opacity: 1;
103 | }
104 | }
105 | .navCloseIcon {
106 | width: 20%;
107 | margin: 10px;
108 | }
109 | nav svg {
110 | float: left;
111 | }
112 | .sideMenu {
113 | width: 244px;
114 | padding: 8px;
115 | background-color: #202022;
116 | }
117 | .sideMenuButton {
118 | border: 1px solid hsl(0deg 0% 100% / 20%);
119 | border-radius: 5px;
120 | padding: 10px;
121 | text-align: left;
122 | font-size: 14px;
123 | transition: all 0.25s ease;
124 | -webkit-transition: all 0.25s ease;
125 | -moz-transition: all 0.25s ease;
126 | -o-transition: all 0.25s ease;
127 | }
128 | .navPrompt:hover,
129 | .sideMenuButton:hover {
130 | cursor: pointer;
131 | background-color: hsla(240, 9%, 59%, 0.1);
132 | }
133 | .sideMenuButton span {
134 | font-size: 20px;
135 | font-weight: 500;
136 | padding-left: 6px;
137 | padding-right: 10px;
138 | }
139 | .chatBox {
140 | flex: 1;
141 | background-color: #353540;
142 | position: relative;
143 | line-height: 24px;
144 | color: #d1d5db;
145 | font-size: 16px;
146 | }
147 | #introsection::before,
148 | #introsection::after {
149 | content: " ";
150 | float: left;
151 | color: rgb(0, 134, 244);
152 | }
153 | #introsection {
154 | text-align: left;
155 | padding: 20px;
156 | }
157 | #introsection h1 {
158 | padding-top: 20px;
159 | line-height: 33px;
160 | }
161 | #introsection h2 {
162 | font-size: 16px;
163 | font-weight: 400;
164 | }
165 | #introsection ul {
166 | list-style-type: square;
167 | }
168 | #introsection pre {
169 | margin: 0;
170 | display: inline;
171 | }
172 | .chatLogWrapper {
173 | height: 80vh;
174 | overflow-y: auto;
175 | }
176 |
177 | /* adding custom scrollbar */
178 | ::-webkit-scrollbar {
179 | width: 8px;
180 | background-color: #575969;
181 | }
182 | ::-webkit-scrollbar-thumb {
183 | background-clip: content-box;
184 | border-color: transparent;
185 | border-style: solid;
186 | border-width: 1px 2px;
187 | background-color: rgb(243, 241, 241);
188 | }
189 |
190 | ::-moz-scrollbar {
191 | width: 8px;
192 | background-color: #575969;
193 | }
194 | ::-moz-scrollbar-thumb {
195 | background-clip: content-box;
196 | border-color: transparent;
197 | border-style: solid;
198 | border-width: 1px 2px;
199 | background-color: rgb(243, 241, 241);
200 | }
201 |
202 | .chatPromptWrapper {
203 | max-width: 800px;
204 | margin: auto;
205 | padding: 24px;
206 | text-align: left;
207 | display: flex;
208 | justify-content: left;
209 | /* align-items: center; */
210 | column-gap: 25px;
211 | }
212 |
213 | .userSVG {
214 | transform: scale(0.6);
215 | }
216 | .botMessageMainContainer {
217 | width: 100%;
218 | background-color: #444654;
219 | position: relative;
220 | }
221 | .botMessageWrapper {
222 | max-width: 800px;
223 | margin: auto;
224 | padding: 24px;
225 | text-align: left;
226 | display: flex;
227 | justify-content: left;
228 | /* align-items: center; */
229 | column-gap: 25px;
230 | }
231 | .stop-messgage {
232 | position: absolute;
233 | bottom: 10px;
234 | right: 100px;
235 | width: fit-content;
236 | padding: 10px 15px;
237 | border-radius: 10%;
238 | border: 1px solid rgb(86, 88, 105);
239 | background-color: rgb(52, 53, 65);
240 | color: rgb(217, 217, 217);
241 | cursor: pointer;
242 | }
243 | .stop-messgage:hover {
244 | background-color: rgb(64, 65, 79);
245 | /* border: none; */
246 | }
247 | .errorMessage {
248 | color: #ef4444;
249 | font-size: 16px;
250 | line-height: 24px;
251 | }
252 |
253 | .openaiSVG {
254 | transform: scale(0.5);
255 | }
256 | #avatar {
257 | display: flex;
258 | align-items: center;
259 | justify-content: center;
260 | width: 36px;
261 | height: 36px;
262 | border-radius: 50%;
263 | object-fit: contain;
264 | object-position: center;
265 | }
266 |
267 | .inputPromptWrapper {
268 | margin-top: 40px;
269 | left: 50%;
270 | right: 50%;
271 | bottom: 0;
272 | position: relative;
273 | transform: translate(-50%, -50%);
274 | width: 80%;
275 | max-height: 200px;
276 | height: 55px;
277 | background-color: #41414e;
278 | border-radius: 5px;
279 | box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.25);
280 | display: flex;
281 | }
282 | .inputPrompttTextarea {
283 | padding: 10px;
284 | flex: 1;
285 | resize: none;
286 | background-color: #41414e;
287 | color: #fff;
288 | font-size: 16px;
289 | outline: none;
290 | border: none;
291 | overflow-y: hidden;
292 | }
293 | form button {
294 | background: rgb(65, 65, 78);
295 | border: none;
296 | position: absolute;
297 | top: 20%;
298 | right: 15px;
299 | width: 35px;
300 | height: 45px;
301 | }
302 |
303 | @media (hover: hover) {
304 | button:hover {
305 | cursor: pointer;
306 | background: #212023;
307 | border-radius: 20%;
308 | }
309 | }
310 |
311 | .loginContainer {
312 | background: var(--primary-bg-color);
313 | width: 100%;
314 | height: 100%;
315 | font-family: var(--text-font);
316 | }
317 |
318 | .loginContainerContent {
319 | display: flex;
320 | align-items: center;
321 | justify-content: center;
322 | flex-direction: column;
323 | height: 100%;
324 | }
325 |
326 | .loginContainerContent svg {
327 | padding-bottom: 30px;
328 | }
329 |
330 | .loginContainer h1 {
331 | font-size: 30px;
332 | margin: 0;
333 | }
334 |
335 | .loginContainer p {
336 | font-size: 18px;
337 | line-height: 5px;
338 | }
339 |
340 | .loginButtonWrapper {
341 | display: flex;
342 | align-items: center;
343 | column-gap: 15px;
344 | margin-top: 20px;
345 | }
346 |
347 | #loginButton {
348 | padding: 10px 25px;
349 | border-radius: 7px;
350 | color: #fff;
351 | background: #10a37f;
352 | border: none;
353 | font-size: 16px;
354 | cursor: pointer;
355 | }
356 | #loginButton:hover {
357 | background-color: rgb(26, 127, 100);
358 | }
359 |
360 | @media screen and (min-width: 768px) {
361 | .inputPromptWrapper {
362 | position: absolute;
363 | }
364 | }
365 |
366 | @media screen and (max-width: 1024px) {
367 | .App {
368 | display: block;
369 | }
370 | header {
371 | display: flex;
372 | align-items: center;
373 | background: #353441;
374 | border-bottom: 1px solid hsl(0deg 0% 100% / 20%);
375 | padding: 4px 0 0 12px;
376 | }
377 | nav {
378 | display: flex;
379 | }
380 | .sideMenu {
381 | display: none;
382 | }
383 | .chatBox {
384 | position: static;
385 | }
386 | .chatPromptWrapper {
387 | padding: 12px;
388 | }
389 | .botMessageWrapper {
390 | padding: 12px;
391 | }
392 | .stop-messgage {
393 | right: 5px;
394 | font-size: 13px;
395 | padding: 8px 15px;
396 | }
397 | .userSVG {
398 | transform: scale(0.5);
399 | }
400 | .openaiSVG {
401 | transform: scale(0.4);
402 | }
403 | #avatar {
404 | width: 30px;
405 | height: 30px;
406 | }
407 | #introsection {
408 | padding: 20px 20px 40px 20px;
409 | font-size: 14px;
410 | }
411 | #introsection h1,
412 | pre {
413 | font-size: 16px;
414 | white-space: pre-wrap;
415 | }
416 | #introsection h2 {
417 | font-size: 14px;
418 | }
419 | }
420 |
421 | @media screen and (min-width: 1536px) {
422 | .loginContainer h1 {
423 | font-size: 40px;
424 | }
425 | .loginContainer p {
426 | font-size: 25px;
427 | }
428 | #loginButton {
429 | font-size: 22px;
430 | }
431 | }
432 |
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import "./normal.css";
2 | import "./App.css";
3 | import Home from "./pages/Home";
4 | import Login from "./pages/Login";
5 | import LoginForm from "./components/login/LoginForm";
6 | import { Navigate, Route, Routes } from "react-router-dom";
7 | import { useContext } from "react";
8 | import { AuthContext } from "./context/AuthContext";
9 |
10 | function App() {
11 | const { currentUser } = useContext(AuthContext);
12 |
13 | const RequireAuth = ({ children }) => {
14 | return currentUser ? children : ;
15 | };
16 |
17 | return (
18 |
19 |
20 |
26 |
27 |
28 | }
29 | />
30 | } />
31 | } />
32 |
33 |
34 | );
35 | }
36 |
37 | export default App;
38 |
--------------------------------------------------------------------------------
/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/client/src/components/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Avatar = ({ children, bg, className }) => {
4 | return (
5 |
8 | );
9 | };
10 |
11 | export default Avatar;
12 |
--------------------------------------------------------------------------------
/client/src/components/BotResponse.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useState } from "react";
3 |
4 | const BotResponse = ({ response, chatLogRef }) => {
5 | const [botResoponse, setBotResponse] = useState("");
6 | const [isPrinting, setIsPrinting] = useState(true);
7 | const [isButtonVisible, setIsButtonVisible] = useState(false);
8 |
9 | useEffect(() => {
10 | let index = 1;
11 | let msg = setInterval(() => {
12 | if (response !== " - The Ultimate AI Assistant") {
13 | setIsButtonVisible(true);
14 | }
15 | if (!isPrinting) {
16 | // if isPrinting is false, clear interval and return
17 | clearInterval(msg);
18 | return;
19 | }
20 | setBotResponse(response.slice(0, index));
21 | if (index >= response.length) {
22 | clearInterval(msg);
23 | setIsButtonVisible(false);
24 | }
25 | index++;
26 |
27 | // scroll to the bottom of the page whenever the messages array is updated
28 | if (chatLogRef !== undefined) {
29 | chatLogRef.current.scrollIntoView({
30 | behavior: "smooth",
31 | block: "end",
32 | });
33 | }
34 | }, 50);
35 | return () => clearInterval(msg); // clear interval on component unmount
36 | }, [chatLogRef, response, isPrinting]);
37 |
38 | const stopPrinting = () => setIsPrinting(!isPrinting);
39 |
40 | return (
41 | <>
42 |
43 | {botResoponse}
44 | {botResoponse === response ? "" : "|"}
45 |
46 | {isButtonVisible && (
47 |
48 | {isPrinting ? "Stop Message" : "Regenerate Message"}
49 |
50 | )}
51 | >
52 | );
53 | };
54 |
55 | export default BotResponse;
56 |
--------------------------------------------------------------------------------
/client/src/components/Button.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Button = ({ text, handleClick }) => {
4 | return (
5 |
6 | {text}
7 |
8 | );
9 | };
10 |
11 | export default Button;
12 |
--------------------------------------------------------------------------------
/client/src/components/BuyMeACoffeeButton.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const BuyMeACoffeeButton = () => {
4 | const style = {
5 | backgroundColor: "#FFDD00",
6 | };
7 | return (
8 |
26 | );
27 | };
28 |
29 | export default BuyMeACoffeeButton;
30 |
--------------------------------------------------------------------------------
/client/src/components/Error.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Error = ({ err }) => {
4 | return (
5 |
6 | An error occurred - "{err.message}". Refresh the page and try again later.
7 |
8 | );
9 | };
10 |
11 | export default Error;
12 |
--------------------------------------------------------------------------------
/client/src/components/IntroSection.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import BotResponse from "./BotResponse";
3 |
4 | const IntroSection = () => {
5 | return (
6 |
7 |
8 | Introducing Talkbot
9 |
10 |
11 |
12 | A cutting-edge AI-powered app that provides instant answers to any
13 | question you may have. With Talkbot, you'll never be left searching for
14 | answers again. Whether you need information for school or work, or just
15 | want to know the latest news, Talkbot has you covered.
16 |
17 | Features:
18 |
19 | Instant answers to any question
20 | Deep learning technology that improves with usage
21 | Continuously Learning
22 | User-friendly interface
23 | Available 24/7
24 |
25 |
26 | Say goodbye to endless searching and typing, and say hello to TalkBot,
27 | your personal AI assistant. Try it now and see for yourself how TalkBot
28 | can make your life easier.
29 |
30 |
31 | );
32 | };
33 |
34 | export default IntroSection;
35 |
--------------------------------------------------------------------------------
/client/src/components/Loading.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PulseLoader from "react-spinners/PulseLoader";
3 |
4 | const Loading = () => {
5 | const override = {
6 | color: "#fff",
7 | loading: true,
8 | };
9 |
10 | return (
11 |
21 | );
22 | };
23 |
24 | export default Loading;
25 |
--------------------------------------------------------------------------------
/client/src/components/NavContent.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import NavLinksContainer from "./NavLinksContainer";
3 | import NavPrompt from "./NavPrompt";
4 | import NewChat from "./NewChat";
5 |
6 | const NavContent = ({ chatLog, setChatLog, setShowMenu }) => {
7 | return (
8 | <>
9 |
10 |
11 | {chatLog.map(
12 | (chat, idx) =>
13 | chat.botMessage && (
14 |
15 | )
16 | )}
17 |
18 |
19 | >
20 | );
21 | };
22 |
23 | export default NavContent;
24 |
--------------------------------------------------------------------------------
/client/src/components/NavLink.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { signOut } from "firebase/auth";
3 | import { auth } from "../firebase.config";
4 | import { AuthContext } from "../context/AuthContext";
5 | import { Link } from "react-router-dom";
6 |
7 | const NavLinks = ({ svg, link, text, setChatLog }) => {
8 | const { dispatch } = useContext(AuthContext);
9 |
10 | const handleClick = async (text) => {
11 | if (text === "Clear Conversations") setChatLog([]);
12 | if (text === "Log out") {
13 | try {
14 | let logOut = await signOut(auth);
15 | console.log("logOut", logOut);
16 | dispatch({ type: "LOGOUT" });
17 | } catch (error) {
18 | console.log("error happen during sign out", error);
19 | }
20 | }
21 | };
22 |
23 | return (
24 | handleClick(text)}
30 | >
31 |
32 | {svg}
33 |
{text}
34 |
35 |
36 | );
37 | };
38 |
39 | export default NavLinks;
40 |
--------------------------------------------------------------------------------
/client/src/components/NavLinksContainer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import NavLinks from "./NavLink";
3 | import BuyMeACoffeeButton from "./BuyMeACoffeeButton";
4 |
5 | const NavLinksContainer = ({ chatLog, setChatLog }) => {
6 | return (
7 |
8 | {chatLog.length > 0 && (
9 |
21 |
29 |
39 |
50 |
51 | }
52 | text="Clear Conversations"
53 | setChatLog={setChatLog}
54 | />
55 | )}
56 |
66 | {"discord_fill"}
67 |
68 |
69 |
73 |
74 |
75 | }
76 | text="OpenAI Discord"
77 | link="https://discord.com/invite/openai"
78 | />
79 |
88 |
95 |
96 | }
97 | text="Updates & FAQ"
98 | link="https://help.openai.com/en/collections/3742473-chatgpt"
99 | />
100 |
110 |
117 |
118 | }
119 | text="Log out"
120 | link=""
121 | />
122 |
123 |
124 | );
125 | };
126 |
127 | export default NavLinksContainer;
128 |
--------------------------------------------------------------------------------
/client/src/components/NavPrompt.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const NavPrompt = ({ chatPrompt, setShowMenu }) => {
4 | const chatPromptCharacters = chatPrompt.split("");
5 | const navPromptHref = `navPrompt-${chatPrompt.replace(/[^a-zA-Z0-9]/g, "-")}`;
6 |
7 | return (
8 |
34 | );
35 | };
36 |
37 | export default NavPrompt;
38 |
--------------------------------------------------------------------------------
/client/src/components/NewChat.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const NewChat = ({ setChatLog, setShowMenu }) => {
4 | return (
5 | {
8 | setChatLog([]);
9 | setShowMenu(false);
10 | }}
11 | >
12 | +
13 | New chat
14 |
15 | );
16 | };
17 |
18 | export default NewChat;
19 |
--------------------------------------------------------------------------------
/client/src/components/SvgComponent.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const SvgComponent = ({ w, h, stroke }) => {
4 | return (
5 |
14 |
18 |
19 | );
20 | };
21 |
22 | export default SvgComponent;
23 |
--------------------------------------------------------------------------------
/client/src/components/login/LoginForm.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react";
2 | import "../signup/signupform.css";
3 | import { signInWithEmailAndPassword, signInWithPopup } from "firebase/auth";
4 | import { auth, goggleAuthProvider } from "../../firebase.config";
5 | import { AuthContext } from "../../context/AuthContext";
6 | import { useNavigate } from "react-router-dom";
7 | import SvgComponent from "../SvgComponent";
8 |
9 | const SignupForm = () => {
10 | const [loginEmail, setLoginEmail] = useState("");
11 | const [loginPassword, setLoginPassword] = useState("");
12 | const [errorMessage, setErrorMessage] = useState("");
13 | const [showLoginPassword, setShowLoginPassword] = useState(true);
14 |
15 | const { dispatch } = useContext(AuthContext);
16 | const navigate = useNavigate();
17 |
18 | const handleLogin = async (e) => {
19 | e.preventDefault();
20 |
21 | try {
22 | let userCredential = await signInWithEmailAndPassword(
23 | auth,
24 | loginEmail,
25 | loginPassword
26 | );
27 | const user = userCredential.user;
28 | dispatch({ type: "LOGIN", payload: user });
29 | // once user is signed in navigate them to the home page
30 | navigate("/");
31 | } catch (error) {
32 | const errorCode = error.code;
33 | const errorMessage = error.message;
34 | console.log(errorCode, errorMessage);
35 | setErrorMessage(errorMessage);
36 | }
37 | };
38 |
39 | const handleSignInWithGoggle = async () => {
40 | try {
41 | let userCredential = await signInWithPopup(auth, goggleAuthProvider);
42 | const user = userCredential.user;
43 | dispatch({ type: "LOGIN", payload: user });
44 | console.log("user", user);
45 | // once user is signed in navigate them to the home page
46 | navigate("/");
47 | } catch (error) {
48 | const errorCode = error.code;
49 | const errorMessage = error.message;
50 | console.log(errorCode, errorMessage);
51 | setErrorMessage(errorMessage);
52 | }
53 | };
54 |
55 | return (
56 |
57 |
58 |
Welcome Back
59 |
125 |
OR
126 |
127 |
128 |
134 |
138 |
142 |
146 |
150 |
151 |
152 | Continue with Goggle
153 |
154 |
155 | );
156 | };
157 |
158 | export default SignupForm;
159 |
--------------------------------------------------------------------------------
/client/src/components/signup/SignUpForm.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react";
2 | import "./signupform.css";
3 | import { createUserWithEmailAndPassword, signInWithPopup } from "firebase/auth";
4 | import { auth, db, goggleAuthProvider } from "../../firebase.config";
5 | import { AuthContext } from "../../context/AuthContext";
6 | import { useNavigate } from "react-router-dom";
7 | import SvgComponent from "../SvgComponent";
8 | import { addDoc, collection } from "firebase/firestore";
9 |
10 | const SignupForm = () => {
11 | const [email, setEmail] = useState("");
12 | const [password, setPassword] = useState("");
13 | const [errorMessage, setErrorMessage] = useState("");
14 | const [showPassword, setShowPassword] = useState(true);
15 |
16 | const { dispatch } = useContext(AuthContext);
17 | const navigate = useNavigate();
18 |
19 | const handleSignup = async (e) => {
20 | e.preventDefault();
21 |
22 | try {
23 | let userCredential = await createUserWithEmailAndPassword(
24 | auth,
25 | email,
26 | password
27 | );
28 | const user = userCredential.user;
29 | dispatch({ type: "SIGNUP", payload: user });
30 |
31 | // add user to firebase database
32 | const docRef = await addDoc(collection(db, "users"), {
33 | email,
34 | password,
35 | date_of_sign_up: new Date(),
36 | });
37 | console.log("Document written with ID: ", docRef.id);
38 |
39 | // once user is signed in navigate them to the home page
40 | navigate("/");
41 | } catch (error) {
42 | const errorCode = error.code;
43 | const errorMessage = error.message;
44 | console.log(errorCode, errorMessage);
45 | setErrorMessage(errorMessage);
46 | }
47 | };
48 |
49 | const handleSignUpWithGoggle = async () => {
50 | try {
51 | let userCredential = await signInWithPopup(auth, goggleAuthProvider);
52 | const user = userCredential.user;
53 | dispatch({ type: "SIGNUP", payload: user });
54 | console.log("user", user);
55 |
56 | // data when user signup with goggle account
57 | const email = user.email;
58 | const user_ID_from_Goggle_Sign_up = user.uid;
59 | // add user to firebase database
60 | const docRef = await addDoc(collection(db, "users"), {
61 | email,
62 | user_ID_from_Goggle_Sign_up,
63 | date_of_sign_up: new Date(),
64 | });
65 | console.log("Document written with ID: ", docRef.id);
66 | // once user is signed in navigate them to the home page
67 | navigate("/");
68 | } catch (error) {
69 | const errorCode = error.code;
70 | const errorMessage = error.message;
71 | console.log(errorCode, errorMessage);
72 | setErrorMessage(errorMessage);
73 | }
74 | };
75 |
76 | return (
77 |
78 |
79 |
Create your account
80 |
146 |
OR
147 |
148 |
149 |
155 |
159 |
163 |
167 |
171 |
172 |
173 | Continue with Goggle
174 |
175 |
176 | );
177 | };
178 |
179 | export default SignupForm;
180 |
--------------------------------------------------------------------------------
/client/src/components/signup/signupform.css:
--------------------------------------------------------------------------------
1 | .signupFormContainer {
2 | background: #fff;
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | justify-content: center;
7 | height: 100%;
8 | width: 100%;
9 | font-family: var(--text-font);
10 | }
11 | .signupFormContainer h1 {
12 | color: #2d333a;
13 | }
14 | .signupFormContainer form {
15 | display: flex;
16 | flex-direction: column;
17 | align-items: center;
18 | justify-content: center;
19 | }
20 | .signupFormContainer input {
21 | width: 250px;
22 | padding: 12px;
23 | padding-bottom: 10px;
24 | margin-bottom: 10px;
25 | border-radius: 5px;
26 | }
27 | .signupFormContainer input:focus {
28 | outline: none;
29 | border-color: #505ef6;
30 | }
31 |
32 | .signupFormContainer button {
33 | width: 275px;
34 | border: none;
35 | border-radius: 5px;
36 | padding: 12px;
37 | margin-top: 5px;
38 | background-color: #10a37f;
39 | color: #fff;
40 | cursor: pointer;
41 | position: static;
42 | }
43 |
44 | .signupFormContainer button:hover {
45 | background: #16c399;
46 | }
47 |
48 | .signupFormContainer span {
49 | font-size: 15px;
50 | color: red;
51 | margin-top: 10px;
52 | }
53 |
54 | #signupPassword {
55 | display: flex;
56 | align-items: center;
57 | position: relative;
58 | }
59 |
60 | #signupPassword svg {
61 | position: absolute;
62 | top: 10px;
63 | right: 10px;
64 | cursor: pointer;
65 | }
66 |
67 | .signupSeparator::before,
68 | .signupSeparator::after {
69 | content: "\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0";
70 | text-decoration: line-through;
71 | padding: 0 15px;
72 | color: #a9acb0;
73 | }
74 |
75 | .signupSeparator {
76 | font-size: 16px;
77 | color: #2d333a;
78 | padding: 20px 0;
79 | }
80 |
81 | #signupWithGoggle {
82 | background: #fff !important;
83 | color: #2d333a !important;
84 | border: 1px solid #202123 !important;
85 | font-size: 18px;
86 | display: flex;
87 | align-items: flex-start;
88 | column-gap: 20px;
89 | }
90 |
91 | #signupWithGoggle:hover {
92 | background-color: rgb(236, 236, 236) !important;
93 | }
94 |
--------------------------------------------------------------------------------
/client/src/context/AuthContext.js:
--------------------------------------------------------------------------------
1 | import { createContext, useEffect, useReducer } from "react";
2 | import reducer from "./AuthReducer";
3 |
4 | const initialState = {
5 | // currentUser must be object so JSON string must be parsed into JS object
6 | currentUser: JSON.parse(localStorage.getItem("user")) || null,
7 | };
8 |
9 | export const AuthContext = createContext(initialState);
10 |
11 | export const AuthContextProvider = ({ children }) => {
12 | const [state, dispatch] = useReducer(reducer, initialState);
13 |
14 | useEffect(() => {
15 | // need to convert JS object to string to store in localStorage
16 | localStorage.setItem("user", JSON.stringify(state.currentUser));
17 | }, [state.currentUser]);
18 |
19 | return (
20 |
21 | {children}
22 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/client/src/context/AuthReducer.js:
--------------------------------------------------------------------------------
1 | function AuthReducer(state, action) {
2 | switch (action.type) {
3 | case "LOGIN": {
4 | return {
5 | ...state,
6 | currentUser: action.payload,
7 | };
8 | }
9 | case "SIGNUP": {
10 | return {
11 | ...state,
12 | currentUser: action.payload,
13 | };
14 | }
15 | case "LOGOUT": {
16 | return {
17 | currentUser: "",
18 | };
19 | }
20 | default: {
21 | return state;
22 | }
23 | }
24 | }
25 |
26 | export default AuthReducer;
27 |
--------------------------------------------------------------------------------
/client/src/firebase.config.js:
--------------------------------------------------------------------------------
1 | // Import the functions you need from the SDKs you need
2 | import { initializeApp } from "firebase/app";
3 | import { getAuth, GoogleAuthProvider } from "firebase/auth";
4 | import { getFirestore } from "firebase/firestore";
5 |
6 | const firebaseConfig = {
7 | apiKey: process.env.REACT_APP_FIREBASE_KEY,
8 | authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
9 | projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
10 | storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
11 | messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
12 | appId: process.env.REACT_APP_FIREBASE_APP_ID,
13 | measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
14 | };
15 |
16 | // Initialize Firebase
17 | const firebaseApp = initializeApp(firebaseConfig);
18 | const auth = getAuth(firebaseApp);
19 | const goggleAuthProvider = new GoogleAuthProvider();
20 |
21 | // Initialize Cloud Firestore and get a reference to the service
22 | const db = getFirestore(firebaseApp);
23 |
24 | export { auth, goggleAuthProvider, db };
25 |
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import reportWebVitals from "./reportWebVitals";
6 | import { BrowserRouter } from "react-router-dom";
7 | import { AuthContextProvider } from "./context/AuthContext";
8 |
9 | const root = ReactDOM.createRoot(document.getElementById("root"));
10 | root.render(
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | // If you want to start measuring performance in your app, pass a function
21 | // to log results (for example: reportWebVitals(console.log))
22 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
23 | reportWebVitals();
24 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/normal.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input {
178 | /* 1 */
179 | overflow: visible;
180 | }
181 |
182 | /**
183 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
184 | * 1. Remove the inheritance of text transform in Firefox.
185 | */
186 |
187 | button,
188 | select {
189 | /* 1 */
190 | text-transform: none;
191 | }
192 |
193 | /**
194 | * Correct the inability to style clickable types in iOS and Safari.
195 | */
196 |
197 | button,
198 | [type="button"],
199 | [type="reset"],
200 | [type="submit"] {
201 | -webkit-appearance: button;
202 | }
203 |
204 | /**
205 | * Remove the inner border and padding in Firefox.
206 | */
207 |
208 | button::-moz-focus-inner,
209 | [type="button"]::-moz-focus-inner,
210 | [type="reset"]::-moz-focus-inner,
211 | [type="submit"]::-moz-focus-inner {
212 | border-style: none;
213 | padding: 0;
214 | }
215 |
216 | /**
217 | * Restore the focus styles unset by the previous rule.
218 | */
219 |
220 | button:-moz-focusring,
221 | [type="button"]:-moz-focusring,
222 | [type="reset"]:-moz-focusring,
223 | [type="submit"]:-moz-focusring {
224 | outline: 1px dotted ButtonText;
225 | }
226 |
227 | /**
228 | * Correct the padding in Firefox.
229 | */
230 |
231 | fieldset {
232 | padding: 0.35em 0.75em 0.625em;
233 | }
234 |
235 | /**
236 | * 1. Correct the text wrapping in Edge and IE.
237 | * 2. Correct the color inheritance from `fieldset` elements in IE.
238 | * 3. Remove the padding so developers are not caught out when they zero out
239 | * `fieldset` elements in all browsers.
240 | */
241 |
242 | legend {
243 | box-sizing: border-box; /* 1 */
244 | color: inherit; /* 2 */
245 | display: table; /* 1 */
246 | max-width: 100%; /* 1 */
247 | padding: 0; /* 3 */
248 | white-space: normal; /* 1 */
249 | }
250 |
251 | /**
252 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
253 | */
254 |
255 | progress {
256 | vertical-align: baseline;
257 | }
258 |
259 | /**
260 | * Remove the default vertical scrollbar in IE 10+.
261 | */
262 |
263 | textarea {
264 | overflow: auto;
265 | }
266 |
267 | /**
268 | * 1. Add the correct box sizing in IE 10.
269 | * 2. Remove the padding in IE 10.
270 | */
271 |
272 | [type="checkbox"],
273 | [type="radio"] {
274 | box-sizing: border-box; /* 1 */
275 | padding: 0; /* 2 */
276 | }
277 |
278 | /**
279 | * Correct the cursor style of increment and decrement buttons in Chrome.
280 | */
281 |
282 | [type="number"]::-webkit-inner-spin-button,
283 | [type="number"]::-webkit-outer-spin-button {
284 | height: auto;
285 | }
286 |
287 | /**
288 | * 1. Correct the odd appearance in Chrome and Safari.
289 | * 2. Correct the outline style in Safari.
290 | */
291 |
292 | [type="search"] {
293 | -webkit-appearance: textfield; /* 1 */
294 | outline-offset: -2px; /* 2 */
295 | }
296 |
297 | /**
298 | * Remove the inner padding in Chrome and Safari on macOS.
299 | */
300 |
301 | [type="search"]::-webkit-search-decoration {
302 | -webkit-appearance: none;
303 | }
304 |
305 | /**
306 | * 1. Correct the inability to style clickable types in iOS and Safari.
307 | * 2. Change font properties to `inherit` in Safari.
308 | */
309 |
310 | ::-webkit-file-upload-button {
311 | -webkit-appearance: button; /* 1 */
312 | font: inherit; /* 2 */
313 | }
314 |
315 | /* Interactive
316 | ========================================================================== */
317 |
318 | /*
319 | * Add the correct display in Edge, IE 10+, and Firefox.
320 | */
321 |
322 | details {
323 | display: block;
324 | }
325 |
326 | /*
327 | * Add the correct display in all browsers.
328 | */
329 |
330 | summary {
331 | display: list-item;
332 | }
333 |
334 | /* Misc
335 | ========================================================================== */
336 |
337 | /**
338 | * Add the correct display in IE 10+.
339 | */
340 |
341 | template {
342 | display: none;
343 | }
344 |
345 | /**
346 | * Add the correct display in IE 10.
347 | */
348 |
349 | [hidden] {
350 | display: none;
351 | }
352 |
--------------------------------------------------------------------------------
/client/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import Avatar from "../components/Avatar";
3 | import BotResponse from "../components/BotResponse";
4 | import Error from "../components/Error";
5 | import IntroSection from "../components/IntroSection";
6 | import Loading from "../components/Loading";
7 | import NavContent from "../components/NavContent";
8 | import SvgComponent from "../components/SvgComponent";
9 |
10 | const Home = () => {
11 | const [showMenu, setShowMenu] = useState(false);
12 | const [inputPrompt, setInputPrompt] = useState("");
13 | const [chatLog, setChatLog] = useState([]);
14 | const [err, setErr] = useState(false);
15 | const [responseFromAPI, setResponseFromAPI] = useState(false);
16 |
17 | const chatLogEndRef = useRef(null);
18 |
19 | const handleSubmit = async (e) => {
20 | e.preventDefault();
21 | if (!responseFromAPI && inputPrompt.trim() !== "") {
22 | const newChatLogEntry = { chatPrompt: inputPrompt, botMessage: null };
23 | setChatLog((prevChatLog) => [...prevChatLog, newChatLogEntry]);
24 |
25 | // hide the keyboard in mobile devices
26 | e.target.querySelector("input").blur();
27 |
28 | setInputPrompt(""); // Clear input after submitting
29 | setResponseFromAPI(true); // Indicate that a response is being awaited
30 |
31 | try {
32 | const response = await fetch("http://localhost:4000/respond", {
33 | method: "POST",
34 | headers: { "Content-Type": "application/json" },
35 | body: JSON.stringify({ message: inputPrompt }),
36 | });
37 | const data = await response.json();
38 |
39 | // Update chat log with the new response
40 | setChatLog((prevChatLog) => [
41 | ...prevChatLog.slice(0, prevChatLog.length - 1), // all entries except the last
42 | { ...newChatLogEntry, botMessage: data.botResponse }, // update the last entry with the bot's response
43 | ]);
44 |
45 | setErr(false);
46 | } catch (error) {
47 | setErr(error);
48 | console.error(error);
49 | } finally {
50 | setResponseFromAPI(false); // Reset after receiving the response
51 | }
52 | }
53 | };
54 |
55 | useEffect(() => {
56 | // Scroll to the bottom of the chat log to show the latest message
57 | if (chatLogEndRef.current) {
58 | chatLogEndRef.current.scrollIntoView({
59 | behavior: "smooth",
60 | block: "end",
61 | });
62 | }
63 | }, [chatLog]);
64 |
65 | return (
66 | <>
67 |
68 |
69 |
setShowMenu(true)}>
70 |
79 |
80 |
81 |
82 |
83 | TalkBot
84 |
85 |
86 | {showMenu && (
87 |
88 |
89 |
94 |
95 |
96 |
setShowMenu(false)}
105 | >
106 |
107 |
108 |
109 |
110 | )}
111 |
112 |
119 |
120 |
121 | {chatLog.length > 0 ? (
122 |
123 | {chatLog.map((chat, idx) => (
124 |
125 | {/* User message */}
126 |
127 |
128 |
129 | {/* User avatar */}
130 |
131 |
{chat.chatPrompt}
132 |
133 |
134 | {/* Bot response */}
135 |
136 |
137 |
138 | {/* Bot avatar */}
139 |
140 | {chat.botMessage === "Loading..." ? (
141 |
142 | ) : err ? (
143 |
144 | ) : (
145 |
{chat.botMessage}
146 | )}
147 |
148 |
149 |
150 | ))}
151 |
{" "}
152 | {/* Invisible element to scroll into view */}
153 |
154 | ) : (
155 |
156 | )}
157 |
158 |
189 |
190 | >
191 | );
192 | };
193 |
194 | export default Home;
195 |
--------------------------------------------------------------------------------
/client/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Button from "../components/Button";
3 | import SvgComponent from "../components/SvgComponent";
4 | import SignupForm from "../components/signup/SignUpForm";
5 | import { useNavigate } from "react-router-dom";
6 |
7 | const Login = () => {
8 | const [isSignupFormVisible, setIsSignupFormVisible] = useState(false);
9 |
10 | const navigate = useNavigate();
11 |
12 | const handleClick = async (purpose) => {
13 | if (purpose === "signup") {
14 | setIsSignupFormVisible(true);
15 | }
16 | if (purpose === "login") {
17 | navigate("/login");
18 | }
19 | };
20 |
21 | return (
22 | <>
23 | {!isSignupFormVisible ? (
24 |
25 |
26 |
27 |
Welcome to Talkbot
28 |
Your Ultimate AI Assistant
29 |
30 | handleClick("login")} />
31 | handleClick("signup")}
34 | />
35 |
36 |
37 |
38 | ) : (
39 |
40 | )}
41 | >
42 | );
43 | };
44 |
45 | export default Login;
46 |
--------------------------------------------------------------------------------
/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | .env
26 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | require("dotenv").config();
2 | const { OpenAI } = require("openai");
3 | const express = require("express");
4 | const bodyParser = require("body-parser");
5 | const cors = require("cors");
6 |
7 | // Initialize express app
8 | const app = express();
9 | const port = 4000;
10 |
11 | const openai = new OpenAI({
12 | apiKey: process.env.OPENAI_API_KEY, // This is also the default, can be omitted
13 | });
14 | // Middleware
15 | app.use(bodyParser.json());
16 | app.use(cors());
17 |
18 | // Route to handle POST requests
19 | app.post("/respond", async (req, res) => {
20 | try {
21 | const { message } = req.body;
22 | console.log("MESSAGE: ", message);
23 | const chatCompletion = await openai.chat.completions.create({
24 | model: "gpt-3.5-turbo",
25 | messages: [{ role: "user", content: message }],
26 | });
27 |
28 | console.log("PASSED");
29 | console.log("OpenAI Response:", chatCompletion.choices[0].message.content);
30 |
31 | // Send the ChatGPT response back to the client
32 | res.json({ botResponse: chatCompletion.choices[0].message.content });
33 | } catch (error) {
34 | console.error("Error calling OpenAI:", error);
35 | res.status(500).json({ error: "Failed to generate response from OpenAI" });
36 | }
37 | });
38 |
39 | // Start the server
40 | app.listen(port, () => {
41 | console.log(`Server listening on port ${port}`);
42 | });
43 |
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clone-chatgpt-server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "clone-chatgpt-server",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "body-parser": "^1.20.1",
13 | "cors": "^2.8.5",
14 | "dotenv": "^16.0.3",
15 | "express": "^4.18.2",
16 | "morgan": "^1.10.0",
17 | "openai": "^4.28.4"
18 | }
19 | },
20 | "node_modules/@types/node": {
21 | "version": "18.19.23",
22 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.23.tgz",
23 | "integrity": "sha512-wtE3d0OUfNKtZYAqZb8HAWGxxXsImJcPUAgZNw+dWFxO6s5tIwIjyKnY76tsTatsNCLJPkVYwUpq15D38ng9Aw==",
24 | "dependencies": {
25 | "undici-types": "~5.26.4"
26 | }
27 | },
28 | "node_modules/@types/node-fetch": {
29 | "version": "2.6.11",
30 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz",
31 | "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==",
32 | "dependencies": {
33 | "@types/node": "*",
34 | "form-data": "^4.0.0"
35 | }
36 | },
37 | "node_modules/abort-controller": {
38 | "version": "3.0.0",
39 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
40 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
41 | "dependencies": {
42 | "event-target-shim": "^5.0.0"
43 | },
44 | "engines": {
45 | "node": ">=6.5"
46 | }
47 | },
48 | "node_modules/accepts": {
49 | "version": "1.3.8",
50 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
51 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
52 | "dependencies": {
53 | "mime-types": "~2.1.34",
54 | "negotiator": "0.6.3"
55 | },
56 | "engines": {
57 | "node": ">= 0.6"
58 | }
59 | },
60 | "node_modules/agentkeepalive": {
61 | "version": "4.5.0",
62 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
63 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
64 | "dependencies": {
65 | "humanize-ms": "^1.2.1"
66 | },
67 | "engines": {
68 | "node": ">= 8.0.0"
69 | }
70 | },
71 | "node_modules/array-flatten": {
72 | "version": "1.1.1",
73 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
74 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
75 | },
76 | "node_modules/asynckit": {
77 | "version": "0.4.0",
78 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
79 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
80 | },
81 | "node_modules/base-64": {
82 | "version": "0.1.0",
83 | "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
84 | "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
85 | },
86 | "node_modules/basic-auth": {
87 | "version": "2.0.1",
88 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
89 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
90 | "dependencies": {
91 | "safe-buffer": "5.1.2"
92 | },
93 | "engines": {
94 | "node": ">= 0.8"
95 | }
96 | },
97 | "node_modules/basic-auth/node_modules/safe-buffer": {
98 | "version": "5.1.2",
99 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
100 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
101 | },
102 | "node_modules/body-parser": {
103 | "version": "1.20.1",
104 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
105 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
106 | "dependencies": {
107 | "bytes": "3.1.2",
108 | "content-type": "~1.0.4",
109 | "debug": "2.6.9",
110 | "depd": "2.0.0",
111 | "destroy": "1.2.0",
112 | "http-errors": "2.0.0",
113 | "iconv-lite": "0.4.24",
114 | "on-finished": "2.4.1",
115 | "qs": "6.11.0",
116 | "raw-body": "2.5.1",
117 | "type-is": "~1.6.18",
118 | "unpipe": "1.0.0"
119 | },
120 | "engines": {
121 | "node": ">= 0.8",
122 | "npm": "1.2.8000 || >= 1.4.16"
123 | }
124 | },
125 | "node_modules/bytes": {
126 | "version": "3.1.2",
127 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
128 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
129 | "engines": {
130 | "node": ">= 0.8"
131 | }
132 | },
133 | "node_modules/call-bind": {
134 | "version": "1.0.2",
135 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
136 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
137 | "dependencies": {
138 | "function-bind": "^1.1.1",
139 | "get-intrinsic": "^1.0.2"
140 | },
141 | "funding": {
142 | "url": "https://github.com/sponsors/ljharb"
143 | }
144 | },
145 | "node_modules/charenc": {
146 | "version": "0.0.2",
147 | "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
148 | "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
149 | "engines": {
150 | "node": "*"
151 | }
152 | },
153 | "node_modules/combined-stream": {
154 | "version": "1.0.8",
155 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
156 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
157 | "dependencies": {
158 | "delayed-stream": "~1.0.0"
159 | },
160 | "engines": {
161 | "node": ">= 0.8"
162 | }
163 | },
164 | "node_modules/content-disposition": {
165 | "version": "0.5.4",
166 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
167 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
168 | "dependencies": {
169 | "safe-buffer": "5.2.1"
170 | },
171 | "engines": {
172 | "node": ">= 0.6"
173 | }
174 | },
175 | "node_modules/content-type": {
176 | "version": "1.0.4",
177 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
178 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
179 | "engines": {
180 | "node": ">= 0.6"
181 | }
182 | },
183 | "node_modules/cookie": {
184 | "version": "0.5.0",
185 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
186 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
187 | "engines": {
188 | "node": ">= 0.6"
189 | }
190 | },
191 | "node_modules/cookie-signature": {
192 | "version": "1.0.6",
193 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
194 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
195 | },
196 | "node_modules/cors": {
197 | "version": "2.8.5",
198 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
199 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
200 | "dependencies": {
201 | "object-assign": "^4",
202 | "vary": "^1"
203 | },
204 | "engines": {
205 | "node": ">= 0.10"
206 | }
207 | },
208 | "node_modules/crypt": {
209 | "version": "0.0.2",
210 | "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
211 | "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
212 | "engines": {
213 | "node": "*"
214 | }
215 | },
216 | "node_modules/debug": {
217 | "version": "2.6.9",
218 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
219 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
220 | "dependencies": {
221 | "ms": "2.0.0"
222 | }
223 | },
224 | "node_modules/delayed-stream": {
225 | "version": "1.0.0",
226 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
227 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
228 | "engines": {
229 | "node": ">=0.4.0"
230 | }
231 | },
232 | "node_modules/depd": {
233 | "version": "2.0.0",
234 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
235 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
236 | "engines": {
237 | "node": ">= 0.8"
238 | }
239 | },
240 | "node_modules/destroy": {
241 | "version": "1.2.0",
242 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
243 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
244 | "engines": {
245 | "node": ">= 0.8",
246 | "npm": "1.2.8000 || >= 1.4.16"
247 | }
248 | },
249 | "node_modules/digest-fetch": {
250 | "version": "1.3.0",
251 | "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
252 | "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==",
253 | "dependencies": {
254 | "base-64": "^0.1.0",
255 | "md5": "^2.3.0"
256 | }
257 | },
258 | "node_modules/dotenv": {
259 | "version": "16.0.3",
260 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
261 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
262 | "engines": {
263 | "node": ">=12"
264 | }
265 | },
266 | "node_modules/ee-first": {
267 | "version": "1.1.1",
268 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
269 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
270 | },
271 | "node_modules/encodeurl": {
272 | "version": "1.0.2",
273 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
274 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
275 | "engines": {
276 | "node": ">= 0.8"
277 | }
278 | },
279 | "node_modules/escape-html": {
280 | "version": "1.0.3",
281 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
282 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
283 | },
284 | "node_modules/etag": {
285 | "version": "1.8.1",
286 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
287 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
288 | "engines": {
289 | "node": ">= 0.6"
290 | }
291 | },
292 | "node_modules/event-target-shim": {
293 | "version": "5.0.1",
294 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
295 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
296 | "engines": {
297 | "node": ">=6"
298 | }
299 | },
300 | "node_modules/express": {
301 | "version": "4.18.2",
302 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
303 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
304 | "dependencies": {
305 | "accepts": "~1.3.8",
306 | "array-flatten": "1.1.1",
307 | "body-parser": "1.20.1",
308 | "content-disposition": "0.5.4",
309 | "content-type": "~1.0.4",
310 | "cookie": "0.5.0",
311 | "cookie-signature": "1.0.6",
312 | "debug": "2.6.9",
313 | "depd": "2.0.0",
314 | "encodeurl": "~1.0.2",
315 | "escape-html": "~1.0.3",
316 | "etag": "~1.8.1",
317 | "finalhandler": "1.2.0",
318 | "fresh": "0.5.2",
319 | "http-errors": "2.0.0",
320 | "merge-descriptors": "1.0.1",
321 | "methods": "~1.1.2",
322 | "on-finished": "2.4.1",
323 | "parseurl": "~1.3.3",
324 | "path-to-regexp": "0.1.7",
325 | "proxy-addr": "~2.0.7",
326 | "qs": "6.11.0",
327 | "range-parser": "~1.2.1",
328 | "safe-buffer": "5.2.1",
329 | "send": "0.18.0",
330 | "serve-static": "1.15.0",
331 | "setprototypeof": "1.2.0",
332 | "statuses": "2.0.1",
333 | "type-is": "~1.6.18",
334 | "utils-merge": "1.0.1",
335 | "vary": "~1.1.2"
336 | },
337 | "engines": {
338 | "node": ">= 0.10.0"
339 | }
340 | },
341 | "node_modules/finalhandler": {
342 | "version": "1.2.0",
343 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
344 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
345 | "dependencies": {
346 | "debug": "2.6.9",
347 | "encodeurl": "~1.0.2",
348 | "escape-html": "~1.0.3",
349 | "on-finished": "2.4.1",
350 | "parseurl": "~1.3.3",
351 | "statuses": "2.0.1",
352 | "unpipe": "~1.0.0"
353 | },
354 | "engines": {
355 | "node": ">= 0.8"
356 | }
357 | },
358 | "node_modules/form-data": {
359 | "version": "4.0.0",
360 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
361 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
362 | "dependencies": {
363 | "asynckit": "^0.4.0",
364 | "combined-stream": "^1.0.8",
365 | "mime-types": "^2.1.12"
366 | },
367 | "engines": {
368 | "node": ">= 6"
369 | }
370 | },
371 | "node_modules/form-data-encoder": {
372 | "version": "1.7.2",
373 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
374 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
375 | },
376 | "node_modules/formdata-node": {
377 | "version": "4.4.1",
378 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
379 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
380 | "dependencies": {
381 | "node-domexception": "1.0.0",
382 | "web-streams-polyfill": "4.0.0-beta.3"
383 | },
384 | "engines": {
385 | "node": ">= 12.20"
386 | }
387 | },
388 | "node_modules/formdata-node/node_modules/web-streams-polyfill": {
389 | "version": "4.0.0-beta.3",
390 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
391 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
392 | "engines": {
393 | "node": ">= 14"
394 | }
395 | },
396 | "node_modules/forwarded": {
397 | "version": "0.2.0",
398 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
399 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
400 | "engines": {
401 | "node": ">= 0.6"
402 | }
403 | },
404 | "node_modules/fresh": {
405 | "version": "0.5.2",
406 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
407 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
408 | "engines": {
409 | "node": ">= 0.6"
410 | }
411 | },
412 | "node_modules/function-bind": {
413 | "version": "1.1.1",
414 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
415 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
416 | },
417 | "node_modules/get-intrinsic": {
418 | "version": "1.1.3",
419 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
420 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
421 | "dependencies": {
422 | "function-bind": "^1.1.1",
423 | "has": "^1.0.3",
424 | "has-symbols": "^1.0.3"
425 | },
426 | "funding": {
427 | "url": "https://github.com/sponsors/ljharb"
428 | }
429 | },
430 | "node_modules/has": {
431 | "version": "1.0.3",
432 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
433 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
434 | "dependencies": {
435 | "function-bind": "^1.1.1"
436 | },
437 | "engines": {
438 | "node": ">= 0.4.0"
439 | }
440 | },
441 | "node_modules/has-symbols": {
442 | "version": "1.0.3",
443 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
444 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
445 | "engines": {
446 | "node": ">= 0.4"
447 | },
448 | "funding": {
449 | "url": "https://github.com/sponsors/ljharb"
450 | }
451 | },
452 | "node_modules/http-errors": {
453 | "version": "2.0.0",
454 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
455 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
456 | "dependencies": {
457 | "depd": "2.0.0",
458 | "inherits": "2.0.4",
459 | "setprototypeof": "1.2.0",
460 | "statuses": "2.0.1",
461 | "toidentifier": "1.0.1"
462 | },
463 | "engines": {
464 | "node": ">= 0.8"
465 | }
466 | },
467 | "node_modules/humanize-ms": {
468 | "version": "1.2.1",
469 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
470 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
471 | "dependencies": {
472 | "ms": "^2.0.0"
473 | }
474 | },
475 | "node_modules/iconv-lite": {
476 | "version": "0.4.24",
477 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
478 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
479 | "dependencies": {
480 | "safer-buffer": ">= 2.1.2 < 3"
481 | },
482 | "engines": {
483 | "node": ">=0.10.0"
484 | }
485 | },
486 | "node_modules/inherits": {
487 | "version": "2.0.4",
488 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
489 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
490 | },
491 | "node_modules/ipaddr.js": {
492 | "version": "1.9.1",
493 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
494 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
495 | "engines": {
496 | "node": ">= 0.10"
497 | }
498 | },
499 | "node_modules/is-buffer": {
500 | "version": "1.1.6",
501 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
502 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
503 | },
504 | "node_modules/md5": {
505 | "version": "2.3.0",
506 | "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
507 | "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
508 | "dependencies": {
509 | "charenc": "0.0.2",
510 | "crypt": "0.0.2",
511 | "is-buffer": "~1.1.6"
512 | }
513 | },
514 | "node_modules/media-typer": {
515 | "version": "0.3.0",
516 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
517 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
518 | "engines": {
519 | "node": ">= 0.6"
520 | }
521 | },
522 | "node_modules/merge-descriptors": {
523 | "version": "1.0.1",
524 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
525 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
526 | },
527 | "node_modules/methods": {
528 | "version": "1.1.2",
529 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
530 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
531 | "engines": {
532 | "node": ">= 0.6"
533 | }
534 | },
535 | "node_modules/mime": {
536 | "version": "1.6.0",
537 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
538 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
539 | "bin": {
540 | "mime": "cli.js"
541 | },
542 | "engines": {
543 | "node": ">=4"
544 | }
545 | },
546 | "node_modules/mime-db": {
547 | "version": "1.52.0",
548 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
549 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
550 | "engines": {
551 | "node": ">= 0.6"
552 | }
553 | },
554 | "node_modules/mime-types": {
555 | "version": "2.1.35",
556 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
557 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
558 | "dependencies": {
559 | "mime-db": "1.52.0"
560 | },
561 | "engines": {
562 | "node": ">= 0.6"
563 | }
564 | },
565 | "node_modules/morgan": {
566 | "version": "1.10.0",
567 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
568 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
569 | "dependencies": {
570 | "basic-auth": "~2.0.1",
571 | "debug": "2.6.9",
572 | "depd": "~2.0.0",
573 | "on-finished": "~2.3.0",
574 | "on-headers": "~1.0.2"
575 | },
576 | "engines": {
577 | "node": ">= 0.8.0"
578 | }
579 | },
580 | "node_modules/morgan/node_modules/on-finished": {
581 | "version": "2.3.0",
582 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
583 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
584 | "dependencies": {
585 | "ee-first": "1.1.1"
586 | },
587 | "engines": {
588 | "node": ">= 0.8"
589 | }
590 | },
591 | "node_modules/ms": {
592 | "version": "2.0.0",
593 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
594 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
595 | },
596 | "node_modules/negotiator": {
597 | "version": "0.6.3",
598 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
599 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
600 | "engines": {
601 | "node": ">= 0.6"
602 | }
603 | },
604 | "node_modules/node-domexception": {
605 | "version": "1.0.0",
606 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
607 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
608 | "funding": [
609 | {
610 | "type": "github",
611 | "url": "https://github.com/sponsors/jimmywarting"
612 | },
613 | {
614 | "type": "github",
615 | "url": "https://paypal.me/jimmywarting"
616 | }
617 | ],
618 | "engines": {
619 | "node": ">=10.5.0"
620 | }
621 | },
622 | "node_modules/node-fetch": {
623 | "version": "2.7.0",
624 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
625 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
626 | "dependencies": {
627 | "whatwg-url": "^5.0.0"
628 | },
629 | "engines": {
630 | "node": "4.x || >=6.0.0"
631 | },
632 | "peerDependencies": {
633 | "encoding": "^0.1.0"
634 | },
635 | "peerDependenciesMeta": {
636 | "encoding": {
637 | "optional": true
638 | }
639 | }
640 | },
641 | "node_modules/object-assign": {
642 | "version": "4.1.1",
643 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
644 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
645 | "engines": {
646 | "node": ">=0.10.0"
647 | }
648 | },
649 | "node_modules/object-inspect": {
650 | "version": "1.12.2",
651 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
652 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
653 | "funding": {
654 | "url": "https://github.com/sponsors/ljharb"
655 | }
656 | },
657 | "node_modules/on-finished": {
658 | "version": "2.4.1",
659 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
660 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
661 | "dependencies": {
662 | "ee-first": "1.1.1"
663 | },
664 | "engines": {
665 | "node": ">= 0.8"
666 | }
667 | },
668 | "node_modules/on-headers": {
669 | "version": "1.0.2",
670 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
671 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
672 | "engines": {
673 | "node": ">= 0.8"
674 | }
675 | },
676 | "node_modules/openai": {
677 | "version": "4.28.4",
678 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.28.4.tgz",
679 | "integrity": "sha512-RNIwx4MT/F0zyizGcwS+bXKLzJ8QE9IOyigDG/ttnwB220d58bYjYFp0qjvGwEFBO6+pvFVIDABZPGDl46RFsg==",
680 | "dependencies": {
681 | "@types/node": "^18.11.18",
682 | "@types/node-fetch": "^2.6.4",
683 | "abort-controller": "^3.0.0",
684 | "agentkeepalive": "^4.2.1",
685 | "digest-fetch": "^1.3.0",
686 | "form-data-encoder": "1.7.2",
687 | "formdata-node": "^4.3.2",
688 | "node-fetch": "^2.6.7",
689 | "web-streams-polyfill": "^3.2.1"
690 | },
691 | "bin": {
692 | "openai": "bin/cli"
693 | }
694 | },
695 | "node_modules/parseurl": {
696 | "version": "1.3.3",
697 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
698 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
699 | "engines": {
700 | "node": ">= 0.8"
701 | }
702 | },
703 | "node_modules/path-to-regexp": {
704 | "version": "0.1.7",
705 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
706 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
707 | },
708 | "node_modules/proxy-addr": {
709 | "version": "2.0.7",
710 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
711 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
712 | "dependencies": {
713 | "forwarded": "0.2.0",
714 | "ipaddr.js": "1.9.1"
715 | },
716 | "engines": {
717 | "node": ">= 0.10"
718 | }
719 | },
720 | "node_modules/qs": {
721 | "version": "6.11.0",
722 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
723 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
724 | "dependencies": {
725 | "side-channel": "^1.0.4"
726 | },
727 | "engines": {
728 | "node": ">=0.6"
729 | },
730 | "funding": {
731 | "url": "https://github.com/sponsors/ljharb"
732 | }
733 | },
734 | "node_modules/range-parser": {
735 | "version": "1.2.1",
736 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
737 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
738 | "engines": {
739 | "node": ">= 0.6"
740 | }
741 | },
742 | "node_modules/raw-body": {
743 | "version": "2.5.1",
744 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
745 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
746 | "dependencies": {
747 | "bytes": "3.1.2",
748 | "http-errors": "2.0.0",
749 | "iconv-lite": "0.4.24",
750 | "unpipe": "1.0.0"
751 | },
752 | "engines": {
753 | "node": ">= 0.8"
754 | }
755 | },
756 | "node_modules/safe-buffer": {
757 | "version": "5.2.1",
758 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
759 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
760 | "funding": [
761 | {
762 | "type": "github",
763 | "url": "https://github.com/sponsors/feross"
764 | },
765 | {
766 | "type": "patreon",
767 | "url": "https://www.patreon.com/feross"
768 | },
769 | {
770 | "type": "consulting",
771 | "url": "https://feross.org/support"
772 | }
773 | ]
774 | },
775 | "node_modules/safer-buffer": {
776 | "version": "2.1.2",
777 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
778 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
779 | },
780 | "node_modules/send": {
781 | "version": "0.18.0",
782 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
783 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
784 | "dependencies": {
785 | "debug": "2.6.9",
786 | "depd": "2.0.0",
787 | "destroy": "1.2.0",
788 | "encodeurl": "~1.0.2",
789 | "escape-html": "~1.0.3",
790 | "etag": "~1.8.1",
791 | "fresh": "0.5.2",
792 | "http-errors": "2.0.0",
793 | "mime": "1.6.0",
794 | "ms": "2.1.3",
795 | "on-finished": "2.4.1",
796 | "range-parser": "~1.2.1",
797 | "statuses": "2.0.1"
798 | },
799 | "engines": {
800 | "node": ">= 0.8.0"
801 | }
802 | },
803 | "node_modules/send/node_modules/ms": {
804 | "version": "2.1.3",
805 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
806 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
807 | },
808 | "node_modules/serve-static": {
809 | "version": "1.15.0",
810 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
811 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
812 | "dependencies": {
813 | "encodeurl": "~1.0.2",
814 | "escape-html": "~1.0.3",
815 | "parseurl": "~1.3.3",
816 | "send": "0.18.0"
817 | },
818 | "engines": {
819 | "node": ">= 0.8.0"
820 | }
821 | },
822 | "node_modules/setprototypeof": {
823 | "version": "1.2.0",
824 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
825 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
826 | },
827 | "node_modules/side-channel": {
828 | "version": "1.0.4",
829 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
830 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
831 | "dependencies": {
832 | "call-bind": "^1.0.0",
833 | "get-intrinsic": "^1.0.2",
834 | "object-inspect": "^1.9.0"
835 | },
836 | "funding": {
837 | "url": "https://github.com/sponsors/ljharb"
838 | }
839 | },
840 | "node_modules/statuses": {
841 | "version": "2.0.1",
842 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
843 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
844 | "engines": {
845 | "node": ">= 0.8"
846 | }
847 | },
848 | "node_modules/toidentifier": {
849 | "version": "1.0.1",
850 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
851 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
852 | "engines": {
853 | "node": ">=0.6"
854 | }
855 | },
856 | "node_modules/tr46": {
857 | "version": "0.0.3",
858 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
859 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
860 | },
861 | "node_modules/type-is": {
862 | "version": "1.6.18",
863 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
864 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
865 | "dependencies": {
866 | "media-typer": "0.3.0",
867 | "mime-types": "~2.1.24"
868 | },
869 | "engines": {
870 | "node": ">= 0.6"
871 | }
872 | },
873 | "node_modules/undici-types": {
874 | "version": "5.26.5",
875 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
876 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
877 | },
878 | "node_modules/unpipe": {
879 | "version": "1.0.0",
880 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
881 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
882 | "engines": {
883 | "node": ">= 0.8"
884 | }
885 | },
886 | "node_modules/utils-merge": {
887 | "version": "1.0.1",
888 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
889 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
890 | "engines": {
891 | "node": ">= 0.4.0"
892 | }
893 | },
894 | "node_modules/vary": {
895 | "version": "1.1.2",
896 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
897 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
898 | "engines": {
899 | "node": ">= 0.8"
900 | }
901 | },
902 | "node_modules/web-streams-polyfill": {
903 | "version": "3.3.3",
904 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
905 | "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
906 | "engines": {
907 | "node": ">= 8"
908 | }
909 | },
910 | "node_modules/webidl-conversions": {
911 | "version": "3.0.1",
912 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
913 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
914 | },
915 | "node_modules/whatwg-url": {
916 | "version": "5.0.0",
917 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
918 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
919 | "dependencies": {
920 | "tr46": "~0.0.3",
921 | "webidl-conversions": "^3.0.0"
922 | }
923 | }
924 | },
925 | "dependencies": {
926 | "@types/node": {
927 | "version": "18.19.23",
928 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.23.tgz",
929 | "integrity": "sha512-wtE3d0OUfNKtZYAqZb8HAWGxxXsImJcPUAgZNw+dWFxO6s5tIwIjyKnY76tsTatsNCLJPkVYwUpq15D38ng9Aw==",
930 | "requires": {
931 | "undici-types": "~5.26.4"
932 | }
933 | },
934 | "@types/node-fetch": {
935 | "version": "2.6.11",
936 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz",
937 | "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==",
938 | "requires": {
939 | "@types/node": "*",
940 | "form-data": "^4.0.0"
941 | }
942 | },
943 | "abort-controller": {
944 | "version": "3.0.0",
945 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
946 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
947 | "requires": {
948 | "event-target-shim": "^5.0.0"
949 | }
950 | },
951 | "accepts": {
952 | "version": "1.3.8",
953 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
954 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
955 | "requires": {
956 | "mime-types": "~2.1.34",
957 | "negotiator": "0.6.3"
958 | }
959 | },
960 | "agentkeepalive": {
961 | "version": "4.5.0",
962 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
963 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
964 | "requires": {
965 | "humanize-ms": "^1.2.1"
966 | }
967 | },
968 | "array-flatten": {
969 | "version": "1.1.1",
970 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
971 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
972 | },
973 | "asynckit": {
974 | "version": "0.4.0",
975 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
976 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
977 | },
978 | "base-64": {
979 | "version": "0.1.0",
980 | "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
981 | "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
982 | },
983 | "basic-auth": {
984 | "version": "2.0.1",
985 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
986 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
987 | "requires": {
988 | "safe-buffer": "5.1.2"
989 | },
990 | "dependencies": {
991 | "safe-buffer": {
992 | "version": "5.1.2",
993 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
994 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
995 | }
996 | }
997 | },
998 | "body-parser": {
999 | "version": "1.20.1",
1000 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
1001 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
1002 | "requires": {
1003 | "bytes": "3.1.2",
1004 | "content-type": "~1.0.4",
1005 | "debug": "2.6.9",
1006 | "depd": "2.0.0",
1007 | "destroy": "1.2.0",
1008 | "http-errors": "2.0.0",
1009 | "iconv-lite": "0.4.24",
1010 | "on-finished": "2.4.1",
1011 | "qs": "6.11.0",
1012 | "raw-body": "2.5.1",
1013 | "type-is": "~1.6.18",
1014 | "unpipe": "1.0.0"
1015 | }
1016 | },
1017 | "bytes": {
1018 | "version": "3.1.2",
1019 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1020 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
1021 | },
1022 | "call-bind": {
1023 | "version": "1.0.2",
1024 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
1025 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
1026 | "requires": {
1027 | "function-bind": "^1.1.1",
1028 | "get-intrinsic": "^1.0.2"
1029 | }
1030 | },
1031 | "charenc": {
1032 | "version": "0.0.2",
1033 | "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
1034 | "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="
1035 | },
1036 | "combined-stream": {
1037 | "version": "1.0.8",
1038 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1039 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1040 | "requires": {
1041 | "delayed-stream": "~1.0.0"
1042 | }
1043 | },
1044 | "content-disposition": {
1045 | "version": "0.5.4",
1046 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
1047 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
1048 | "requires": {
1049 | "safe-buffer": "5.2.1"
1050 | }
1051 | },
1052 | "content-type": {
1053 | "version": "1.0.4",
1054 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
1055 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
1056 | },
1057 | "cookie": {
1058 | "version": "0.5.0",
1059 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
1060 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
1061 | },
1062 | "cookie-signature": {
1063 | "version": "1.0.6",
1064 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
1065 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
1066 | },
1067 | "cors": {
1068 | "version": "2.8.5",
1069 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1070 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
1071 | "requires": {
1072 | "object-assign": "^4",
1073 | "vary": "^1"
1074 | }
1075 | },
1076 | "crypt": {
1077 | "version": "0.0.2",
1078 | "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
1079 | "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="
1080 | },
1081 | "debug": {
1082 | "version": "2.6.9",
1083 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1084 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1085 | "requires": {
1086 | "ms": "2.0.0"
1087 | }
1088 | },
1089 | "delayed-stream": {
1090 | "version": "1.0.0",
1091 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1092 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
1093 | },
1094 | "depd": {
1095 | "version": "2.0.0",
1096 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1097 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
1098 | },
1099 | "destroy": {
1100 | "version": "1.2.0",
1101 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
1102 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
1103 | },
1104 | "digest-fetch": {
1105 | "version": "1.3.0",
1106 | "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
1107 | "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==",
1108 | "requires": {
1109 | "base-64": "^0.1.0",
1110 | "md5": "^2.3.0"
1111 | }
1112 | },
1113 | "dotenv": {
1114 | "version": "16.0.3",
1115 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
1116 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
1117 | },
1118 | "ee-first": {
1119 | "version": "1.1.1",
1120 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1121 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
1122 | },
1123 | "encodeurl": {
1124 | "version": "1.0.2",
1125 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
1126 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
1127 | },
1128 | "escape-html": {
1129 | "version": "1.0.3",
1130 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1131 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
1132 | },
1133 | "etag": {
1134 | "version": "1.8.1",
1135 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
1136 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
1137 | },
1138 | "event-target-shim": {
1139 | "version": "5.0.1",
1140 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
1141 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
1142 | },
1143 | "express": {
1144 | "version": "4.18.2",
1145 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
1146 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
1147 | "requires": {
1148 | "accepts": "~1.3.8",
1149 | "array-flatten": "1.1.1",
1150 | "body-parser": "1.20.1",
1151 | "content-disposition": "0.5.4",
1152 | "content-type": "~1.0.4",
1153 | "cookie": "0.5.0",
1154 | "cookie-signature": "1.0.6",
1155 | "debug": "2.6.9",
1156 | "depd": "2.0.0",
1157 | "encodeurl": "~1.0.2",
1158 | "escape-html": "~1.0.3",
1159 | "etag": "~1.8.1",
1160 | "finalhandler": "1.2.0",
1161 | "fresh": "0.5.2",
1162 | "http-errors": "2.0.0",
1163 | "merge-descriptors": "1.0.1",
1164 | "methods": "~1.1.2",
1165 | "on-finished": "2.4.1",
1166 | "parseurl": "~1.3.3",
1167 | "path-to-regexp": "0.1.7",
1168 | "proxy-addr": "~2.0.7",
1169 | "qs": "6.11.0",
1170 | "range-parser": "~1.2.1",
1171 | "safe-buffer": "5.2.1",
1172 | "send": "0.18.0",
1173 | "serve-static": "1.15.0",
1174 | "setprototypeof": "1.2.0",
1175 | "statuses": "2.0.1",
1176 | "type-is": "~1.6.18",
1177 | "utils-merge": "1.0.1",
1178 | "vary": "~1.1.2"
1179 | }
1180 | },
1181 | "finalhandler": {
1182 | "version": "1.2.0",
1183 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1184 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1185 | "requires": {
1186 | "debug": "2.6.9",
1187 | "encodeurl": "~1.0.2",
1188 | "escape-html": "~1.0.3",
1189 | "on-finished": "2.4.1",
1190 | "parseurl": "~1.3.3",
1191 | "statuses": "2.0.1",
1192 | "unpipe": "~1.0.0"
1193 | }
1194 | },
1195 | "form-data": {
1196 | "version": "4.0.0",
1197 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
1198 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
1199 | "requires": {
1200 | "asynckit": "^0.4.0",
1201 | "combined-stream": "^1.0.8",
1202 | "mime-types": "^2.1.12"
1203 | }
1204 | },
1205 | "form-data-encoder": {
1206 | "version": "1.7.2",
1207 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
1208 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
1209 | },
1210 | "formdata-node": {
1211 | "version": "4.4.1",
1212 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
1213 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
1214 | "requires": {
1215 | "node-domexception": "1.0.0",
1216 | "web-streams-polyfill": "4.0.0-beta.3"
1217 | },
1218 | "dependencies": {
1219 | "web-streams-polyfill": {
1220 | "version": "4.0.0-beta.3",
1221 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
1222 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="
1223 | }
1224 | }
1225 | },
1226 | "forwarded": {
1227 | "version": "0.2.0",
1228 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1229 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
1230 | },
1231 | "fresh": {
1232 | "version": "0.5.2",
1233 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1234 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
1235 | },
1236 | "function-bind": {
1237 | "version": "1.1.1",
1238 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1239 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
1240 | },
1241 | "get-intrinsic": {
1242 | "version": "1.1.3",
1243 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
1244 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
1245 | "requires": {
1246 | "function-bind": "^1.1.1",
1247 | "has": "^1.0.3",
1248 | "has-symbols": "^1.0.3"
1249 | }
1250 | },
1251 | "has": {
1252 | "version": "1.0.3",
1253 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1254 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1255 | "requires": {
1256 | "function-bind": "^1.1.1"
1257 | }
1258 | },
1259 | "has-symbols": {
1260 | "version": "1.0.3",
1261 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1262 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
1263 | },
1264 | "http-errors": {
1265 | "version": "2.0.0",
1266 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1267 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1268 | "requires": {
1269 | "depd": "2.0.0",
1270 | "inherits": "2.0.4",
1271 | "setprototypeof": "1.2.0",
1272 | "statuses": "2.0.1",
1273 | "toidentifier": "1.0.1"
1274 | }
1275 | },
1276 | "humanize-ms": {
1277 | "version": "1.2.1",
1278 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
1279 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
1280 | "requires": {
1281 | "ms": "^2.0.0"
1282 | }
1283 | },
1284 | "iconv-lite": {
1285 | "version": "0.4.24",
1286 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1287 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1288 | "requires": {
1289 | "safer-buffer": ">= 2.1.2 < 3"
1290 | }
1291 | },
1292 | "inherits": {
1293 | "version": "2.0.4",
1294 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1295 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1296 | },
1297 | "ipaddr.js": {
1298 | "version": "1.9.1",
1299 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1300 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
1301 | },
1302 | "is-buffer": {
1303 | "version": "1.1.6",
1304 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
1305 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
1306 | },
1307 | "md5": {
1308 | "version": "2.3.0",
1309 | "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
1310 | "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
1311 | "requires": {
1312 | "charenc": "0.0.2",
1313 | "crypt": "0.0.2",
1314 | "is-buffer": "~1.1.6"
1315 | }
1316 | },
1317 | "media-typer": {
1318 | "version": "0.3.0",
1319 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1320 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
1321 | },
1322 | "merge-descriptors": {
1323 | "version": "1.0.1",
1324 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1325 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
1326 | },
1327 | "methods": {
1328 | "version": "1.1.2",
1329 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1330 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
1331 | },
1332 | "mime": {
1333 | "version": "1.6.0",
1334 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1335 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
1336 | },
1337 | "mime-db": {
1338 | "version": "1.52.0",
1339 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1340 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
1341 | },
1342 | "mime-types": {
1343 | "version": "2.1.35",
1344 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1345 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1346 | "requires": {
1347 | "mime-db": "1.52.0"
1348 | }
1349 | },
1350 | "morgan": {
1351 | "version": "1.10.0",
1352 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
1353 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
1354 | "requires": {
1355 | "basic-auth": "~2.0.1",
1356 | "debug": "2.6.9",
1357 | "depd": "~2.0.0",
1358 | "on-finished": "~2.3.0",
1359 | "on-headers": "~1.0.2"
1360 | },
1361 | "dependencies": {
1362 | "on-finished": {
1363 | "version": "2.3.0",
1364 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
1365 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
1366 | "requires": {
1367 | "ee-first": "1.1.1"
1368 | }
1369 | }
1370 | }
1371 | },
1372 | "ms": {
1373 | "version": "2.0.0",
1374 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1375 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1376 | },
1377 | "negotiator": {
1378 | "version": "0.6.3",
1379 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1380 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
1381 | },
1382 | "node-domexception": {
1383 | "version": "1.0.0",
1384 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
1385 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
1386 | },
1387 | "node-fetch": {
1388 | "version": "2.7.0",
1389 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
1390 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
1391 | "requires": {
1392 | "whatwg-url": "^5.0.0"
1393 | }
1394 | },
1395 | "object-assign": {
1396 | "version": "4.1.1",
1397 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1398 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
1399 | },
1400 | "object-inspect": {
1401 | "version": "1.12.2",
1402 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
1403 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
1404 | },
1405 | "on-finished": {
1406 | "version": "2.4.1",
1407 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1408 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1409 | "requires": {
1410 | "ee-first": "1.1.1"
1411 | }
1412 | },
1413 | "on-headers": {
1414 | "version": "1.0.2",
1415 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
1416 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
1417 | },
1418 | "openai": {
1419 | "version": "4.28.4",
1420 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.28.4.tgz",
1421 | "integrity": "sha512-RNIwx4MT/F0zyizGcwS+bXKLzJ8QE9IOyigDG/ttnwB220d58bYjYFp0qjvGwEFBO6+pvFVIDABZPGDl46RFsg==",
1422 | "requires": {
1423 | "@types/node": "^18.11.18",
1424 | "@types/node-fetch": "^2.6.4",
1425 | "abort-controller": "^3.0.0",
1426 | "agentkeepalive": "^4.2.1",
1427 | "digest-fetch": "^1.3.0",
1428 | "form-data-encoder": "1.7.2",
1429 | "formdata-node": "^4.3.2",
1430 | "node-fetch": "^2.6.7",
1431 | "web-streams-polyfill": "^3.2.1"
1432 | }
1433 | },
1434 | "parseurl": {
1435 | "version": "1.3.3",
1436 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1437 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1438 | },
1439 | "path-to-regexp": {
1440 | "version": "0.1.7",
1441 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1442 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1443 | },
1444 | "proxy-addr": {
1445 | "version": "2.0.7",
1446 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1447 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1448 | "requires": {
1449 | "forwarded": "0.2.0",
1450 | "ipaddr.js": "1.9.1"
1451 | }
1452 | },
1453 | "qs": {
1454 | "version": "6.11.0",
1455 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1456 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1457 | "requires": {
1458 | "side-channel": "^1.0.4"
1459 | }
1460 | },
1461 | "range-parser": {
1462 | "version": "1.2.1",
1463 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1464 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
1465 | },
1466 | "raw-body": {
1467 | "version": "2.5.1",
1468 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
1469 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
1470 | "requires": {
1471 | "bytes": "3.1.2",
1472 | "http-errors": "2.0.0",
1473 | "iconv-lite": "0.4.24",
1474 | "unpipe": "1.0.0"
1475 | }
1476 | },
1477 | "safe-buffer": {
1478 | "version": "5.2.1",
1479 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1480 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
1481 | },
1482 | "safer-buffer": {
1483 | "version": "2.1.2",
1484 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1485 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1486 | },
1487 | "send": {
1488 | "version": "0.18.0",
1489 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1490 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1491 | "requires": {
1492 | "debug": "2.6.9",
1493 | "depd": "2.0.0",
1494 | "destroy": "1.2.0",
1495 | "encodeurl": "~1.0.2",
1496 | "escape-html": "~1.0.3",
1497 | "etag": "~1.8.1",
1498 | "fresh": "0.5.2",
1499 | "http-errors": "2.0.0",
1500 | "mime": "1.6.0",
1501 | "ms": "2.1.3",
1502 | "on-finished": "2.4.1",
1503 | "range-parser": "~1.2.1",
1504 | "statuses": "2.0.1"
1505 | },
1506 | "dependencies": {
1507 | "ms": {
1508 | "version": "2.1.3",
1509 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1510 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1511 | }
1512 | }
1513 | },
1514 | "serve-static": {
1515 | "version": "1.15.0",
1516 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1517 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1518 | "requires": {
1519 | "encodeurl": "~1.0.2",
1520 | "escape-html": "~1.0.3",
1521 | "parseurl": "~1.3.3",
1522 | "send": "0.18.0"
1523 | }
1524 | },
1525 | "setprototypeof": {
1526 | "version": "1.2.0",
1527 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1528 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1529 | },
1530 | "side-channel": {
1531 | "version": "1.0.4",
1532 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1533 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1534 | "requires": {
1535 | "call-bind": "^1.0.0",
1536 | "get-intrinsic": "^1.0.2",
1537 | "object-inspect": "^1.9.0"
1538 | }
1539 | },
1540 | "statuses": {
1541 | "version": "2.0.1",
1542 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1543 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
1544 | },
1545 | "toidentifier": {
1546 | "version": "1.0.1",
1547 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1548 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
1549 | },
1550 | "tr46": {
1551 | "version": "0.0.3",
1552 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
1553 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
1554 | },
1555 | "type-is": {
1556 | "version": "1.6.18",
1557 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1558 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1559 | "requires": {
1560 | "media-typer": "0.3.0",
1561 | "mime-types": "~2.1.24"
1562 | }
1563 | },
1564 | "undici-types": {
1565 | "version": "5.26.5",
1566 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
1567 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
1568 | },
1569 | "unpipe": {
1570 | "version": "1.0.0",
1571 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1572 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
1573 | },
1574 | "utils-merge": {
1575 | "version": "1.0.1",
1576 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1577 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
1578 | },
1579 | "vary": {
1580 | "version": "1.1.2",
1581 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1582 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
1583 | },
1584 | "web-streams-polyfill": {
1585 | "version": "3.3.3",
1586 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
1587 | "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="
1588 | },
1589 | "webidl-conversions": {
1590 | "version": "3.0.1",
1591 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
1592 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
1593 | },
1594 | "whatwg-url": {
1595 | "version": "5.0.0",
1596 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
1597 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
1598 | "requires": {
1599 | "tr46": "~0.0.3",
1600 | "webidl-conversions": "^3.0.0"
1601 | }
1602 | }
1603 | }
1604 | }
1605 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clone-chatgpt-server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "Sushant Dhimal",
10 | "license": "ISC",
11 | "dependencies": {
12 | "body-parser": "^1.20.1",
13 | "cors": "^2.8.5",
14 | "dotenv": "^16.0.3",
15 | "express": "^4.18.2",
16 | "morgan": "^1.10.0",
17 | "openai": "^4.28.4"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------