├── .gitignore ├── LICENSE ├── README.md ├── client ├── package-lock.json ├── package.json ├── public │ ├── icon.png │ └── index.html └── src │ ├── index.css │ ├── index.js │ ├── pages │ ├── MainPage.js │ ├── PageNotFound.js │ ├── RoadMap.js │ ├── components │ │ ├── MapPoint.js │ │ └── SideBar.js │ └── styles │ │ ├── MainPage.css │ │ ├── PageNotFound.css │ │ └── RoadMap.css │ └── x-mark.png └── server ├── index.js ├── package-lock.json ├── package.json └── weberror.js /.gitignore: -------------------------------------------------------------------------------- 1 | client/node_modules 2 | server/node_modules 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 octo8 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # RoadAI 3 | 4 | AI powered web-application for generating roadmaps. 5 | 6 | # DEMO 7 | https://roadai.vercel.app/ 8 | 9 | # Run locally 10 | 11 | Install packages 12 | 13 | ``` cd ./client && npm install``` 14 | 15 | ``` cd ./server && npm install``` 16 | 17 | ### Run client 18 | 19 | ``` cd ./client && npm run ``` 20 | 21 | ### Run server 22 | 23 | Insert your mongodb configuration to `````` 24 | 25 | ``` cd ./server && node ./index.js``` 26 | 27 | 28 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@fortawesome/react-fontawesome": "^0.2.0", 7 | "@testing-library/jest-dom": "^5.17.0", 8 | "@testing-library/react": "^13.4.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "geist": "^1.3.0", 11 | "react": "^18.3.0", 12 | "react-dom": "^18.3.0", 13 | "react-router-dom": "^6.23.0", 14 | "react-scripts": "5.0.1", 15 | "react-toastify": "^10.0.5", 16 | "react-xarrows": "^2.0.2", 17 | "web-vitals": "^2.1.4" 18 | }, 19 | "scripts": { 20 | "start": "react-scripts start", 21 | "build": "react-scripts build", 22 | "test": "react-scripts test", 23 | "eject": "react-scripts eject" 24 | }, 25 | "eslintConfig": { 26 | "extends": [ 27 | "react-app", 28 | "react-app/jest" 29 | ] 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "options": { 44 | "proxy": "http://localhost:3001" 45 | }, 46 | "devDependencies": { 47 | "gh-pages": "^6.1.1" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /client/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/octo8eight/roadai-src/7ed603c8799fbff9bf0b33e33b0d4571d4bc29a6/client/public/icon.png -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Road.AI 19 | 20 | 21 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Inter", 3 | sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | background: #111113; 7 | min-height: 100vh; 8 | max-height: 100vh; 9 | width: 100%; 10 | padding: 0; 11 | margin: 0; 12 | background-image: radial-gradient(circle, #19191B 2px, #111113 2px); 13 | background-size: 3em 3em; 14 | background-position: center center; 15 | } 16 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import MainPage from './pages/MainPage'; 5 | import RoadMap from './pages/RoadMap'; 6 | import PageNotFound from './pages/PageNotFound'; 7 | import { BrowserRouter, Routes, Route } from "react-router-dom"; 8 | 9 | const root = ReactDOM.createRoot(document.getElementById('root')); 10 | root.render( 11 | 12 | 13 | } /> 14 | } /> 15 | }/> 16 | 17 | 18 | ); -------------------------------------------------------------------------------- /client/src/pages/MainPage.js: -------------------------------------------------------------------------------- 1 | import "./styles/MainPage.css"; 2 | import { React, useEffect, useState } from "react"; 3 | import { ToastContainer, toast, Bounce } from "react-toastify"; 4 | import "react-toastify/dist/ReactToastify.css"; 5 | 6 | function MainPage() { 7 | const [openAIKey, setOpenAIKey] = useState(""); 8 | const [prompt, setPrompt] = useState(""); 9 | const [answer, setAnswer] = useState(null); 10 | 11 | // Sending data to server 12 | const callBackAPI = async () => { 13 | toast.info("Generating roadmap.", { theme: "dark" }); 14 | const response = await fetch("http://localhost:3001/", { 15 | method: "POST", 16 | headers: { 17 | "Content-Type": "application/json", 18 | }, 19 | body: JSON.stringify({ openai_key: openAIKey, prompt: prompt }), 20 | }); 21 | const body = await response.json(); 22 | 23 | // Error handling 24 | if (response.status !== 200) { 25 | toast.error(`${body.msg}`, { theme: "dark" }); 26 | } else if (response.status === 200) { 27 | setAnswer(`${body.id}`); 28 | } 29 | }; 30 | 31 | useEffect(() => {}, []); 32 | 33 | // Button handle 34 | const submitHandle = async (e) => { 35 | e.preventDefault(); 36 | console.log(openAIKey, prompt); 37 | await callBackAPI(); 38 | }; 39 | 40 | return ( 41 |
42 |
43 |
44 |

Road.AI

45 |
46 |
47 | setOpenAIKey(e.target.value)} 52 | /> 53 |
54 |
55 | setPrompt(e.target.value)} 60 | /> 61 |
62 |
63 | 66 |
67 | {answer ? ( 68 | Roadmap 69 | ) : null} 70 |
71 | 72 |
73 | ); 74 | } 75 | 76 | export default MainPage; 77 | -------------------------------------------------------------------------------- /client/src/pages/PageNotFound.js: -------------------------------------------------------------------------------- 1 | import {React} from "react"; 2 | import "./styles/PageNotFound.css" 3 | function PageNotFound() { 4 | return( 5 |
6 |

404 Error. Page not found.

7 |
8 | ); 9 | } 10 | 11 | export default PageNotFound -------------------------------------------------------------------------------- /client/src/pages/RoadMap.js: -------------------------------------------------------------------------------- 1 | import { React, useEffect, useState } from "react"; 2 | import { useParams } from "react-router-dom"; 3 | import "./styles/RoadMap.css"; 4 | import MapPoint from "./components/MapPoint"; 5 | import { useNavigate } from "react-router-dom"; 6 | 7 | function RoadMap() { 8 | const id = useParams().mapId; 9 | const [mapData, setMapData] = useState(null); 10 | const redirect = useNavigate(); 11 | 12 | async function fetchData(mapId) { 13 | await fetch(`http://localhost:3001/map/${mapId}`, { 14 | method: "GET", 15 | }) 16 | .then(async (response) => { 17 | const data = await response.json(); 18 | const parsedData = JSON.parse(data.map.data); 19 | setMapData(parsedData); 20 | }) 21 | .catch(() => { 22 | redirect("/404"); 23 | }); 24 | } 25 | 26 | useEffect(() => { 27 | fetchData(id); 28 | }, [id]); 29 | 30 | return ( 31 |
32 | {mapData ? :

Loading...

} 33 |
34 | ); 35 | } 36 | 37 | export default RoadMap; 38 | -------------------------------------------------------------------------------- /client/src/pages/components/MapPoint.js: -------------------------------------------------------------------------------- 1 | import { React, useEffect, useState } from "react"; 2 | import Xarrow from "react-xarrows"; 3 | import Sidebar from "./SideBar"; 4 | 5 | function MapPoint(props) { 6 | const data = props.data.roadmap; 7 | 8 | const [mapPoints, setMapPoints] = useState([]); 9 | const [showSidebar, setShowSidebar] = useState(false); 10 | const [currentPoint, setCurrentPoint] = useState({ children: [] }); 11 | 12 | function toggleSidebar() { 13 | setShowSidebar(!showSidebar); 14 | } 15 | 16 | function handleOpenSideBar(e, data) { 17 | e.preventDefault(); 18 | if (currentPoint === data) { 19 | toggleSidebar(); 20 | } else { 21 | setCurrentPoint(data); 22 | setShowSidebar(true); 23 | } 24 | } 25 | 26 | useEffect(() => { 27 | console.log(data); 28 | const points = []; 29 | Object.keys(data).forEach((key) => { 30 | points.push(data[key].name); 31 | }); 32 | setMapPoints(points); 33 | }, [data]); 34 | return ( 35 |
36 | {/*
37 |

Arrays and objects

38 |
*/} 39 | 40 | {Object.keys(data).map((key) => { 41 | return ( 42 |
{ 47 | handleOpenSideBar(e, data[key]); 48 | }} 49 | > 50 |

{data[key].name}

51 |
52 | ); 53 | })} 54 | {mapPoints.map((point, pointIndex) => { 55 | if (mapPoints.includes(mapPoints[pointIndex + 1])) { 56 | return ( 57 | 63 | ); 64 | } 65 | })} 66 | 71 |
72 | ); 73 | } 74 | 75 | export default MapPoint; 76 | -------------------------------------------------------------------------------- /client/src/pages/components/SideBar.js: -------------------------------------------------------------------------------- 1 | import { React, useState, useEffect } from "react"; 2 | 3 | function Sidebar(props) { 4 | const [showSidebar, setShowSidebar] = useState(false); 5 | function toggleSidebar(e) { 6 | e.preventDefault(); 7 | setShowSidebar(!showSidebar); 8 | props.parentToggle(); 9 | } 10 | useEffect(() => { 11 | setShowSidebar(props.show); 12 | }, [props.show]); 13 | return ( 14 |
15 |
16 |
toggleSidebar(e)}> 17 | 24 | 25 | 26 |
27 | 28 |
29 |

{props.data.name}

30 |

{props.data.description}

31 |

Additional steps:

32 | {props.data.children.map((child) => { 33 | return ( 34 | <> 35 |
36 | {child.name} 37 |

{child.description}

38 |
39 | 40 | ); 41 | })} 42 |
43 |
44 |
45 | ); 46 | } 47 | 48 | export default Sidebar; 49 | -------------------------------------------------------------------------------- /client/src/pages/styles/MainPage.css: -------------------------------------------------------------------------------- 1 | .mainContainer { 2 | margin: auto; 3 | } 4 | 5 | .MainPage { 6 | display: flex; 7 | align-items: center; 8 | height: 100vh; 9 | } 10 | 11 | .mainText { 12 | margin: auto; 13 | color: white; 14 | width: fit-content; 15 | height: fit-content; 16 | text-shadow: 0px 0px 87px rgba(255, 255, 255, 1); 17 | } 18 | .openaikey { 19 | width: fit-content; 20 | height: fit-content; 21 | margin: auto; 22 | } 23 | .openaikey_input { 24 | color: black; 25 | width: 100%; 26 | padding: 12px 20px; 27 | margin: 8px 0; 28 | box-sizing: border-box; 29 | border: 2px solid #393A40; 30 | border-radius: 30px; 31 | transition: padding 0.25s; 32 | outline: none; 33 | box-shadow: 0px 0px 112px rgba(255, 255, 255, 1); 34 | } 35 | 36 | .openaikey_input:hover { 37 | padding: 15px 23px; 38 | transition: all 0.25s; 39 | } 40 | 41 | .openaikey_input:focus { 42 | border-color: #405EB2; 43 | padding: 15px 23px; 44 | } 45 | 46 | .prompt_input { 47 | color: black; 48 | width: 100%; 49 | padding: 12px 20px; 50 | margin: 8px 0; 51 | box-sizing: border-box; 52 | border: 2px solid #393A40; 53 | border-radius: 30px; 54 | transition: padding 0.25s; 55 | outline: none; 56 | box-shadow: 0px 0px 112px rgba(255, 255, 255, 1); 57 | } 58 | 59 | .prompt_input:hover { 60 | padding: 15px 23px; 61 | transition: all 0.25s; 62 | } 63 | 64 | .prompt_input:focus { 65 | border-color: #405EB2; 66 | padding: 15px 23px; 67 | } 68 | 69 | .submitButton { 70 | margin: auto; 71 | width: fit-content; 72 | height: fit-content; 73 | } 74 | 75 | .submitButton_button { 76 | background-color: #3D63DD; 77 | border-radius: 30px; 78 | border-width: 0; 79 | color: white; 80 | font-family: 'Inter', sans-serif; 81 | font-weight: bolder; 82 | cursor: pointer; 83 | display: inline-block; 84 | margin: 0; 85 | padding: 10px 12px; 86 | text-align: center; 87 | transition: all 200ms; 88 | vertical-align: baseline; 89 | white-space: nowrap; 90 | user-select: none; 91 | -webkit-user-select: none; 92 | touch-action: manipulation; 93 | } 94 | 95 | .submitButton_button:hover { 96 | padding: 12px 14px; 97 | background-color: #3455c2; 98 | transition: all 200ms; 99 | } 100 | 101 | .submitButton_button:active { 102 | background-color: #253d8b; 103 | transition: all 200ms; 104 | } 105 | 106 | .responseText { 107 | color: white; 108 | } -------------------------------------------------------------------------------- /client/src/pages/styles/PageNotFound.css: -------------------------------------------------------------------------------- 1 | .PageNotFound { 2 | width: fit-content; 3 | height: fit-content; 4 | position: absolute; 5 | left: 0; 6 | right: 0; 7 | top: 0; 8 | bottom: 0; 9 | margin: auto; 10 | 11 | } 12 | .text { 13 | text-shadow: 0px 0px 87px rgba(255, 255, 255, 1); 14 | } -------------------------------------------------------------------------------- /client/src/pages/styles/RoadMap.css: -------------------------------------------------------------------------------- 1 | *{ 2 | color: white; 3 | } 4 | 5 | .RoadMap{ 6 | display: flex; 7 | width: fit-content; 8 | height: fit-content; 9 | margin: auto; 10 | padding-top: 50px; 11 | } 12 | 13 | .MapPoint { 14 | background: #93B4FF; 15 | width: fit-content; 16 | padding: 4px; 17 | border-radius: 30px; 18 | border: #687fb6 solid 3px; 19 | margin: auto; 20 | margin-bottom: 75px; 21 | transition: all 200ms; 22 | } 23 | .MapPointChild { 24 | background: #93B4FF; 25 | width: fit-content; 26 | padding: 4px; 27 | border-radius: 30px; 28 | border: #687fb6 solid 3px; 29 | margin: auto; 30 | margin-bottom: 75px; 31 | transition: all 200ms; 32 | } 33 | 34 | .MapPoint:hover { 35 | background-color: #7690cc; 36 | border-color: #4b5c83; 37 | transition: all 200ms; 38 | } 39 | 40 | .Sidebar.active { 41 | right: 0; 42 | transition: 500ms; 43 | } 44 | 45 | .Sidebar { 46 | right: -100%; 47 | position: fixed; 48 | top: 0; 49 | height: 100%; 50 | width: 25%; 51 | background-color: #111725; 52 | transition: 800ms; 53 | } 54 | 55 | .closeButton { 56 | display: flex; 57 | align-items: center; 58 | width: 35px; 59 | height: 35px; 60 | background-color: #3F5CB0; 61 | border-radius: 100%; 62 | margin-top: 5px; 63 | margin-left: 10px; 64 | transition: all 200ms; 65 | 66 | } 67 | 68 | .closeButton:hover{ 69 | background-color: rgb(37, 61, 139); 70 | transition: all 200ms; 71 | } 72 | 73 | #closeImg { 74 | fill: white; 75 | margin: auto; 76 | } 77 | 78 | 79 | .pointContent { 80 | width: fit-content; 81 | margin-left: 10px; 82 | overflow: auto; 83 | } -------------------------------------------------------------------------------- /client/src/x-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/octo8eight/roadai-src/7ed603c8799fbff9bf0b33e33b0d4571d4bc29a6/client/src/x-mark.png -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const { MongoClient, ServerApiVersion, ObjectId } = require("mongodb"); 4 | const OpenAI = require("openai"); 5 | const uri = ""; 6 | const client = new MongoClient(uri, { 7 | serverApi: { 8 | version: ServerApiVersion.v1, 9 | strict: true, 10 | deprecationErrors: true, 11 | }, 12 | }); 13 | const { WebError } = require("./weberror.js"); 14 | 15 | // Adding generated roadmap to database 16 | async function sendRoadMap(roadmapObject) { 17 | await client.connect(); 18 | const db = client.db("roadai"); 19 | const roadmaps = db.collection("roadmaps"); 20 | const result = await roadmaps.insertOne({ 21 | data: JSON.stringify(roadmapObject), 22 | }); 23 | 24 | await client.close(); 25 | return result.insertedId.toString(); 26 | } 27 | 28 | //Generating roadmap 29 | async function generateRoadMap(apiKey, prompt) { 30 | const openai = new OpenAI({ apiKey: apiKey }); 31 | const completion = await openai.chat.completions.create({ 32 | messages: [ 33 | { 34 | role: "system", 35 | content: `Your response must be only json file. Genereate as much as possible. Below will be instruction *{here will be your genertaed text}. You need to generate roadmap for: ${prompt}. JSON structure (every object and item must be strictly placed): 36 | {"roadmap": { 37 | *{point you wil generate}: {name: "*{you need to generate short name}", description: "*{you need to generate description}", children: [*{the same structure if it has additional points to get on}]} 38 | *{generate another points like upper one} 39 | }}`, 40 | }, 41 | ], 42 | model: "gpt-3.5-turbo", 43 | }); 44 | const answer = JSON.parse(completion.choices[0].message.content); 45 | return await sendRoadMap(answer); 46 | } 47 | 48 | // Fetching roadmap for database 49 | async function getMapData(mapId) { 50 | await client.connect(); 51 | const db = client.db("roadai"); 52 | const roadmaps = db.collection("roadmaps"); 53 | const mapData = await roadmaps.findOne({ _id: new ObjectId(mapId) }); 54 | 55 | await client.close(); 56 | 57 | return mapData; 58 | } 59 | 60 | app.listen(3001, () => { 61 | console.log("Example app listening on port 3001!"); 62 | }); 63 | 64 | app.use((req, res, next) => { 65 | res.setHeader("Access-Control-Allow-Origin", "*"); 66 | res.setHeader( 67 | "Access-Control-Allow-Methods", 68 | "GET, POST, OPTIONS, PUT, PATCH, DELETE", 69 | ); 70 | res.setHeader( 71 | "Access-Control-Allow-Headers", 72 | "X-Requested-With,Content-Type,Authorization", 73 | ); 74 | res.setHeader("Access-Control-Allow-Credentials", true); 75 | next(); 76 | }); 77 | 78 | app.use(express.json()); 79 | 80 | app.post("/", async (req, res, next) => { 81 | let body = req.body; 82 | await generateRoadMap(body.openai_key, body.prompt) 83 | .then((roadmap) => { 84 | res.status(200).send({ 85 | id: roadmap, 86 | }); 87 | }) 88 | .catch((e) => { 89 | if (e instanceof OpenAI.AuthenticationError) { 90 | next(new WebError(401, "Incorrect API key!")); 91 | } else { 92 | next(new WebError(0, "Unknown error.")); 93 | } 94 | }); 95 | }); 96 | 97 | app.get("/map/:mapId", async (req, res, next) => { 98 | const mapId = req.params.mapId; 99 | await getMapData(mapId) 100 | .then((mapdata) => { 101 | res.status(200).send({ 102 | map: mapdata, 103 | }); 104 | }) 105 | .catch((err) => { 106 | console.log(err); 107 | next(new WebError(404, "Roadmap not found.")); 108 | }); 109 | }); 110 | 111 | //Error handling 112 | app.use((err, req, res, next) => { 113 | res.status(err.status).send({ msg: err.message }); 114 | }); 115 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "server", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.19.2", 13 | "mongodb": "^6.5.0", 14 | "openai": "^4.38.5" 15 | } 16 | }, 17 | "node_modules/@mongodb-js/saslprep": { 18 | "version": "1.1.5", 19 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", 20 | "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", 21 | "dependencies": { 22 | "sparse-bitfield": "^3.0.3" 23 | } 24 | }, 25 | "node_modules/@types/node": { 26 | "version": "18.19.31", 27 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.31.tgz", 28 | "integrity": "sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==", 29 | "dependencies": { 30 | "undici-types": "~5.26.4" 31 | } 32 | }, 33 | "node_modules/@types/node-fetch": { 34 | "version": "2.6.11", 35 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", 36 | "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", 37 | "dependencies": { 38 | "@types/node": "*", 39 | "form-data": "^4.0.0" 40 | } 41 | }, 42 | "node_modules/@types/webidl-conversions": { 43 | "version": "7.0.3", 44 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 45 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 46 | }, 47 | "node_modules/@types/whatwg-url": { 48 | "version": "11.0.4", 49 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", 50 | "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", 51 | "dependencies": { 52 | "@types/webidl-conversions": "*" 53 | } 54 | }, 55 | "node_modules/abort-controller": { 56 | "version": "3.0.0", 57 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 58 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 59 | "dependencies": { 60 | "event-target-shim": "^5.0.0" 61 | }, 62 | "engines": { 63 | "node": ">=6.5" 64 | } 65 | }, 66 | "node_modules/accepts": { 67 | "version": "1.3.8", 68 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 69 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 70 | "dependencies": { 71 | "mime-types": "~2.1.34", 72 | "negotiator": "0.6.3" 73 | }, 74 | "engines": { 75 | "node": ">= 0.6" 76 | } 77 | }, 78 | "node_modules/agentkeepalive": { 79 | "version": "4.5.0", 80 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", 81 | "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", 82 | "dependencies": { 83 | "humanize-ms": "^1.2.1" 84 | }, 85 | "engines": { 86 | "node": ">= 8.0.0" 87 | } 88 | }, 89 | "node_modules/array-flatten": { 90 | "version": "1.1.1", 91 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 92 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 93 | }, 94 | "node_modules/asynckit": { 95 | "version": "0.4.0", 96 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 97 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 98 | }, 99 | "node_modules/body-parser": { 100 | "version": "1.20.2", 101 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", 102 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", 103 | "dependencies": { 104 | "bytes": "3.1.2", 105 | "content-type": "~1.0.5", 106 | "debug": "2.6.9", 107 | "depd": "2.0.0", 108 | "destroy": "1.2.0", 109 | "http-errors": "2.0.0", 110 | "iconv-lite": "0.4.24", 111 | "on-finished": "2.4.1", 112 | "qs": "6.11.0", 113 | "raw-body": "2.5.2", 114 | "type-is": "~1.6.18", 115 | "unpipe": "1.0.0" 116 | }, 117 | "engines": { 118 | "node": ">= 0.8", 119 | "npm": "1.2.8000 || >= 1.4.16" 120 | } 121 | }, 122 | "node_modules/bson": { 123 | "version": "6.6.0", 124 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", 125 | "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", 126 | "engines": { 127 | "node": ">=16.20.1" 128 | } 129 | }, 130 | "node_modules/bytes": { 131 | "version": "3.1.2", 132 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 133 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 134 | "engines": { 135 | "node": ">= 0.8" 136 | } 137 | }, 138 | "node_modules/call-bind": { 139 | "version": "1.0.7", 140 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 141 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 142 | "dependencies": { 143 | "es-define-property": "^1.0.0", 144 | "es-errors": "^1.3.0", 145 | "function-bind": "^1.1.2", 146 | "get-intrinsic": "^1.2.4", 147 | "set-function-length": "^1.2.1" 148 | }, 149 | "engines": { 150 | "node": ">= 0.4" 151 | }, 152 | "funding": { 153 | "url": "https://github.com/sponsors/ljharb" 154 | } 155 | }, 156 | "node_modules/combined-stream": { 157 | "version": "1.0.8", 158 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 159 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 160 | "dependencies": { 161 | "delayed-stream": "~1.0.0" 162 | }, 163 | "engines": { 164 | "node": ">= 0.8" 165 | } 166 | }, 167 | "node_modules/content-disposition": { 168 | "version": "0.5.4", 169 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 170 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 171 | "dependencies": { 172 | "safe-buffer": "5.2.1" 173 | }, 174 | "engines": { 175 | "node": ">= 0.6" 176 | } 177 | }, 178 | "node_modules/content-type": { 179 | "version": "1.0.5", 180 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 181 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 182 | "engines": { 183 | "node": ">= 0.6" 184 | } 185 | }, 186 | "node_modules/cookie": { 187 | "version": "0.6.0", 188 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", 189 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", 190 | "engines": { 191 | "node": ">= 0.6" 192 | } 193 | }, 194 | "node_modules/cookie-signature": { 195 | "version": "1.0.6", 196 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 197 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 198 | }, 199 | "node_modules/debug": { 200 | "version": "2.6.9", 201 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 202 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 203 | "dependencies": { 204 | "ms": "2.0.0" 205 | } 206 | }, 207 | "node_modules/define-data-property": { 208 | "version": "1.1.4", 209 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 210 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 211 | "dependencies": { 212 | "es-define-property": "^1.0.0", 213 | "es-errors": "^1.3.0", 214 | "gopd": "^1.0.1" 215 | }, 216 | "engines": { 217 | "node": ">= 0.4" 218 | }, 219 | "funding": { 220 | "url": "https://github.com/sponsors/ljharb" 221 | } 222 | }, 223 | "node_modules/delayed-stream": { 224 | "version": "1.0.0", 225 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 226 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 227 | "engines": { 228 | "node": ">=0.4.0" 229 | } 230 | }, 231 | "node_modules/depd": { 232 | "version": "2.0.0", 233 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 234 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 235 | "engines": { 236 | "node": ">= 0.8" 237 | } 238 | }, 239 | "node_modules/destroy": { 240 | "version": "1.2.0", 241 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 242 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 243 | "engines": { 244 | "node": ">= 0.8", 245 | "npm": "1.2.8000 || >= 1.4.16" 246 | } 247 | }, 248 | "node_modules/ee-first": { 249 | "version": "1.1.1", 250 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 251 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 252 | }, 253 | "node_modules/encodeurl": { 254 | "version": "1.0.2", 255 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 256 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 257 | "engines": { 258 | "node": ">= 0.8" 259 | } 260 | }, 261 | "node_modules/es-define-property": { 262 | "version": "1.0.0", 263 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 264 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 265 | "dependencies": { 266 | "get-intrinsic": "^1.2.4" 267 | }, 268 | "engines": { 269 | "node": ">= 0.4" 270 | } 271 | }, 272 | "node_modules/es-errors": { 273 | "version": "1.3.0", 274 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 275 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 276 | "engines": { 277 | "node": ">= 0.4" 278 | } 279 | }, 280 | "node_modules/escape-html": { 281 | "version": "1.0.3", 282 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 283 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 284 | }, 285 | "node_modules/etag": { 286 | "version": "1.8.1", 287 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 288 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 289 | "engines": { 290 | "node": ">= 0.6" 291 | } 292 | }, 293 | "node_modules/event-target-shim": { 294 | "version": "5.0.1", 295 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 296 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 297 | "engines": { 298 | "node": ">=6" 299 | } 300 | }, 301 | "node_modules/express": { 302 | "version": "4.19.2", 303 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", 304 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", 305 | "dependencies": { 306 | "accepts": "~1.3.8", 307 | "array-flatten": "1.1.1", 308 | "body-parser": "1.20.2", 309 | "content-disposition": "0.5.4", 310 | "content-type": "~1.0.4", 311 | "cookie": "0.6.0", 312 | "cookie-signature": "1.0.6", 313 | "debug": "2.6.9", 314 | "depd": "2.0.0", 315 | "encodeurl": "~1.0.2", 316 | "escape-html": "~1.0.3", 317 | "etag": "~1.8.1", 318 | "finalhandler": "1.2.0", 319 | "fresh": "0.5.2", 320 | "http-errors": "2.0.0", 321 | "merge-descriptors": "1.0.1", 322 | "methods": "~1.1.2", 323 | "on-finished": "2.4.1", 324 | "parseurl": "~1.3.3", 325 | "path-to-regexp": "0.1.7", 326 | "proxy-addr": "~2.0.7", 327 | "qs": "6.11.0", 328 | "range-parser": "~1.2.1", 329 | "safe-buffer": "5.2.1", 330 | "send": "0.18.0", 331 | "serve-static": "1.15.0", 332 | "setprototypeof": "1.2.0", 333 | "statuses": "2.0.1", 334 | "type-is": "~1.6.18", 335 | "utils-merge": "1.0.1", 336 | "vary": "~1.1.2" 337 | }, 338 | "engines": { 339 | "node": ">= 0.10.0" 340 | } 341 | }, 342 | "node_modules/finalhandler": { 343 | "version": "1.2.0", 344 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 345 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 346 | "dependencies": { 347 | "debug": "2.6.9", 348 | "encodeurl": "~1.0.2", 349 | "escape-html": "~1.0.3", 350 | "on-finished": "2.4.1", 351 | "parseurl": "~1.3.3", 352 | "statuses": "2.0.1", 353 | "unpipe": "~1.0.0" 354 | }, 355 | "engines": { 356 | "node": ">= 0.8" 357 | } 358 | }, 359 | "node_modules/form-data": { 360 | "version": "4.0.0", 361 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 362 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 363 | "dependencies": { 364 | "asynckit": "^0.4.0", 365 | "combined-stream": "^1.0.8", 366 | "mime-types": "^2.1.12" 367 | }, 368 | "engines": { 369 | "node": ">= 6" 370 | } 371 | }, 372 | "node_modules/form-data-encoder": { 373 | "version": "1.7.2", 374 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 375 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" 376 | }, 377 | "node_modules/formdata-node": { 378 | "version": "4.4.1", 379 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 380 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 381 | "dependencies": { 382 | "node-domexception": "1.0.0", 383 | "web-streams-polyfill": "4.0.0-beta.3" 384 | }, 385 | "engines": { 386 | "node": ">= 12.20" 387 | } 388 | }, 389 | "node_modules/formdata-node/node_modules/web-streams-polyfill": { 390 | "version": "4.0.0-beta.3", 391 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 392 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", 393 | "engines": { 394 | "node": ">= 14" 395 | } 396 | }, 397 | "node_modules/forwarded": { 398 | "version": "0.2.0", 399 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 400 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 401 | "engines": { 402 | "node": ">= 0.6" 403 | } 404 | }, 405 | "node_modules/fresh": { 406 | "version": "0.5.2", 407 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 408 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 409 | "engines": { 410 | "node": ">= 0.6" 411 | } 412 | }, 413 | "node_modules/function-bind": { 414 | "version": "1.1.2", 415 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 416 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 417 | "funding": { 418 | "url": "https://github.com/sponsors/ljharb" 419 | } 420 | }, 421 | "node_modules/get-intrinsic": { 422 | "version": "1.2.4", 423 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 424 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 425 | "dependencies": { 426 | "es-errors": "^1.3.0", 427 | "function-bind": "^1.1.2", 428 | "has-proto": "^1.0.1", 429 | "has-symbols": "^1.0.3", 430 | "hasown": "^2.0.0" 431 | }, 432 | "engines": { 433 | "node": ">= 0.4" 434 | }, 435 | "funding": { 436 | "url": "https://github.com/sponsors/ljharb" 437 | } 438 | }, 439 | "node_modules/gopd": { 440 | "version": "1.0.1", 441 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 442 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 443 | "dependencies": { 444 | "get-intrinsic": "^1.1.3" 445 | }, 446 | "funding": { 447 | "url": "https://github.com/sponsors/ljharb" 448 | } 449 | }, 450 | "node_modules/has-property-descriptors": { 451 | "version": "1.0.2", 452 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 453 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 454 | "dependencies": { 455 | "es-define-property": "^1.0.0" 456 | }, 457 | "funding": { 458 | "url": "https://github.com/sponsors/ljharb" 459 | } 460 | }, 461 | "node_modules/has-proto": { 462 | "version": "1.0.3", 463 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 464 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 465 | "engines": { 466 | "node": ">= 0.4" 467 | }, 468 | "funding": { 469 | "url": "https://github.com/sponsors/ljharb" 470 | } 471 | }, 472 | "node_modules/has-symbols": { 473 | "version": "1.0.3", 474 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 475 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 476 | "engines": { 477 | "node": ">= 0.4" 478 | }, 479 | "funding": { 480 | "url": "https://github.com/sponsors/ljharb" 481 | } 482 | }, 483 | "node_modules/hasown": { 484 | "version": "2.0.2", 485 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 486 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 487 | "dependencies": { 488 | "function-bind": "^1.1.2" 489 | }, 490 | "engines": { 491 | "node": ">= 0.4" 492 | } 493 | }, 494 | "node_modules/http-errors": { 495 | "version": "2.0.0", 496 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 497 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 498 | "dependencies": { 499 | "depd": "2.0.0", 500 | "inherits": "2.0.4", 501 | "setprototypeof": "1.2.0", 502 | "statuses": "2.0.1", 503 | "toidentifier": "1.0.1" 504 | }, 505 | "engines": { 506 | "node": ">= 0.8" 507 | } 508 | }, 509 | "node_modules/humanize-ms": { 510 | "version": "1.2.1", 511 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 512 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 513 | "dependencies": { 514 | "ms": "^2.0.0" 515 | } 516 | }, 517 | "node_modules/iconv-lite": { 518 | "version": "0.4.24", 519 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 520 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 521 | "dependencies": { 522 | "safer-buffer": ">= 2.1.2 < 3" 523 | }, 524 | "engines": { 525 | "node": ">=0.10.0" 526 | } 527 | }, 528 | "node_modules/inherits": { 529 | "version": "2.0.4", 530 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 531 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 532 | }, 533 | "node_modules/ipaddr.js": { 534 | "version": "1.9.1", 535 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 536 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 537 | "engines": { 538 | "node": ">= 0.10" 539 | } 540 | }, 541 | "node_modules/media-typer": { 542 | "version": "0.3.0", 543 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 544 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 545 | "engines": { 546 | "node": ">= 0.6" 547 | } 548 | }, 549 | "node_modules/memory-pager": { 550 | "version": "1.5.0", 551 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 552 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 553 | }, 554 | "node_modules/merge-descriptors": { 555 | "version": "1.0.1", 556 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 557 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 558 | }, 559 | "node_modules/methods": { 560 | "version": "1.1.2", 561 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 562 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 563 | "engines": { 564 | "node": ">= 0.6" 565 | } 566 | }, 567 | "node_modules/mime": { 568 | "version": "1.6.0", 569 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 570 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 571 | "bin": { 572 | "mime": "cli.js" 573 | }, 574 | "engines": { 575 | "node": ">=4" 576 | } 577 | }, 578 | "node_modules/mime-db": { 579 | "version": "1.52.0", 580 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 581 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 582 | "engines": { 583 | "node": ">= 0.6" 584 | } 585 | }, 586 | "node_modules/mime-types": { 587 | "version": "2.1.35", 588 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 589 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 590 | "dependencies": { 591 | "mime-db": "1.52.0" 592 | }, 593 | "engines": { 594 | "node": ">= 0.6" 595 | } 596 | }, 597 | "node_modules/mongodb": { 598 | "version": "6.5.0", 599 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", 600 | "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", 601 | "dependencies": { 602 | "@mongodb-js/saslprep": "^1.1.5", 603 | "bson": "^6.4.0", 604 | "mongodb-connection-string-url": "^3.0.0" 605 | }, 606 | "engines": { 607 | "node": ">=16.20.1" 608 | }, 609 | "peerDependencies": { 610 | "@aws-sdk/credential-providers": "^3.188.0", 611 | "@mongodb-js/zstd": "^1.1.0", 612 | "gcp-metadata": "^5.2.0", 613 | "kerberos": "^2.0.1", 614 | "mongodb-client-encryption": ">=6.0.0 <7", 615 | "snappy": "^7.2.2", 616 | "socks": "^2.7.1" 617 | }, 618 | "peerDependenciesMeta": { 619 | "@aws-sdk/credential-providers": { 620 | "optional": true 621 | }, 622 | "@mongodb-js/zstd": { 623 | "optional": true 624 | }, 625 | "gcp-metadata": { 626 | "optional": true 627 | }, 628 | "kerberos": { 629 | "optional": true 630 | }, 631 | "mongodb-client-encryption": { 632 | "optional": true 633 | }, 634 | "snappy": { 635 | "optional": true 636 | }, 637 | "socks": { 638 | "optional": true 639 | } 640 | } 641 | }, 642 | "node_modules/mongodb-connection-string-url": { 643 | "version": "3.0.0", 644 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", 645 | "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", 646 | "dependencies": { 647 | "@types/whatwg-url": "^11.0.2", 648 | "whatwg-url": "^13.0.0" 649 | } 650 | }, 651 | "node_modules/mongodb-connection-string-url/node_modules/tr46": { 652 | "version": "4.1.1", 653 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 654 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 655 | "dependencies": { 656 | "punycode": "^2.3.0" 657 | }, 658 | "engines": { 659 | "node": ">=14" 660 | } 661 | }, 662 | "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { 663 | "version": "7.0.0", 664 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 665 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 666 | "engines": { 667 | "node": ">=12" 668 | } 669 | }, 670 | "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { 671 | "version": "13.0.0", 672 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 673 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 674 | "dependencies": { 675 | "tr46": "^4.1.1", 676 | "webidl-conversions": "^7.0.0" 677 | }, 678 | "engines": { 679 | "node": ">=16" 680 | } 681 | }, 682 | "node_modules/ms": { 683 | "version": "2.0.0", 684 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 685 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 686 | }, 687 | "node_modules/negotiator": { 688 | "version": "0.6.3", 689 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 690 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 691 | "engines": { 692 | "node": ">= 0.6" 693 | } 694 | }, 695 | "node_modules/node-domexception": { 696 | "version": "1.0.0", 697 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 698 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 699 | "funding": [ 700 | { 701 | "type": "github", 702 | "url": "https://github.com/sponsors/jimmywarting" 703 | }, 704 | { 705 | "type": "github", 706 | "url": "https://paypal.me/jimmywarting" 707 | } 708 | ], 709 | "engines": { 710 | "node": ">=10.5.0" 711 | } 712 | }, 713 | "node_modules/node-fetch": { 714 | "version": "2.7.0", 715 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 716 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 717 | "dependencies": { 718 | "whatwg-url": "^5.0.0" 719 | }, 720 | "engines": { 721 | "node": "4.x || >=6.0.0" 722 | }, 723 | "peerDependencies": { 724 | "encoding": "^0.1.0" 725 | }, 726 | "peerDependenciesMeta": { 727 | "encoding": { 728 | "optional": true 729 | } 730 | } 731 | }, 732 | "node_modules/object-inspect": { 733 | "version": "1.13.1", 734 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 735 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 736 | "funding": { 737 | "url": "https://github.com/sponsors/ljharb" 738 | } 739 | }, 740 | "node_modules/on-finished": { 741 | "version": "2.4.1", 742 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 743 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 744 | "dependencies": { 745 | "ee-first": "1.1.1" 746 | }, 747 | "engines": { 748 | "node": ">= 0.8" 749 | } 750 | }, 751 | "node_modules/openai": { 752 | "version": "4.38.5", 753 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.38.5.tgz", 754 | "integrity": "sha512-Ym5GJL98ZhLJJ7enBx53jjG3vwN/fsB+Ozh46nnRZZS9W1NiYqbwkJ+sXd3dkCIiWIgcyyOPL2Zr8SQAzbpj3g==", 755 | "dependencies": { 756 | "@types/node": "^18.11.18", 757 | "@types/node-fetch": "^2.6.4", 758 | "abort-controller": "^3.0.0", 759 | "agentkeepalive": "^4.2.1", 760 | "form-data-encoder": "1.7.2", 761 | "formdata-node": "^4.3.2", 762 | "node-fetch": "^2.6.7", 763 | "web-streams-polyfill": "^3.2.1" 764 | }, 765 | "bin": { 766 | "openai": "bin/cli" 767 | } 768 | }, 769 | "node_modules/parseurl": { 770 | "version": "1.3.3", 771 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 772 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 773 | "engines": { 774 | "node": ">= 0.8" 775 | } 776 | }, 777 | "node_modules/path-to-regexp": { 778 | "version": "0.1.7", 779 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 780 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 781 | }, 782 | "node_modules/proxy-addr": { 783 | "version": "2.0.7", 784 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 785 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 786 | "dependencies": { 787 | "forwarded": "0.2.0", 788 | "ipaddr.js": "1.9.1" 789 | }, 790 | "engines": { 791 | "node": ">= 0.10" 792 | } 793 | }, 794 | "node_modules/punycode": { 795 | "version": "2.3.1", 796 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 797 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 798 | "engines": { 799 | "node": ">=6" 800 | } 801 | }, 802 | "node_modules/qs": { 803 | "version": "6.11.0", 804 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 805 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 806 | "dependencies": { 807 | "side-channel": "^1.0.4" 808 | }, 809 | "engines": { 810 | "node": ">=0.6" 811 | }, 812 | "funding": { 813 | "url": "https://github.com/sponsors/ljharb" 814 | } 815 | }, 816 | "node_modules/range-parser": { 817 | "version": "1.2.1", 818 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 819 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 820 | "engines": { 821 | "node": ">= 0.6" 822 | } 823 | }, 824 | "node_modules/raw-body": { 825 | "version": "2.5.2", 826 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 827 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 828 | "dependencies": { 829 | "bytes": "3.1.2", 830 | "http-errors": "2.0.0", 831 | "iconv-lite": "0.4.24", 832 | "unpipe": "1.0.0" 833 | }, 834 | "engines": { 835 | "node": ">= 0.8" 836 | } 837 | }, 838 | "node_modules/safe-buffer": { 839 | "version": "5.2.1", 840 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 841 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 842 | "funding": [ 843 | { 844 | "type": "github", 845 | "url": "https://github.com/sponsors/feross" 846 | }, 847 | { 848 | "type": "patreon", 849 | "url": "https://www.patreon.com/feross" 850 | }, 851 | { 852 | "type": "consulting", 853 | "url": "https://feross.org/support" 854 | } 855 | ] 856 | }, 857 | "node_modules/safer-buffer": { 858 | "version": "2.1.2", 859 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 860 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 861 | }, 862 | "node_modules/send": { 863 | "version": "0.18.0", 864 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 865 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 866 | "dependencies": { 867 | "debug": "2.6.9", 868 | "depd": "2.0.0", 869 | "destroy": "1.2.0", 870 | "encodeurl": "~1.0.2", 871 | "escape-html": "~1.0.3", 872 | "etag": "~1.8.1", 873 | "fresh": "0.5.2", 874 | "http-errors": "2.0.0", 875 | "mime": "1.6.0", 876 | "ms": "2.1.3", 877 | "on-finished": "2.4.1", 878 | "range-parser": "~1.2.1", 879 | "statuses": "2.0.1" 880 | }, 881 | "engines": { 882 | "node": ">= 0.8.0" 883 | } 884 | }, 885 | "node_modules/send/node_modules/ms": { 886 | "version": "2.1.3", 887 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 888 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 889 | }, 890 | "node_modules/serve-static": { 891 | "version": "1.15.0", 892 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 893 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 894 | "dependencies": { 895 | "encodeurl": "~1.0.2", 896 | "escape-html": "~1.0.3", 897 | "parseurl": "~1.3.3", 898 | "send": "0.18.0" 899 | }, 900 | "engines": { 901 | "node": ">= 0.8.0" 902 | } 903 | }, 904 | "node_modules/set-function-length": { 905 | "version": "1.2.2", 906 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 907 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 908 | "dependencies": { 909 | "define-data-property": "^1.1.4", 910 | "es-errors": "^1.3.0", 911 | "function-bind": "^1.1.2", 912 | "get-intrinsic": "^1.2.4", 913 | "gopd": "^1.0.1", 914 | "has-property-descriptors": "^1.0.2" 915 | }, 916 | "engines": { 917 | "node": ">= 0.4" 918 | } 919 | }, 920 | "node_modules/setprototypeof": { 921 | "version": "1.2.0", 922 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 923 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 924 | }, 925 | "node_modules/side-channel": { 926 | "version": "1.0.6", 927 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", 928 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", 929 | "dependencies": { 930 | "call-bind": "^1.0.7", 931 | "es-errors": "^1.3.0", 932 | "get-intrinsic": "^1.2.4", 933 | "object-inspect": "^1.13.1" 934 | }, 935 | "engines": { 936 | "node": ">= 0.4" 937 | }, 938 | "funding": { 939 | "url": "https://github.com/sponsors/ljharb" 940 | } 941 | }, 942 | "node_modules/sparse-bitfield": { 943 | "version": "3.0.3", 944 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 945 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 946 | "dependencies": { 947 | "memory-pager": "^1.0.2" 948 | } 949 | }, 950 | "node_modules/statuses": { 951 | "version": "2.0.1", 952 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 953 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 954 | "engines": { 955 | "node": ">= 0.8" 956 | } 957 | }, 958 | "node_modules/toidentifier": { 959 | "version": "1.0.1", 960 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 961 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 962 | "engines": { 963 | "node": ">=0.6" 964 | } 965 | }, 966 | "node_modules/tr46": { 967 | "version": "0.0.3", 968 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 969 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 970 | }, 971 | "node_modules/type-is": { 972 | "version": "1.6.18", 973 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 974 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 975 | "dependencies": { 976 | "media-typer": "0.3.0", 977 | "mime-types": "~2.1.24" 978 | }, 979 | "engines": { 980 | "node": ">= 0.6" 981 | } 982 | }, 983 | "node_modules/undici-types": { 984 | "version": "5.26.5", 985 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 986 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 987 | }, 988 | "node_modules/unpipe": { 989 | "version": "1.0.0", 990 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 991 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 992 | "engines": { 993 | "node": ">= 0.8" 994 | } 995 | }, 996 | "node_modules/utils-merge": { 997 | "version": "1.0.1", 998 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 999 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1000 | "engines": { 1001 | "node": ">= 0.4.0" 1002 | } 1003 | }, 1004 | "node_modules/vary": { 1005 | "version": "1.1.2", 1006 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1007 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1008 | "engines": { 1009 | "node": ">= 0.8" 1010 | } 1011 | }, 1012 | "node_modules/web-streams-polyfill": { 1013 | "version": "3.3.3", 1014 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", 1015 | "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", 1016 | "engines": { 1017 | "node": ">= 8" 1018 | } 1019 | }, 1020 | "node_modules/webidl-conversions": { 1021 | "version": "3.0.1", 1022 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1023 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 1024 | }, 1025 | "node_modules/whatwg-url": { 1026 | "version": "5.0.0", 1027 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1028 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1029 | "dependencies": { 1030 | "tr46": "~0.0.3", 1031 | "webidl-conversions": "^3.0.0" 1032 | } 1033 | } 1034 | } 1035 | } 1036 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "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 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.19.2", 14 | "mongodb": "^6.5.0", 15 | "openai": "^4.38.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/weberror.js: -------------------------------------------------------------------------------- 1 | 2 | // Error class with status and message 3 | class WebError extends Error { 4 | constructor(status, message, ...args) { 5 | super(status, message, ...args); 6 | this.status = status; 7 | this.message = message; 8 | } 9 | } 10 | 11 | module.exports = { WebError }; --------------------------------------------------------------------------------