From 7e4fb4f595a83dfe202b2fb3af574e9ccbbd79d8 Mon Sep 17 00:00:00 2001 From: Abel Date: Fri, 23 Feb 2024 20:18:06 +0100 Subject: [PATCH 01/94] Changed order of quality goals --- docs/src/01_introduction_and_goals.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/01_introduction_and_goals.adoc b/docs/src/01_introduction_and_goals.adoc index 87c25b63..160dfd74 100644 --- a/docs/src/01_introduction_and_goals.adoc +++ b/docs/src/01_introduction_and_goals.adoc @@ -77,10 +77,10 @@ A table with quality goals and concrete scenarios, ordered by priorities [options="header",cols="1,3"] |=== |Quality Goal|Description +| _Learnability_ | _Any user must be able to use the app with ease. The interface must remind the user to the one in Saber y Ganar quiz show._ | _Satisfaction_ | _Users will not get repeated questions in at least a hundred questions._ | _Modularity_ | _The application will be divided in modules so that a change on one component has minimal impact on other components._ | _Testability_ | _The application should be able to go through different test and complete them successfully._ -| _Learnability_ | _Any user must be able to use the app with ease. The interface must remind the user to the one in Saber y Ganar quiz show._ | _Time behaviour_ | _Users will not have to wait more than 500ms to get a new question._ |=== From 34755fb8bfe684acd70ec04936d158cecae95ddd Mon Sep 17 00:00:00 2001 From: Abel Date: Fri, 23 Feb 2024 21:44:30 +0100 Subject: [PATCH 02/94] Corrected cohesion and spelling errors and restructured section 4 --- docs/src/02_architecture_constraints.adoc | 2 +- docs/src/04_solution_strategy.adoc | 12 ++++-------- docs/src/07_deployment_view.adoc | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/src/02_architecture_constraints.adoc b/docs/src/02_architecture_constraints.adoc index 3e7ebafa..ac6d7f0d 100644 --- a/docs/src/02_architecture_constraints.adoc +++ b/docs/src/02_architecture_constraints.adoc @@ -33,7 +33,7 @@ See https://docs.arc42.org/section-2/[Architecture Constraints] in the arc42 doc |*OS/Browser Independence* |The project must be available to the maximum amount of users feasible. That includes support for mainstream OSs (_Windows_, _Linux_, _MacOS_) and browsers. (_Chrome_, _Safari_, _Firefox_, _Edge_) |*Usage of _REACT_* |The _REACT JS_ framework will be used to develop the front-end of the project. |*Docker* | The application will operate within a Docker environment. -|*Version Control* |In order of the project to be graded adequately, it must use _GitHub_ as its version control system. The contributions of each team member and agreements reached must be easily traceable. +|*Version Control* |In order for the project to be graded adequately, it must use _GitHub_ as its version control system. The contributions of each team member and agreements reached must be easily traceable. |*Wikidata* | To generate questions, WikiData would be used as a knowledge base. Wikidata is a free and open knowledge base that can be read and edited by both humans and machines. Wikidata acts as central storage for the structured data of its sister Wikimedia projects, including Wikipedia, Wikivoyage, Wiktionary, Wikisource and others. |*Continuous integration and delivery* |The development must progress through frequent integration of small changes into the main branch. New features must be automatically deployed with ease. (In our case, using _Docker_) |=== diff --git a/docs/src/04_solution_strategy.adoc b/docs/src/04_solution_strategy.adoc index 84832e17..63ace935 100644 --- a/docs/src/04_solution_strategy.adoc +++ b/docs/src/04_solution_strategy.adoc @@ -8,7 +8,6 @@ ifndef::imagesdir[:imagesdir: ../images] In order to develop the application and adhere to the constraints, we selected the following technologies: - ReactJS: JavaScript library that streamlines the development of graphical interfaces for web applications. -- TypeScript: Extension of JavaScript, bolstering it with type support for improved development. - GitHub: Platform offering remote repository services for project development, task management, and version control. - MongoDB: A non-linear database selected to oversee storage of diverse application contents, with each microservice possessing its dedicated database. - NodeJS: Facilitates efficient management of asynchronous events, notably beneficial for scalable network applications and database administration. @@ -22,13 +21,13 @@ We will use PlantUML and UMLet for creating the documentation's diagrams. === Approaches to Achieve Top Quality Goals -[cols="1,2,3"] +[cols="1,2,3" options="header"] |=== | Quality Goal | Scenario | Solution Approach -| Privacy -| Users seek reassurance in the safety and privacy of their data within our app. -| Ensuring user data security and privacy within the application. +| Scalability +| The application's design must accommodate changes effortlessly throughout its lifecycle. +| Employing a microservices approach to minimize code repetition and enhance understanding of application distribution, ensuring future scalability. | Usability | Seamless execution of all application functions is crucial for user satisfaction. @@ -38,9 +37,6 @@ We will use PlantUML and UMLet for creating the documentation's diagrams. | Application architecture must facilitate seamless addition or modification of functionalities with minimal code changes. | Implementing design patterns and adhering to code conventions to ensure clean and maintainable code. Additionally, prioritizing testing during development for long-term maintainability. -| Scalability -| The application's design must accommodate changes effortlessly throughout its lifecycle. -| Employing a microservices approach to minimize code repetition and enhance understanding of application distribution, ensuring future scalability. |=== diff --git a/docs/src/07_deployment_view.adoc b/docs/src/07_deployment_view.adoc index 239f6db9..84766759 100644 --- a/docs/src/07_deployment_view.adoc +++ b/docs/src/07_deployment_view.adoc @@ -68,4 +68,4 @@ Final product will be deployed in http://wiq.sytes.net/ (if that does not work, Quality and/or Performance Features:: As for performance features, our current Azure MV has 2 GiB RAM and 1vCPU. If that was not enough, we can always switch to an Oracle VM, which has better resources for free. -Each microservice has its own container aswell as its own database in case of needing one. \ No newline at end of file +Each microservice has its own container as well as its own database in case of needing one. \ No newline at end of file From 86442c0914dac15df59d2980cf9ab66f7ac692c9 Mon Sep 17 00:00:00 2001 From: Abel Date: Fri, 23 Feb 2024 21:45:33 +0100 Subject: [PATCH 03/94] Reestructured some table headings --- docs/src/03_system_scope_and_context.adoc | 2 +- docs/src/05_building_block_view.adoc | 32 +++++++++++------------ docs/src/11_technical_risks.adoc | 2 +- docs/src/12_glossary.adoc | 2 +- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/docs/src/03_system_scope_and_context.adoc b/docs/src/03_system_scope_and_context.adoc index 0d7b66c8..3fc2a647 100644 --- a/docs/src/03_system_scope_and_context.adoc +++ b/docs/src/03_system_scope_and_context.adoc @@ -45,7 +45,7 @@ The title of the table is the name of your system, the three columns contain the **** -[cols=3 options="header"] +[cols="1,2,2" options="header"] |=== |Entity |Input |Output |*User* | App usage and experience. | The user will introduce and send its credentials every time it creates a new account or logs into an existing one. diff --git a/docs/src/05_building_block_view.adoc b/docs/src/05_building_block_view.adoc index a386e81f..9b7f3678 100644 --- a/docs/src/05_building_block_view.adoc +++ b/docs/src/05_building_block_view.adoc @@ -71,7 +71,7 @@ Its headline is the name of the black box. **** [options="header"] -[cols="1,2"] +[cols="1,4"] |=== |Name |Description |User @@ -119,22 +119,15 @@ image::05_level2Diagram.png[Level 2 Diagram] ==== Contained Building Blocks -[options="header"] -[cols="1,2"] +[cols="1,4" options="header"] |=== |Name |Description -|Web App -|Layer in which the user will interact directly and which will connect with the different services. -|Questions Service -|Microservice to generate the questions used by the application from WikiData -|Game Service -|Microservice that implements the quiz game -|Question Historic Service -|Microservice that stores the generated questions for later consultation -|User Statistics Service -|Microservice that stores the statistics of the games played by the user. -|Authentification Service -|Authentication microservice that allows the user to register and log in. +|Web App |Layer in which the user will interact directly and which will connect with the different services. +|Questions Service |Microservice to generate the questions used by the application from WikiData +|Game Service |Microservice that implements the quiz game +|Question Historic Service |Microservice that stores the generated questions for later consultation +|User Statistics Service |Microservice that stores the statistics of the games played by the user. +|Authentification Service |Authentication microservice that allows the user to register and log in. |=== === Level 3 @@ -147,20 +140,25 @@ To display the inner architecture of the different microservices, as well as how ==== Contained Building Blocks -[options="header"] -[cols="1,2"] +[cols="1,4" options="header"] |=== |Name |Description + |Questions Generator |Contains the required templates and proceedings to construct questions. In order to do so, it delegates the Wikidata querying to the Wikidata extractor. When the data is returned, the question is formulated through templates. + |Wikidata Extractor |Handles extraction and formatting of Wikidata’s output. It’s queries must cover all necessary information in order to construct the question(s), including not only the correct response, but also believable and coherent “decoy responses”. + |Questions Historic Controller |Receives the generated questions, and sends them to the database. Besides, it also handles recovering them from the database and sending them where they are needed. (e.g: as response from an API call, or to the UI) + |User Statistics Controller |Receives various information about the player’s performance in the match. There, some processing may occur before storing it in the database. Also handles retrieving the information and sending it where it’s needed (e.g: as response from an API call, or to the UI). + |Game Controller |Handles all the game’s logic; where the user input’s processing takes place. It can request questions to the Questions Microservice, and also gather user statistics, to later be set to the User Statistics Controller. + |UI for the game and statistics |Handles appeareance and presentation. Actions taken by the user are communicated to their respective controllers, that may respond accordingly. |=== diff --git a/docs/src/11_technical_risks.adoc b/docs/src/11_technical_risks.adoc index b488dee0..21b52120 100644 --- a/docs/src/11_technical_risks.adoc +++ b/docs/src/11_technical_risks.adoc @@ -24,7 +24,7 @@ See https://docs.arc42.org/section-11/[Risks and Technical Debt] in the arc42 do **** -[options="header"] +[cols="2,4" options="header"] |=== |Risk |Consequence diff --git a/docs/src/12_glossary.adoc b/docs/src/12_glossary.adoc index fcc1b635..63766987 100644 --- a/docs/src/12_glossary.adoc +++ b/docs/src/12_glossary.adoc @@ -30,7 +30,7 @@ See https://docs.arc42.org/section-12/[Glossary] in the arc42 documentation. **** -[cols="e,2e" options="header"] +[cols="1,4" options="header"] |=== |Term |Definition From 7f0c9b0a5f38e958cd7a5d91efe4ea9872737e8e Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 24 Feb 2024 10:44:22 +0100 Subject: [PATCH 04/94] =?UTF-8?q?Primera=20version=20del=20un=20ejemplo=20?= =?UTF-8?q?con=20una=20pregunta=20y=20a=C3=B1adida=20un=20poco=20de=20nave?= =?UTF-8?q?gabilidad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/package-lock.json | 39 +++++++++++++++++++++++++ webapp/package.json | 1 + webapp/src/App.js | 2 +- webapp/src/components/FirstGame.css | 15 ++++++++++ webapp/src/components/FirstGame.js | 45 +++++++++++++++++++++++++++++ webapp/src/components/Login.js | 5 ++++ webapp/src/index.js | 21 +++++++++++++- 7 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 webapp/src/components/FirstGame.css create mode 100644 webapp/src/components/FirstGame.js diff --git a/webapp/package-lock.json b/webapp/package-lock.json index bcc358d5..a4595721 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -17,6 +17,7 @@ "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.22.1", "react-scripts": "5.0.1", "web-vitals": "^3.5.1" }, @@ -5026,6 +5027,14 @@ "node": ">=12" } }, + "node_modules/@remix-run/router": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", + "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -22030,6 +22039,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz", + "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==", + "dependencies": { + "@remix-run/router": "1.15.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz", + "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==", + "dependencies": { + "@remix-run/router": "1.15.1", + "react-router": "6.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 6e59b09b..18a15f71 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -12,6 +12,7 @@ "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.22.1", "react-scripts": "5.0.1", "web-vitals": "^3.5.1" }, diff --git a/webapp/src/App.js b/webapp/src/App.js index 910935ab..06c2736a 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -17,7 +17,7 @@ function App() { - Welcome to wiq_0 + Welcome to wiq_06c {showLogin ? : } diff --git a/webapp/src/components/FirstGame.css b/webapp/src/components/FirstGame.css new file mode 100644 index 00000000..f56cd259 --- /dev/null +++ b/webapp/src/components/FirstGame.css @@ -0,0 +1,15 @@ +button { + font-size: 20px; + width: 200px; + height: 50px; + justify-content: center; + margin-bottom: 15px; +} + +.questionStructure .answers { + display: flex; + justify-content: center; /* Alinea los elementos en el centro horizontal / + align-items: center; / Alinea los elementos en el centro vertical / + height: 100vh; / Ajusta la altura al 100% del viewport */ +} + \ No newline at end of file diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js new file mode 100644 index 00000000..dbfa99c0 --- /dev/null +++ b/webapp/src/components/FirstGame.js @@ -0,0 +1,45 @@ +import React, { useState } from 'react'; +import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +import './FirstGame.css'; + +const Quiz = () => { + const question = '¿Cuál es la capital de España?'; + const options = ['Madrid', 'Barcelona', 'Valencia', 'Sevilla']; + const correctAnswer = 'Madrid'; + + const [selectedOption, setSelectedOption] = useState(null); + const [isCorrect, setIsCorrect] = useState(null); + + + const checkAnswer = () => { + setIsCorrect(selectedOption === correctAnswer); + }; + + return ( + + +
+ + {question} + + {options.map((option, index) => ( +
+ +
+ ))} +
+ {isCorrect !== null && ( +

{isCorrect ? '¡Respuesta correcta!' : 'Respuesta incorrecta.'}

+ )} +
+ ); +}; + +export default Quiz; diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login.js index 0ad6268e..b9d17bab 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login.js @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import axios from 'axios'; import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +import { useNavigate } from 'react-router-dom'; // Importa useHistory const Login = () => { const [username, setUsername] = useState(''); @@ -13,6 +14,8 @@ const Login = () => { const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + const navigation = useNavigate(); // Añade esto + const loginUser = async () => { try { const response = await axios.post(`${apiEndpoint}/login`, { username, password }); @@ -24,6 +27,8 @@ const Login = () => { setLoginSuccess(true); setOpenSnackbar(true); + navigation("/firstGame") + } catch (error) { setError(error.response.data.error); } diff --git a/webapp/src/index.js b/webapp/src/index.js index d563c0fb..f0e61d85 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -4,10 +4,28 @@ import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; +import { + createBrowserRouter, + RouterProvider, + Route, + Routes, + useNavigate, + MemoryRouter + as Router +} from "react-router-dom"; + +import FirstGame from './components/FirstGame'; + + const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + + + }> + }> + + ); @@ -15,3 +33,4 @@ root.render( // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); + From 588cc02effb33f6fbb4926936dbd91d5f4749ce1 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 24 Feb 2024 13:10:50 +0100 Subject: [PATCH 05/94] =?UTF-8?q?A=C3=B1adido=20un=20contador=20de=20tiemp?= =?UTF-8?q?o=20visual?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 50 ++++++++ package.json | 5 + webapp/src/components/CircularProgressBar.js | 29 +++++ webapp/src/components/FirstGame.css | 28 ++++- webapp/src/components/FirstGame.js | 125 +++++++++++++++---- 5 files changed, 209 insertions(+), 28 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 webapp/src/components/CircularProgressBar.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..f9ce8791 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,50 @@ +{ + "name": "wiq_es6c", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "react-circular-progressbar": "^2.1.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-circular-progressbar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.1.0.tgz", + "integrity": "sha512-xp4THTrod4aLpGy68FX/k1Q3nzrfHUjUe5v6FsdwXBl3YVMwgeXYQKDrku7n/D6qsJA9CuunarAboC2xCiKs1g==", + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..5ba66912 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "react-circular-progressbar": "^2.1.0" + } +} diff --git a/webapp/src/components/CircularProgressBar.js b/webapp/src/components/CircularProgressBar.js new file mode 100644 index 00000000..39336ba4 --- /dev/null +++ b/webapp/src/components/CircularProgressBar.js @@ -0,0 +1,29 @@ +import { CircularProgressbar } from 'react-circular-progressbar'; +import 'react-circular-progressbar/dist/styles.css'; +import React, { useState, useEffect } from 'react'; +import { Container, Typography } from '@mui/material'; + + +function CircularProgress() { + const [percentage, setPercentage] = useState(100); + var control = 100 + useEffect(() => { + const intervalId = setInterval(() => { + // Generar un nuevo porcentaje de progreso aleatorio (solo para propósitos de demostración) + control = control - 1 + setPercentage(control); // Actualizar el estado con el nuevo porcentaje + }, 100); // Intervalo de 1000 milisegundos (1 segundo) + + // Limpiar el intervalo cuando el componente se desmonte + return () => clearInterval(intervalId); + }, []); // La dependencia vacía asegura que useEffect solo se ejecute una vez al montar el componente + + return ( +
+ +
+ ); + } + + + export default CircularProgress(); \ No newline at end of file diff --git a/webapp/src/components/FirstGame.css b/webapp/src/components/FirstGame.css index f56cd259..0f620ae0 100644 --- a/webapp/src/components/FirstGame.css +++ b/webapp/src/components/FirstGame.css @@ -12,4 +12,30 @@ button { align-items: center; / Alinea los elementos en el centro vertical / height: 100vh; / Ajusta la altura al 100% del viewport */ } - \ No newline at end of file + +.allAnswers { + width:100%; + display: block; +} + +.asnwers { + width:100%; +} +.progressBar { + height: 100%; + margin-top: 10; + width:10%; + display: inline-block; +} + +.question { + height: 100%; + width: 90%; + display: inline-block; +} + +.questionText { + display: flex; + margin-bottom: 25px; + +} \ No newline at end of file diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index dbfa99c0..ebe3abf6 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -1,45 +1,116 @@ -import React, { useState } from 'react'; -import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { Container, Typography } from '@mui/material'; import './FirstGame.css'; +import { CircularProgressbar } from 'react-circular-progressbar'; +import 'react-circular-progressbar/dist/styles.css'; +import CircularProgress from './CircularProgressBar'; const Quiz = () => { - const question = '¿Cuál es la capital de España?'; - const options = ['Madrid', 'Barcelona', 'Valencia', 'Sevilla']; - const correctAnswer = 'Madrid'; + const questions = [ + { + question: '¿Cuál es la capital de España?', + options: ['Madrid', 'Barcelona', 'Valencia', 'Sevilla'], + correctAnswer: 'Madrid', + }, + { + question: '¿Cual es la capital de Francia?', + options: ['Touluse', 'Paris', 'Lyon', 'Marseille'], + correctAnswer: 'Paris' + } + // Agrega más preguntas aquí + ]; + const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedOption, setSelectedOption] = useState(null); const [isCorrect, setIsCorrect] = useState(null); + const esperar = (ms) => { + return new Promise(resolve => setTimeout(resolve, ms)); + }; + + function ProgressComponent({ initialPercentage }) { + const [percentage, setPercentage] = useState(initialPercentage); + + useEffect(() => { + const intervalId = setInterval(() => { + // Simulando un progreso que cambia dinámicamente + const newPercentage = percentage < 100 ? percentage + 1 : 0; + setPercentage(newPercentage); + }, 100); // Cambia el progreso cada 100 milisegundos + + return () => clearInterval(intervalId); + }, [percentage]); // El efecto se ejecuta cada vez que 'percentage' cambia + } + const checkAnswer = async (option) => { + setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); + setSelectedOption(option); + + const botonIncorrecta = document.getElementById('option-' + questions[currentQuestionIndex].options.indexOf(option)) + if (!isCorrect) { + + botonIncorrecta.style.backgroundColor = 'red' - const checkAnswer = () => { - setIsCorrect(selectedOption === correctAnswer); + } + const numberAnswer = questions[currentQuestionIndex].options.indexOf(questions[currentQuestionIndex].correctAnswer) + const botonCorrecta = document.getElementById('option-' + numberAnswer) + botonCorrecta.style.backgroundColor = 'green' + // Pasar a la siguiente pregunta después de responder + + await esperar(2000); // Espera 2000 milisegundos (2 segundos) + botonIncorrecta.style.backgroundColor = 'lightgrey' + botonCorrecta.style.backgroundColor = 'lightgrey' + console.log(questions.length-1) + console.log(currentQuestionIndex) + if (questions.length-1 !== currentQuestionIndex) { + + setCurrentQuestionIndex((prevIndex) => prevIndex + 1); + } + + }; return ( - - -
- - {question} - - {options.map((option, index) => ( -
- -
- ))} + + + +
+
+ + {questions[currentQuestionIndex].question} + +
+ +
+ +
+
+ {questions[currentQuestionIndex].options.map((option, index) => ( +
+ +
+ + + + ) + + )} +
- {isCorrect !== null && ( + {/* {isCorrect !== null && (

{isCorrect ? '¡Respuesta correcta!' : 'Respuesta incorrecta.'}

- )} + )} */}
); }; + + export default Quiz; From ff3891c059c2cee9ef51b684989a2d905fe785a0 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 24 Feb 2024 13:44:28 +0100 Subject: [PATCH 06/94] Commit antes de una probable explosion --- webapp/src/components/CircularProgressBar.js | 23 +++++++++----------- webapp/src/components/FirstGame.js | 8 +++++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/webapp/src/components/CircularProgressBar.js b/webapp/src/components/CircularProgressBar.js index 39336ba4..79bbab03 100644 --- a/webapp/src/components/CircularProgressBar.js +++ b/webapp/src/components/CircularProgressBar.js @@ -4,26 +4,23 @@ import React, { useState, useEffect } from 'react'; import { Container, Typography } from '@mui/material'; -function CircularProgress() { - const [percentage, setPercentage] = useState(100); - var control = 100 + +function CircularProgress(initialValue) { + const [percentage, setPercentage] = useState(initialValue); + useEffect(() => { const intervalId = setInterval(() => { - // Generar un nuevo porcentaje de progreso aleatorio (solo para propósitos de demostración) - control = control - 1 - setPercentage(control); // Actualizar el estado con el nuevo porcentaje - }, 100); // Intervalo de 1000 milisegundos (1 segundo) + setPercentage(prevPercentage => prevPercentage - 1); // Actualizar el estado con el nuevo porcentaje + }, 100); // Intervalo de 100 milisegundos (0.1 segundo) // Limpiar el intervalo cuando el componente se desmonte return () => clearInterval(intervalId); }, []); // La dependencia vacía asegura que useEffect solo se ejecute una vez al montar el componente - + + var listaDevolver = [, percentage] return ( -
- -
+ listaDevolver ); } - - export default CircularProgress(); \ No newline at end of file + export default CircularProgress; \ No newline at end of file diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index ebe3abf6..c1277977 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -23,6 +23,10 @@ const Quiz = () => { const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedOption, setSelectedOption] = useState(null); const [isCorrect, setIsCorrect] = useState(null); + const MiComponente = CircularProgress(100); + const MiCircularProgressbar = MiComponente[0]; + const MiPercentage = MiComponente[1]; + const esperar = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); @@ -81,7 +85,7 @@ const Quiz = () => {
- + {MiCircularProgressbar}
{questions[currentQuestionIndex].options.map((option, index) => ( @@ -108,7 +112,7 @@ const Quiz = () => {

{isCorrect ? '¡Respuesta correcta!' : 'Respuesta incorrecta.'}

)} */} - ); + );) }; From 3c528d969fcbe697c306cba504dcd921db7b378c Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 24 Feb 2024 13:55:29 +0100 Subject: [PATCH 07/94] Intento numero 1 de aprobar --- webapp/src/components/FirstGame.js | 45 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index c1277977..3b0a3c2b 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -3,7 +3,6 @@ import { Container, Typography } from '@mui/material'; import './FirstGame.css'; import { CircularProgressbar } from 'react-circular-progressbar'; import 'react-circular-progressbar/dist/styles.css'; -import CircularProgress from './CircularProgressBar'; const Quiz = () => { const questions = [ @@ -22,29 +21,43 @@ const Quiz = () => { const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedOption, setSelectedOption] = useState(null); - const [isCorrect, setIsCorrect] = useState(null); - const MiComponente = CircularProgress(100); - const MiCircularProgressbar = MiComponente[0]; - const MiPercentage = MiComponente[1]; - + const [isCorrect, setIsCorrect] = useState(true); const esperar = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); }; - function ProgressComponent({ initialPercentage }) { - const [percentage, setPercentage] = useState(initialPercentage); - + function CircularProgress(valorInicial) { + const [percentage, setPercentage] = useState(valorInicial); + useEffect(() => { const intervalId = setInterval(() => { - // Simulando un progreso que cambia dinámicamente - const newPercentage = percentage < 100 ? percentage + 1 : 0; - setPercentage(newPercentage); - }, 100); // Cambia el progreso cada 100 milisegundos + if (percentage <= 0) { + clearInterval(intervalId); // Detener el intervalo + return 0; // Mantener percentage en 0 + } else { + setPercentage(prevPercentage => prevPercentage - 1); // Actualizar el estado con el nuevo porcentaje + } + }, 100); // Intervalo de 100 milisegundos (0.1 segundo) + // Limpiar el intervalo cuando el componente se desmonte return () => clearInterval(intervalId); - }, [percentage]); // El efecto se ejecuta cada vez que 'percentage' cambia + }, []); // La dependencia vacía asegura que useEffect solo se ejecute una vez al montar el componente + + var listaDevolver = [, percentage] + return ( + listaDevolver + ); } + + const [MiCircularProgressbar, MiPercentage] = CircularProgress(100); + + useEffect(() => { + if (MiPercentage === 0) { + // Realizar alguna acción cuando MiPercentage llegue a 0 + } + }, [MiPercentage]); // Este efecto se ejecuta cada vez que 'MiPercentage' cambia + const checkAnswer = async (option) => { setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); setSelectedOption(option); @@ -112,9 +125,7 @@ const Quiz = () => {

{isCorrect ? '¡Respuesta correcta!' : 'Respuesta incorrecta.'}

)} */} - );) + ); }; - - export default Quiz; From 47d84bed78af1d91179fb1c7e7f7781afcf42f5e Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 24 Feb 2024 16:26:16 +0100 Subject: [PATCH 08/94] The arrow direction has been removed and the image insertion has been replaced by the code that generates it --- docs/images/08_domain_model.png | Bin 24220 -> 0 bytes docs/src/08_concepts.adoc | 38 +++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) delete mode 100644 docs/images/08_domain_model.png diff --git a/docs/images/08_domain_model.png b/docs/images/08_domain_model.png deleted file mode 100644 index 1fcf2a76ad948c158185394c4f56202fd702fc42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24220 zcmagGcRZGF_&;pV>=lu{S5`^(h$1WFMrKGNWXs;8Y?90nq1>Tlb5oJx&Wb1_6_R9c z&vDV`^Z9;%&+mCXe|f!b*L9ueb)Ls~AMfLRUUB-mniOO#WH>lD6c@DA4RLUAlW}nH z*h%o`C#lg`FN7Lb^!!27c2YU`Xe-0-vFLzHladCGS+nZkA zt}bF%-CTWo-?GDF3a=ZXy#Dze2N#~>m*Z_Xru+32bi=pB)MDEdjBXZgM-v)=bXDLKkZPj)K`ndMyCR;q`WeIDsB z7!S`X=rsAD4LSO#%0!LN5`^t%&;6D`#qwY%vICeN#J$4EO|{fTe;k?3*p{0h{xym+ z|D`oC?04g=bY7BD0)OZX)2FS^FZ<<6wH398?!G(m!Mx6e`GdUqD40iqlZ3ax-yprPLB_1$um>fihWGRnf=YaD}Q`} zDo^^Wt*>g8JyW`zRJEoH%je6Ve>QUZow)MY)_MA-Lez+*-sfr7DNg;FZ`699|CABG zav;a>zQ3#U^h4+Ty2t8;@Dn|+-reFlV6p!ZU5M2U2!E5ZU6gO|n!mqacR*F=wdrUI z3zspjFllOvC5qHt`!T~j{+YqG*d#&!lQ=k6LNBPR82MTK%JmPV__(uKM6W_)SLI}P zT_aqb`i6)`k-=bUypXwhxVh>t-sk7ddDXQQMZjO}H#uxkVU+Sg$c9NPL^E@5v&-69@KI_@1aP?jU2ZpK;F`=7?9i!xboU)Q6Nk*(8;c(}*+Ma@^te&4#4XV_D$kvV$e6^g zlw8aht+|%=*2kYy1&bYdcD2If$@cdLZo}oqH$FVnsM^?TWqbYVm485h>h&tC=K0|# zJsEhH9-Q8ruc+Fj`4x8b#EeJ9#q>f(PTQ+now{~^{H&@P^Mb@3ebfBXn zLbzWDmX2nXyE15JJvaEhp3+_?8F_#|Hcr^Gp|-X4V1B6L_e5*oM2>i6WF$eX@>qOA z=j+$1GgYno)AQCZ-NS?}TZ0uA*4KZHq5Ixu2p?>IO}dg|q5^wRz;4U@ixzXs$HzxU z=iOv`1We`Uj~{PL__DY}_NSDiCLecoX*v0fj*VS&biAcuPI$PZ38I7rQG_Z^bnVND zZ0BsY`jif4F1E|M+(YZ;%GsN_$6S4V=lW1NgBDsZUvc;4;ZUKN>5Fu9bZTm9N$g6L zL9g``w~C#I%I)15Yl{mosl3|#0|WKB%EFbZQDj(FZEbCfS|^&@1G%)rV2WS-zTV~1 zhiUhrqEpx+A@kBV51-lzvp*?KvKJs4eA*Lv$4ndKvc zBV!Z6S*7l|C(ceoqr&9G^nW+w{|`G?wtHg!JU%!;Je)qXtV{s8cjW)yCypMb+8)Jw z`a%3cmLCUQg&8eFUTQz$9s)1XcNAmO+w#MOLbAL$RL-G)*zi-jox>fmywH}{ABIoN z(O-N0vX$s1#EuImF_JVjPu&>@*frmN3KN>n$M?U*q^!`Ba69MT@r9>6HhOaj;w?+7 ztAStdo=Htj^<#JvH}@MY_;;vHQ*N^_P5zz{L=^FiqVrQz9@CwqhQC67WqzC)jiRQrA`P;8wzxH-_O)62g_k4*AJo{Aim1*^~8ODv()gvD~IKf)0 zb6>Lg_Qv=1^Q1q)8cVeACEmU3I`HUyEDg6-vi0SqnbDZ0*Kgk36ERDT{k}Rkfacsd zB_Zp|&dy%VN=u8!PbH3P)pcefP)&g%_JFb`rt1vi8a$B<51RUf?ND=OpC`pd23}R! zMiDCH!bm5Tf}1?Pz81B3!81evt8iLDR*Pms*08LjYIo~LzUk8|%ulyGfAor4HNCWZ z74PF8<*D-TbgVKx3fJM z9UbNA9kSQ6TH>rSGc(hOrw_|UA1fu^{+@St_SY{3hqv^otW&ml1nn1p^yMF{eYDQa z$q5e+-+VLu#dfx&I%cw*bU%p)iH96~BBzY*vMYYh4&V{qq1=sfkht~?^QpmGSTH_5 zK3q6n8kgX1a#j|}y)>IQ@q<5<64TF7`#Ze{kFJ0Cp-A&GMskmp#3e-#S#bv2&kf$Z z7t=X>$IEV8hOV3`1kZQ=5t%Pp_8GgbxTg`S>hc^ z&n2o9B_u?}l2&kRpb4tZw7*HYIL>Y>&L2Fp(x+5qSVAUUsZ32nLt}&6*tDlO&=>aP zHRqpNBOg<2T{z=FR|@xKL&M=G7N$?kWp2id3qG-KJ-K`9*C&~MgYbw5uu_8GJ|5S2 z*ON`v7F|U~_%~@Xe~;JWM~4rDnlK3F%6dGEh`@I`BO}A`g0Lr{+hCe{3rY9kS?FVg zo0-YYU%G^LWDSQevbxYH-P&0ET&Na%6 zg`ZG?cAvrotj#lsn$ycA-DQ!Pwj%Tvd8URwAh~?#RGcCwrpMe`pI9}^v1!cUuw;1u z9OkWS)*(jbdYA0y(o{!EN=kQkH})W$55Jaebw%HSeBk*F)7kERgR6*bp)GCw{ro~p zF5=NY;^t3Xmateu9DV;jN=Q@eic=H+*NbRyEUvn@lJmai5SW(`;p)G?B)b z-)9=0FQw|)<~nf?lj&u-WuhiWD_q&L)a=TFz0+X+YEd)oRIWYhh#PyJQ9 zYRHK$KYGOdX1Y&_Ut%J!Gw#AW!mf!-HUe>{4~+|N#Q>B*ncvuja^qf5&oPi__E6^Xk_+G5!J{#Oi=4s}q3TYsd^9k80JTdvb8 z1!v}E_bvs*jK8}2Ht_aB+=V_uEt|gabht$z{N(p_wZm9d8LlG^!@LnC=d0uBzdXQf z^*i}NNN@UF#Ry$m9(l6$eRhd&s6pYOvGHIeMt4R!tdZ^(mp+m@^+r;I>*%q@-?<*K zCRiUt@BjDMS~P*Ukk9LL*Wp@jn*C?RKgQ_JNzB#bJbrsceH*nPJT&#s6OEH^qr#aO z&V9{QS>}sv9~tyo(BS=dZA`u=%QEg<^p>q-KXOoJvL#W@+XgAd@N^ToKzRPux{NG0 zz3EP#?|AmYo?5Iu9IF@CP9I%QYCA`lLyq<0IhtB122+o-a<}tnY<-k0Qvoev9bjY^ zk6>t&04_2P>^A}O!W_>`z_Z8!C<_UZA*kuazqt4R12Dkj4uSD0&+j^NAE}GmA|oTQ zj~!|BQ7k`xA{UaY#d2R$?tvndZpPg`1O1U67K=qyvRE)<4n(HnELGMn|{t; zlGl23ezzW+tkw8&ADN^1)qzKsbai#Tj4oWca>emomWn0~A^e_gw>Vz!*1G5O?QO;! z9&cEO@ngdh0M~%qN_wcx03)(YwI1xBIAw$LEaO|0Mvif7@LmFwc>k-|K$x%S(&nG9 zFI>mMC1cN3a*2f3)OhOX9J9nvA*E-uTd}vde_3B2CQ@!%W%bFH%i zgI727k!rxzb7AC}?-ze!>8ZInW)_zDnHhUg+o2~G8=rkATt7F+T%SdNePc{D)DtdQ zZ0CFiA78%KmCRWnilU&TJP9b=_+|q>9iPr|g#a%U>iDW2$#`ow-j3Gc82YY*aE1BHYfXQl=wY0jRD5)Qs>WEn(V<0#{F8 zzEYKG)t9xOA6HCNW^kjTMtJVuzu(f*0w5K@ImAy-Z|`sCrjwNRCx?v5_RqR+JPAei ztvBavQ+%uo?8O5fVPRoONeJQ3ITEl~tU=NF4>IX7A(Vl(B_$>P{{GK=N0Y-3m+|YH zqzI7$fA6(<$bFoZ|{l9H;iY7UUyz37A7Bo(~tXTr#MULVy)%pQoNSQ4&<3l{X^tHuvvvtMZxjMI(UWI$ltR9Y zjXhvjA)_QCe|8~H;kM&FriN&ZWJO{ss-)FbFQHg^f^E_B)DLXHcK3ERN{fW9zRQvj zHmNKq(!z!Pc<}}dl|{xmJts$psqD@~@XoIRJ*AR={s~UAz5YvEbLdS+4AqT~Pxp4W zJR5Mj#RWtn2xjm!}vs59UA9O$P%p z!9b3o-!tm!&iH?cr1ZonKm6 zsd@FHkPN1DS~)N<5OCOB*{>yVvpuK>z33&_A#(W?_z#sES4@N)>DcZd}e(X z$FHkJSPmV7=ytAkcR7K<&D;|s6kESI(P~|)%a$WiKMCe%yfQx|3_x8t@oK6DN*UY& z@Wrfv9Ulb4q22W{H}>F7PNijt7o2L*MwO^%_T8y~sY~_pqbGCE`8N3e-XFGb%MiB? zhKk=loZw;B%a<>~iTl2M`7$uDvM^d>&%g4cugc^J3jtEo!+LvWoMrc*V^513t8-Ix zKndK}_Vbe+jEjv8Rk$Z)Tn@#C`>I9V%@kKc=5sy^%intDj;7PByi)Eu_JWj@beE&7 z(73{cnVA_K2=&W}GdE{u6p5*)Vdrsc2CJ+?b~pc=ttz3TrUt+tajh>895m^jSs=iq z*x#QUnKCJeI-op#`PL3Y>tgFVS`DTse73$Jk}i3%F8mCvmbP4c7AdTpIKY{ewY6`W z``bUo(L^%d?9#3rS(%yVP0qNC=-1!+mh-WH>ZEPRWLp>%x-g4p^?+=^fRW|+88oAb z3Z$i@DO+3hJrFoHh=Qu$&mdmem0GF5PZtg zA<%j)jHHmIGBVC}dgzN*W@Q}@CQtCDuH#&#E4}ohYC?R)ePsWWJY zh5i(KlNgQAW4%kD(Gz{!e;ne!>*2+C`>*(lcC@v-VH^M9( z-lmgMQbwE5F3_1ix5C20iif!QDq#y$O(})O z#>Ujn-1Q>$yw#fG<>Mn}@Q@&Ve|11F9bJI8P_HAVohj1Yof};UC6+r2yl`S{>?xtj z!9k-XmcMJ70^Eoz5EzM{WD9D{pF4-S&*632!=lWG?wiBL5I!({p$mcj$=V5SSAY~o zF;!K+AyLhh@og?P{$>>T?vDaY@pJSg`)NOA1$(5hohq%$3dv3s> zQyShvNEQ-C0;6bghCTUlSv%=@8y zHRr77Bg;mgqgx)*|C=rQSDtR}>{MB|<|R63Gl^S46p4NR;*J)qXgb$nhNNv!qQ%I0 zOsl8yU7EyuL|&^4kNwkfTM>fhTa2#GJAMuhoIB?=z1tvDLwTg3NrMyu4k^?ow{G16 zp3ZBe32(U4ObX^N7k?aJTjdwU*+K?XKCFIn$-dNvIn*k7_`$QZ1Ofg@rYf~C7| ze*hay6sX|mhE%cB)6+9Bz;*1NOiX*bGZsk7*QgIzb8Ze;1Ik2) zX*LxSjdg=pTq4&ryn2G9^I+N5%8vnqW=SV3$NN58aU@ONy3!i_d1z?J<`kANfN&hr zm5W?_EWDh^8(29tRn^(D#L;@sYZEO&a{^pQ8mB(v_NCIIZZU$GY8HIedt1?u9)2zm+<%PbxbKfjz@z)V+)7d;Jb6fZv2N%<_8 z2V|6MoLqqbG`+MgAqjrJ)I5HmRL^%78-`+lO7TjL@ zS$FjfrCdBo7$y~$K9dOj5Dg$aY``>&giM}$t2Q5cYqLP+?+S6;ej2pK!}<-H$*toYct zV)%huiy0tqx0bE%`+GaPu3x98Lhy&;S;MLm1= zY*V8UI7fTss~Efs?HJ(B{e~!@2l1k=ZUPb;li4%7DBv2*_{MHI*JxA zcS(Oj0>ak(M}=Q#bpw0THxJkRGyRG)H6!Dd>utcRH{DLhct>dj8*Bnh0rW)<^L8;n zHTwQ0dZqj$F`@I#8#MxRLv&7VE*l-46cBvX4n5mjTPi%9oVXW#7svhO#KCY*k<9gd zhquSsOz!IH0-$N7kCL=Wz%&GI-GbN;1i{NL;4LeR9%Cw&55gE3pB)E!`@(bhcR3zz zl(Boj#v(-A9V}IO+4@<)_@0`k{NAa>)_}}$tsJ6 z4FNv#u~qZ-Om|xMukzyJVz>kLdH(&GiPhz0ybzBEB3E9bA#`X!;5K-u4zUdgb1hbw zXPe2S$lqC>77~d}8j2#^Q<-JxKNX% z@FI!-+V(sK?^B&y$ohhrT>KK^H*js43d%Zo>)WGC4`u~0_^=oPA`}Hgwoy>@Mo0G> z{By4|1tvZziCxZ1fK9{iuU8FnRMPS5Zf=JVB=0I1gLAKeEjjRl0W~%?|-V9;WM0TaTM6N1$d1c(FlCXL+9hGT^TQyPxgpBIEn2TCk zo3L}U0?RCiKBzNw)Y0Pd#5F8H%RaqQ-w))vTznJJ;ma#-`Na#7C42>6k#Qbudo!GX zgbL;;Leri9R~O6Z`TGZF&NyKUoIX4R;Kr|;!=ZuoBRzIZ#JZ)axw$z%eR>< zI`7t7{aL~C!5&r#JA$*e*47iy&ne=slop~fp;Wx9N()odA`w3ApKscU?yqTRw?;im z@SL*l1~_ob%WE8M+fncN1B?Qm$9VE&Zxyl@|C?CX0J!H5$@}WntF{%d5|~UYQ7Mi4 zud?0jFouhQ<-6RJ%#y`mi!%;lS6))Tb6AbcIIn=2|I)kza9~y-74gK*NW$pyKOLnO zmy_%rCc;|LBC{fkv{8M=PK99XcZ8veqjw6oMv85F86lx^trRY-QTMxdkxxvXUg>s~ zflR!(t*4_Cser!ABw;JKL2tYm>yE*y&a}RRHrS_GQsKJ+k%R}U!2W$O;9-KdjwK~G zH*PIqo&L)hw_A44jD}!mC*un~5Tvy3Zzog$Bw^S$nUt+IHaBN^p0O$;&L{FM@8MfE znslB`$r3%(^+E1R_K;lhJ^6jx|2lBc&RXu}}NQbAk$WnlP$B0R>Y1{%s3e7^lbG1$BWgFtHyj)6Ye7BX1 z>Fk`=Q=pQ^oFT!VuR4I-shSHFeA-ZQGPMt#fBwU_A@{MockbMoi9esn+I{jfrc4th z+kFRUC}wK9%=!(q4f7`%1|g$RB1&mxMp5(5FJ9N89J-q4tV%92IHB52fF*{oP~G!O zl%>;+^mFs=I;e&K3tYT#AuP!YKuh%*id5)lM!ImQE7O{o+A*hJB+i7fTB;;jgHGH~~+(@qEiF9CS z*;^ljgg0Pt0@pkpA#{D;h{TmgMy0)rMVzLB9HDiwS{HP6qxadQ0}BZ0Sy^>Vt7#g1 zel-N|1;~}lm(w!B^N8SigB&7MR8&hwDO?)BjJ26$x)r)FX)3v6GX`V+=OeX^_0`x( zym;3Ng>0vIr0o8QBD^9w_UDfsdbo7x|Gc5cTn$$zG9;i}!PuDeC*mYOa(!n7!ZE2) zcx1w7&(;G(2UbcPaxavB=FshAXV;70jCjJ6oOMEvVo8rG%7F`BuG#nZNwy&c*i3;~ zG_ZA-AuUs~$?@>;07bHoEmY&=7#fxp-MnmeEeB;zuIh8DJ!l@*qUpc#{A%dnp(=N&(I zCpOmI(=#F>Q}FU5-``)x^F{~MY?;3Si}D!~^U0e1Rll>z}IDD^d4Sz90A)?+Ue^R7+{_9sYXEBQxF3@zoe*HQ+ zuA-u%wN)vEsuImZ>FhtqR|$sp#H=PdasK3?!}fHtE2*(lXUl^PxeQm1Lf3Hp_e38< zigva$K?+9*Mt&IY=%v(7(U|dGmIZDx!Xj$VbAZl8{}CTQjk^sDbz}9!PrNDaCiE@plmR<)6^g zNA2FQ!jO!gTs{L23yc{Q(l0l992$x)W(z$r?Er4$zhoa%x(832gf$!gEw@12>id!|2ob(4coxmVWBw7F= zn}CSO5mW;Vk92d*!Nkve@#_%#jgAf^5e`||y|9pMZrS7~k>d*;dmk6MayQ7o9GoIDSJ(XaD`iacIfUpL{SJT#@G_bJ!)`N)EP3(oe=&I2S-s&gNY z{0Ixs%ggPU96QS8#mkr|a@&|kP3I%bqlO-8BtRS+Fkp*-;45K!f7wDc;x3G9H;t%T zxLR2XC%?Ca-@|#p3e=^w&~bvMrY69BMC4fI2eKY^u>W8?emm=~PS1ah*Qf0|K9G~+ zmzjSO`jN!qk1$jYAO8*nz#n)C?7sskT10IB=m;kwXW~4O%FapF8%7u$sb~&fRM`F; z%2~d@CZ~@@Fc08}`HbLyk$QGehWtC}c3~#BZj~9&bo>2Hi&|RYEuw!in`PxTo z*BMz-vV}$sgh}3v?F-Au&80B?^shQb^ECZ25GklNiU{M=@sDQe~-jGc;Cn13xy3DKgujGmc6L>9E_a7&+o=sKYRT&f%nZ>A`xt}%%Kcz)E_3ayBFWv<6 ztvCK{`?huGd>462uv``Tg?Q5MCuiNStUo$;@MLqjM;sCgNhz5dn^AO2`6cq7brZoS zq@AeQh9r(K1>*0n4vLikLnBNkdD<^R4!ZJqk`;w*y#czPRmLfXc9R03GQs0K%0;B7 zXIfmHAQaVyX_z3aDLs8B#SId2@~@}u^-cuj0wDo39qR(11j=1o3Ks{(dHP}KMKpT< z1QO=RluI0Sa;UVog&XJZ=@hW}+niHeMAKF7qz#%3u7$sPTO6dXfjNW%#zUN57ne-MQ*BJ|qY z*#Wi%ndH&fhLvc~aucu{-#fhib8eTR;I)u`B8zH<3$FlJ!6x{Ouml z-sAvafgzF=5cw$y%nab1fus8(Fx6s8z#NX(d(M@K0o(Oj#n$W|q$B{1a^>1U1OXW| z>;Q}$cse9eptFt>M>$v~o>cgRv^oC0{wXD?%szJC`QEKbTjqq7vt6 z=^0aF-o4YYwzeiFCO&trG2~$H9)SVMq!bEb=l$nJuYmgV?|S<-{?45%jXt7e+Q!m1 z$B)ZJdl@0}5?m7`^aFlT(MLIVOiU;V3dSYQQ_(YWK}G8dvC$s7Du3^R zE3RT9Ns+}a+6Io0Bot$K0^FoLw{tWV9+3?=;s?M~j!Ni!wcVm5(+<{Ah} z3ZM08BR>H!vxSs#^vtgX=*nIY+~MKl&z0@Nl##V#n=K|LAix^zL3{BItgajg7Lis9 z@OwuaPysaC2c*(0M+76Vx+Xusxxgxl4(Elet~XEs-)3easVX%OANn{9>7ITv^D?>y zGlgLXL+k1`fYqKY>pdFwaTv@4M3Pv8+@o;~@u6OjbDzXv8)7~hS7r$mR-odzn>c?A zNL^O?OcrQS4?-&XA5Q_QZ~B-Na)UYwI7%V2>KX95S-Vay-~ry{E9L*a*~Rv87$ijk zV&Z}SMg%q=cw>>jBdVk9zs$g*##nHa>~5vAD+EZpPqy6x8wT_W(HZvq%wuFNo?152 z@?M0_G;|_8*0{O2zTE!ZY*=zpWe*DU2>>}EG3v)pyM2+j@1nlB_UG#xwD~hTjoH%1 zh6ZTh$?57-rlibp|S9z3_+ z8S-P5K@rie=H$eiy#!vL6HH9R2Pz{;rKS7}nS)F^_;K5hfH=K#wE+!HkPlBR&P251 z2#x`yq2WHCET^cb2t{{vXVl=v`ug{Iw|^Q<_Xq}m_m_}APC_qyZUoA#WnAcZF*LN6 zF5tk3)_f6@Qwourz`5U?XaN!E9=yztrhVd|(*_neD!|t^ULG9AXWo~lFZt;=*gvEju({$cOebA1N zrluw;bRmZ93ajG$S=&DspcJRF5{h+ag~nS^k|I|RWO1gZ7|_}5lFbC^YHM>>07W=? z@b#&6tL`*0)yc>qfZn$%fUue>fA-+P%Q0~OkLfIuqz=9yPTJB)!x)_MwN_tSFL7tWV@s(Jkp;QD2v?+}x*` zbdu0xW@+Dpr`L^U#k3o*vA({MK^yseCD4OBo!m9k8fot<4- z2y2`+c|xl{Xp(Qen|Oj^i5=>*=m8;gr>s#p-cmO+E9wwPn#O>b-H<4QA z=D;J0KX|@Wa~0jnGvWU#=pP|UDieN+(n?e}l0yMonQ&=_Yy1M$|Tp%}q(4+T>V!&$b?FwMvy7xrTY7h`7KtBg=NJvDK`lzB- zP{20DjTG8tTXUuPx2%`58!i4bD|OU`3m1}Y-AA#n9PxsbSw}LIa&mIIlJR&8A|L7^ z`x9#osjb4e;{3h)=grMO0Xbze1yu}C%CHutH#qq8pY%B`$7|k%0d*6F=8^J@7Yhblt%149wZ$c-u zqoV`rZ&J+i%E}lBhbdp6jXFRF^W{*kz^{+eI;o6;twOZiBo*5C#IVHODz=ZKi;H=3 zl}IU~qGoVio;$v0d8#dYt(SFywmfEVa1b5~QTuReU%X8D=jP^S3QHS6Isuucgtof6 z8u|$T<7Hs4K0dL4Djd0^4MOTxMLN37u+t9AesFXY!0zEc`b)HvSkGdfEJqP~2z)c4 z(O!mrJ|L3*!<{1N>h1LbflSUTQgSZpnEr!`coZYF8^V=X`h5UoV2+)XKOVr|X{L^v zF|edAt>9uThITASZypvkK*O8FbFQCv$p`>k+hsIPh%GZChpwrHNNi){4zS5{WjA4W z9@c_nJlhBu8A3gvNux^wj#5xhEUAXg6De=H4D*JPORRxeyTiru}vjbCG$hj&S+ zLdQ(H${k&Hadx8h0GN)$*SOBQDV=xL^Lu5uMBt{ooIM|;+kF6q6h!zz!Lj#`u}C`s z9dr0XwK{=;yU#-`x4Fv z0ej!R1Cb37+J8Ujz;Y}VP%Ut3hU~Bo( zy&bgKV`Jy!#84omG!m1uDboXlNvYw!MztC7N~^4pp`boP6<7gOmS;P5QP67P`na4_pN_kpMd7#l}LxtY6oz| z3)4})+jiI!ojvg!t`flMfgwlojb?GbWwFT**Y(LO&}q^az5Uq%8H@_ zvh<`$0+j!vk6}?k>ku*cG8Z&DnD+KC3k_Qa*4f^UYXI%QRz@|2IVu*6A-r3a&nGUV6*0dD+6j%Qc4P#TK$*qwzD^(k%rKT zQ0*Z)a_GLyPEMj-Myo;X;begnfq>Ynl9Hfy^Q&v!oQ5hD9MwFUmJ!FC`OM86pgEhH zgCMFy(%o76xdFYhw0@*<0;dtoF96g7I)00q@jqpAEfAL=Z6+fp=k@?+p)7dwxiuu@ z?^78vy;W=(asVy^SnNOY7Xgu9&p;#{^3O$xyHT<$ju&ZC9o>cefXFuh3jcRYN_zTW zi8j-JSHMxHEl5uPaKr-i{Gez1f)*Na;9zOl*`Hd1 zZvTCt1?tmRVDEreEj;p4efR;wI_OFMx-I;`t)S2h&B*^^29#q!0XzPWA6kQ(p+oxL z51=xIVl69i9$MX*Dz?{?pwNTkKz~Pl13v(=JncLfdvrxRW9B+kddo{o1^-P0WHuBh zPD8ngL=R+M(2s?%`~V3{001B;D*qRjKwKMsSLWEdq^%#L?8;T+1peg`-*W2?}=i^azWHxa1Mu zm$_jA$G;%%Y7)Zfn%Nb#cYxEJ(!jWUeK$ZBF+ljX29yqPK}U%O69*v(f1HxR*QA}W zHc&Qug_V$ylFki389U@Tifte>JwZA)AT@;|rJs;-1|(JZM8`rCIW0r!k2TFDI>iGK z1Q^r>qyS!Fub^JP@ZhxTpgW&AC=s1v0G-#mj`>VsqP)T~HsNpq#I2CcCEFvhq&l~J z@b1XRkG|jE-S-MJKI=70E&CIQYA@VWara4qhlEHk7=lIFN}hp{5&bGfdnu$UMOa;O zoos2+NWxDK$p_n^(XF(zPy;nfKVj^BnDT>bpvS{T`mfH?SQfA#>PqO|zRQ+L5L13f z5J_kW1Ti?(X*~$F5QwEDC1>$6JP!8vAWi}|H$WJBcDyC%#I+mBE*Z78(r3=pLB|+N zILsj>HSqD{$M*L2-d;%NULLx=KyOdF97;Vo_#)^wIbRSPs6jARp_sp3WAESqTpf6c zi4Lj_B&d@C5!o<%mZf1hKzQgE)fYH!0E#NS!BI$b!((^TW3I-$+WrEF+#o_;Wa8k% z$v57lChJ^3F6ZS0>8p6ihT#qwIZ_ETf&S-Ej35Dfd1k3TGWPB>NE?8k4uBUpKV;*t zLo*DUsJJ~_1g*XX9EsO}{9tD;BBs}~uBEH%qxokmav^-xPNMw9K(gc;O4iiUe z+d=a`e&cc{hKe2I4e?=}HEqboR!2#AnSnp}x)URSGobJe!HI)*Q@~m|)X7jpaaTO5 zXt#q3M+vwKP^&^un7Qj-G>B%3$*F0O&h;Vp1{?4~-OtYtIt^Wwe&5U6B|(xT#%Kqt z2hl#pRE3E{6`TX)BqrdlS?PwcEV4cesJ-pAdK#TA{Rn4LGP3YY?)`o&eJ^O79$h*C zo9c4z!&(OfZK#~V2{oCV@SLO|%1Ft|W{D{uhhn-=<>>uSlaP>L*VXn;f>H{=FD%Uf zp_Wx|p2Aq68u5{JD0_K%0jpr-?P*C0#|sPlZX;S)oGFj()$70o9bV+je^U>lcDwStNR`gg9rNeo*3 zpm`XPjNZdlO1n#HL%rPP)SzyQINym78hAW)G)MduEZY1x@DD6=6LQe7z`MYb`S|h8 zAyezAsvjD=S_i$E&$cfqlDL+K-t$Zyxj1o)wklgDX*fpru zfboN*ayM{$uGH2RvgkedKkVp3^3}JX>{mS41?C7QU5+o=|K?51E`}M`?&?*K0{l1P zz;eK}KOD}22|VcfVA%&~hpRBn+=8?XO^o@aonY44HfU@rxs04Te9Sy@8ix(q`E?f^ zn+*FFBusctom%P9a&qGMJRmkWf2e}u^(3XD`mys9NG{+IL?El)mvn&lJOIb~(ZmQnl5yaB zh{pl~0>Gm)7cQY&T>n5+hJ$_pF|x&MK-l91W5v<(j*pLn^kKoOuSaN;FKg#f$~GLI zdkm^WI7w{V2WcAZ3P7d698{ZbpBrACW4a#~AJ3u`EPrS*&#BqjCmvtscb;Sz!c14K zL+uT0El~unSUFgB(s7CK3Tilj_Hi8y1PtQGuV0s5FjTsELjMsW%2jx%mx>jz8i-^l z7)m$FCj1;U!32TlgtXzr#02~F%v?M`MouNI&<>U7K#RCv<2nb%kT2;#c4V^1=?vi8 zs`YZ1=nz>9IfIZFFv7GTkZOd(%cfH>EKl%1lH=Y3e$)gb6yP4dzIwX4kI1d?DOmmJ zUNW6HaY8$icl~Gu>@HvA;p0=4x|{g+4PEjrTQhJD?typz39oE&#T-Ab!fj^c)c5ou@Zls_c#D+plHkR z+0+D#7dPgy9mZpK<+Z~x)r!~$Wu{dp1M>z5>(khueWb1Y0s)?JB<6jr+-Q92BR)2kt202#o;d+%TvOWblwbH?^6ti~(a&vQw^Z11*jkT-oyJ`1J>`omgqB^-SJ4+Ij42231ph_|InVTQ;Y=SJVK{p!= z+J5H+MKvFMETHKWYML8(PfYt|uir33y&I(#t_IDcL(HJrS0jJ|zyEAI?ya?%z_z zUtJiz+?O_9gcf-ZnwtXuSNoIrDJf7pHy!Nn5JiNEp@SN{=2Fws)eoQ2|L(yVy*@g$ z*&R|kKChp{mzHAAoxTL=hsUuTD=#3DfS11otosgR)j2%%n^rA>NZbc@N^nD%xdIEZ z7J$m(dowzKEE72^2@XO?z- zeu#W~GTT2O>fSw5M@MMQ!=Cs2LD1S3=hxwBV09MzOA;I(G5GlUew=42Kop>KKGQUc zARqyTd?}fwH1h!jSTLApy%CX@1aFjqO7L|%% zPPZ?+P((f?cZmVyXHsDTu$dI@3`K+7t{-%%)FzOL0MNV>=dF=6+b?`Tq5+Bm069AT z)rE54a*v@|dPvRr<5(b4k)O1^pv9fwJw{0hEC*keoSh6X%!}W?A==7@Hpb9III7@% zNI!MQO<2<`9d`b;2Gp0($cG~t^g%}V%$9yj<;eS2Lm}%$0ZgP}BycOq zF|>WzGURS`759NH!5wUkGlUyn#iBe`nAge|jsn zW^;vdCBMX3W28L@(KYO>m;9WA<>m@So7dgU&C2R>Yg2n541@`!Cpc6lq;=uK)H!Vh z%tN9LST*AxdgiLOf_NmbIz_N<_IIY?m>q6$)jj zNYy_o50b4;K)NQy1T4>xp1YjvUFrkTH|#WDcQ<@BKx5K{uvxV>!`1d4Q@OO5SYkYi z7M(%l*d<7^dVrro*lR*e$y(4uZ7~Uq4)%;ayV)nOcOknA1;_y#xpE*!<8fY;!?EIC zapwWpEZUq5SV1aP;)(cXOhG}x?5xw#Rg((~I=pgr386IrClI}o#$-_!T+`O3{9vd3 zMH316&-Msn$U_f6Krg~$t!(#!^GVTA?{8?# zVKqPl9K%4Bk?}kr3J!nZ-aaBw?Z1MvmP%bvV^s*Kg=&#Q1ioZ)V~q?*Ge|0D58ou# z#pyf>lt1vz214PXGJ~&cu?_Nrm1YA%&8m>ea{Hd&#i-h=NnxfrzR!==@MraOcgN9X z-n)0tI3No9at9pZhrOAIvdY%@Wc08wKs5V|AFFmRozMH>>zsr`o zHvyzOq#?Q9#chfZdnpy(L+#);f(~;z0bjEj z1Gx~$^pN4HSfsl?e4v?EQxg{v0qV~V{A<@4UJGy|Vv11kjKi6GL;E7A&i!qrE=C{< zXB?VPk1|;&l4)Su>@W>MJ1?4>6;`?GFM&*SYH|{XoI|k86L7%OSdJ0inRTkqj7})n z!6QX4Ny`6L^m2U_8e??{5RAO^gWpch<@}s3%7$0M_K-QexFi77qI$tO(vyEyS4IB) z@=bm4!&-FLefa2&aQxl7QC*NWUl}(-Wfda)phc$R(LL1>uVAi69ggWlQ5p@A1w=xW zmKf+8uw;o%0bGprinaciO$>F$N+-m{G0Xe8LkSCCGU<9j$i(>b($nhq?f>gR4%Dr4 zia?*E6#bSs%BBEi7Yp$4L}ua5E2lXFZ!vBXu1ww|R#!sQ1I%jZH^7}~)?rcxkeA2) z(e=h-Bnd70^g7i??({!GccG)Hly=?W*a|2ip{`1ZiO~epiKSfp(o9}*B*leqFZufT zeAkhH^E`l&^>v(`g=(Jw!whGUd1CpY!4(}H{*`01n?GM!`|b#}xgPr0(RXzO*OHB$ zQjE*=akCxWSwQP==hje!UJhefrjz>(QsOE&;SA*teC1^uqV4LhF{b6nr=>X1t%YP6 z!3wteSE7o0T_^tCTdo=*3&PVywSppQiyHw@WHJbwL@sjfn!@)|{P(uKpL&7aP6}c* zL9VT$w;M7B{ZdYHPC`x^IA;y6a3C{X>=HBtcLP&P?Qk&KL!mE z-Dr1A7mFm^g~NeTj_=TOD){p;$UrxPRWGx#3@#`uDPmnFz?A?{ zAAbwSrzR%yJLAwSXKpq@Rt1_$+VvCtJHkc$YbnNXp4RZPi z1`Z(Ie2ysRQ&W%AI(51Ft6YbpeGg=AoCY1?DRR^IPU1-l%)t)N{zMOlzlRSNah*V% z(R(G0VHoIX_#^ckdNaGE9P5p z1-=m$`Z~0vYvX{k=$OFg6`4z$GG#pB<|I0DN7a_I8gVJq8Krh{EH8nzzQ^J=F$6^9 zi!7IlkG{x~zJm9dd;Jo5osa@gvK?Rv8!p36xvtr6eIGj3|NR&RB|wuPx1jiVTB*zO z03ud&6rgF^e2J^k^%zMHEe=~?ov>Y8MJc0UVYK`mCf_^Q|IbGhDgiv10jLNC0DOi3 z6}7INuLw3@AR#WTu*nw^$pukr9$iKZI0Gyz5PUqS6c7~63H4@sB* zb1lK)o^C;Ug$~cBu`woLlXs(|_13Mytq1$(1VIh!0X|TeG4u5+^rlj%Y?;-g2|yW% zp!g6F)=m}J-+BwMVSgrlp-uT&nys+*oinv$F6ZOO$nPkUtLX3v3B`k{WtHIBax#X# z7cj8>@PI2;Vr12jIUyRZS+Nq$B-g>x+*qRB1ElD(UNi3R7u|4aFQi9Qv!>8>8NyJSJ z+IH1lAUMo0nY8mCr^`9h@#54s2WKi6)s8WdZV(reEc{QA?>P58-z!&gN=tu0e~g)q zuH&~tibFebqUrUo2Z>_Jd!*>A+G|tgUW@=Uv0te#do+y2jIR!Y`1e16x`@dP8O?)MF&rFZHz;g$lM393?a zgkL`G+PMc@A}a3%G=)mf|=%4XwM3(SAQHkLZ~AL)!UQl z7s%(1KHPZVMGBt>tnUJU={DI69m2zaug88XjYDreqUJl<)#)r3iL9B!TLlqVB`K1< z4jr0I&W%U6;TTGREg>=JB+HB*r+)tVC9U&U9uSSy@O3VCJ9kOQU2rUk=UgXoB_lQ1 zl&Xl*rOr-V55kZi@8yyU&^*0UpzQFex9-IfvK;PK6?OrXxG*ZUnh^o;*c8P^`q zblb)$wmCDkj2MeTqS=~tPz{MhcvkPC!)B7oIVq8tuoXF!T2!V`s`trM4jqV=LwKUp zGpQUB9ri{~qGeCs>t`L_=kxx*{eJg-|E~MGzSnhqudlfnND_1lFfKy;h%%<$tB7+S zy(AK{6oi5r0<2GT7&DpvS%;as&u3>M+>WfKb@=S86e~=Ehb>QByS{&R4Yc$iRdieE z=5(`ljo@33Cv4_gN^#K7u@sKmz@cY}8<-G1RSR5%D7ZyG%JRj&J5Dnj0+)ahTk9jV1cUm0H zeL{4J6FFVZGgPSOL;RUg+D{$xiHfq1?iXfH3oYpFW!=mn0q+%{A)@ zAAxFalZ&7)`07^UOf9E+?Cj5T1qRr0SD=yg9eTt;wK<}dri95}_FVKXtOq%cDx&BP zKLZb=iFwpeLz~eLFXEu{4WXxY-$&y0Ug4gK-9uh{IuA8yam3iE-}6{%n`Ji+cg`B| zR3bU$qkqT-CinbHaiAHh)Q)!Adw;92dPwPj!<*fa_X42*^%;6myNd(j^o_`v{7Rs6 z;Doo(LCQ0^IYJB7v)r&NVpEr}q30gBr7ksWGN|@6p%g|x_o#kgip9s7Y1Q@pd*dzH zuu97K?3E;48+o2XR9}dt$f1su47CAaAwU~Y5YU)0U8@oXXLmc46`{?_?KY0+%3!rW zVk$FX@D`|r#cF7m980{jznV8HpkMn#*^dPFp9jq{9}^%n1)k0reM$SmK{bb7f!{4>Zp%UzV2JW_d*2qyP2BSx?RiLXn8dd%eA8n60+uB{%u4d01oF zMscQFI-c@=_S36dbrO)$=H3~mG@1lbGtDp9?tF=WKBez9l#VBBRzG%5Dirpi{%!4R zO~qt)FP?1ETk7(SMP8%F7ELbZc0@*V3sA0gvT5t5AqSIPAe#WGuiMR+M!}>icm&dc zR^jMkn9PKl#@IphzBYhq(x^0h1M&D=Qc%_?soGr~K%#pXD-!C(W`+U|-e z`~2mYkcC{{ZDGg!7uwQN+f0|Q)lO_6ACG~q3nW1is$PPHeNX~GJ!zeVnK%6c<64j> z&5`C#v#nj_DT1ayWHUv@#dV@hn>T~bkNYNRJ2(8KdYW7Wff6e#^$Wz4FFHul?bk77 zRi#!2vy51-*4`P%A*lfdCc$uysYY%E*NF{Z4 z+cpAU!<;l3V-*)Hs`LnT{-&^Z7YZuhXHacEVXKiw!+n%M?W-!0rT%5)q(NFqg=|_M z18R@z7eeQCie3O@i|#@oTX~>?$?00UygeZN|I_NH*+N6~}$B-3)R6l!q0 zlGjzJmI=)sWwE<%CO~PSR|En>(m|%XT$9l#0;meQf6$8w;Q(+Sv6t)5m7>BDbOcNapQXG!D zpg=lwtXJZ2>-IpGYO>Y6{wC2EPS1ze?_+ObUny%n%j?brhj9Y`CPG@U@y9bMchGld z;g*iInJ(sKhDPPt+km+ww3z{)p#^E>ZaNa>)%b(a~l~3$C)e zWZBsqN7CDmi5G4xswDhEh$4AwBaQyezVgAOwm6#Yu5)Bc;f)CjZ<**$$@7E|*HQ*k zdU;i+j>4D9!oWS<<0gMG&oaTSCdxUlho^Qtydw-*{0u#um-jXzb~tr`cClg$A?SDDA%J&xmhlFU+T!c*h}Yx2P>+*wb^*m2Gcwg$e8zW%mmyijX%r?C&&Y zIQMdiX8)@>jy6YMjBTm;|39jPG9L#Kj(@Ebp`5W3>#)Q! z)zLY@B>;JfYL8a3U)m$@$yqoAv=CQ(PCU`@{V9N@_GPZr(r55r?5YCsFagG|gYo=0 zog~Fa>G4Tc0jnvz+eWAx+QlSZ?PV1O=-I&>~=GO^jd z?)b2vi#$NYa(u-{gLPvaye{vt%<%b#%V-ft+Rk`-MtIn1EujSCA=T8%`SI({Wyf6& z74Oi?03aPZHMG=d4a+loN+<8~)-=jCI7W*(m<{?|JDK) z5o#0*jrV9gAElGHij4&JXf4tyo=WGHWoko}Zr^%W*27L&$a2uF+&I0bJKXYe83A#w4GI%u4 z2V>N>PP_>aNho{Aj+KW!SsyOqQ_6DXF6x+kAF7?r8BI5l8gdx^&FhL1%kbN}L1{-7 zEHg<~s{bo7WhJ~z0XA!bl&|{+6$hn!Q!?AJ|?GGVx08 MtGrx(cVcn>3+DCr#{d8T diff --git a/docs/src/08_concepts.adoc b/docs/src/08_concepts.adoc index e12e3995..a60c985c 100644 --- a/docs/src/08_concepts.adoc +++ b/docs/src/08_concepts.adoc @@ -57,4 +57,40 @@ See https://docs.arc42.org/section-8/[Concepts] in the arc42 documentation. === Domain model -image::08_domain_model.png["Domain model"] \ No newline at end of file + +[plantuml,"domain model",png] +---- +!pragma layout smetana +skinparam style strictuml + +class User { + + long: user_id; + + String: username; + + String: password; +} + +class Game{ +} + +class Question{ + + String: question; + + List answers; + + String: correctAnswer; +} + +class History{ + + int: rightTotalAnswers; + + int: wrongTotalAnswers; +} + +class GameStats{ + + int: rightAnswers; + + int: wrongAnswers; +} + +History "1" -- "1" User: consulta +History "1" -- "*" GameStats: componen +Game "1" -- "*" Question: tiene +User "1" -- "*" Game: juega +Game "1" -- "1" GameStats: genera +---- \ No newline at end of file From 0e5b801c42036b0d1eb911a844bde025318e8193 Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Sat, 24 Feb 2024 20:45:49 +0100 Subject: [PATCH 09/94] first version of the backend for the question stororage microservice --- storeQuestionService/.dockerignore | 2 + storeQuestionService/Dockerfile | 20 + storeQuestionService/package-lock.json | 5487 +++++++++++++++++++++++ storeQuestionService/package.json | 32 + storeQuestionService/store-q-model.js | 13 + storeQuestionService/store-q-service.js | 90 + storeQuestionService/store-q.test.js | 59 + 7 files changed, 5703 insertions(+) create mode 100644 storeQuestionService/.dockerignore create mode 100644 storeQuestionService/Dockerfile create mode 100644 storeQuestionService/package-lock.json create mode 100644 storeQuestionService/package.json create mode 100644 storeQuestionService/store-q-model.js create mode 100644 storeQuestionService/store-q-service.js create mode 100644 storeQuestionService/store-q.test.js diff --git a/storeQuestionService/.dockerignore b/storeQuestionService/.dockerignore new file mode 100644 index 00000000..3091757a --- /dev/null +++ b/storeQuestionService/.dockerignore @@ -0,0 +1,2 @@ +node_modules +coverage \ No newline at end of file diff --git a/storeQuestionService/Dockerfile b/storeQuestionService/Dockerfile new file mode 100644 index 00000000..f43e2df7 --- /dev/null +++ b/storeQuestionService/Dockerfile @@ -0,0 +1,20 @@ +# Use an official Node.js runtime as a parent image +FROM node:20 + +# Set the working directory in the container +WORKDIR /usr/src/userservice + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install app dependencies +RUN npm install + +# Copy the app source code to the working directory +COPY . . + +# Expose the port the app runs on +EXPOSE 8001 + +# Define the command to run your app +CMD ["node", "user-service.js"] diff --git a/storeQuestionService/package-lock.json b/storeQuestionService/package-lock.json new file mode 100644 index 00000000..a9495291 --- /dev/null +++ b/storeQuestionService/package-lock.json @@ -0,0 +1,5487 @@ +{ + "name": "store-question-service", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "store-question-service", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "bcrypt": "^5.1.1", + "body-parser": "^1.20.2", + "express": "^4.18.2", + "jsonwebtoken": "^9.0.2", + "mongoose": "^8.0.4" + }, + "devDependencies": { + "jest": "^29.7.0", + "mongodb-memory-server": "^9.1.5", + "supertest": "^6.3.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz", + "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", + "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "20.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.7.tgz", + "integrity": "sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/bson": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", + "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "engines": { + "node": ">=16.20.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001576", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", + "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.623", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz", + "integrity": "sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dev": true, + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "devOptional": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mongodb": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", + "integrity": "sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^2.6.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-memory-server": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-9.1.5.tgz", + "integrity": "sha512-m7yewXoyctu2lwISq/sazwOV/LBkPmAm4ulwoP6J4zzv78ESlAIuQEHoL2+45CTlwxiRM5hfVBQe9HIYEFaBWw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "mongodb-memory-server-core": "9.1.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-9.1.5.tgz", + "integrity": "sha512-mevjdWrxym+MzMoNsFfCtrXwK3ndb0xHKj+fHT1xoT4l+uflEqvLHt+aRdJrTW5GTGYeVlYHQpQ8hLKMeEL6cg==", + "dev": true, + "dependencies": { + "async-mutex": "^0.4.0", + "camelcase": "^6.3.0", + "debug": "^4.3.4", + "find-cache-dir": "^3.3.2", + "follow-redirects": "^1.15.3", + "https-proxy-agent": "^7.0.2", + "mongodb": "^5.9.1", + "new-find-package-json": "^2.0.0", + "semver": "^7.5.4", + "tar-stream": "^3.0.0", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/bson": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", + "dev": true, + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mongodb-memory-server-core/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/mongodb": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz", + "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==", + "dev": true, + "dependencies": { + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "@mongodb-js/saslprep": "^1.1.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.0.0", + "kerberos": "^1.0.0 || ^2.0.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-memory-server-core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mongoose": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.4.tgz", + "integrity": "sha512-wN9qvdevX3+922VnLT7CpaZRT3jmVCBOK2QMHMGeScQxDRnFMPpkuI9StEPpZo/3x8t+kbzH7F8RMPsyNwyM4w==", + "dependencies": { + "bson": "^6.2.0", + "kareem": "2.5.1", + "mongodb": "6.2.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/new-find-package-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-2.0.0.tgz", + "integrity": "sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/new-find-package-json/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/new-find-package-json/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "devOptional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "devOptional": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamx": { + "version": "2.15.6", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", + "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superagent": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", + "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.1.2", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/superagent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/supertest": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", + "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==", + "dev": true, + "dependencies": { + "methods": "^1.1.2", + "superagent": "^8.1.2" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/storeQuestionService/package.json b/storeQuestionService/package.json new file mode 100644 index 00000000..94ccdbe2 --- /dev/null +++ b/storeQuestionService/package.json @@ -0,0 +1,32 @@ +{ + "name": "store-question-service", + "version": "1.0.0", + "description": "Service incharge of storing the questions generated by the system", + "main": "service.js", + "scripts": { + "start": "node store-q-service.js", + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/arquisoft/wiq_es6c.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/arquisoft/wiq_es6c/issues" + }, + "homepage": "https://github.com/arquisoft/wiq_es6c#readme", + "dependencies": { + "bcrypt": "^5.1.1", + "body-parser": "^1.20.2", + "express": "^4.18.2", + "jsonwebtoken": "^9.0.2", + "mongoose": "^8.0.4" + }, + "devDependencies": { + "jest": "^29.7.0", + "mongodb-memory-server": "^9.1.5", + "supertest": "^6.3.4" + } +} diff --git a/storeQuestionService/store-q-model.js b/storeQuestionService/store-q-model.js new file mode 100644 index 00000000..77ddfe45 --- /dev/null +++ b/storeQuestionService/store-q-model.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); + +const questionStorageSchema = new mongoose.Schema({ + question: { + type: String, + required: true, + }, + answers: [{ type: String, required: true }], +}); + +const Question = mongoose.model('Question', questionStorageSchema); + +module.exports = Question; diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js new file mode 100644 index 00000000..219f2ed2 --- /dev/null +++ b/storeQuestionService/store-q-service.js @@ -0,0 +1,90 @@ +const express = require('express'); +const mongoose = require('mongoose'); +const bodyParser = require('body-parser'); +const Question = require('./store-q-model'); + +const app = express(); +const port = 8004; + +// Middleware to parse JSON in request body +app.use(bodyParser.json()); + +// Connect to MongoDB +const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/userdb'; +mongoose.connect(mongoUri); + +// Function to validate required fields in the request body +function validateRequiredFields(req, requiredFields) { + for (const field of requiredFields) { + if (!(field in req.body)) { + throw new Error(`Missing required field: ${field}`); + } + } +} + +app.post('/addquestion', async (req, res) => { + try { + // Check if required fields are present in the request body + validateRequiredFields(req, ['question', 'answers']); + + const newQuestion = new Question({ + question: req.body.question, + answers: req.body.answers, + }); + + await newQuestion.save(); + res.json(newQuestion); + } catch (error) { + res.status(400).json({ error: error.message }); + } +}); + +app.post('/addquestions', async (req, res) => { + try { + // Check if required fields are present in the request body + if (!Array.isArray(req.body)) { + throw new Error('Invalid request format. Expected an array of questions.'); + } + for (const question of req.body) { + validateRequiredFields(question, ['question', 'answers']); + } + + const newQuestions = []; + + for (const questionData of req.body) { + const newQuestion = new Question({ + question: questionData.question, + answers: questionData.answers, + }); + + await newQuestion.save(); + newQuestions.push(newQuestion); + } + + res.json(newQuestions); + } catch (error) { + res.status(400).json({ error: error.message }); + } +}); + + +app.get('/questions', async (req, res) => { + try { + const questions = await Question.find({}); // Get all questions + res.json(questions); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +const server = app.listen(port, () => { + console.log(`Store questions service listening at http://localhost:${port}`); +}); + +// Listen for the 'close' event on the Express.js server +server.on('close', () => { + // Close the Mongoose connection + mongoose.connection.close(); +}); + +module.exports = server; diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js new file mode 100644 index 00000000..425849a5 --- /dev/null +++ b/storeQuestionService/store-q.test.js @@ -0,0 +1,59 @@ +const request = require('supertest'); +const { MongoMemoryServer } = require('mongodb-memory-server'); + +let mongoServer; +let app; + +beforeAll(async () => { + mongoServer = await MongoMemoryServer.create(); + const mongoUri = mongoServer.getUri(); + process.env.MONGODB_URI = mongoUri; + app = require('./store-q-service'); +}); + +afterAll(async () => { + app.close(); + await mongoServer.stop(); +}); + +describe('Store questions service', () => { + it('should add a new question on POST /addquestion', async () => { + const newQuestion = { + question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + answers: ['Segovia','León','Valladolid','Ninguna'], + }; + + const response = await request(app).post('/addquestion').send(newQuestion); + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('question', 'answers'); + }); +}); + +describe('Store questions service', () => { + it('should get all questions on GET /questions', async () => { + const newQuestion1 = { + question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + answers: ['Segovia','León','Valladolid','Ninguna'], + }; + const newQuestion2 = { + question: '¿Cuál es la capital Italia?', + answers: ['Roma','Nápoles','Florencia','Milán'], + }; + const newQuestion3 = { + question: '¿Cuál es el país mas poblado de la tierra?', + answers: ['China','Estados Unidos','Brazil','India'], + }; + + request(app).post('/addquestion').send(newQuestion1); + request(app).post('/addquestion').send(newQuestion2); + request(app).post('/addquestion').send(newQuestion3); + + const response = await request(app).get('/questions'); + + expect(response.status).toBe(200); + expect(response.body).toEqual( + expect.arrayContaining([newQuestion1, newQuestion2, newQuestion3]) + ); + }); +}); + From a0ad56cc87d8202c6b8aa6dd2519a3d8680138bf Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Sat, 24 Feb 2024 20:49:19 +0100 Subject: [PATCH 10/94] Minor fix dokerfile --- storeQuestionService/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storeQuestionService/Dockerfile b/storeQuestionService/Dockerfile index f43e2df7..cc024411 100644 --- a/storeQuestionService/Dockerfile +++ b/storeQuestionService/Dockerfile @@ -2,7 +2,7 @@ FROM node:20 # Set the working directory in the container -WORKDIR /usr/src/userservice +WORKDIR /usr/src/storequestionservice # Copy package.json and package-lock.json to the working directory COPY package*.json ./ @@ -14,7 +14,7 @@ RUN npm install COPY . . # Expose the port the app runs on -EXPOSE 8001 +EXPOSE 8004 # Define the command to run your app -CMD ["node", "user-service.js"] +CMD ["node", "store-q-service.js"] From b8eb19908e074dd14f94aa6a9a60d1872185d0d2 Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Sun, 25 Feb 2024 19:00:02 +0100 Subject: [PATCH 11/94] Added timestampt to stored questions model --- storeQuestionService/store-q-model.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storeQuestionService/store-q-model.js b/storeQuestionService/store-q-model.js index 77ddfe45..f3423c9a 100644 --- a/storeQuestionService/store-q-model.js +++ b/storeQuestionService/store-q-model.js @@ -6,6 +6,10 @@ const questionStorageSchema = new mongoose.Schema({ required: true, }, answers: [{ type: String, required: true }], + createdAt: { + type: Date, + default: Date.now, + }, }); const Question = mongoose.model('Question', questionStorageSchema); From e7510d0a09159865fa8546f608fc5bc8b88741d1 Mon Sep 17 00:00:00 2001 From: Abel Date: Sun, 25 Feb 2024 19:54:36 +0100 Subject: [PATCH 12/94] Added ports, the gateway container and the new relations between components in the deployment view. Also changed the import of the diagram for its generating plantUML code --- docs/src/07_deployment_view.adoc | 56 +++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/docs/src/07_deployment_view.adoc b/docs/src/07_deployment_view.adoc index 84766759..ec5469dd 100644 --- a/docs/src/07_deployment_view.adoc +++ b/docs/src/07_deployment_view.adoc @@ -55,7 +55,61 @@ Describe (usually in a combination of diagrams, tables, and text): For multiple environments or alternative deployments please copy and adapt this section of arc42 for all relevant environments. **** -image::deployment.png["Deployment View"] +[plantuml,"Deployment View",png] +---- +!pragma layout smetana + +cloud "Azure Cloud" { + node "Virtual Machine" { + node "Docker" { + node "App Container"{ + node "Web App" + } + node "Gateway Container"{ + node "Gateway Service" + } + node "User Container"{ + node "User Service" + } + node "Auth Container"{ + node "Auth Service" + } + node "Game Container"{ + node "Game Generator Service" + } + node "Questions History Container"{ + node "Questions History Service" + } + node "User Stats Container"{ + node "User Stats Service" + } + node "Questions Generator Container"{ + node "Questions Generator Service" + } + } + } +} + +cloud "Wikidata" +actor "User" + + +"User" -left- "Web App" : "\t\tHTTP/port:3000\t\t" + +"Web App" -- "Gateway Service" : "port: 8000" + +"Gateway Service" -- "Questions History Service" : "port: 8004 " +"Gateway Service" -- "User Stats Service" : "port: 8003" +"Gateway Service" -up- "Auth Service" : "port: 8002 " +"Gateway Service" -up- "User Service" : "port: 8001" +"Gateway Service" -right- "Game Generator Service" : " port: 8005 " + +"Game Generator Service" -- "User Stats Service" : "port: 8003" +"Game Generator Service" -- "Questions Generator Service" : " port: 8006" + +"Questions Generator Service" -- "Questions History Service" : "port: 8004" +"Questions Generator Service" -- "Wikidata" : "HTTPS" +---- In addition to what is shown in the diagram, we will also use Graphana and Prometheus during the production stage as code monitoring systems. From cf7530aaafa9199738f7a9a307d9928589ea3ba8 Mon Sep 17 00:00:00 2001 From: Abel Date: Sun, 25 Feb 2024 19:55:45 +0100 Subject: [PATCH 13/94] Diagrams theme removed in order for them to be more cohesive with the rest of the diagrams in the documentation --- docs/src/06_runtime_view.adoc | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/docs/src/06_runtime_view.adoc b/docs/src/06_runtime_view.adoc index 5fe3e4e2..024bf5a2 100644 --- a/docs/src/06_runtime_view.adoc +++ b/docs/src/06_runtime_view.adoc @@ -41,9 +41,6 @@ See https://docs.arc42.org/section-6/[Runtime View] in the arc42 documentation. [plantuml,"Question generation 1",png] ---- - -@startuml -!theme vibrant autonumber actor "User" as user @@ -63,8 +60,6 @@ end "Game Service" -> "Question Historic Service" : Sends the shown questions "Game Service" -> "Player Statistics Service" : Sends the user's match data -@enduml - ---- In circumstances in which few questions are needed for the game, it may be possible to extract all of them in a batch without affecting performance and response times. Besides, extracting them this way opens up the possibility of using multiple threads to gather the data, greatly increasing performance. However, if the querying times are too high, this strategy may cause great delays while loading the game. A possible alternative is explained below: @@ -73,9 +68,6 @@ In circumstances in which few questions are needed for the game, it may be possi [plantuml,"Question generation 2",png] ---- - -@startuml -!theme vibrant autonumber actor "User" as user @@ -108,8 +100,6 @@ end "Game Service" -> "Question Historic Service" : Sends the shown questions "Game Service" -> "Player Statistics Service" : Sends the user's match data -@enduml - ---- In cases where a lot of questions are needed, or wikidata querying has a great impact on performance, this alternative may prove to be convenient. By distributing the data fetching along the entire match, bottlenecks on performance will be reduced. Depending on the system load (or, optionally client device's specifications!) batch sizes may vary, adapting to maintain responsiveness. @@ -118,9 +108,6 @@ In cases where a lot of questions are needed, or wikidata querying has a great i [plantuml,"Consult Statistics",png] ---- - -@startuml -!theme vibrant autonumber actor "User" as user @@ -129,16 +116,12 @@ user -> "Player Statistics Service" : Requests user data "Player Statistics Service" -> "MongoDB Server" : Makes petition through REST API "MongoDB Server" -> "Player Statistics Service" : Returns information "Player Statistics Service" -> user : Shows data -@enduml - ---- === User consults questions used in games. [plantuml,"Consult questions",png] ---- -@startuml -!theme vibrant autonumber actor "User" as user @@ -147,5 +130,4 @@ user -> "Question Historic Service" : Requests user data "Question Historic Service" -> "MongoDB Server" : Makes petition through REST API "MongoDB Server" -> "Question Historic Service" : Returns information "Question Historic Service" -> user : Shows data -@enduml ---- From 185511581e8b029a1e66b3871a44c6ac59cc6c9d Mon Sep 17 00:00:00 2001 From: Abel Date: Sun, 25 Feb 2024 20:02:41 +0100 Subject: [PATCH 14/94] Changed the imports of the diagrams for its generating plantUML code. Also added the Gateway Service to them, the new relations between components and updated the tables accordingly. --- docs/images/05_Level_3_Diagram.png | Bin 72515 -> 0 bytes docs/images/05_level1Diagram.png | Bin 5225 -> 0 bytes docs/images/05_level2Diagram.png | Bin 29778 -> 0 bytes docs/src/05_building_block_view.adoc | 118 +++++++++++++++++++++++---- 4 files changed, 104 insertions(+), 14 deletions(-) delete mode 100644 docs/images/05_Level_3_Diagram.png delete mode 100644 docs/images/05_level1Diagram.png delete mode 100644 docs/images/05_level2Diagram.png diff --git a/docs/images/05_Level_3_Diagram.png b/docs/images/05_Level_3_Diagram.png deleted file mode 100644 index 4c654c4307202b208c80a2bec17bcb1f1262d124..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72515 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 MzjR*WH*3E8U+6woVE_OC diff --git a/docs/images/05_level1Diagram.png b/docs/images/05_level1Diagram.png deleted file mode 100644 index eb2fdd2956a3a168a645d9924894ed87af207f7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5225 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 diff --git a/docs/images/05_level2Diagram.png b/docs/images/05_level2Diagram.png deleted file mode 100644 index 6e4ddedbd985d62bbf8b0a6b5c73f5b48af94895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29778 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
&_AsOh`-8-H^;1 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 diff --git a/docs/src/05_building_block_view.adoc b/docs/src/05_building_block_view.adoc index 9b7f3678..7d9d2e6b 100644 --- a/docs/src/05_building_block_view.adoc +++ b/docs/src/05_building_block_view.adoc @@ -45,8 +45,13 @@ In the best case you will get away with examples or simple signatures. === Level 1: Overall System's whitebox -image::05_level1Diagram.png[Level 1 Diagram] +[plantuml,"Level 1 Diagram",png] +---- +!pragma layout smetana +:User: -> [WIQ App] : "Interacts with" +[WIQ App] <.> [WikiData] : "Gets data" +---- ==== Motivation @@ -110,8 +115,24 @@ according the the following black box template: **** -image::05_level2Diagram.png[Level 2 Diagram] - +[plantuml,"Level 2 Diagram",png] +---- +!pragma layout smetana + +:User: +package "WIQ App" { +:User: -> [WebApp] : " Interacts " +[WebApp] <-> [Gateway Service] : Redirects Requests +[Gateway Service] <--down-> [Game Service] : Plays +[Gateway Service] <-- [Question Historic Service] : Loads data +[Gateway Service] <-- [User Statistics Service] : Loads data +[Gateway Service] <-> [UserAuth Service] : Logs in / Registers +[Game Service] -> [User Statistics Service] : Stores data +[Game Service] <-left-> [Questions Service] : Gets questions +[Questions Service] -up-> [Question Historic Service] : Stores data +} +[Questions Service] <.left.> [WikiData] : " Gets data " +---- ==== Motivation @@ -123,20 +144,86 @@ image::05_level2Diagram.png[Level 2 Diagram] |=== |Name |Description |Web App |Layer in which the user will interact directly and which will connect with the different services. +|Gateway Service |Microservice that redirects the requests from the WebApp to its corresponding microservices |Questions Service |Microservice to generate the questions used by the application from WikiData |Game Service |Microservice that implements the quiz game |Question Historic Service |Microservice that stores the generated questions for later consultation |User Statistics Service |Microservice that stores the statistics of the games played by the user. -|Authentification Service |Authentication microservice that allows the user to register and log in. +|UserAuth Service |Authentication microservices that allows the user to register and log in. |=== === Level 3 -image::05_Level_3_Diagram.png[Level 3 Diagram] +[plantuml,"Level 3 Diagram",png] +---- +!pragma layout smetana + +actor "User" +rectangle "Wikidata" + +package "WIQ App"{ + + component "WebApp" + component "Gateway Service" as GatewayS + + package "Game Service" { + component "Game Controller" + } + + package "User Statistics Service" as USS { + component "Statistics Controller" + database "Database" as USDB + } + + package "Questions Historic Service" as QHS{ + component "Question Historic Controller" as QHController + database "Database" as QhDB + } + package "Questions Service"{ + component "Wikidata Extractor" + component "Questions Generator" + database "Database" as QSDB + } + package "UserAuth Service" { + component "Auth Service" + component "User Service" + database "Database" as UADB + } +} + +User -right-> WebApp : Uses +WebApp <-right-> GatewayS: Redirects requests + +GatewayS <--up--> "UserAuth Service" : "Handles user\nlogin/registry" +GatewayS <-down-> "Game Service" : "Handles user current game\n" +GatewayS <--up-- "QHS" : "\nReceives generated\nquestions" +GatewayS <--- "USS" : "Receives\t\t\t\nuser statistics\t\t\t" + +"Game Service" <---> "Questions Service" : "Receives question petitions,\nsends questions\n\n" +"Game Service" ---> "USS" : "Sends user\t\nstatistics\t\t" +"Questions Service" -up-> "QHS" : "Sends\ngenerated\nquestions" + +"Wikidata" .up.> "Wikidata Extractor" : "Returns data" +"Wikidata" <.up. "Wikidata Extractor" : "Queries" +"Wikidata Extractor" --> QSDB +"Questions Generator" <-- QSDB +"Questions Generator" --> QSDB + +"QHController" --> QhDB +"QHController" <-- QhDB + +"Statistics Controller" --> USDB +"Statistics Controller" <-- USDB + +"Auth Service" --> UADB +"Auth Service" <-- UADB +"User Service" --> UADB +"User Service" <-- UADB +---- ==== Motivation -To display the inner architecture of the different microservices, as well as how do their components interact with themselves and with other components from other microsystems. All microservices follow the MVC architectural pattern, to the exception of the questions generator service. (since it has no UI to handle) +To display the inner architecture of the different microservices, as well as how do their components interact with themselves and with other components from other microsystems. All microservices follow the MVC architectural pattern, to the exception of those who have no UI to handle. ==== Contained Building Blocks @@ -144,11 +231,14 @@ To display the inner architecture of the different microservices, as well as how |=== |Name |Description -|Questions Generator -|Contains the required templates and proceedings to construct questions. In order to do so, it delegates the Wikidata querying to the Wikidata extractor. When the data is returned, the question is formulated through templates. +|User Service +|It retrieves the data from new users and registers them in the database. -|Wikidata Extractor -|Handles extraction and formatting of Wikidata’s output. It’s queries must cover all necessary information in order to construct the question(s), including not only the correct response, but also believable and coherent “decoy responses”. +|Auth Service +|It retrieves the data from returning users and checks if they are in the database. + +|Game Controller +|Handles all the game’s logic; where the user input’s processing takes place. It can request questions to the Questions Microservice, and also gather user statistics, to later be sent to the User Statistics Controller. |Questions Historic Controller |Receives the generated questions, and sends them to the database. Besides, it also handles recovering them from the database and sending them where they are needed. (e.g: as response from an API call, or to the UI) @@ -156,9 +246,9 @@ To display the inner architecture of the different microservices, as well as how |User Statistics Controller |Receives various information about the player’s performance in the match. There, some processing may occur before storing it in the database. Also handles retrieving the information and sending it where it’s needed (e.g: as response from an API call, or to the UI). -|Game Controller -|Handles all the game’s logic; where the user input’s processing takes place. It can request questions to the Questions Microservice, and also gather user statistics, to later be set to the User Statistics Controller. +|Questions Generator +|Contains the required templates and proceedings to construct questions. In order to do so, it delegates the Wikidata querying to the Wikidata extractor. It gets the data through the database so when the data is returned, the question is formulated through templates. -|UI for the game and statistics -|Handles appeareance and presentation. Actions taken by the user are communicated to their respective controllers, that may respond accordingly. +|Wikidata Extractor +|Handles extraction and formatting of Wikidata’s output. It’s queries must cover all necessary information in order to construct the question(s), including not only the correct response, but also believable and coherent “decoy responses”. It stores the data retrieved on the database. |=== From 36dd1b37484b2ac9c5659ca63780e6fad7148d20 Mon Sep 17 00:00:00 2001 From: Abel Date: Sun, 25 Feb 2024 20:21:40 +0100 Subject: [PATCH 15/94] Changed the import of the Technical Context diagram for its generating plantUML code --- docs/images/03_Technical_Context.png | Bin 12074 -> 0 bytes docs/src/03_system_scope_and_context.adoc | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) delete mode 100644 docs/images/03_Technical_Context.png diff --git a/docs/images/03_Technical_Context.png b/docs/images/03_Technical_Context.png deleted file mode 100644 index 9b2025517fc2284be650679658492474ae6b6b26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12074 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 Date: Sun, 25 Feb 2024 20:44:13 +0100 Subject: [PATCH 16/94] Added whitespaces to improve the formatting of the diagram --- docs/src/07_deployment_view.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/07_deployment_view.adoc b/docs/src/07_deployment_view.adoc index ec5469dd..86631271 100644 --- a/docs/src/07_deployment_view.adoc +++ b/docs/src/07_deployment_view.adoc @@ -59,7 +59,7 @@ For multiple environments or alternative deployments please copy and adapt this ---- !pragma layout smetana -cloud "Azure Cloud" { +cloud "Azure Cloud\n" { node "Virtual Machine" { node "Docker" { node "App Container"{ @@ -68,19 +68,19 @@ cloud "Azure Cloud" { node "Gateway Container"{ node "Gateway Service" } - node "User Container"{ + node " User Container "{ node "User Service" } - node "Auth Container"{ + node " Auth Container "{ node "Auth Service" } - node "Game Container"{ + node "\tGame Container\t"{ node "Game Generator Service" } node "Questions History Container"{ node "Questions History Service" } - node "User Stats Container"{ + node "User Stats Container\t"{ node "User Stats Service" } node "Questions Generator Container"{ From e2e6f3b6ee1b91d687974c6cd7c3091b655d4cd1 Mon Sep 17 00:00:00 2001 From: Liliana Date: Mon, 26 Feb 2024 19:47:40 +0100 Subject: [PATCH 17/94] =?UTF-8?q?Correcci=C3=B3n=20documentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/src/10_quality_requirements.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/10_quality_requirements.adoc b/docs/src/10_quality_requirements.adoc index 13134a57..b315bfa6 100644 --- a/docs/src/10_quality_requirements.adoc +++ b/docs/src/10_quality_requirements.adoc @@ -96,7 +96,7 @@ occurs. |The user must correctly answer questions on different topics. This will improve the user experience and maintain the interest of the participants. |High -|Integrity +|Reliability |The game must be played without errors. |The answer determined as correct for each question by the system shall be the one that is actually correct. |Medium From b2941cf28892ce3944599e9cf535735318db0135 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Thu, 29 Feb 2024 23:41:16 +0100 Subject: [PATCH 18/94] Inicio del prototipo del almacen de preguntas --- webapp/src/storeQuestion/App.jsx | 32 ++++++ .../src/storeQuestion/components/Question.jsx | 18 +++ webapp/src/storeQuestion/css/questions.css | 105 ++++++++++++++++++ webapp/src/storeQuestion/main.jsx | 10 ++ 4 files changed, 165 insertions(+) create mode 100644 webapp/src/storeQuestion/App.jsx create mode 100644 webapp/src/storeQuestion/components/Question.jsx create mode 100644 webapp/src/storeQuestion/css/questions.css create mode 100644 webapp/src/storeQuestion/main.jsx diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx new file mode 100644 index 00000000..052b0e24 --- /dev/null +++ b/webapp/src/storeQuestion/App.jsx @@ -0,0 +1,32 @@ +import Question from './components/Question'; + +function App(){ + const newQuestion = { + question: '¿Cuál es tu pregunta?', + answers: ['Respuesta 1', 'Respuesta 2', 'Respuesta 3', 'Respuesta 4'] + }; + + const newQuestion1 = { + question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + answers: ['Segovia','León','Valladolid','Ninguna'], + }; + const newQuestion2 = { + question: '¿Cuál es la capital Italia?', + answers: ['Roma','Nápoles','Florencia','Milán'], + }; + const newQuestion3 = { + question: '¿Cuál es el país mas poblado de la tierra?', + answers: ['China','Estados Unidos','Brazil','India'], + }; + + return ( + <> + + + + + + ); +} + +export default App; \ No newline at end of file diff --git a/webapp/src/storeQuestion/components/Question.jsx b/webapp/src/storeQuestion/components/Question.jsx new file mode 100644 index 00000000..cd14a5bc --- /dev/null +++ b/webapp/src/storeQuestion/components/Question.jsx @@ -0,0 +1,18 @@ +import React from 'react'; + +function Question(props) { + const { newQuestion } = props; + + return ( +
+

{newQuestion.question}

+
+ {newQuestion.answers.map((answer, index) => ( +

{answer}

+ ))} +
+
+ ); +} + +export default Question; diff --git a/webapp/src/storeQuestion/css/questions.css b/webapp/src/storeQuestion/css/questions.css new file mode 100644 index 00000000..bb400f08 --- /dev/null +++ b/webapp/src/storeQuestion/css/questions.css @@ -0,0 +1,105 @@ +/* Right Answers */ +/*{ + /* RGB & HSL params *//* + --label-r: 0; + --label-g: 255; + --label-b: 0; + --label-h: 120; + --label-s: 100; + --label-l: 50; + + --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); + --lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1)); + --lightness-threshold: 0.6; + --background-alpha: 0.18; + --border-alpha: 0.3; + --lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch)); + color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); + background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); + border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); +}*/ + +/* Wrong Answers */ +/*{ + /* RGB & HSL params *//* + --label-r: 255; + --label-g: 0; + --label-b: 0; + --label-h: 0; + --label-s: 100; + --label-l: 50; + + --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); + --lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1)); + --lightness-threshold: 0.6; + --background-alpha: 0.18; + --border-alpha: 0.3; + --lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch)); + color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); + background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); + border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); +}*/ + +.question{ + /* RGB & HSL params */ + --label-r: 128; + --label-g: 128; + --label-b: 128; + --label-h: 0; + --label-s: 0; + --label-l: 50; + + --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); + --lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1)); + --lightness-threshold: 0.6; + --background-alpha: 0.18; + --border-alpha: 0.3; + --lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch)); + color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); + background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); + border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); + +} + +body{ + background-color: #0d1117; +} + +.question .grid p{ + width: max-content; + border-style: dashed; + border-radius: 15%; + border-width: 1px; + padding: 1rem; + + /* RGB & HSL params */ + --label-r: 128; + --label-g: 128; + --label-b: 128; + --label-h: 0; + --label-s: 0; + --label-l: 50; + + --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); + --lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1)); + --lightness-threshold: 0.6; + --background-alpha: 0.18; + --border-alpha: 0.3; + --lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch)); + color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); + background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); + border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); +} + +.question .grid{ + display: grid; + grid-template-columns: auto auto; + padding: 5px; +} + +#root { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(40%, 1fr)); + padding: 5px; + grid-gap: 10px; +} diff --git a/webapp/src/storeQuestion/main.jsx b/webapp/src/storeQuestion/main.jsx new file mode 100644 index 00000000..883ef991 --- /dev/null +++ b/webapp/src/storeQuestion/main.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.jsx' +//import 'bootstrap/dist/css/bootstrap.css' + +ReactDOM.createRoot(document.getElementById('root')).render( + + + , +) From f2cea6626734c731d2ec5b3f0d259a656e2b8fea Mon Sep 17 00:00:00 2001 From: Abel Date: Fri, 1 Mar 2024 01:30:35 +0100 Subject: [PATCH 19/94] First version for the question service API --- .../questionsgenerator/Dockerfile | 20 + .../questionsgenerator/package-lock.json | 1297 +++++++++++++++++ .../questionsgenerator/package.json | 28 + .../questionsgenerator/questions-model.js | 43 + .../questionsgenerator/questions-service.js | 57 + 5 files changed, 1445 insertions(+) create mode 100644 questionsservice/questionsgenerator/Dockerfile create mode 100644 questionsservice/questionsgenerator/package-lock.json create mode 100644 questionsservice/questionsgenerator/package.json create mode 100644 questionsservice/questionsgenerator/questions-model.js create mode 100644 questionsservice/questionsgenerator/questions-service.js diff --git a/questionsservice/questionsgenerator/Dockerfile b/questionsservice/questionsgenerator/Dockerfile new file mode 100644 index 00000000..6faf38d4 --- /dev/null +++ b/questionsservice/questionsgenerator/Dockerfile @@ -0,0 +1,20 @@ +# Use an official Node.js runtime as a parent image +FROM node:20 + +# Set the working directory in the container +WORKDIR /usr/src/questionsservice/questionsgenerator + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install app dependencies +RUN npm install + +# Copy the app source code to the working directory +COPY . . + +# Expose the port the app runs on +EXPOSE 8006 + +# Define the command to run your app +CMD ["node", "questions-service.js"] diff --git a/questionsservice/questionsgenerator/package-lock.json b/questionsservice/questionsgenerator/package-lock.json new file mode 100644 index 00000000..1e7651d8 --- /dev/null +++ b/questionsservice/questionsgenerator/package-lock.json @@ -0,0 +1,1297 @@ +{ + "name": "questionsgenerator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "questionsgenerator", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^4.18.2", + "mongoose": "^8.2.0" + }, + "devDependencies": { + "nodemon": "^3.1.0" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", + "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bson": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", + "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", + "engines": { + "node": ">=16.20.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mongodb": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", + "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.0.tgz", + "integrity": "sha512-la93n6zCYRbPS+c5N9oTDAktvREy5OT9OCljp1Tah0y3+p8UPMTAoabWaLZMdzYruOtF9/9GRf6MasaZjiZP1A==", + "dependencies": { + "bson": "^6.2.0", + "kareem": "2.5.1", + "mongodb": "6.3.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", + "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/questionsservice/questionsgenerator/package.json b/questionsservice/questionsgenerator/package.json new file mode 100644 index 00000000..01986053 --- /dev/null +++ b/questionsservice/questionsgenerator/package.json @@ -0,0 +1,28 @@ +{ + "name": "questionsgenerator", + "version": "1.0.0", + "description": "Questions service, in charge of generating and returning random questions in the application", + "main": "questions-model.js", + "scripts": { + "devStart": "nodemon questions-service.js", + "start": "node questions-service.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/arquisoft/wiq_es6c.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/arquisoft/wiq_es6c/issues" + }, + "homepage": "https://github.com/arquisoft/wiq_es6c#readme", + "dependencies": { + "express": "^4.18.2", + "mongoose": "^8.2.0" + }, + "devDependencies": { + "nodemon": "^3.1.0" + } +} diff --git a/questionsservice/questionsgenerator/questions-model.js b/questionsservice/questionsgenerator/questions-model.js new file mode 100644 index 00000000..621f61bf --- /dev/null +++ b/questionsservice/questionsgenerator/questions-model.js @@ -0,0 +1,43 @@ +const mongoose = require('mongoose'); + +const questionSchema = new mongoose.Schema({ + pregunta: { + type: String, + required: true + }, + respuestas: { + type: [String], + required: true + }, + createdAt: { + type: Date, + required: true, + default: Date.now + } +}); + +const requestSchema = new mongoose.Schema({ + n_preguntas: { + type: Number, + required: true, + default: 1 + }, + n_respuestas: { + type: Number, + required: true, + default: 4 + }, + tema: { + type: String, + required: true, + default: "todos" + } +}); + +const Question = mongoose.model('Question', questionSchema); +const Request = mongoose.model('Request', requestSchema); + +module.exports = { + Question, + Request +}; \ No newline at end of file diff --git a/questionsservice/questionsgenerator/questions-service.js b/questionsservice/questionsgenerator/questions-service.js new file mode 100644 index 00000000..6b97c119 --- /dev/null +++ b/questionsservice/questionsgenerator/questions-service.js @@ -0,0 +1,57 @@ +const express = require('express'); +const mongoose = require('mongoose'); +const {Question} = require('./questions-model') +const {Request} = require('./questions-model') + +const app = express(); +const port = 8006; + +// Connect to MongoDB +const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost/questions'; +mongoose.connect(mongoUri); +const db = mongoose.connection; +db.on('error', (error) => console.error(`MongoDB connection error: ${error}`)); +db.once('open', () => console.log("Connected to MongoDB")); + +// Middleware to parse JSON in request body +app.use(express.json()); + +// Route for getting questions +app.get('/questions', async (req, res) => { + try { + const request = new Request({ + n_preguntas: Number(req.body.n_preguntas), + n_respuestas: Number(req.body.n_respuestas), + tema: req.body.tema + }); + + // TODO: Implement logic to fetch questions from MongoDB and send response + // const questions = await Question.find() + // res.json(questions) + const defaultQuestion = new Question({ + pregunta: "¿Cómo me llamo?", + respuestas: ["Abel", "Federico", "Eusebio", "Gervasio"] + }); + res.json(defaultQuestion); + } catch (error) { + // res.status(500).json({ message: error.message }) + res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +app.use((err, req, res, next) => { + console.error(`An error occurred: ${err}`); + res.status(500).send(`An error occurred: ${err.message}`); +}); + +// Start the server +const server = app.listen(port, () => { + console.log(`Questions Service listening at http://localhost:${port}`); +}); + +server.on('close', () => { + // Close the Mongoose connection + mongoose.connection.close(); + }); + +module.exports = server From 494e137f89934a3af1d8725b62070b6a22f60f9a Mon Sep 17 00:00:00 2001 From: Liliana Date: Fri, 1 Mar 2024 09:28:38 +0100 Subject: [PATCH 20/94] imagen arbol actualizada --- docs/images/QualityTree.png | Bin 80328 -> 83428 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/QualityTree.png b/docs/images/QualityTree.png index 6266b73f273723ffec6e08b42122a8b78058c596..e562dda5278faf0311450742ae7f1854cf299a2f 100644 GIT binary patch literal 83428 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
nvu&L^#}cIw;Qda!%u$0rg8Xl%ykBgy^@hzghaJ zb;ARzZx$qhXXi_LGAw=ivM*y{T;@|J@>0x5y)^mqR=cDXB-9GhVi-B8s}N0B*x;ID zA3@a&xLtHmFn!{aU@!VKP_i?4W4=i-NMb}?AxN0$(HiXacm|fCm)`B*Fqn9q|KnSh zWhHY3p;ZZN)>I%CphXiU@D|}H2a0Zx`Xoxlg}~Z^Z_N~ZVAbi&Zh}tIeXLNkHnoFQT`mmqXNYNfmDPqzANkstR^KEPZb|bdGmSRV{nw!OSCvKt!cBM@H@WcgJyE zb&sK$w34Q)uI7l!m2h=t>L274B$b-X!PDy)`fs#b{*@<5O{zz)h+4SC_JO38SN%Cuw-dxG zS3|iO^l+5QkCP>MbQn&jwbPZzK7~_V3Z&(CAG?q<+Ww7gZC;N#Gi6UMr6h;))EOyW z3XwxQB^)J(wViWSPEDiSUAN;3Vl2D~Cfyv*s~Yo=l+pytMdW!@8uFTih+H|ptLD{5 zZ$+F%xe)oWlW}{70iof4gXR?tKF*{&C7jkv-Lo1GrXJ_rH)5)Q z4*=%|#UU|J(i=iT6iVA4kqa}l7HLy6S_4wb(mt-mp`zRt!&BM^(3c&Oo-KX-w35C7ahN|veKM&o z1|ORP*z9dIC+t8TzRvqiP9v_Oiyz@MtChgnQyA|T<8AvW>TB`RO~s=N@NRYap{C&_xf(Re(07K=76psawObHd|vYc-h0(OHXAh}e%Z#!HB3X0sm&v1 zPK^x2Qb+g6RYgIDP1R$n#@K%LP9fg0s?#uY(Wa!42?zEcMx1&QQqMr5=RgBY*9)n) zhy`tfQw1dLdV*op&s~2X^f@y4_L$Igh=Tl$neOH0X@Oif8=Cmwk5R&87l1B=(iMQd zgJklf%UdUBIc#_%PbpZ1z!KVQuU5nO0yo7iRf{g5wjsVw5hgLHhqZ3)jJ9lq8f;fv*7QXmL>QtH z@&l-!og7GXDEe+gw&=oGgghiNk>ayt!||cS)Jy3SFR$J^{_Xt3N5+=)T-w`BpzThY z)m9vemm=Cl2p#vm?@}MPANjO0PVav8Q`Njutg-BMrg#}H%^hmVaV-#2Nzff)=LbSB zc0O8N#Fc=Wu;m`!l8cFYjs2ttvoeYKdFx?dqMay}nXF0Ch7UC{j3As5QS((62|?g8 zSpBhyN=e4neh-$oylK51%%|#+PTa=zWP4Po=EDks@up zrOJ1~g41tUG3Q~_W|b7l2BGn7i)Jv!0>|3y5y=Psu}>@@d5}x}@zO^z+SzOSLOg^W zS7qNS7tr=*Ug)As4t>+;`g0Dq?(<2X8H#`>g;qm!C}{V<7)*94M`RU32{4+-nDo{2 z&Tc;)tb=$> z)c|`BVSfJ$4xTrVJ-koeD?KezT5gb@=5CqiL3*HFVz&4J#|Cm>8En3N)MgFgqI>39 zWp!+kr~?13*%Q;ryuv-Hrj?1&%jhRr{LXfaa3&1Af1VBPhyZutA1M7S*$bBMZTUJs zO^()n_pQ#l8SRj&pk-w1!pR|Zqv~e%nL1Tdq6H}ln4bKo8WXCXM1^}Js`>;vE9ctb z_n)r>u65vKzf^v>t8l{9wL|=CYFpei78$3jjBO8;guUS!cUiT|z#}*Atw` zD#UcVc`@?8)3FqOeOxn?<%9s6hR^{JcruCLkO#cGko^SuONs0%2jcUa z-oS8gw%Arv(qn z$!B5xFV^v8MU};EP8vlf+Yt}F%Od_~ZQ{4-%AK%(` zk5^Ym%SVHNg3U|mw)q`^y}7@K2D)J0qN@D@seAkaA*`v;K<8X%044srjn04niJJdo z4wDR%ZbR=ZchNCu^2E>I-%MU3nA6P~mE6$_Vl)(*{!-sXSk(2L+^O7bHi12{EAKh literal 80328 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�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 z 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

aT*3hoiKN3XqM|CD@whj;E*t-q5JKy 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 From b52653e794680dd29b64f89c12e5677af3b45a5c Mon Sep 17 00:00:00 2001 From: Liliana Date: Fri, 1 Mar 2024 09:33:10 +0100 Subject: [PATCH 21/94] =?UTF-8?q?cambio=20documentaci=C3=B3n=20apartado=20?= =?UTF-8?q?10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/src/10_quality_requirements.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/10_quality_requirements.adoc b/docs/src/10_quality_requirements.adoc index b315bfa6..f48e10c7 100644 --- a/docs/src/10_quality_requirements.adoc +++ b/docs/src/10_quality_requirements.adoc @@ -96,7 +96,7 @@ occurs. |The user must correctly answer questions on different topics. This will improve the user experience and maintain the interest of the participants. |High -|Reliability +|Fiability |The game must be played without errors. |The answer determined as correct for each question by the system shall be the one that is actually correct. |Medium From fc4b0d97fef9a82f5193353b3710d778d9465cbf Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Fri, 1 Mar 2024 11:10:39 +0100 Subject: [PATCH 22/94] Fixes on structured of the data stored --- storeQuestionService/package-lock.json | 16 ---------------- storeQuestionService/package.json | 2 -- storeQuestionService/store-q-model.js | 3 ++- storeQuestionService/store-q-service.js | 20 +++++++++++--------- storeQuestionService/store-q.test.js | 16 ++++++++++------ 5 files changed, 23 insertions(+), 34 deletions(-) diff --git a/storeQuestionService/package-lock.json b/storeQuestionService/package-lock.json index a9495291..a66be16a 100644 --- a/storeQuestionService/package-lock.json +++ b/storeQuestionService/package-lock.json @@ -9,8 +9,6 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "bcrypt": "^5.1.1", - "body-parser": "^1.20.2", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" @@ -2465,20 +2463,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", diff --git a/storeQuestionService/package.json b/storeQuestionService/package.json index 94ccdbe2..97f314fc 100644 --- a/storeQuestionService/package.json +++ b/storeQuestionService/package.json @@ -18,8 +18,6 @@ }, "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { - "bcrypt": "^5.1.1", - "body-parser": "^1.20.2", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" diff --git a/storeQuestionService/store-q-model.js b/storeQuestionService/store-q-model.js index f3423c9a..ffa1730a 100644 --- a/storeQuestionService/store-q-model.js +++ b/storeQuestionService/store-q-model.js @@ -5,7 +5,8 @@ const questionStorageSchema = new mongoose.Schema({ type: String, required: true, }, - answers: [{ type: String, required: true }], + c_answer: { type: String, required: true }, + w_answers: [{ type: String, required: true }], createdAt: { type: Date, default: Date.now, diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 219f2ed2..35332720 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -25,11 +25,12 @@ function validateRequiredFields(req, requiredFields) { app.post('/addquestion', async (req, res) => { try { // Check if required fields are present in the request body - validateRequiredFields(req, ['question', 'answers']); + validateRequiredFields(req, ['question', 'c_answer','w_answers']); const newQuestion = new Question({ question: req.body.question, - answers: req.body.answers, + c_answer: req.body.answers, + w_answers: req.body.answers, }); await newQuestion.save(); @@ -46,19 +47,20 @@ app.post('/addquestions', async (req, res) => { throw new Error('Invalid request format. Expected an array of questions.'); } for (const question of req.body) { - validateRequiredFields(question, ['question', 'answers']); + validateRequiredFields(question, ['question', 'c_answer','w_answers']); } const newQuestions = []; for (const questionData of req.body) { - const newQuestion = new Question({ - question: questionData.question, - answers: questionData.answers, - }); + const newQuestion = new Question({ + question: req.body.question, + c_answer: req.body.answers, + w_answers: req.body.answers, + }); - await newQuestion.save(); - newQuestions.push(newQuestion); + await newQuestion.save(); + newQuestions.push(newQuestion); } res.json(newQuestions); diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 425849a5..1609a694 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -20,12 +20,13 @@ describe('Store questions service', () => { it('should add a new question on POST /addquestion', async () => { const newQuestion = { question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - answers: ['Segovia','León','Valladolid','Ninguna'], + c_answer: 'Ninguna', + w_answers: ['Segovia','León','Valladolid'], }; const response = await request(app).post('/addquestion').send(newQuestion); expect(response.status).toBe(200); - expect(response.body).toHaveProperty('question', 'answers'); + expect(response.body).toHaveProperty('question', 'c_answer', 'w_answers'); }); }); @@ -33,17 +34,20 @@ describe('Store questions service', () => { it('should get all questions on GET /questions', async () => { const newQuestion1 = { question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - answers: ['Segovia','León','Valladolid','Ninguna'], + c_answer: 'Ninguna', + w_answers: ['Segovia','León','Valladolid'], }; const newQuestion2 = { question: '¿Cuál es la capital Italia?', - answers: ['Roma','Nápoles','Florencia','Milán'], + c_answer: 'Roma', + w_answers: ['Nápoles','Florencia','Milán'], }; const newQuestion3 = { question: '¿Cuál es el país mas poblado de la tierra?', - answers: ['China','Estados Unidos','Brazil','India'], + c_answer: 'India', + w_answers: ['China','Estados Unidos','Brazil'], }; - + request(app).post('/addquestion').send(newQuestion1); request(app).post('/addquestion').send(newQuestion2); request(app).post('/addquestion').send(newQuestion3); From 97c355b880ca9f824716b5365b644f4ebe44e50a Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 2 Mar 2024 00:48:16 +0100 Subject: [PATCH 23/94] Added new mongodb_wiki database container and a container for the questiongenerator-service --- docker-compose.yml | 26 +++++++++++++++++++ .../Dockerfile | 4 +-- .../package-lock.json | 4 +-- .../package.json | 8 +++--- .../questiongenerator-model.js} | 0 .../questiongenerator-service.js} | 8 +++--- 6 files changed, 38 insertions(+), 12 deletions(-) rename questionsservice/{questionsgenerator => questiongeneratorservice}/Dockerfile (79%) rename questionsservice/{questionsgenerator => questiongeneratorservice}/package-lock.json (99%) rename questionsservice/{questionsgenerator => questiongeneratorservice}/package.json (75%) rename questionsservice/{questionsgenerator/questions-model.js => questiongeneratorservice/questiongenerator-model.js} (100%) rename questionsservice/{questionsgenerator/questions-service.js => questiongeneratorservice/questiongenerator-service.js} (88%) diff --git a/docker-compose.yml b/docker-compose.yml index 6d256c2a..0fd03c84 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,17 @@ services: networks: - mynetwork + mongodb_wiki: + container_name: mongodb-wiki-${teamname:-defaultASW} + image: mongo + profiles: ["dev", "prod"] + volumes: + - mongodb_wiki_data:/data/db + ports: + - "27018:27017" + networks: + - mynetwork + authservice: container_name: authservice-${teamname:-defaultASW} image: ghcr.io/arquisoft/wiq_es6c/authservice:latest @@ -39,6 +50,20 @@ services: environment: MONGODB_URI: mongodb://mongodb:27017/userdb + questiongeneratorservice: + container_name: questiongeneratorservice-${teamname:-defaultASW} + image: ghcr.io/arquisoft/wiq_es6c/questiongeneratorservice:latest + profiles: ["dev", "prod"] + build: ./questionsservice/questiongeneratorservice + depends_on: + - mongodb_wiki + ports: + - "8007:8006" + networks: + - mynetwork + environment: + MONGODB_URI: mongodb://mongodb_wiki:27017/questions + gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} image: ghcr.io/arquisoft/wiq_es6c/gatewayservice:latest @@ -102,6 +127,7 @@ services: volumes: mongodb_data: + mongodb_wiki_data: prometheus_data: grafana_data: diff --git a/questionsservice/questionsgenerator/Dockerfile b/questionsservice/questiongeneratorservice/Dockerfile similarity index 79% rename from questionsservice/questionsgenerator/Dockerfile rename to questionsservice/questiongeneratorservice/Dockerfile index 6faf38d4..1e9335e0 100644 --- a/questionsservice/questionsgenerator/Dockerfile +++ b/questionsservice/questiongeneratorservice/Dockerfile @@ -2,7 +2,7 @@ FROM node:20 # Set the working directory in the container -WORKDIR /usr/src/questionsservice/questionsgenerator +WORKDIR /usr/src/questionsservice/questiongeneratorservice # Copy package.json and package-lock.json to the working directory COPY package*.json ./ @@ -17,4 +17,4 @@ COPY . . EXPOSE 8006 # Define the command to run your app -CMD ["node", "questions-service.js"] +CMD ["node", "questiongenerator-service.js"] diff --git a/questionsservice/questionsgenerator/package-lock.json b/questionsservice/questiongeneratorservice/package-lock.json similarity index 99% rename from questionsservice/questionsgenerator/package-lock.json rename to questionsservice/questiongeneratorservice/package-lock.json index 1e7651d8..3dbf397a 100644 --- a/questionsservice/questionsgenerator/package-lock.json +++ b/questionsservice/questiongeneratorservice/package-lock.json @@ -1,11 +1,11 @@ { - "name": "questionsgenerator", + "name": "questiongeneratorservice", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "questionsgenerator", + "name": "questiongeneratorservice", "version": "1.0.0", "license": "ISC", "dependencies": { diff --git a/questionsservice/questionsgenerator/package.json b/questionsservice/questiongeneratorservice/package.json similarity index 75% rename from questionsservice/questionsgenerator/package.json rename to questionsservice/questiongeneratorservice/package.json index 01986053..cf6a7e5b 100644 --- a/questionsservice/questionsgenerator/package.json +++ b/questionsservice/questiongeneratorservice/package.json @@ -1,11 +1,11 @@ { - "name": "questionsgenerator", + "name": "questiongeneratorservice", "version": "1.0.0", "description": "Questions service, in charge of generating and returning random questions in the application", - "main": "questions-model.js", + "main": "questiongenerator-service.js", "scripts": { - "devStart": "nodemon questions-service.js", - "start": "node questions-service.js" + "devStart": "nodemon questiongenerator-service.js", + "start": "node questiongenerator-service.js" }, "repository": { "type": "git", diff --git a/questionsservice/questionsgenerator/questions-model.js b/questionsservice/questiongeneratorservice/questiongenerator-model.js similarity index 100% rename from questionsservice/questionsgenerator/questions-model.js rename to questionsservice/questiongeneratorservice/questiongenerator-model.js diff --git a/questionsservice/questionsgenerator/questions-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js similarity index 88% rename from questionsservice/questionsgenerator/questions-service.js rename to questionsservice/questiongeneratorservice/questiongenerator-service.js index 6b97c119..ce6c2d26 100644 --- a/questionsservice/questionsgenerator/questions-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -1,17 +1,17 @@ const express = require('express'); const mongoose = require('mongoose'); -const {Question} = require('./questions-model') -const {Request} = require('./questions-model') +const {Question} = require('./questiongenerator-model') +const {Request} = require('./questiongenerator-model') const app = express(); const port = 8006; // Connect to MongoDB -const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost/questions'; +const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questions'; mongoose.connect(mongoUri); const db = mongoose.connection; db.on('error', (error) => console.error(`MongoDB connection error: ${error}`)); -db.once('open', () => console.log("Connected to MongoDB")); +db.once('open', () => console.log("Connected to MongoDB: %s", mongoUri)); // Middleware to parse JSON in request body app.use(express.json()); From 1fc1f56e8c5b73eaf569f8eaa30125e29d0fe032 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:58:12 +0100 Subject: [PATCH 24/94] Fixed problem with buttons --- webapp/src/components/FirstGame.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index 3b0a3c2b..40d236f9 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -21,7 +21,7 @@ const Quiz = () => { const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedOption, setSelectedOption] = useState(null); - const [isCorrect, setIsCorrect] = useState(true); + const [isCorrect, setIsCorrect] = useState(null); const esperar = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); @@ -52,11 +52,11 @@ const Quiz = () => { const [MiCircularProgressbar, MiPercentage] = CircularProgress(100); - useEffect(() => { - if (MiPercentage === 0) { - // Realizar alguna acción cuando MiPercentage llegue a 0 - } - }, [MiPercentage]); // Este efecto se ejecuta cada vez que 'MiPercentage' cambia + // useEffect(() => { + // if (MiPercentage === 0) { + // // Realizar alguna acción cuando MiPercentage llegue a 0 + // } + // }, [MiPercentage]); // Este efecto se ejecuta cada vez que 'MiPercentage' cambia const checkAnswer = async (option) => { setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); From 0c4c976803605a4b015bf2d2cfe406e64f044d1a Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 2 Mar 2024 13:45:45 +0100 Subject: [PATCH 25/94] Added function to return the number of questions requested --- .../questiongenerator-model.js | 6 +++- .../questiongenerator-service.js | 29 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-model.js b/questionsservice/questiongeneratorservice/questiongenerator-model.js index 621f61bf..d51a3fbe 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-model.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-model.js @@ -5,7 +5,11 @@ const questionSchema = new mongoose.Schema({ type: String, required: true }, - respuestas: { + respuesta_correcta: { + type: String, + required: true + }, + respuestas_incorrectas: { type: [String], required: true }, diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index ce6c2d26..099e87dd 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -16,6 +16,29 @@ db.once('open', () => console.log("Connected to MongoDB: %s", mongoUri)); // Middleware to parse JSON in request body app.use(express.json()); +// Function to generate the required number of questions +function getQuestions(req) { + const response = []; + if ('n_preguntas' in req.body) { + const n_preguntas = Number(req.body.n_preguntas); + for (let index = 0; index < n_preguntas; index++) { + response.push(new Question({ + pregunta: "¿Cómo me llamo?", + respuesta_correcta: "Abel", + respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] + })); + } + } + else { + response.push(new Question({ + pregunta: "¿Cómo me llamo?", + respuesta_correcta: "Abel", + respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] + })); + } + return response +} + // Route for getting questions app.get('/questions', async (req, res) => { try { @@ -27,11 +50,7 @@ app.get('/questions', async (req, res) => { // TODO: Implement logic to fetch questions from MongoDB and send response // const questions = await Question.find() - // res.json(questions) - const defaultQuestion = new Question({ - pregunta: "¿Cómo me llamo?", - respuestas: ["Abel", "Federico", "Eusebio", "Gervasio"] - }); + const defaultQuestion = getQuestions(req) res.json(defaultQuestion); } catch (error) { // res.status(500).json({ message: error.message }) From 301be1a2d44bd4467a62553e02615a1be8a5e2c1 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Mon, 4 Mar 2024 14:47:47 +0100 Subject: [PATCH 26/94] First try to connect to questiongenerator api --- webapp/package-lock.json | 40 ++++++++++++++++++++++++++++++ webapp/package.json | 2 ++ webapp/src/components/FirstGame.js | 23 ++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index a4595721..303e6b1d 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -15,6 +15,7 @@ "@testing-library/react": "^14.1.2", "@testing-library/user-event": "^14.5.2", "axios": "^1.6.5", + "fetch": "^1.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.1", @@ -7432,6 +7433,17 @@ "node": ">=8" } }, + "node_modules/biskviit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/biskviit/-/biskviit-1.0.1.tgz", + "integrity": "sha512-VGCXdHbdbpEkFgtjkeoBN8vRlbj1ZRX2/mxhE8asCCRalUx2nBzOomLJv8Aw/nRt5+ccDb+tPKidg4XxcfGW4w==", + "dependencies": { + "psl": "^1.1.7" + }, + "engines": { + "node": ">=1.0.0" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -9611,6 +9623,25 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha512-bl1LAgiQc4ZWr++pNYUdRe/alecaHFeHxIJ/pNciqGdKXghaTCOwKkbKp6ye7pKZGu/GcaSXFk8PBVhgs+dJdA==", + "dependencies": { + "iconv-lite": "~0.4.13" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -11043,6 +11074,15 @@ "pend": "~1.2.0" } }, + "node_modules/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-5O8TwrGzoNblBG/jtK4NFuZwNCkZX6s5GfRNOaGtm+QGJEuNakSC/i2RW0R93KX6E0jVjNXm6O3CRN4Ql3K+yA==", + "dependencies": { + "biskviit": "1.0.1", + "encoding": "0.1.12" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 18a15f71..bf7583ba 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -10,9 +10,11 @@ "@testing-library/react": "^14.1.2", "@testing-library/user-event": "^14.5.2", "axios": "^1.6.5", + "fetch": "^1.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.1", + "react-circular-progressbar": "^2.1.0", "react-scripts": "5.0.1", "web-vitals": "^3.5.1" }, diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index 40d236f9..56c577e7 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -3,9 +3,26 @@ import { Container, Typography } from '@mui/material'; import './FirstGame.css'; import { CircularProgressbar } from 'react-circular-progressbar'; import 'react-circular-progressbar/dist/styles.css'; +import axios from 'axios'; + +const apiEndpoint = 'http://localhost:8006'; + +var jsonApi = '' + const Quiz = () => { - const questions = [ + + const getQuestions = async() => { + try { + jsonApi = await axios.get(`${apiEndpoint}/questions`); + + } catch (error) { + console.log(error.jsonApi.data.error); + } + }; + + + const questions = [ { question: '¿Cuál es la capital de España?', options: ['Madrid', 'Barcelona', 'Valencia', 'Sevilla'], @@ -58,10 +75,14 @@ const Quiz = () => { // } // }, [MiPercentage]); // Este efecto se ejecuta cada vez que 'MiPercentage' cambia + const checkAnswer = async (option) => { setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); setSelectedOption(option); + getQuestions() + console.log(jsonApi.data) + const botonIncorrecta = document.getElementById('option-' + questions[currentQuestionIndex].options.indexOf(option)) if (!isCorrect) { From b76de84d811754d7284e5f4c1b8e92e36a1f5bf8 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:58:16 +0100 Subject: [PATCH 27/94] Added the menu with navigation --- .../package-lock.json | 21 ++++ .../questiongeneratorservice/package.json | 1 + .../questiongenerator-service.js | 1 + webapp/src/components/FirstGame.js | 81 +++++++-------- webapp/src/components/Login.js | 3 +- webapp/src/components/Menu.js | 99 +++++++++++++++++++ webapp/src/index.js | 2 + 7 files changed, 168 insertions(+), 40 deletions(-) create mode 100644 webapp/src/components/Menu.js diff --git a/questionsservice/questiongeneratorservice/package-lock.json b/questionsservice/questiongeneratorservice/package-lock.json index 3dbf397a..ebaf8660 100644 --- a/questionsservice/questiongeneratorservice/package-lock.json +++ b/questionsservice/questiongeneratorservice/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^8.2.0" }, @@ -229,6 +230,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -900,6 +913,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", diff --git a/questionsservice/questiongeneratorservice/package.json b/questionsservice/questiongeneratorservice/package.json index cf6a7e5b..5685bd45 100644 --- a/questionsservice/questiongeneratorservice/package.json +++ b/questionsservice/questiongeneratorservice/package.json @@ -19,6 +19,7 @@ }, "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { + "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^8.2.0" }, diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 099e87dd..b352941e 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -42,6 +42,7 @@ function getQuestions(req) { // Route for getting questions app.get('/questions', async (req, res) => { try { + res.setHeader("Access-Control-Allow-Origin", "*"); const request = new Request({ n_preguntas: Number(req.body.n_preguntas), n_respuestas: Number(req.body.n_respuestas), diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index 56c577e7..f1c88e8a 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -4,38 +4,52 @@ import './FirstGame.css'; import { CircularProgressbar } from 'react-circular-progressbar'; import 'react-circular-progressbar/dist/styles.css'; import axios from 'axios'; +import { json } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; -const apiEndpoint = 'http://localhost:8006'; - -var jsonApi = '' +var questionsCalled = false const Quiz = () => { - const getQuestions = async() => { - try { - jsonApi = await axios.get(`${apiEndpoint}/questions`); + const questions = useLocation().state.questions; + console.log(questions) + + // useEffect (() => { + // if (!isApiCalledRef) { + // getQuestions(); + // isApiCalledRef = true; + // } + // }, []); // Dependencia vacía para ejecutar solo al montar el componente + + // const getQuestions = async () => { + // try { + // const response = await axios.get(`${apiEndpoint}/questions`); + // for (var i = 0; i < response.data.length; i++) { + // var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]] + // possibleAnswers = shuffleArray(possibleAnswers) + // console.log(possibleAnswers) + // questions.push({ + // question: response.data[0].pregunta, + // options: possibleAnswers, + // correctAnswer: response.data[i].respuesta_correcta + // }) + // } + // console.log(questions) + + // } catch (error) { + // console.error(error); + // } + // }; + // const getQuestions = async() => { + // try { + // jsonApi = await axios.get(`${apiEndpoint}/questions`); - } catch (error) { - console.log(error.jsonApi.data.error); - } - }; + // } catch (error) { + // console.log(error.jsonApi.data.error); + // } + // }; - - const questions = [ - { - question: '¿Cuál es la capital de España?', - options: ['Madrid', 'Barcelona', 'Valencia', 'Sevilla'], - correctAnswer: 'Madrid', - }, - { - question: '¿Cual es la capital de Francia?', - options: ['Touluse', 'Paris', 'Lyon', 'Marseille'], - correctAnswer: 'Paris' - } - // Agrega más preguntas aquí - ]; - const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedOption, setSelectedOption] = useState(null); const [isCorrect, setIsCorrect] = useState(null); @@ -67,7 +81,7 @@ const Quiz = () => { ); } - const [MiCircularProgressbar, MiPercentage] = CircularProgress(100); + // const [MiCircularProgressbar, MiPercentage] = CircularProgress(100); // useEffect(() => { // if (MiPercentage === 0) { @@ -80,9 +94,6 @@ const Quiz = () => { setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); setSelectedOption(option); - getQuestions() - console.log(jsonApi.data) - const botonIncorrecta = document.getElementById('option-' + questions[currentQuestionIndex].options.indexOf(option)) if (!isCorrect) { @@ -97,8 +108,6 @@ const Quiz = () => { await esperar(2000); // Espera 2000 milisegundos (2 segundos) botonIncorrecta.style.backgroundColor = 'lightgrey' botonCorrecta.style.backgroundColor = 'lightgrey' - console.log(questions.length-1) - console.log(currentQuestionIndex) if (questions.length-1 !== currentQuestionIndex) { setCurrentQuestionIndex((prevIndex) => prevIndex + 1); @@ -108,9 +117,7 @@ const Quiz = () => { }; return ( - - - +

@@ -119,7 +126,7 @@ const Quiz = () => {
- {MiCircularProgressbar} + {/* {MiCircularProgressbar} */}
{questions[currentQuestionIndex].options.map((option, index) => ( @@ -134,11 +141,7 @@ const Quiz = () => { {option}
- - - ) - )}
diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login.js index b9d17bab..8937360d 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login.js @@ -27,7 +27,7 @@ const Login = () => { setLoginSuccess(true); setOpenSnackbar(true); - navigation("/firstGame") + navigation("/menu") } catch (error) { setError(error.response.data.error); @@ -38,6 +38,7 @@ const Login = () => { setOpenSnackbar(false); }; + return ( {loginSuccess ? ( diff --git a/webapp/src/components/Menu.js b/webapp/src/components/Menu.js new file mode 100644 index 00000000..0a759a3c --- /dev/null +++ b/webapp/src/components/Menu.js @@ -0,0 +1,99 @@ +import React, { useState, useEffect } from 'react'; +import { Container, Typography } from '@mui/material'; +import './FirstGame.css'; +import 'react-circular-progressbar/dist/styles.css'; +import axios from 'axios'; +import { json } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; // Importa useHistory + +const apiEndpoint = 'http://localhost:8006'; + +var jsonApi = '' + +var isApiCalledRef = false; + + +const DatosContext = React.createContext(); + +var questions = [] + +function shuffleArray(array) { + // Crea una copia del array original + const shuffledArray = [...array]; + + // Recorre el array desde el último elemento hasta el primero + for (let i = shuffledArray.length - 1; i > 0; i--) { + // Genera un índice aleatorio entre 0 y el índice actual + const randomIndex = Math.floor(Math.random() * (i + 1)); + + // Intercambia el elemento actual con el elemento del índice aleatorio + const temp = shuffledArray[i]; + shuffledArray[i] = shuffledArray[randomIndex]; + shuffledArray[randomIndex] = temp; + } + + // Devuelve el array barajado + return shuffledArray; +} + +// useEffect (() => { +// if (!isApiCalledRef) { +// getQuestions(); +// isApiCalledRef = true; +// } +// }, []); + + + + +const Menu = () => { + + const [n_preguntas, setn_preguntas] = useState(5); + + const navigation = useNavigate(); // Añade esto + + const initiateGame = async () => { + if (!isApiCalledRef) { + await getQuestions() + } + isApiCalledRef = true + navigation("/firstGame", {state: {questions}}) + } + + const getQuestions = async () => { + try { + setn_preguntas(5) + const response = await axios.get(`${apiEndpoint}/questions`, {n_preguntas}); + console.log(response.data.length) + for (var i = 0; i < response.data.length; i++) { + var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]] + possibleAnswers = shuffleArray(possibleAnswers) + questions.push({ + question: response.data[0].pregunta, + options: possibleAnswers, + correctAnswer: response.data[i].respuesta_correcta + }) + } + } catch (error) { + console.error(error); + } + console.log(questions) + }; + + return ( + +

Bienvenido a wiq_06c por favor seleccione un modo de juego para comenzar partida:

+ +
+ ); + +} + + +export default Menu; diff --git a/webapp/src/index.js b/webapp/src/index.js index f0e61d85..da7de47c 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -15,6 +15,7 @@ import { } from "react-router-dom"; import FirstGame from './components/FirstGame'; +import Menu from './components/Menu'; const root = ReactDOM.createRoot(document.getElementById('root')); @@ -24,6 +25,7 @@ root.render( }> }> + }> From e8417a700dda898d8907d459e95ce830cf05417c Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Thu, 7 Mar 2024 14:04:23 +0100 Subject: [PATCH 28/94] =?UTF-8?q?Avance=20conexi=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 14 + storeQuestionService/package-lock.json | 417 ++----------------------- storeQuestionService/package.json | 1 + webapp/src/storeQuestion/App.jsx | 36 ++- 4 files changed, 71 insertions(+), 397 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6d256c2a..87efb266 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -99,6 +99,20 @@ services: depends_on: - prometheus + storequestion: + container_name: storequestion-${teamname:-defaultASW} + image: ghcr.io/arquisoft/wiq_es6c/storequestionservice:latest + profiles: ["dev", "prod"] + build: ./storequestionservice + depends_on: + - mongodb + ports: + - "8004:8004" + networks: + - mynetwork + environment: + MONGODB_URI: mongodb://mongodb:27017/userdb + volumes: mongodb_data: diff --git a/storeQuestionService/package-lock.json b/storeQuestionService/package-lock.json index a66be16a..78bc36fc 100644 --- a/storeQuestionService/package-lock.json +++ b/storeQuestionService/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "body-parser": "^1.20.2", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" @@ -1084,25 +1085,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", @@ -1252,11 +1234,6 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1269,38 +1246,6 @@ "node": ">= 0.6" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1320,6 +1265,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1352,23 +1298,6 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1529,20 +1458,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">= 10.0.0" - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/body-parser": { "version": "1.20.2", @@ -1571,6 +1488,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1741,14 +1659,6 @@ "node": ">=10" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -1818,14 +1728,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1856,12 +1758,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -1995,11 +1893,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2017,14 +1910,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2087,7 +1972,8 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -2436,32 +2322,11 @@ "node": ">= 0.6" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/function-bind": { "version": "1.1.2", @@ -2471,25 +2336,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2547,6 +2393,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2630,11 +2477,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -2676,39 +2518,6 @@ "node": ">= 0.8" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -2761,6 +2570,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2807,6 +2617,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -3694,6 +3505,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "dependencies": { "semver": "^6.0.0" }, @@ -3708,6 +3520,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -3809,6 +3622,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3816,48 +3630,6 @@ "node": "*" } }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mongodb": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", @@ -4179,49 +3951,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4234,20 +3963,6 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4269,25 +3984,6 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -4311,6 +4007,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" } @@ -4420,6 +4117,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -4612,19 +4310,6 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4681,20 +4366,6 @@ "node": ">=10" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4775,11 +4446,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, "node_modules/set-function-length": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", @@ -4841,7 +4507,8 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/sisteransi": { "version": "1.0.5", @@ -4945,14 +4612,6 @@ "queue-tick": "^1.0.1" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -4970,6 +4629,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4983,6 +4643,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5113,22 +4774,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/tar-stream": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", @@ -5282,11 +4927,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -5361,14 +5001,6 @@ "node": ">= 8" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -5389,7 +5021,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/write-file-atomic": { "version": "4.0.2", diff --git a/storeQuestionService/package.json b/storeQuestionService/package.json index 97f314fc..b320d87f 100644 --- a/storeQuestionService/package.json +++ b/storeQuestionService/package.json @@ -18,6 +18,7 @@ }, "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { + "body-parser": "^1.20.2", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 052b0e24..5c9194a5 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -1,7 +1,10 @@ import Question from './components/Question'; +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import './css/questions.css'; function App(){ - const newQuestion = { + /*const newQuestion = { question: '¿Cuál es tu pregunta?', answers: ['Respuesta 1', 'Respuesta 2', 'Respuesta 3', 'Respuesta 4'] }; @@ -17,16 +20,39 @@ function App(){ const newQuestion3 = { question: '¿Cuál es el país mas poblado de la tierra?', answers: ['China','Estados Unidos','Brazil','India'], - }; + };*/ + + const [preguntas, setPreguntas] = useState([]); + + useEffect(() => { + const obtenerPreguntas = async () => { + try { + const response = await axios.get('http://localhost:8004/questions').then(setPreguntas(response.data)).error(); + console.log(response) + //setPreguntas(response.data); + } catch (error) { + console.error('Error al obtener las preguntas:', error.response.data.error); + } + }; + obtenerPreguntas(); + }, []); + + return ( - <> + <> + {preguntas.map(question => ( + + ))} + + ); + + /* - - ); + */ } export default App; \ No newline at end of file From e71ea923b63c4f1d94bc47a0bef05381bfe8c760 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Thu, 7 Mar 2024 18:00:43 +0100 Subject: [PATCH 29/94] Unfortunately, light mode --- webapp/src/storeQuestion/css/questions.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/storeQuestion/css/questions.css b/webapp/src/storeQuestion/css/questions.css index bb400f08..550dd804 100644 --- a/webapp/src/storeQuestion/css/questions.css +++ b/webapp/src/storeQuestion/css/questions.css @@ -62,7 +62,7 @@ } body{ - background-color: #0d1117; + background-color: #fff; } .question .grid p{ From e8e7da740eae09dbe67ee216ec890af3290bff35 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Thu, 7 Mar 2024 18:02:38 +0100 Subject: [PATCH 30/94] added commented data for testing purpose --- webapp/src/storeQuestion/App.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 5c9194a5..ec088a1c 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -20,7 +20,9 @@ function App(){ const newQuestion3 = { question: '¿Cuál es el país mas poblado de la tierra?', answers: ['China','Estados Unidos','Brazil','India'], - };*/ + }; + + let preguntas = [newQuestion, newQuestion1, newQuestion2, newQuestion3]*/ const [preguntas, setPreguntas] = useState([]); From 3534e7d9e24c558534bd23fea26c229b44edef02 Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Fri, 8 Mar 2024 09:24:13 +0100 Subject: [PATCH 31/94] Minor fixes --- docker-compose.yml | 2 +- storeQuestionService/store-q-service.js | 2 +- webapp/src/storeQuestion/App.jsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 87efb266..ededb8ec 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,7 +111,7 @@ services: networks: - mynetwork environment: - MONGODB_URI: mongodb://mongodb:27017/userdb + MONGODB_URI: mongodb://mongodb:27017/storedquestion volumes: diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 35332720..a51beaec 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -10,7 +10,7 @@ const port = 8004; app.use(bodyParser.json()); // Connect to MongoDB -const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/userdb'; +const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/storedquestion'; mongoose.connect(mongoUri); // Function to validate required fields in the request body diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 5c9194a5..cc10d10e 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -27,7 +27,7 @@ function App(){ useEffect(() => { const obtenerPreguntas = async () => { try { - const response = await axios.get('http://localhost:8004/questions').then(setPreguntas(response.data)).error(); + const response = await axios.get('http://localhost:8004').then(setPreguntas(response.data)).error(); console.log(response) //setPreguntas(response.data); } catch (error) { From d3104ab53aef3a68cd0813a61597eb1397be503d Mon Sep 17 00:00:00 2001 From: Marcos Barril Villaverde Date: Fri, 8 Mar 2024 09:48:17 +0100 Subject: [PATCH 32/94] Minor fix --- webapp/src/storeQuestion/App.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 935d3845..94c6f683 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -26,12 +26,15 @@ function App(){ const [preguntas, setPreguntas] = useState([]); + const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + useEffect(() => { + const obtenerPreguntas = async () => { try { - const response = await axios.get('http://localhost:8004').then(setPreguntas(response.data)).error(); + const response = await axios.gets(`${apiEndpoint}/questions`).then(setPreguntas(response.data)).error(); console.log(response) - //setPreguntas(response.data); + setPreguntas(response.data); } catch (error) { console.error('Error al obtener las preguntas:', error.response.data.error); } From 2a058914265c5fa550f1e3e61bbcb7ebba1683e2 Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 9 Mar 2024 01:50:06 +0100 Subject: [PATCH 33/94] Changed the way the parameters were received and added more mocked questions --- .../questiongenerator-service.js | 104 +++++++++++++----- 1 file changed, 75 insertions(+), 29 deletions(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 099e87dd..a02ba53b 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -1,10 +1,10 @@ const express = require('express'); const mongoose = require('mongoose'); -const {Question} = require('./questiongenerator-model') -const {Request} = require('./questiongenerator-model') +const { Question } = require('./questiongenerator-model') +const { Request } = require('./questiongenerator-model') const app = express(); -const port = 8006; +const port = 8006; // Connect to MongoDB const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questions'; @@ -16,38 +16,84 @@ db.once('open', () => console.log("Connected to MongoDB: %s", mongoUri)); // Middleware to parse JSON in request body app.use(express.json()); +const mockedQuestions = [ + { + pregunta: "¿Cómo me llamo?", + respuesta_correcta: "Abel", + respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] + }, + { + pregunta: "¿Cuál es el río más largo del mundo?", + respuesta_correcta: "Amazonas", + respuestas_incorrectas: ["Nilo", "Misisipi", "Yangtsé"] + }, + { + pregunta: "¿En qué año comenzó la Segunda Guerra Mundial?", + respuesta_correcta: "1939", + respuestas_incorrectas: ["1941", "1942", "1945"] + }, + { + pregunta: "¿Quién escribió 'El Quijote'?", + respuesta_correcta: "Miguel de Cervantes", + respuestas_incorrectas: ["Garcilaso de la Vega", "Federico García Lorca", "Pablo Neruda"] + }, + { + pregunta: "¿Cuál es el símbolo químico del oro?", + respuesta_correcta: "Au", + respuestas_incorrectas: ["Ag", "Fe", "Cu"] + }, + { + pregunta: "¿Cuál es el planeta más grande del sistema solar?", + respuesta_correcta: "Júpiter", + respuestas_incorrectas: ["Saturno", "Marte", "Venus"] + }, + { + pregunta: "¿Quién pintó la 'Mona Lisa'?", + respuesta_correcta: "Leonardo da Vinci", + respuestas_incorrectas: ["Pablo Picasso", "Vincent van Gogh", "Rembrandt"] + }, + { + pregunta: "¿En qué país se encuentra la Torre Eiffel?", + respuesta_correcta: "Francia", + respuestas_incorrectas: ["Italia", "España", "Alemania"] + }, + { + pregunta: "¿Qué año marcó el fin de la Segunda Guerra Mundial?", + respuesta_correcta: "1945", + respuestas_incorrectas: ["1943", "1944", "1946"] + }, + { + pregunta: "¿Quién escribió 'Romeo y Julieta'?", + respuesta_correcta: "William Shakespeare", + respuestas_incorrectas: ["Jane Austen", "Charles Dickens", "F. Scott Fitzgerald"] + }, + { + pregunta: "¿Qué inventó Thomas Edison?", + respuesta_correcta: "Bombilla eléctrica", + respuestas_incorrectas: ["Teléfono", "Automóvil", "Avión"] + } +] + // Function to generate the required number of questions function getQuestions(req) { + const { n_preguntas, n_respuestas, tema } = req.query; + var preguntas = Number(n_preguntas); + var respuestas = Number(n_respuestas); + var temad = String(tema); + + if (isNaN(preguntas)) { + return mockedQuestions.slice(0, 4); + } const response = []; - if ('n_preguntas' in req.body) { - const n_preguntas = Number(req.body.n_preguntas); - for (let index = 0; index < n_preguntas; index++) { - response.push(new Question({ - pregunta: "¿Cómo me llamo?", - respuesta_correcta: "Abel", - respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] - })); + for (let i = 0; i < preguntas; i++) { + response.push(mockedQuestions[i % 11]); } - } - else { - response.push(new Question({ - pregunta: "¿Cómo me llamo?", - respuesta_correcta: "Abel", - respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] - })); - } - return response + return response } // Route for getting questions app.get('/questions', async (req, res) => { try { - const request = new Request({ - n_preguntas: Number(req.body.n_preguntas), - n_respuestas: Number(req.body.n_respuestas), - tema: req.body.tema - }); - // TODO: Implement logic to fetch questions from MongoDB and send response // const questions = await Question.find() const defaultQuestion = getQuestions(req) @@ -69,8 +115,8 @@ const server = app.listen(port, () => { }); server.on('close', () => { - // Close the Mongoose connection - mongoose.connection.close(); - }); + // Close the Mongoose connection + mongoose.connection.close(); +}); module.exports = server From 24df8f232493b96f659a18d1956febc78a784fb8 Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 9 Mar 2024 21:04:12 +0100 Subject: [PATCH 34/94] Added Cors dependency to let the webapp temporaly make request to the service directly (without passing through the gateway) --- questionsservice/questiongeneratorservice/package.json | 1 + .../questiongeneratorservice/questiongenerator-service.js | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/questionsservice/questiongeneratorservice/package.json b/questionsservice/questiongeneratorservice/package.json index cf6a7e5b..a55addc6 100644 --- a/questionsservice/questiongeneratorservice/package.json +++ b/questionsservice/questiongeneratorservice/package.json @@ -20,6 +20,7 @@ "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "express": "^4.18.2", + "cors": "^2.8.5", "mongoose": "^8.2.0" }, "devDependencies": { diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index a02ba53b..ffaec5f4 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -1,4 +1,5 @@ const express = require('express'); +const cors = require('cors'); const mongoose = require('mongoose'); const { Question } = require('./questiongenerator-model') const { Request } = require('./questiongenerator-model') @@ -16,6 +17,9 @@ db.once('open', () => console.log("Connected to MongoDB: %s", mongoUri)); // Middleware to parse JSON in request body app.use(express.json()); +// Middleware to enable CORS (cross-origin resource sharing). In order for the API to be accessible by other origins (domains). +app.use(cors()); + const mockedQuestions = [ { pregunta: "¿Cómo me llamo?", From 3dc210a3833ce609407f467310dd31137f553c6c Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 9 Mar 2024 21:26:48 +0100 Subject: [PATCH 35/94] Removed unnecesary line --- .../questiongeneratorservice/questiongenerator-service.js | 1 - 1 file changed, 1 deletion(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 3e4e8f90..ffaec5f4 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -98,7 +98,6 @@ function getQuestions(req) { // Route for getting questions app.get('/questions', async (req, res) => { try { - // res.setHeader("Access-Control-Allow-Origin", "*"); // TODO: Implement logic to fetch questions from MongoDB and send response // const questions = await Question.find() const defaultQuestion = getQuestions(req) From 67d4aad788dc43c52726c769f08dd92576815e32 Mon Sep 17 00:00:00 2001 From: Abel Date: Sat, 9 Mar 2024 21:27:51 +0100 Subject: [PATCH 36/94] Added query params (hardcoded) and fixed question display --- webapp/src/components/Menu.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webapp/src/components/Menu.js b/webapp/src/components/Menu.js index 0a759a3c..76bc4110 100644 --- a/webapp/src/components/Menu.js +++ b/webapp/src/components/Menu.js @@ -6,7 +6,7 @@ import axios from 'axios'; import { json } from 'react-router-dom'; import { useNavigate } from 'react-router-dom'; // Importa useHistory -const apiEndpoint = 'http://localhost:8006'; +const apiEndpoint = 'http://localhost:8007'; var jsonApi = '' @@ -63,13 +63,13 @@ const Menu = () => { const getQuestions = async () => { try { setn_preguntas(5) - const response = await axios.get(`${apiEndpoint}/questions`, {n_preguntas}); + const response = await axios.get(`${apiEndpoint}/questions?n_preguntas=${n_preguntas}`); console.log(response.data.length) for (var i = 0; i < response.data.length; i++) { var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]] possibleAnswers = shuffleArray(possibleAnswers) questions.push({ - question: response.data[0].pregunta, + question: response.data[i].pregunta, options: possibleAnswers, correctAnswer: response.data[i].respuesta_correcta }) From cac634d04fca137efc8ac2db95d5c3833edf4118 Mon Sep 17 00:00:00 2001 From: Liliana Date: Mon, 11 Mar 2024 20:26:15 +0100 Subject: [PATCH 37/94] =?UTF-8?q?barra=20de=20navegaci=C3=B3n=20y=20pie=20?= =?UTF-8?q?de=20p=C3=A1gina?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Footer.js | 14 ++++++++++ webapp/src/components/NavBar.css | 46 ++++++++++++++++++++++++++++++++ webapp/src/components/NavBar.js | 29 ++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 webapp/src/components/Footer.js create mode 100644 webapp/src/components/NavBar.css create mode 100644 webapp/src/components/NavBar.js diff --git a/webapp/src/components/Footer.js b/webapp/src/components/Footer.js new file mode 100644 index 00000000..7059ad28 --- /dev/null +++ b/webapp/src/components/Footer.js @@ -0,0 +1,14 @@ +import { AppBar, Toolbar, Typography } from '@mui/material'; + +const Footer = () => { + return ( + + + © WIQ_ES6C + + + ); +}; + +export default Footer; \ No newline at end of file diff --git a/webapp/src/components/NavBar.css b/webapp/src/components/NavBar.css new file mode 100644 index 00000000..54516ebe --- /dev/null +++ b/webapp/src/components/NavBar.css @@ -0,0 +1,46 @@ +nav { + background-color: #1c57c4; + color: #fff; + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 20px; +} + +.logo img { + max-width: 100px; +} + +.nav-links { + list-style: none; + display: flex; + align-items: center; +} + +.nav-links li { + margin-right: 5%; +} + +.nav-links li:last-child { + margin-right: 0%; +} + +.nav-links a { + text-decoration: none; + color: #fff; +} + +.nav-links button { + background-color: transparent; + border: none; + color: #fff; + cursor: pointer; +} + +.nav-links button:hover { + text-decoration: underline; +} + +.nav-links { + margin-left: auto; +} \ No newline at end of file diff --git a/webapp/src/components/NavBar.js b/webapp/src/components/NavBar.js new file mode 100644 index 00000000..392baf94 --- /dev/null +++ b/webapp/src/components/NavBar.js @@ -0,0 +1,29 @@ +import React from 'react'; +import './NavBar.css'; +import { Link } from 'react-router-dom'; + +const Navbar = ({ loggedIn, handleLogout }) => { + return ( + + ); +}; + +export default Navbar; \ No newline at end of file From 0f1f85ac4d9a8395388c44e204780e01605de312 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Tue, 12 Mar 2024 15:57:57 +0100 Subject: [PATCH 38/94] connection fixed, pending style improvement --- docker-compose.yml | 3 ++- gatewayservice/gateway-service.js | 9 +++++++ storeQuestionService/package-lock.json | 21 +++++++++++++++ storeQuestionService/package.json | 1 + webapp/src/storeQuestion/App.jsx | 11 +++++--- .../src/storeQuestion/components/Question.jsx | 7 ++--- webapp/src/storeQuestion/css/questions.css | 26 +++++++++++++++++++ 7 files changed, 70 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ededb8ec..8c92917b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,7 @@ services: environment: AUTH_SERVICE_URL: http://authservice:8002 USER_SERVICE_URL: http://userservice:8001 + STORE_QUESTION_SERVICE_URL: http://storequestionservice:8004 webapp: container_name: webapp-${teamname:-defaultASW} @@ -99,7 +100,7 @@ services: depends_on: - prometheus - storequestion: + storequestionservice: container_name: storequestion-${teamname:-defaultASW} image: ghcr.io/arquisoft/wiq_es6c/storequestionservice:latest profiles: ["dev", "prod"] diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 88b84c8f..2d3732d6 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -8,6 +8,7 @@ const port = 8000; const authServiceUrl = process.env.AUTH_SERVICE_URL || 'http://localhost:8002'; const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8001'; +const storeQuestionsServiceUrl = process.env.STORE_QUESTION_SERVICE_URL || 'http://localhost:8004' app.use(cors()); app.use(express.json()); @@ -41,6 +42,14 @@ app.post('/adduser', async (req, res) => { } }); +app.get('/questions', async (req, res) => { + try { + const response = await axios.get(storeQuestionsServiceUrl+'/questions'); + res.json(response.data); + } catch (error) { + } +}) + // Start the gateway service const server = app.listen(port, () => { console.log(`Gateway Service listening at http://localhost:${port}`); diff --git a/storeQuestionService/package-lock.json b/storeQuestionService/package-lock.json index 78bc36fc..b123e6b1 100644 --- a/storeQuestionService/package-lock.json +++ b/storeQuestionService/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "body-parser": "^1.20.2", + "cors": "^2.8.5", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" @@ -1805,6 +1806,18 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3984,6 +3997,14 @@ "node": ">=8" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", diff --git a/storeQuestionService/package.json b/storeQuestionService/package.json index b320d87f..11ee8410 100644 --- a/storeQuestionService/package.json +++ b/storeQuestionService/package.json @@ -19,6 +19,7 @@ "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "body-parser": "^1.20.2", + "cors": "^2.8.5", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.4" diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 94c6f683..1d3e0318 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -32,7 +32,7 @@ function App(){ const obtenerPreguntas = async () => { try { - const response = await axios.gets(`${apiEndpoint}/questions`).then(setPreguntas(response.data)).error(); + const response = await axios.get(`${apiEndpoint}/questions`) console.log(response) setPreguntas(response.data); } catch (error) { @@ -46,9 +46,12 @@ function App(){ return ( <> - {preguntas.map(question => ( - - ))} +

Almacén de preguntas

+
+ {preguntas.map(question => ( + + ))} +
); diff --git a/webapp/src/storeQuestion/components/Question.jsx b/webapp/src/storeQuestion/components/Question.jsx index cd14a5bc..4b6bf6d7 100644 --- a/webapp/src/storeQuestion/components/Question.jsx +++ b/webapp/src/storeQuestion/components/Question.jsx @@ -7,9 +7,10 @@ function Question(props) {

{newQuestion.question}

- {newQuestion.answers.map((answer, index) => ( -

{answer}

- ))} +

{newQuestion.c_answer}

+ {newQuestion.w_answers.map((answer, index) => ( +

{answer}

+ ))}
); diff --git a/webapp/src/storeQuestion/css/questions.css b/webapp/src/storeQuestion/css/questions.css index 550dd804..75f6c881 100644 --- a/webapp/src/storeQuestion/css/questions.css +++ b/webapp/src/storeQuestion/css/questions.css @@ -91,6 +91,32 @@ body{ border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); } +.question .grid p .right{ + width: max-content; + border-style: dashed; + border-radius: 15%; + border-width: 1px; + padding: 1rem; + + /* RGB & HSL params */ + --label-r: 0; + --label-g: 255; + --label-b: 0; + --label-h: 120; + --label-s: 100; + --label-l: 50; + + --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); + --lightness-switch: max(0, min(calc((1/(var(--lightness-threshold) - var(--perceived-lightness)))), 1)); + --lightness-threshold: 0.6; + --background-alpha: 0.18; + --border-alpha: 0.3; + --lighten-by: calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch)); + color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); + background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); + border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); +} + .question .grid{ display: grid; grid-template-columns: auto auto; From 7fde766490ffa4555bb58aeabec0b696a34a9657 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Tue, 12 Mar 2024 16:01:08 +0100 Subject: [PATCH 39/94] commented code for testing purposes --- storeQuestionService/store-q-service.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index a51beaec..e3d4bf2b 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -72,8 +72,18 @@ app.post('/addquestions', async (req, res) => { app.get('/questions', async (req, res) => { try { + res.setHeader("Access-Control-Allow-Origin", "*");//Puede ser innecesario? const questions = await Question.find({}); // Get all questions res.json(questions); + /*res.json([{ //FORMATO VIEJO + question: '¿Cuál es la capital de la comunidad autónoma de Casstilla y León?', + answers: ['Segovia','León','Valladolid','Ninguna'], + }]);*/ + /*res.json([{ + question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + c_answer: 'Ninguna', + w_answers: ['Segovia','León','Valladolid'] + }]);*/ } catch (error) { res.status(500).json({ error: error.message }); } From 2ccfc612a1fd7385acd61df7d0749c61de585927 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Tue, 12 Mar 2024 16:40:15 +0100 Subject: [PATCH 40/94] Style done --- webapp/src/storeQuestion/css/questions.css | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/webapp/src/storeQuestion/css/questions.css b/webapp/src/storeQuestion/css/questions.css index 75f6c881..8ff1daf3 100644 --- a/webapp/src/storeQuestion/css/questions.css +++ b/webapp/src/storeQuestion/css/questions.css @@ -58,7 +58,8 @@ color: hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%)); background: rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha)); border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); - + border-radius: 3%; + border-style: dashed; } body{ @@ -91,7 +92,7 @@ body{ border-color: hsla(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%), var(--border-alpha)); } -.question .grid p .right{ +.question .grid p.right{ width: max-content; border-style: dashed; border-radius: 15%; @@ -103,7 +104,7 @@ body{ --label-g: 255; --label-b: 0; --label-h: 120; - --label-s: 100; + --label-s: 50; --label-l: 50; --perceived-lightness: calc( ((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255 ); @@ -123,7 +124,13 @@ body{ padding: 5px; } -#root { + +h2{ + width: 100%; + text-align: center; +} + +#root main{ display: grid; grid-template-columns: repeat(auto-fit, minmax(40%, 1fr)); padding: 5px; From 4396167bf16dfccc3807b2dab7cf9911cc0664eb Mon Sep 17 00:00:00 2001 From: Liliana Date: Tue, 12 Mar 2024 19:50:08 +0100 Subject: [PATCH 41/94] change check answers --- webapp/src/components/FirstGame.js | 82 ++---------------------------- 1 file changed, 4 insertions(+), 78 deletions(-) diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index f1c88e8a..003a5be6 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -8,98 +8,26 @@ import { json } from 'react-router-dom'; import { useLocation } from 'react-router-dom'; -var questionsCalled = false - const Quiz = () => { - const questions = useLocation().state.questions; - console.log(questions) - - // useEffect (() => { - // if (!isApiCalledRef) { - // getQuestions(); - // isApiCalledRef = true; - // } - // }, []); // Dependencia vacía para ejecutar solo al montar el componente - // const getQuestions = async () => { - // try { - // const response = await axios.get(`${apiEndpoint}/questions`); - // for (var i = 0; i < response.data.length; i++) { - // var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]] - // possibleAnswers = shuffleArray(possibleAnswers) - // console.log(possibleAnswers) - // questions.push({ - // question: response.data[0].pregunta, - // options: possibleAnswers, - // correctAnswer: response.data[i].respuesta_correcta - // }) - // } - // console.log(questions) - - // } catch (error) { - // console.error(error); - // } - // }; - // const getQuestions = async() => { - // try { - // jsonApi = await axios.get(`${apiEndpoint}/questions`); - - // } catch (error) { - // console.log(error.jsonApi.data.error); - // } - // }; - - const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); - const [selectedOption, setSelectedOption] = useState(null); - const [isCorrect, setIsCorrect] = useState(null); + const [currentQuestionIndex, setCurrentQuestionIndex] = React.useState(0); + const [selectedOption, setSelectedOption] = React.useState(null); + const [isCorrect, setIsCorrect] = React.useState(null); const esperar = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); }; - function CircularProgress(valorInicial) { - const [percentage, setPercentage] = useState(valorInicial); - - useEffect(() => { - const intervalId = setInterval(() => { - if (percentage <= 0) { - clearInterval(intervalId); // Detener el intervalo - return 0; // Mantener percentage en 0 - } else { - setPercentage(prevPercentage => prevPercentage - 1); // Actualizar el estado con el nuevo porcentaje - } - }, 100); // Intervalo de 100 milisegundos (0.1 segundo) - - // Limpiar el intervalo cuando el componente se desmonte - return () => clearInterval(intervalId); - }, []); // La dependencia vacía asegura que useEffect solo se ejecute una vez al montar el componente - - var listaDevolver = [, percentage] - return ( - listaDevolver - ); - } - - // const [MiCircularProgressbar, MiPercentage] = CircularProgress(100); - - // useEffect(() => { - // if (MiPercentage === 0) { - // // Realizar alguna acción cuando MiPercentage llegue a 0 - // } - // }, [MiPercentage]); // Este efecto se ejecuta cada vez que 'MiPercentage' cambia - - const checkAnswer = async (option) => { setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); setSelectedOption(option); const botonIncorrecta = document.getElementById('option-' + questions[currentQuestionIndex].options.indexOf(option)) if (!isCorrect) { - botonIncorrecta.style.backgroundColor = 'red' - } + const numberAnswer = questions[currentQuestionIndex].options.indexOf(questions[currentQuestionIndex].correctAnswer) const botonCorrecta = document.getElementById('option-' + numberAnswer) botonCorrecta.style.backgroundColor = 'green' @@ -109,10 +37,8 @@ const Quiz = () => { botonIncorrecta.style.backgroundColor = 'lightgrey' botonCorrecta.style.backgroundColor = 'lightgrey' if (questions.length-1 !== currentQuestionIndex) { - setCurrentQuestionIndex((prevIndex) => prevIndex + 1); } - }; From 173845ecee5b2199ac45e20f41224a669cd28d71 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 01:32:48 +0100 Subject: [PATCH 42/94] Added the logic to do a simple wikidata query --- .../wikidataExtractor/wikidataConnexion.js | 32 +++++++++++++++++++ .../wikidataExtractor/wikidataQueries.js | 28 ++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 questionsservice/questiongeneratorservice/wikidataExtractor/wikidataConnexion.js create mode 100644 questionsservice/questiongeneratorservice/wikidataExtractor/wikidataQueries.js diff --git a/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataConnexion.js b/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataConnexion.js new file mode 100644 index 00000000..4778add5 --- /dev/null +++ b/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataConnexion.js @@ -0,0 +1,32 @@ +async function consulta(query) { + const apiUrl = `https://query.wikidata.org/sparql?query=${encodeURIComponent(query)}&format=json`; + console.log(query) + const respuesta = await fetch(apiUrl, { + headers: { + 'User-Agent': 'QuestionCrawler/1.0', + 'Accept': 'application/json' + } + }); + // console.log(apiUrl) + // console.log(respuesta) + if (!respuesta.ok) { + console.error('Error al realizar la consulta a Wikidata:', respuesta.statusText); + return; + } + + const datos = await respuesta.json(); + + const resultados = []; + + for (const resultado of datos.results.bindings) { + const resultadoFormateado = {}; + for (const clave in resultado) { + resultadoFormateado[clave] = resultado[clave].value; + } + resultados.push(resultadoFormateado); + } + + return resultados; +} + +module.exports = {consulta} diff --git a/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataQueries.js b/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataQueries.js new file mode 100644 index 00000000..5a606f58 --- /dev/null +++ b/questionsservice/questiongeneratorservice/wikidataExtractor/wikidataQueries.js @@ -0,0 +1,28 @@ +const wikidata = require("./wikidataConnexion"); + +class WikiQueries { + + static async obtenerPaisYCapital() { + const query = ` + SELECT ?countryLabel ?capitalLabel WHERE { + ?country wdt:P31 wd:Q6256. + ?country wdt:P36 ?capital. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + `; + + const results = await wikidata.consulta(query); + // console.log(results) + return results; + } +} + + + + + + + + + +module.exports = WikiQueries \ No newline at end of file From 06928555109931ce011c3b93670fe64a5edabf17 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 01:34:33 +0100 Subject: [PATCH 43/94] Added the logic in the api to generate random questions based on the simple query --- .../questiongenerator-service.js | 173 +++++++++++------- 1 file changed, 107 insertions(+), 66 deletions(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index ffaec5f4..88aec913 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -7,6 +7,7 @@ const { Request } = require('./questiongenerator-model') const app = express(); const port = 8006; +const WikiQueries = require('./wikidataExtractor/wikidataQueries') // Connect to MongoDB const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questions'; mongoose.connect(mongoUri); @@ -20,79 +21,119 @@ app.use(express.json()); // Middleware to enable CORS (cross-origin resource sharing). In order for the API to be accessible by other origins (domains). app.use(cors()); -const mockedQuestions = [ - { - pregunta: "¿Cómo me llamo?", - respuesta_correcta: "Abel", - respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] - }, - { - pregunta: "¿Cuál es el río más largo del mundo?", - respuesta_correcta: "Amazonas", - respuestas_incorrectas: ["Nilo", "Misisipi", "Yangtsé"] - }, - { - pregunta: "¿En qué año comenzó la Segunda Guerra Mundial?", - respuesta_correcta: "1939", - respuestas_incorrectas: ["1941", "1942", "1945"] - }, - { - pregunta: "¿Quién escribió 'El Quijote'?", - respuesta_correcta: "Miguel de Cervantes", - respuestas_incorrectas: ["Garcilaso de la Vega", "Federico García Lorca", "Pablo Neruda"] - }, - { - pregunta: "¿Cuál es el símbolo químico del oro?", - respuesta_correcta: "Au", - respuestas_incorrectas: ["Ag", "Fe", "Cu"] - }, - { - pregunta: "¿Cuál es el planeta más grande del sistema solar?", - respuesta_correcta: "Júpiter", - respuestas_incorrectas: ["Saturno", "Marte", "Venus"] - }, - { - pregunta: "¿Quién pintó la 'Mona Lisa'?", - respuesta_correcta: "Leonardo da Vinci", - respuestas_incorrectas: ["Pablo Picasso", "Vincent van Gogh", "Rembrandt"] - }, - { - pregunta: "¿En qué país se encuentra la Torre Eiffel?", - respuesta_correcta: "Francia", - respuestas_incorrectas: ["Italia", "España", "Alemania"] - }, - { - pregunta: "¿Qué año marcó el fin de la Segunda Guerra Mundial?", - respuesta_correcta: "1945", - respuestas_incorrectas: ["1943", "1944", "1946"] - }, - { - pregunta: "¿Quién escribió 'Romeo y Julieta'?", - respuesta_correcta: "William Shakespeare", - respuestas_incorrectas: ["Jane Austen", "Charles Dickens", "F. Scott Fitzgerald"] - }, - { - pregunta: "¿Qué inventó Thomas Edison?", - respuesta_correcta: "Bombilla eléctrica", - respuestas_incorrectas: ["Teléfono", "Automóvil", "Avión"] +var mockedQuestions = [] +var isWikiChecked = false +var elementos + +function shuffle(array) { + let currentIndex = array.length; + let randomIndex; + + // Mientras queden elementos para mezclar. + while (currentIndex > 0) { + // Escoge un elemento aleatorio. + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + + // Intercambia el elemento actual con el elemento aleatorio. + [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; } -] + + return array; +} + +const generateQuestion = async () => { + if (!isWikiChecked) { + elementos = await WikiQueries.obtenerPaisYCapital() + isWikiChecked = true + } + elementos = shuffle(elementos) + console.log("caca", elementos) + mockedQuestions = [{ + pregunta: "¿Cual es la capital de " + elementos[0].countryLabel + "?", + respuesta_correcta: elementos[0].capitalLabel, + respuestas_incorrectas: [elementos[1].capitalLabel, elementos[2].capitalLabel, elementos[3].capitalLabel] + }] + console.log(mockedQuestions) +} + + +// const mockedQuestions = [ +// { +// pregunta: "¿Cómo me llamo?", +// respuesta_correcta: "Abel", +// respuestas_incorrectas: ["Federico", "Eusebio", "Gervasio"] +// }, +// { +// pregunta: "¿Cuál es el río más largo del mundo?", +// respuesta_correcta: "Amazonas", +// respuestas_incorrectas: ["Nilo", "Misisipi", "Yangtsé"] +// }, +// { +// pregunta: "¿En qué año comenzó la Segunda Guerra Mundial?", +// respuesta_correcta: "1939", +// respuestas_incorrectas: ["1941", "1942", "1945"] +// }, +// { +// pregunta: "¿Quién escribió 'El Quijote'?", +// respuesta_correcta: "Miguel de Cervantes", +// respuestas_incorrectas: ["Garcilaso de la Vega", "Federico García Lorca", "Pablo Neruda"] +// }, +// { +// pregunta: "¿Cuál es el símbolo químico del oro?", +// respuesta_correcta: "Au", +// respuestas_incorrectas: ["Ag", "Fe", "Cu"] +// }, +// { +// pregunta: "¿Cuál es el planeta más grande del sistema solar?", +// respuesta_correcta: "Júpiter", +// respuestas_incorrectas: ["Saturno", "Marte", "Venus"] +// }, +// { +// pregunta: "¿Quién pintó la 'Mona Lisa'?", +// respuesta_correcta: "Leonardo da Vinci", +// respuestas_incorrectas: ["Pablo Picasso", "Vincent van Gogh", "Rembrandt"] +// }, +// { +// pregunta: "¿En qué país se encuentra la Torre Eiffel?", +// respuesta_correcta: "Francia", +// respuestas_incorrectas: ["Italia", "España", "Alemania"] +// }, +// { +// pregunta: "¿Qué año marcó el fin de la Segunda Guerra Mundial?", +// respuesta_correcta: "1945", +// respuestas_incorrectas: ["1943", "1944", "1946"] +// }, +// { +// pregunta: "¿Quién escribió 'Romeo y Julieta'?", +// respuesta_correcta: "William Shakespeare", +// respuestas_incorrectas: ["Jane Austen", "Charles Dickens", "F. Scott Fitzgerald"] +// }, +// { +// pregunta: "¿Qué inventó Thomas Edison?", +// respuesta_correcta: "Bombilla eléctrica", +// respuestas_incorrectas: ["Teléfono", "Automóvil", "Avión"] +// } +// ] // Function to generate the required number of questions -function getQuestions(req) { +async function getQuestions(req) { const { n_preguntas, n_respuestas, tema } = req.query; var preguntas = Number(n_preguntas); var respuestas = Number(n_respuestas); var temad = String(tema); - if (isNaN(preguntas)) { - return mockedQuestions.slice(0, 4); - } - const response = []; - for (let i = 0; i < preguntas; i++) { - response.push(mockedQuestions[i % 11]); - } - return response + // if (isNaN(preguntas)) { + // generateQuestion() + // console.log("merda", mockedQuestions) + // return mockedQuestions.slice(0, 4); + // } + // const response = []; + await generateQuestion() + // for (let i = 0; i < preguntas; i++) { + // response.push(mockedQuestions[i % 11]); + // } + return mockedQuestions } // Route for getting questions @@ -100,7 +141,7 @@ app.get('/questions', async (req, res) => { try { // TODO: Implement logic to fetch questions from MongoDB and send response // const questions = await Question.find() - const defaultQuestion = getQuestions(req) + const defaultQuestion = await getQuestions(req) res.json(defaultQuestion); } catch (error) { // res.status(500).json({ message: error.message }) From ac5a2a23c5f5c13815c3a603d908e54ef8360669 Mon Sep 17 00:00:00 2001 From: Abel Date: Wed, 13 Mar 2024 02:24:10 +0100 Subject: [PATCH 44/94] Added call to the question store service API for storing the generated questions (pending for testing) --- docker-compose.yml | 2 + .../package-lock.json | 93 +++++++++++++++++++ .../questiongeneratorservice/package.json | 1 + .../questiongenerator-service.js | 47 +++++----- 4 files changed, 122 insertions(+), 21 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0fd03c84..a0a48ea2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,12 +57,14 @@ services: build: ./questionsservice/questiongeneratorservice depends_on: - mongodb_wiki + - storequestionservice ports: - "8007:8006" networks: - mynetwork environment: MONGODB_URI: mongodb://mongodb_wiki:27017/questions + STORE_QUESTION_SERVICE_URL: http://storequestionservice:8004 gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} diff --git a/questionsservice/questiongeneratorservice/package-lock.json b/questionsservice/questiongeneratorservice/package-lock.json index 3dbf397a..2240421b 100644 --- a/questionsservice/questiongeneratorservice/package-lock.json +++ b/questionsservice/questiongeneratorservice/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "axios": "^1.6.5", + "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^8.2.0" }, @@ -73,6 +75,21 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -191,6 +208,17 @@ "fsevents": "~2.3.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -229,6 +257,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -253,6 +293,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -385,6 +433,38 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -900,6 +980,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -956,6 +1044,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", diff --git a/questionsservice/questiongeneratorservice/package.json b/questionsservice/questiongeneratorservice/package.json index a55addc6..026b5970 100644 --- a/questionsservice/questiongeneratorservice/package.json +++ b/questionsservice/questiongeneratorservice/package.json @@ -20,6 +20,7 @@ "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "express": "^4.18.2", + "axios": "^1.6.5", "cors": "^2.8.5", "mongoose": "^8.2.0" }, diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 88aec913..505a7a99 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -1,5 +1,6 @@ const express = require('express'); const cors = require('cors'); +const axios = require('axios'); const mongoose = require('mongoose'); const { Question } = require('./questiongenerator-model') const { Request } = require('./questiongenerator-model') @@ -7,7 +8,9 @@ const { Request } = require('./questiongenerator-model') const app = express(); const port = 8006; -const WikiQueries = require('./wikidataExtractor/wikidataQueries') +const questionHistoryServiceUrl = process.env.QUESTION_HISTORY_SERVICE_URL || 'http://localhost:8004'; + +const WikiQueries = require('./wikidataExtractor/wikidataQueries'); // Connect to MongoDB const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questions'; mongoose.connect(mongoUri); @@ -21,9 +24,9 @@ app.use(express.json()); // Middleware to enable CORS (cross-origin resource sharing). In order for the API to be accessible by other origins (domains). app.use(cors()); -var mockedQuestions = [] -var isWikiChecked = false -var elementos +var mockedQuestions = []; +var isWikiChecked = false; +var elementos; function shuffle(array) { let currentIndex = array.length; @@ -31,12 +34,12 @@ function shuffle(array) { // Mientras queden elementos para mezclar. while (currentIndex > 0) { - // Escoge un elemento aleatorio. - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; + // Escoge un elemento aleatorio. + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; - // Intercambia el elemento actual con el elemento aleatorio. - [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; + // Intercambia el elemento actual con el elemento aleatorio. + [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; } return array; @@ -44,17 +47,17 @@ function shuffle(array) { const generateQuestion = async () => { if (!isWikiChecked) { - elementos = await WikiQueries.obtenerPaisYCapital() - isWikiChecked = true + elementos = await WikiQueries.obtenerPaisYCapital(); + isWikiChecked = true; } - elementos = shuffle(elementos) - console.log("caca", elementos) + elementos = shuffle(elementos); + console.log("caca", elementos); mockedQuestions = [{ pregunta: "¿Cual es la capital de " + elementos[0].countryLabel + "?", respuesta_correcta: elementos[0].capitalLabel, respuestas_incorrectas: [elementos[1].capitalLabel, elementos[2].capitalLabel, elementos[3].capitalLabel] - }] - console.log(mockedQuestions) + }]; + console.log(mockedQuestions); } @@ -129,11 +132,11 @@ async function getQuestions(req) { // return mockedQuestions.slice(0, 4); // } // const response = []; - await generateQuestion() - // for (let i = 0; i < preguntas; i++) { - // response.push(mockedQuestions[i % 11]); - // } - return mockedQuestions + await generateQuestion(); + // for (let i = 0; i < preguntas; i++) { + // response.push(mockedQuestions[i % 11]); + // } + return mockedQuestions; } // Route for getting questions @@ -141,7 +144,9 @@ app.get('/questions', async (req, res) => { try { // TODO: Implement logic to fetch questions from MongoDB and send response // const questions = await Question.find() - const defaultQuestion = await getQuestions(req) + const defaultQuestion = await getQuestions(req); + + const questionsHistoryResponse = await axios.post(questionHistoryServiceUrl + '/history/questions', defaultQuestion); res.json(defaultQuestion); } catch (error) { // res.status(500).json({ message: error.message }) From c0e34cc1085cc934505b482fbe2c514c0f0b9eaf Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:08:44 +0100 Subject: [PATCH 45/94] Update storeQuestionService/store-q-service.js Route changed to maintain standards Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index e3d4bf2b..af5bed2c 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -70,7 +70,7 @@ app.post('/addquestions', async (req, res) => { }); -app.get('/questions', async (req, res) => { +app.get('/history/questions', async (req, res) => { try { res.setHeader("Access-Control-Allow-Origin", "*");//Puede ser innecesario? const questions = await Question.find({}); // Get all questions From 5c2a97cd7282df673b78614fb1f95af098fc4827 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:27:00 +0100 Subject: [PATCH 46/94] Update storeQuestionService/store-q-service.js Route changed to maintain standards Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index af5bed2c..6e42adba 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -22,7 +22,7 @@ function validateRequiredFields(req, requiredFields) { } } -app.post('/addquestion', async (req, res) => { +app.post('/history/questions', async (req, res) => { try { // Check if required fields are present in the request body validateRequiredFields(req, ['question', 'c_answer','w_answers']); From e1b5a7cfee3cf132fd5d46adf2fe25da65a68ca9 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:28:01 +0100 Subject: [PATCH 47/94] Update storeQuestionService/store-q-service.js Body-parser is not longer use as it functions are already present at the last version of express Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 6e42adba..514633ef 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -7,7 +7,7 @@ const app = express(); const port = 8004; // Middleware to parse JSON in request body -app.use(bodyParser.json()); +app.use(express.json()); // Connect to MongoDB const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/storedquestion'; From 419cbc7353c8ee891c6110abc60cc9052279ee8b Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:30:14 +0100 Subject: [PATCH 48/94] Update package.json to delete unused dependencies --- storeQuestionService/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/storeQuestionService/package.json b/storeQuestionService/package.json index 11ee8410..5de3b128 100644 --- a/storeQuestionService/package.json +++ b/storeQuestionService/package.json @@ -18,7 +18,6 @@ }, "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { - "body-parser": "^1.20.2", "cors": "^2.8.5", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", From 4001c439f64a4c7d294063b1513f510d95addec7 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:34:29 +0100 Subject: [PATCH 49/94] Update store-q-model.js to fix convention names --- storeQuestionService/store-q-model.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/storeQuestionService/store-q-model.js b/storeQuestionService/store-q-model.js index ffa1730a..36903049 100644 --- a/storeQuestionService/store-q-model.js +++ b/storeQuestionService/store-q-model.js @@ -1,14 +1,21 @@ const mongoose = require('mongoose'); const questionStorageSchema = new mongoose.Schema({ - question: { + pregunta: { type: String, required: true, }, - c_answer: { type: String, required: true }, - w_answers: [{ type: String, required: true }], + respuesta_correcta: { + type: String, + required: true + }, + respuestas_incorrectas: [{ + type: String, + required: true + }], createdAt: { type: Date, + required: true, default: Date.now, }, }); From 62b6aba33e173645d7f0ffdf70343cf3c6f46594 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:39:17 +0100 Subject: [PATCH 50/94] Update store-q-service.js to fix changes in data structure --- storeQuestionService/store-q-service.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 514633ef..66e47ccf 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -25,12 +25,13 @@ function validateRequiredFields(req, requiredFields) { app.post('/history/questions', async (req, res) => { try { // Check if required fields are present in the request body - validateRequiredFields(req, ['question', 'c_answer','w_answers']); + validateRequiredFields(req, ['pregunta', 'respuesta_correcta','respuestas_incorrectas']); const newQuestion = new Question({ - question: req.body.question, - c_answer: req.body.answers, - w_answers: req.body.answers, + pregunta: req.body.pregunta, + respuesta_correcta: req.body.respuesta_correcta, + respuestas_incorrectas: req.body.respuestas_incorrectas, + createdAt: req.body.createdAt }); await newQuestion.save(); @@ -47,16 +48,17 @@ app.post('/addquestions', async (req, res) => { throw new Error('Invalid request format. Expected an array of questions.'); } for (const question of req.body) { - validateRequiredFields(question, ['question', 'c_answer','w_answers']); + validateRequiredFields(question, ['pregunta', 'respuesta_correcta','respuestas_incorrectas']); } const newQuestions = []; for (const questionData of req.body) { const newQuestion = new Question({ - question: req.body.question, - c_answer: req.body.answers, - w_answers: req.body.answers, + pregunta: req.body.pregunta, + respuesta_correcta: req.body.respuesta_correcta, + respuestas_incorrectas: req.body.respuestas_incorrectas, + createdAt: req.body.createdAt }); await newQuestion.save(); @@ -80,9 +82,9 @@ app.get('/history/questions', async (req, res) => { answers: ['Segovia','León','Valladolid','Ninguna'], }]);*/ /*res.json([{ - question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - c_answer: 'Ninguna', - w_answers: ['Segovia','León','Valladolid'] + pregunta: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + respuesta_incorrecta: 'Ninguna', + respuestas_incorrectas: ['Segovia','León','Valladolid'] }]);*/ } catch (error) { res.status(500).json({ error: error.message }); From edb344979e3dd577e5a9a49a6718b522df4ba166 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:41:28 +0100 Subject: [PATCH 51/94] Update store-q-service.js to fix post functions route --- storeQuestionService/store-q-service.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 66e47ccf..bbabbd21 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -22,7 +22,7 @@ function validateRequiredFields(req, requiredFields) { } } -app.post('/history/questions', async (req, res) => { +app.post('/history/question', async (req, res) => { try { // Check if required fields are present in the request body validateRequiredFields(req, ['pregunta', 'respuesta_correcta','respuestas_incorrectas']); @@ -41,7 +41,7 @@ app.post('/history/questions', async (req, res) => { } }); -app.post('/addquestions', async (req, res) => { +app.post('/history/questions', async (req, res) => { try { // Check if required fields are present in the request body if (!Array.isArray(req.body)) { From 06d5a200f5ab5d012c1ac9a7dc04464f1204a125 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:46:26 +0100 Subject: [PATCH 52/94] Update storeQuestionService/store-q-service.js to delete unecesary line of code Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q-service.js | 1 - 1 file changed, 1 deletion(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index bbabbd21..f66eb077 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -74,7 +74,6 @@ app.post('/history/questions', async (req, res) => { app.get('/history/questions', async (req, res) => { try { - res.setHeader("Access-Control-Allow-Origin", "*");//Puede ser innecesario? const questions = await Question.find({}); // Get all questions res.json(questions); /*res.json([{ //FORMATO VIEJO From e7d110891bb9e20baac718989ffaba66f0b522bf Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 12:26:35 +0100 Subject: [PATCH 53/94] Update gateway-service.js added error managment to question service --- gatewayservice/gateway-service.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 2d3732d6..f78ee7dd 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -47,6 +47,7 @@ app.get('/questions', async (req, res) => { const response = await axios.get(storeQuestionsServiceUrl+'/questions'); res.json(response.data); } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); } }) From b3f302a57de1493e635e484a8308f81698bf4fbc Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:29:09 +0100 Subject: [PATCH 54/94] Updated the game so we can have unlimited questions --- webapp/src/components/FirstGame.js | 47 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index 003a5be6..d3789cf6 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -7,9 +7,9 @@ import axios from 'axios'; import { json } from 'react-router-dom'; import { useLocation } from 'react-router-dom'; - +const apiEndpoint = 'http://localhost:8007'; const Quiz = () => { - const questions = useLocation().state.questions; + var questions = useLocation().state.questions; const [currentQuestionIndex, setCurrentQuestionIndex] = React.useState(0); const [selectedOption, setSelectedOption] = React.useState(null); @@ -19,7 +19,48 @@ const Quiz = () => { return new Promise(resolve => setTimeout(resolve, ms)); }; + + function shuffleArray(array) { + // Crea una copia del array original + const shuffledArray = [...array]; + + // Recorre el array desde el último elemento hasta el primero + for (let i = shuffledArray.length - 1; i > 0; i--) { + // Genera un índice aleatorio entre 0 y el índice actual + const randomIndex = Math.floor(Math.random() * (i + 1)); + + // Intercambia el elemento actual con el elemento del índice aleatorio + const temp = shuffledArray[i]; + shuffledArray[i] = shuffledArray[randomIndex]; + shuffledArray[randomIndex] = temp; + } + + // Devuelve el array barajado + return shuffledArray; + } + + + const getQuestions = async () => { + try { + const response = await axios.get(`${apiEndpoint}/questions?n_preguntas=${1}`); + console.log(response.data.length) + for (var i = 0; i < response.data.length; i++) { + var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]] + possibleAnswers = shuffleArray(possibleAnswers) + questions.push({ + question: response.data[i].pregunta, + options: possibleAnswers, + correctAnswer: response.data[i].respuesta_correcta + }) + } + } catch (error) { + console.error(error); + } + console.log(questions) +}; + const checkAnswer = async (option) => { + getQuestions() setIsCorrect(option === questions[currentQuestionIndex].correctAnswer); setSelectedOption(option); @@ -39,6 +80,8 @@ const Quiz = () => { if (questions.length-1 !== currentQuestionIndex) { setCurrentQuestionIndex((prevIndex) => prevIndex + 1); } + setIsCorrect(false) + }; From eef9653969c42c6330605db445041b7572ee0583 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:50:44 +0100 Subject: [PATCH 55/94] Update gatewayservice/gateway-service.js fixed new route in questions Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- gatewayservice/gateway-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index f78ee7dd..cb973755 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -44,7 +44,7 @@ app.post('/adduser', async (req, res) => { app.get('/questions', async (req, res) => { try { - const response = await axios.get(storeQuestionsServiceUrl+'/questions'); + const response = await axios.get(storeQuestionsServiceUrl+'/history/questions'); res.json(response.data); } catch (error) { res.status(error.response.status).json({ error: error.response.data.error }); From a015019fe721035f91a224fb8176182f62d0f949 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:50:59 +0100 Subject: [PATCH 56/94] Update storeQuestionService/store-q.test.js Added new route in tests Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 1609a694..54ff4176 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -24,7 +24,7 @@ describe('Store questions service', () => { w_answers: ['Segovia','León','Valladolid'], }; - const response = await request(app).post('/addquestion').send(newQuestion); + const response = await request(app).post('/history/question').send(newQuestion); expect(response.status).toBe(200); expect(response.body).toHaveProperty('question', 'c_answer', 'w_answers'); }); From e352872f8b0132ae9313409de1190844ef2cbfb5 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:51:23 +0100 Subject: [PATCH 57/94] Update storeQuestionService/store-q.test.js Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 54ff4176..8b6f5fee 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -31,7 +31,7 @@ describe('Store questions service', () => { }); describe('Store questions service', () => { - it('should get all questions on GET /questions', async () => { + it('should get all questions on GET /history/questions', async () => { const newQuestion1 = { question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', c_answer: 'Ninguna', From de2e940a6141545b0496d5010e5fbe2e122f0816 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:51:32 +0100 Subject: [PATCH 58/94] Update storeQuestionService/store-q.test.js Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 8b6f5fee..4d1894f9 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -52,7 +52,7 @@ describe('Store questions service', () => { request(app).post('/addquestion').send(newQuestion2); request(app).post('/addquestion').send(newQuestion3); - const response = await request(app).get('/questions'); + const response = await request(app).get('/history/questions'); expect(response.status).toBe(200); expect(response.body).toEqual( From 5d228418f1023ad7e6e7ab0bdaeefb2f7acfb506 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:51:40 +0100 Subject: [PATCH 59/94] Update storeQuestionService/store-q.test.js Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 4d1894f9..b849a181 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -17,7 +17,7 @@ afterAll(async () => { }); describe('Store questions service', () => { - it('should add a new question on POST /addquestion', async () => { + it('should add a new question on POST /history/question', async () => { const newQuestion = { question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', c_answer: 'Ninguna', From bab06821c9878682e5009417aeea5331db8d59f7 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:00 +0100 Subject: [PATCH 60/94] Update storeQuestionService/store-q.test.js Added new route in tests Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index b849a181..eab8baff 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -50,7 +50,7 @@ describe('Store questions service', () => { request(app).post('/addquestion').send(newQuestion1); request(app).post('/addquestion').send(newQuestion2); - request(app).post('/addquestion').send(newQuestion3); + request(app).post('/history/question').send(newQuestion3); const response = await request(app).get('/history/questions'); From fe390aff2abbf87faa4118c7fa7e6231f00dabc3 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:09 +0100 Subject: [PATCH 61/94] Update storeQuestionService/store-q.test.js Added new route in tests Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index eab8baff..5e279a4d 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -49,7 +49,7 @@ describe('Store questions service', () => { }; request(app).post('/addquestion').send(newQuestion1); - request(app).post('/addquestion').send(newQuestion2); + request(app).post('/history/question').send(newQuestion2); request(app).post('/history/question').send(newQuestion3); const response = await request(app).get('/history/questions'); From 933ce9e7a30a2c3696718d0c99c76a260b067825 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:19 +0100 Subject: [PATCH 62/94] Update storeQuestionService/store-q.test.js Added new route in tests Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index 5e279a4d..af64cb95 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -48,7 +48,7 @@ describe('Store questions service', () => { w_answers: ['China','Estados Unidos','Brazil'], }; - request(app).post('/addquestion').send(newQuestion1); + request(app).post('/history/question').send(newQuestion1); request(app).post('/history/question').send(newQuestion2); request(app).post('/history/question').send(newQuestion3); From 9536c6b639053470d2957b8dad0a56cf3a4d3cdf Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:52:31 +0100 Subject: [PATCH 63/94] Update gatewayservice/gateway-service.js Added new route in tests Co-authored-by: Abel <114153419+AbelMH1@users.noreply.github.com> --- gatewayservice/gateway-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index cb973755..9a969b11 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -42,7 +42,7 @@ app.post('/adduser', async (req, res) => { } }); -app.get('/questions', async (req, res) => { +app.get('/history/questions', async (req, res) => { try { const response = await axios.get(storeQuestionsServiceUrl+'/history/questions'); res.json(response.data); From 40f07955c78002879679f621e4a0565745be8c61 Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:58:36 +0100 Subject: [PATCH 64/94] Update store-q.test.js fixed questions format --- storeQuestionService/store-q.test.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index af64cb95..b9aeb2ac 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -19,9 +19,10 @@ afterAll(async () => { describe('Store questions service', () => { it('should add a new question on POST /history/question', async () => { const newQuestion = { - question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - c_answer: 'Ninguna', - w_answers: ['Segovia','León','Valladolid'], + pregunta: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + respuesta_correcta: 'Ninguna', + respuestas_incorrectas: ['Segovia','León','Valladolid'], + createdAt: '<2002-02-02>' }; const response = await request(app).post('/history/question').send(newQuestion); @@ -33,19 +34,22 @@ describe('Store questions service', () => { describe('Store questions service', () => { it('should get all questions on GET /history/questions', async () => { const newQuestion1 = { - question: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - c_answer: 'Ninguna', - w_answers: ['Segovia','León','Valladolid'], + pregunta: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', + respuesta_correcta: 'Ninguna', + respuestas_incorrectas: ['Segovia','León','Valladolid'], + createdAt: '<2002-02-02>' }; const newQuestion2 = { - question: '¿Cuál es la capital Italia?', - c_answer: 'Roma', - w_answers: ['Nápoles','Florencia','Milán'], + pregunta: '¿Cuál es la capital Italia?', + respuesta_correcta: 'Roma', + respuestas_incorrectas: ['Nápoles','Florencia','Milán'], + createdAt: '<2002-02-02>' }; const newQuestion3 = { - question: '¿Cuál es el país mas poblado de la tierra?', - c_answer: 'India', - w_answers: ['China','Estados Unidos','Brazil'], + pregunta: '¿Cuál es el país mas poblado de la tierra?', + respuesta_correcta: 'India', + respuestas_incorrectas: ['China','Estados Unidos','Brazil'], + createdAt: '<2002-02-02>' }; request(app).post('/history/question').send(newQuestion1); From 559b2239ef3fb80d9de41a5cbb7e622c395499c1 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:01:32 +0100 Subject: [PATCH 65/94] Fixed problem of dependencies --- webapp/package-lock.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 303e6b1d..26ab6de7 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -17,6 +17,7 @@ "axios": "^1.6.5", "fetch": "^1.1.0", "react": "^18.2.0", + "react-circular-progressbar": "^2.1.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.1", "react-scripts": "5.0.1", @@ -21932,6 +21933,14 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, + "node_modules/react-circular-progressbar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.1.0.tgz", + "integrity": "sha512-xp4THTrod4aLpGy68FX/k1Q3nzrfHUjUe5v6FsdwXBl3YVMwgeXYQKDrku7n/D6qsJA9CuunarAboC2xCiKs1g==", + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", From a0c33a7d0acc22af1379062ffa02ec6317bde6d8 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:24:29 +0100 Subject: [PATCH 66/94] Fixed problem with login test apparently --- webapp/src/components/Context.js | 17 +++++++++++++++++ webapp/src/components/Login.test.js | 16 ++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 webapp/src/components/Context.js diff --git a/webapp/src/components/Context.js b/webapp/src/components/Context.js new file mode 100644 index 00000000..9e5bdcea --- /dev/null +++ b/webapp/src/components/Context.js @@ -0,0 +1,17 @@ +import React, { createContext, useContext, useState } from 'react'; + +const Context = createContext(); + +export function UserProvider({ children }) { + const [usernameGlobal, setUsernameGlobal] = useState(''); + + return ( + + {children} + + ); +} + +export function useUser() { + return useContext(Context); +} \ No newline at end of file diff --git a/webapp/src/components/Login.test.js b/webapp/src/components/Login.test.js index af102dcf..1d9282c6 100644 --- a/webapp/src/components/Login.test.js +++ b/webapp/src/components/Login.test.js @@ -3,6 +3,10 @@ import { render, fireEvent, screen, waitFor, act } from '@testing-library/react' import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import Login from './Login'; +import { Context } from './Context'; +import { BrowserRouter as Router } from 'react-router-dom'; + + const mockAxios = new MockAdapter(axios); @@ -12,7 +16,9 @@ describe('Login component', () => { }); it('should log in successfully', async () => { - render(); + render( + + ); const usernameInput = screen.getByLabelText(/Username/i); const passwordInput = screen.getByLabelText(/Password/i); @@ -34,7 +40,13 @@ describe('Login component', () => { }); it('should handle error when logging in', async () => { - render(); + + render( + + + + + ); const usernameInput = screen.getByLabelText(/Username/i); const passwordInput = screen.getByLabelText(/Password/i); From cc0cf8800d125908e4c56ef76227ab0e9736a7e6 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:28:07 +0100 Subject: [PATCH 67/94] Added the login into the inder for navigation --- webapp/src/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webapp/src/index.js b/webapp/src/index.js index da7de47c..bf6814c8 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -16,6 +16,7 @@ import { import FirstGame from './components/FirstGame'; import Menu from './components/Menu'; +import Login from './components/Login' const root = ReactDOM.createRoot(document.getElementById('root')); @@ -26,6 +27,7 @@ root.render( }> }> }> + }> From c5681f2d2b4b9557d6b8f3cc995a4d50203e4d28 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:38:44 +0100 Subject: [PATCH 68/94] Fixed problems witho second part of text at login and problems with app test --- webapp/src/App.test.js | 11 ++++++++++- webapp/src/components/Login.test.js | 7 +++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 9aa27757..0319a782 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -1,8 +1,17 @@ import { render, screen } from '@testing-library/react'; import App from './App'; +import { Context } from './components/Context'; +import { Router } from 'react-router-dom'; + test('renders learn react link', () => { - render(); + render( + + + + + + ); const linkElement = screen.getByText(/Welcome to wiq_0/i); expect(linkElement).toBeInTheDocument(); }); diff --git a/webapp/src/components/Login.test.js b/webapp/src/components/Login.test.js index 1d9282c6..5d83593b 100644 --- a/webapp/src/components/Login.test.js +++ b/webapp/src/components/Login.test.js @@ -16,9 +16,12 @@ describe('Login component', () => { }); it('should log in successfully', async () => { - render( + render( + + - ); + + ); const usernameInput = screen.getByLabelText(/Username/i); const passwordInput = screen.getByLabelText(/Password/i); From ecd16b9e9acbcb353aaff905e757ad969a844ecc Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:47:29 +0100 Subject: [PATCH 69/94] Trying to fix error on how we call th context.js --- webapp/src/App.test.js | 6 ++--- webapp/src/components/Context.js | 2 +- webapp/src/components/Login.test.js | 35 +++++++++++++++-------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 0319a782..c6c4561e 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -1,16 +1,16 @@ import { render, screen } from '@testing-library/react'; import App from './App'; -import { Context } from './components/Context'; +import { ContextFun } from './components/Context'; import { Router } from 'react-router-dom'; test('renders learn react link', () => { render( - + - + ); const linkElement = screen.getByText(/Welcome to wiq_0/i); expect(linkElement).toBeInTheDocument(); diff --git a/webapp/src/components/Context.js b/webapp/src/components/Context.js index 9e5bdcea..8a23041c 100644 --- a/webapp/src/components/Context.js +++ b/webapp/src/components/Context.js @@ -2,7 +2,7 @@ import React, { createContext, useContext, useState } from 'react'; const Context = createContext(); -export function UserProvider({ children }) { +export function ContextFun({ children }) { const [usernameGlobal, setUsernameGlobal] = useState(''); return ( diff --git a/webapp/src/components/Login.test.js b/webapp/src/components/Login.test.js index 5d83593b..3149be03 100644 --- a/webapp/src/components/Login.test.js +++ b/webapp/src/components/Login.test.js @@ -3,8 +3,8 @@ import { render, fireEvent, screen, waitFor, act } from '@testing-library/react' import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import Login from './Login'; -import { Context } from './Context'; -import { BrowserRouter as Router } from 'react-router-dom'; +import { ContextFun } from './Context'; +import { BrowserRouter as Router } from 'react-router-dom'; @@ -17,11 +17,11 @@ describe('Login component', () => { it('should log in successfully', async () => { render( - - - - - ); + + + + + ); const usernameInput = screen.getByLabelText(/Username/i); const passwordInput = screen.getByLabelText(/Password/i); @@ -32,10 +32,10 @@ describe('Login component', () => { // Simulate user input await act(async () => { - fireEvent.change(usernameInput, { target: { value: 'testUser' } }); - fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); - fireEvent.click(loginButton); - }); + fireEvent.change(usernameInput, { target: { value: 'testUser' } }); + fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); + fireEvent.click(loginButton); + }); // Verify that the user information is displayed expect(screen.getByText(/Hello testUser!/i)).toBeInTheDocument(); @@ -43,12 +43,13 @@ describe('Login component', () => { }); it('should handle error when logging in', async () => { - - render( - - - - + + render( + + + + + ); const usernameInput = screen.getByLabelText(/Username/i); From 6b1ecae1837aff8a966351c05247a138482c3c8c Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:53:57 +0100 Subject: [PATCH 70/94] Fixed Login test, tryung to fix app test --- webapp/src/App.test.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index c6c4561e..b4ffdf62 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -6,11 +6,7 @@ import { Router } from 'react-router-dom'; test('renders learn react link', () => { render( - - - - - + ); const linkElement = screen.getByText(/Welcome to wiq_0/i); expect(linkElement).toBeInTheDocument(); From d7a0a7a7d6089f56d3ee48b6504d632c6f7c5273 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 15:58:36 +0100 Subject: [PATCH 71/94] Return to the previous version of app test --- webapp/src/App.test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index b4ffdf62..c6c4561e 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -6,7 +6,11 @@ import { Router } from 'react-router-dom'; test('renders learn react link', () => { render( - + + + + + ); const linkElement = screen.getByText(/Welcome to wiq_0/i); expect(linkElement).toBeInTheDocument(); From 4ca2be46c0ae121e0b2d850441a660118e705984 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 16:01:46 +0100 Subject: [PATCH 72/94] Trying to fix the app text with an update on the index --- webapp/src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/webapp/src/index.js b/webapp/src/index.js index bf6814c8..ea595119 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -28,6 +28,7 @@ root.render( }> }> }> + }> From df1e22f001836d2bb50d5ff781f05bfb3396e6b6 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 16:04:41 +0100 Subject: [PATCH 73/94] Making the test a bit more simple --- webapp/src/App.test.js | 4 ++-- webapp/src/index.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index c6c4561e..5e93f49b 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -12,6 +12,6 @@ test('renders learn react link', () => { ); - const linkElement = screen.getByText(/Welcome to wiq_0/i); - expect(linkElement).toBeInTheDocument(); + // const linkElement = screen.getByText(/Welcome to wiq_0/i); + // expect(linkElement).toBeInTheDocument(); }); diff --git a/webapp/src/index.js b/webapp/src/index.js index ea595119..bf6814c8 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -28,7 +28,6 @@ root.render( }> }> }> - }> From 80cbfe1b9950a5da3fb7424e0927e5f0745fb46f Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 16:09:41 +0100 Subject: [PATCH 74/94] Trying to fix again the app text pls kill me --- webapp/src/App.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 5e93f49b..883e0404 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react'; import App from './App'; import { ContextFun } from './components/Context'; -import { Router } from 'react-router-dom'; +import { BrowserRouter as Router } from 'react-router-dom'; test('renders learn react link', () => { From 5d916296c0769b7a2844eaa00f0970086e68a9af Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 16:16:56 +0100 Subject: [PATCH 75/94] Deleted useless file --- webapp/src/storeQuestion/main.jsx | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 webapp/src/storeQuestion/main.jsx diff --git a/webapp/src/storeQuestion/main.jsx b/webapp/src/storeQuestion/main.jsx deleted file mode 100644 index 883ef991..00000000 --- a/webapp/src/storeQuestion/main.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.jsx' -//import 'bootstrap/dist/css/bootstrap.css' - -ReactDOM.createRoot(document.getElementById('root')).render( - - - , -) From d43156c562699df94580400e06ec8d9df166e6be Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 16:27:28 +0100 Subject: [PATCH 76/94] Eliminated unussed resources for that moment --- webapp/src/components/CircularProgressBar.js | 26 ----------- webapp/src/components/Footer.js | 14 ------ webapp/src/components/NavBar.css | 46 -------------------- webapp/src/components/NavBar.js | 29 ------------ 4 files changed, 115 deletions(-) delete mode 100644 webapp/src/components/CircularProgressBar.js delete mode 100644 webapp/src/components/Footer.js delete mode 100644 webapp/src/components/NavBar.css delete mode 100644 webapp/src/components/NavBar.js diff --git a/webapp/src/components/CircularProgressBar.js b/webapp/src/components/CircularProgressBar.js deleted file mode 100644 index 79bbab03..00000000 --- a/webapp/src/components/CircularProgressBar.js +++ /dev/null @@ -1,26 +0,0 @@ -import { CircularProgressbar } from 'react-circular-progressbar'; -import 'react-circular-progressbar/dist/styles.css'; -import React, { useState, useEffect } from 'react'; -import { Container, Typography } from '@mui/material'; - - - -function CircularProgress(initialValue) { - const [percentage, setPercentage] = useState(initialValue); - - useEffect(() => { - const intervalId = setInterval(() => { - setPercentage(prevPercentage => prevPercentage - 1); // Actualizar el estado con el nuevo porcentaje - }, 100); // Intervalo de 100 milisegundos (0.1 segundo) - - // Limpiar el intervalo cuando el componente se desmonte - return () => clearInterval(intervalId); - }, []); // La dependencia vacía asegura que useEffect solo se ejecute una vez al montar el componente - - var listaDevolver = [, percentage] - return ( - listaDevolver - ); - } - - export default CircularProgress; \ No newline at end of file diff --git a/webapp/src/components/Footer.js b/webapp/src/components/Footer.js deleted file mode 100644 index 7059ad28..00000000 --- a/webapp/src/components/Footer.js +++ /dev/null @@ -1,14 +0,0 @@ -import { AppBar, Toolbar, Typography } from '@mui/material'; - -const Footer = () => { - return ( - - - © WIQ_ES6C - - - ); -}; - -export default Footer; \ No newline at end of file diff --git a/webapp/src/components/NavBar.css b/webapp/src/components/NavBar.css deleted file mode 100644 index 54516ebe..00000000 --- a/webapp/src/components/NavBar.css +++ /dev/null @@ -1,46 +0,0 @@ -nav { - background-color: #1c57c4; - color: #fff; - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 20px; -} - -.logo img { - max-width: 100px; -} - -.nav-links { - list-style: none; - display: flex; - align-items: center; -} - -.nav-links li { - margin-right: 5%; -} - -.nav-links li:last-child { - margin-right: 0%; -} - -.nav-links a { - text-decoration: none; - color: #fff; -} - -.nav-links button { - background-color: transparent; - border: none; - color: #fff; - cursor: pointer; -} - -.nav-links button:hover { - text-decoration: underline; -} - -.nav-links { - margin-left: auto; -} \ No newline at end of file diff --git a/webapp/src/components/NavBar.js b/webapp/src/components/NavBar.js deleted file mode 100644 index 392baf94..00000000 --- a/webapp/src/components/NavBar.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import './NavBar.css'; -import { Link } from 'react-router-dom'; - -const Navbar = ({ loggedIn, handleLogout }) => { - return ( - - ); -}; - -export default Navbar; \ No newline at end of file From e5b66779ec3d7b5c6d769b70f80fadcb56bdf1fa Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 16:44:31 +0100 Subject: [PATCH 77/94] First try in test for firstGame --- webapp/src/App.test.js | 4 ++-- webapp/src/components/FirstGame.test.js | 20 ++++++++++++++++++++ webapp/src/components/Menu.test.js | 0 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 webapp/src/components/FirstGame.test.js create mode 100644 webapp/src/components/Menu.test.js diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 883e0404..7235d3a7 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -12,6 +12,6 @@ test('renders learn react link', () => { ); - // const linkElement = screen.getByText(/Welcome to wiq_0/i); - // expect(linkElement).toBeInTheDocument(); + const linkElement = screen.getByText(/Welcome to wiq_0/i); + expect(linkElement).toBeInTheDocument(); }); diff --git a/webapp/src/components/FirstGame.test.js b/webapp/src/components/FirstGame.test.js new file mode 100644 index 00000000..92e1e91c --- /dev/null +++ b/webapp/src/components/FirstGame.test.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import FirstGame from './FirstGame'; +import { ContextFun } from './Context'; +import { BrowserRouter as Router } from 'react-router-dom'; + + +test('renders learn react link', () => { + render( + + + + + + ); + const linkElement = screen.getByText(/¿Cual es/i); + expect(linkElement).toBeInTheDocument(); + }); \ No newline at end of file diff --git a/webapp/src/components/Menu.test.js b/webapp/src/components/Menu.test.js new file mode 100644 index 00000000..e69de29b From 3e40311abb381ee0fa9227db41775d2f9b24b583 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 16:49:43 +0100 Subject: [PATCH 78/94] Fixed body-parser problem and commented mock question --- storeQuestionService/store-q-service.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index f66eb077..058d3649 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -1,6 +1,5 @@ const express = require('express'); const mongoose = require('mongoose'); -const bodyParser = require('body-parser'); const Question = require('./store-q-model'); const app = express(); @@ -82,7 +81,7 @@ app.get('/history/questions', async (req, res) => { }]);*/ /*res.json([{ pregunta: '¿Cuál es la capital de la comunidad autónoma de Castilla y León?', - respuesta_incorrecta: 'Ninguna', + respuesta_correcta: 'Ninguna', respuestas_incorrectas: ['Segovia','León','Valladolid'] }]);*/ } catch (error) { From 95b4d1bac500c134259205315801ee2f6c89ecf4 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 16:50:57 +0100 Subject: [PATCH 79/94] added post history/question. It works, i ve tested it. --- gatewayservice/gateway-service.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 9a969b11..1debf4dd 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -42,6 +42,15 @@ app.post('/adduser', async (req, res) => { } }); +app.post('/history/question', async (req, res) => { + try { + const response = await axios.post(storeQuestionsServiceUrl+'/history/question', req.body); + res.json(response.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}) + app.get('/history/questions', async (req, res) => { try { const response = await axios.get(storeQuestionsServiceUrl+'/history/questions'); From 1ae5550830b6e9050ed6fb12fd5390b02e6c666a Mon Sep 17 00:00:00 2001 From: MarcosBarrilVillaverde <114151873+MarcosBarrilVillaverde@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:01:50 +0100 Subject: [PATCH 80/94] Update store-q.test.js fixed --- storeQuestionService/store-q.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storeQuestionService/store-q.test.js b/storeQuestionService/store-q.test.js index b9aeb2ac..4ffd62af 100644 --- a/storeQuestionService/store-q.test.js +++ b/storeQuestionService/store-q.test.js @@ -27,7 +27,7 @@ describe('Store questions service', () => { const response = await request(app).post('/history/question').send(newQuestion); expect(response.status).toBe(200); - expect(response.body).toHaveProperty('question', 'c_answer', 'w_answers'); + expect(response.body).toHaveProperty('pregunta', 'respuesta_correcta', 'respuestas_incorrectas'); }); }); From cd1e826c2afa2636680d0f8e402e3b4f770b4983 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 17:16:04 +0100 Subject: [PATCH 81/94] Desisto de hacer los test de momento --- webapp/src/components/FirstGame.test.js | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/webapp/src/components/FirstGame.test.js b/webapp/src/components/FirstGame.test.js index 92e1e91c..29b21fbc 100644 --- a/webapp/src/components/FirstGame.test.js +++ b/webapp/src/components/FirstGame.test.js @@ -1,20 +1,20 @@ -import React from 'react'; -import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; -import FirstGame from './FirstGame'; -import { ContextFun } from './Context'; -import { BrowserRouter as Router } from 'react-router-dom'; +// import React from 'react'; +// import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; +// import axios from 'axios'; +// import MockAdapter from 'axios-mock-adapter'; +// import FirstGame from './FirstGame'; +// import { ContextFun } from './Context'; +// import { BrowserRouter as Router } from 'react-router-dom'; -test('renders learn react link', () => { - render( - - - - - - ); - const linkElement = screen.getByText(/¿Cual es/i); - expect(linkElement).toBeInTheDocument(); - }); \ No newline at end of file +// test('renders learn react link', () => { +// render( +// +// +// +// +// +// ); +// const linkElement = screen.getByText(/¿Cual es/i); +// expect(linkElement).toBeInTheDocument(); +// }); \ No newline at end of file From 85108d29efe946c3ba709545fcbe86ccf407fa23 Mon Sep 17 00:00:00 2001 From: alegarman2002 Date: Wed, 13 Mar 2024 17:19:19 +0100 Subject: [PATCH 82/94] Booro los archivos --- webapp/src/components/FirstGame.test.js | 20 -------------------- webapp/src/components/Menu.test.js | 0 2 files changed, 20 deletions(-) delete mode 100644 webapp/src/components/FirstGame.test.js delete mode 100644 webapp/src/components/Menu.test.js diff --git a/webapp/src/components/FirstGame.test.js b/webapp/src/components/FirstGame.test.js deleted file mode 100644 index 29b21fbc..00000000 --- a/webapp/src/components/FirstGame.test.js +++ /dev/null @@ -1,20 +0,0 @@ -// import React from 'react'; -// import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; -// import axios from 'axios'; -// import MockAdapter from 'axios-mock-adapter'; -// import FirstGame from './FirstGame'; -// import { ContextFun } from './Context'; -// import { BrowserRouter as Router } from 'react-router-dom'; - - -// test('renders learn react link', () => { -// render( -// -// -// -// -// -// ); -// const linkElement = screen.getByText(/¿Cual es/i); -// expect(linkElement).toBeInTheDocument(); -// }); \ No newline at end of file diff --git a/webapp/src/components/Menu.test.js b/webapp/src/components/Menu.test.js deleted file mode 100644 index e69de29b..00000000 From 3f5e7873a947c8ae4e0e5a2526a664faf9aca68b Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 18:08:54 +0100 Subject: [PATCH 83/94] removed history post method --- gatewayservice/gateway-service.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 1debf4dd..9a969b11 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -42,15 +42,6 @@ app.post('/adduser', async (req, res) => { } }); -app.post('/history/question', async (req, res) => { - try { - const response = await axios.post(storeQuestionsServiceUrl+'/history/question', req.body); - res.json(response.data); - } catch (error) { - res.status(error.response.status).json({ error: error.response.data.error }); - } -}) - app.get('/history/questions', async (req, res) => { try { const response = await axios.get(storeQuestionsServiceUrl+'/history/questions'); From 0ba8671aa9257ca0f03b8dff6d64018708ab9492 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 18:09:49 +0100 Subject: [PATCH 84/94] Fixed connection --- storeQuestionService/store-q-service.js | 62 +++++++++++++------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 058d3649..44623c6c 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -13,9 +13,11 @@ const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/storedque mongoose.connect(mongoUri); // Function to validate required fields in the request body -function validateRequiredFields(req, requiredFields) { +function validateRequiredFields(body, requiredFields) { for (const field of requiredFields) { - if (!(field in req.body)) { + if (!(field in body)) { + console.log(field) + console.log(body) throw new Error(`Missing required field: ${field}`); } } @@ -24,7 +26,7 @@ function validateRequiredFields(req, requiredFields) { app.post('/history/question', async (req, res) => { try { // Check if required fields are present in the request body - validateRequiredFields(req, ['pregunta', 'respuesta_correcta','respuestas_incorrectas']); + validateRequiredFields(req.body, ['pregunta', 'respuesta_correcta', 'respuestas_incorrectas']); const newQuestion = new Question({ pregunta: req.body.pregunta, @@ -41,33 +43,35 @@ app.post('/history/question', async (req, res) => { }); app.post('/history/questions', async (req, res) => { - try { - // Check if required fields are present in the request body - if (!Array.isArray(req.body)) { - throw new Error('Invalid request format. Expected an array of questions.'); - } - for (const question of req.body) { - validateRequiredFields(question, ['pregunta', 'respuesta_correcta','respuestas_incorrectas']); - } - - const newQuestions = []; - - for (const questionData of req.body) { - const newQuestion = new Question({ - pregunta: req.body.pregunta, - respuesta_correcta: req.body.respuesta_correcta, - respuestas_incorrectas: req.body.respuestas_incorrectas, - createdAt: req.body.createdAt - }); + try { + // Check if required fields are present in the request body + if (!Array.isArray(req.body)) { + throw new Error('Invalid request format. Expected an array of questions.'); + } + for (const question of req.body) { + console.log(question) + validateRequiredFields(question, ['pregunta', 'respuesta_correcta', 'respuestas_incorrectas']); + } + console.log("Pasa validación") + const newQuestions = []; + + for (const questionData of req.body) { + console.log(questionData) + const newQuestion = new Question({ + pregunta: questionData.pregunta, + respuesta_correcta: questionData.respuesta_correcta, + respuestas_incorrectas: questionData.respuestas_incorrectas, + createdAt: questionData.createdAt + }); + + await newQuestion.save(); + newQuestions.push(newQuestion); + } - await newQuestion.save(); - newQuestions.push(newQuestion); - } - - res.json(newQuestions); - } catch (error) { - res.status(400).json({ error: error.message }); - } + res.json(newQuestions); + } catch (error) { + res.status(400).json({ error: error.message }); + } }); From cefa642ce27845d1014e96a4fa3fc652f99b96ff Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 18:10:26 +0100 Subject: [PATCH 85/94] Fixed frontend problems due to format change in questions --- webapp/src/storeQuestion/App.jsx | 7 ++++--- webapp/src/storeQuestion/components/Question.jsx | 13 ++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 1d3e0318..902e94b7 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -28,12 +28,12 @@ function App(){ const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + useEffect(() => { const obtenerPreguntas = async () => { try { - const response = await axios.get(`${apiEndpoint}/questions`) - console.log(response) + const response = await axios.get(`${apiEndpoint}/history/questions`) setPreguntas(response.data); } catch (error) { console.error('Error al obtener las preguntas:', error.response.data.error); @@ -41,9 +41,10 @@ function App(){ }; obtenerPreguntas(); + //eslint-disable-next-line }, []); - + console.log(preguntas) return ( <>

Almacén de preguntas

diff --git a/webapp/src/storeQuestion/components/Question.jsx b/webapp/src/storeQuestion/components/Question.jsx index 4b6bf6d7..fe4918f1 100644 --- a/webapp/src/storeQuestion/components/Question.jsx +++ b/webapp/src/storeQuestion/components/Question.jsx @@ -5,13 +5,20 @@ function Question(props) { return (
-

{newQuestion.question}

+

{newQuestion.pregunta}

-

{newQuestion.c_answer}

- {newQuestion.w_answers.map((answer, index) => ( +
+

{newQuestion.respuesta_correcta}

+
+ {newQuestion.respuestas_incorrectas.map((answer, index) => ( +

{answer}

+
))}
+
+
{newQuestion.createdAt.substring(0,10)}
+
); } From f10856ffff6879bed256005fbab3dfbec3cbb309 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 18:10:35 +0100 Subject: [PATCH 86/94] Improved style --- webapp/src/storeQuestion/css/questions.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/webapp/src/storeQuestion/css/questions.css b/webapp/src/storeQuestion/css/questions.css index 8ff1daf3..bc21cd2e 100644 --- a/webapp/src/storeQuestion/css/questions.css +++ b/webapp/src/storeQuestion/css/questions.css @@ -130,9 +130,24 @@ h2{ text-align: center; } +h3{ + text-align: center; +} + #root main{ display: grid; grid-template-columns: repeat(auto-fit, minmax(40%, 1fr)); padding: 5px; grid-gap: 10px; } + +.container{ + display: flex; + justify-content: center; +} + +.container.footer{ + display: flex; + justify-content: right; + margin-right: 1em; +} \ No newline at end of file From 8e4c669b7601505f5b97c8403c981c5ec49c7465 Mon Sep 17 00:00:00 2001 From: Marco Quintana Date: Wed, 13 Mar 2024 18:25:15 +0100 Subject: [PATCH 87/94] Removing console logs --- storeQuestionService/store-q-service.js | 5 ----- webapp/src/storeQuestion/App.jsx | 1 - 2 files changed, 6 deletions(-) diff --git a/storeQuestionService/store-q-service.js b/storeQuestionService/store-q-service.js index 44623c6c..89b52aa5 100644 --- a/storeQuestionService/store-q-service.js +++ b/storeQuestionService/store-q-service.js @@ -16,8 +16,6 @@ mongoose.connect(mongoUri); function validateRequiredFields(body, requiredFields) { for (const field of requiredFields) { if (!(field in body)) { - console.log(field) - console.log(body) throw new Error(`Missing required field: ${field}`); } } @@ -49,14 +47,11 @@ app.post('/history/questions', async (req, res) => { throw new Error('Invalid request format. Expected an array of questions.'); } for (const question of req.body) { - console.log(question) validateRequiredFields(question, ['pregunta', 'respuesta_correcta', 'respuestas_incorrectas']); } - console.log("Pasa validación") const newQuestions = []; for (const questionData of req.body) { - console.log(questionData) const newQuestion = new Question({ pregunta: questionData.pregunta, respuesta_correcta: questionData.respuesta_correcta, diff --git a/webapp/src/storeQuestion/App.jsx b/webapp/src/storeQuestion/App.jsx index 902e94b7..1844fc2c 100644 --- a/webapp/src/storeQuestion/App.jsx +++ b/webapp/src/storeQuestion/App.jsx @@ -44,7 +44,6 @@ function App(){ //eslint-disable-next-line }, []); - console.log(preguntas) return ( <>

Almacén de preguntas

From 951564a9eb762fd8e031269e18970572eff46fb8 Mon Sep 17 00:00:00 2001 From: Liliana Date: Wed, 13 Mar 2024 19:29:23 +0100 Subject: [PATCH 88/94] sonarcloud problem solved (??) --- webapp/src/components/FirstGame.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/FirstGame.js b/webapp/src/components/FirstGame.js index d3789cf6..e11e9589 100644 --- a/webapp/src/components/FirstGame.js +++ b/webapp/src/components/FirstGame.js @@ -19,6 +19,11 @@ const Quiz = () => { return new Promise(resolve => setTimeout(resolve, ms)); }; + function secureRandomNumber(max) { + const randomBytes = new Uint32Array(1); + window.crypto.getRandomValues(randomBytes); + return randomBytes[0] % max; + } function shuffleArray(array) { // Crea una copia del array original @@ -27,8 +32,9 @@ const Quiz = () => { // Recorre el array desde el último elemento hasta el primero for (let i = shuffledArray.length - 1; i > 0; i--) { // Genera un índice aleatorio entre 0 y el índice actual - const randomIndex = Math.floor(Math.random() * (i + 1)); - + //const randomIndex = Math.floor(Math.random() * (i + 1)); + const randomIndex = secureRandomNumber(i + 1); + // Intercambia el elemento actual con el elemento del índice aleatorio const temp = shuffledArray[i]; shuffledArray[i] = shuffledArray[randomIndex]; From ff8991023995470a5edff54845d24622be6ead30 Mon Sep 17 00:00:00 2001 From: Liliana Date: Wed, 13 Mar 2024 19:33:44 +0100 Subject: [PATCH 89/94] sonarcloud problem solved at menu --- webapp/src/components/Menu.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/Menu.js b/webapp/src/components/Menu.js index 76bc4110..990e84de 100644 --- a/webapp/src/components/Menu.js +++ b/webapp/src/components/Menu.js @@ -17,6 +17,12 @@ const DatosContext = React.createContext(); var questions = [] +function secureRandomNumber(max) { + const randomBytes = new Uint32Array(1); + window.crypto.getRandomValues(randomBytes); + return randomBytes[0] % max; +} + function shuffleArray(array) { // Crea una copia del array original const shuffledArray = [...array]; @@ -24,7 +30,8 @@ function shuffleArray(array) { // Recorre el array desde el último elemento hasta el primero for (let i = shuffledArray.length - 1; i > 0; i--) { // Genera un índice aleatorio entre 0 y el índice actual - const randomIndex = Math.floor(Math.random() * (i + 1)); + //const randomIndex = Math.floor(Math.random() * (i + 1)); + const randomIndex = secureRandomNumber(i + 1); // Intercambia el elemento actual con el elemento del índice aleatorio const temp = shuffledArray[i]; From 4f412328c35d2afe7b1975125f9c6ccf7bb40cf1 Mon Sep 17 00:00:00 2001 From: Abel Date: Wed, 13 Mar 2024 21:22:29 +0100 Subject: [PATCH 90/94] Removed unnecesary mongoose schema and model --- .../questiongenerator-model.js | 21 +------------------ .../questiongenerator-service.js | 1 - 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-model.js b/questionsservice/questiongeneratorservice/questiongenerator-model.js index d51a3fbe..3279053d 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-model.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-model.js @@ -20,28 +20,9 @@ const questionSchema = new mongoose.Schema({ } }); -const requestSchema = new mongoose.Schema({ - n_preguntas: { - type: Number, - required: true, - default: 1 - }, - n_respuestas: { - type: Number, - required: true, - default: 4 - }, - tema: { - type: String, - required: true, - default: "todos" - } -}); const Question = mongoose.model('Question', questionSchema); -const Request = mongoose.model('Request', requestSchema); module.exports = { - Question, - Request + Question }; \ No newline at end of file diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 505a7a99..3083e7d5 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -3,7 +3,6 @@ const cors = require('cors'); const axios = require('axios'); const mongoose = require('mongoose'); const { Question } = require('./questiongenerator-model') -const { Request } = require('./questiongenerator-model') const app = express(); const port = 8006; From da7421e3e703fb1ec23f6f8e2222dd2de9ad8ac1 Mon Sep 17 00:00:00 2001 From: Abel Date: Wed, 13 Mar 2024 21:26:49 +0100 Subject: [PATCH 91/94] Removed unnecesary console.log --- .../questiongeneratorservice/questiongenerator-service.js | 1 - 1 file changed, 1 deletion(-) diff --git a/questionsservice/questiongeneratorservice/questiongenerator-service.js b/questionsservice/questiongeneratorservice/questiongenerator-service.js index 3083e7d5..118849a1 100644 --- a/questionsservice/questiongeneratorservice/questiongenerator-service.js +++ b/questionsservice/questiongeneratorservice/questiongenerator-service.js @@ -50,7 +50,6 @@ const generateQuestion = async () => { isWikiChecked = true; } elementos = shuffle(elementos); - console.log("caca", elementos); mockedQuestions = [{ pregunta: "¿Cual es la capital de " + elementos[0].countryLabel + "?", respuesta_correcta: elementos[0].capitalLabel, From 38ada23f21d06d1a9e7734b1cdada37d5b00ed56 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:56:13 +0100 Subject: [PATCH 92/94] Eliminated the unnecessary files --- package-lock.json | 50 ----------------------------------------------- package.json | 5 ----- 2 files changed, 55 deletions(-) delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index f9ce8791..00000000 --- a/package-lock.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "wiq_es6c", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "react-circular-progressbar": "^2.1.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-circular-progressbar": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.1.0.tgz", - "integrity": "sha512-xp4THTrod4aLpGy68FX/k1Q3nzrfHUjUe5v6FsdwXBl3YVMwgeXYQKDrku7n/D6qsJA9CuunarAboC2xCiKs1g==", - "peerDependencies": { - "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 5ba66912..00000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "react-circular-progressbar": "^2.1.0" - } -} From 52663cb3bc225b7eae7f411a6bc068a05982f079 Mon Sep 17 00:00:00 2001 From: alegarman2002 <116609314+alegarman2002@users.noreply.github.com> Date: Wed, 13 Mar 2024 22:30:45 +0100 Subject: [PATCH 93/94] First part of adding the button to see the historic questions --- webapp/src/components/Menu.js | 12 ++++++++++++ webapp/src/index.js | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/Menu.js b/webapp/src/components/Menu.js index 990e84de..da48b6a0 100644 --- a/webapp/src/components/Menu.js +++ b/webapp/src/components/Menu.js @@ -87,6 +87,10 @@ const Menu = () => { console.log(questions) }; + const openStoredQuestions = async () => { + navigation("/firstGame") + } + return (

Bienvenido a wiq_06c por favor seleccione un modo de juego para comenzar partida:

@@ -97,6 +101,14 @@ const Menu = () => { > Clasico + +
); diff --git a/webapp/src/index.js b/webapp/src/index.js index bf6814c8..18cbf3e7 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -16,7 +16,8 @@ import { import FirstGame from './components/FirstGame'; import Menu from './components/Menu'; -import Login from './components/Login' +import Login from './components/Login'; +import AppQuestion from './storeQuestion/App' const root = ReactDOM.createRoot(document.getElementById('root')); From bfddeec74c809c6e19666c5fb7a49c5a9a5e62a8 Mon Sep 17 00:00:00 2001 From: Liliana Date: Wed, 13 Mar 2024 22:46:47 +0100 Subject: [PATCH 94/94] add button for stored questions --- webapp/src/components/Menu.js | 6 +++--- webapp/src/index.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/webapp/src/components/Menu.js b/webapp/src/components/Menu.js index da48b6a0..9677f6c9 100644 --- a/webapp/src/components/Menu.js +++ b/webapp/src/components/Menu.js @@ -88,7 +88,7 @@ const Menu = () => { }; const openStoredQuestions = async () => { - navigation("/firstGame") + navigation("/appQuestion") } return ( @@ -102,11 +102,11 @@ const Menu = () => { Clasico
diff --git a/webapp/src/index.js b/webapp/src/index.js index 18cbf3e7..0e09a394 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -27,6 +27,7 @@ root.render( }> }> + }> }> }>