diff --git a/.dockerignore b/.dockerignore new file mode 100755 index 00000000..d45ad13e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +.github +Dockerfile +.dockerignore +*.heapsnapshot +*.log \ No newline at end of file diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index dcaac7f9..ee6a9f6d --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ /node_modules/ /tmp/* +.clinic/ # Config files config-test.js +*.log +*.heapsnapshot +*.crt +!DemoCA.crt \ No newline at end of file diff --git a/DemoCA.crt b/DemoCA.crt new file mode 100755 index 00000000..eec572bd --- /dev/null +++ b/DemoCA.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIUCmGeUFwNiGdJZLwpkevTf29wjrowDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwNjI1MTk0NjA4WhcNMjkw +NjIyMTk0NjA4WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBANKAEz3dPmYJvwjhSBssR0jP5JK7CO8iOqzhcqzy +cFb05hr9unPtPS76lrEEkYSgklwW5X4aVTOfqrJkc0RyoLwyYjmPei45xRiFeTfu +FA1cAwbRAriTuOySvp8U0H/J8WDCNrNrhDags9wzbtBZuTJt1UCNYXYJyHMF2NE3 +7fO86x3AVW30v0iiHa00ev2Fk5YZkKUYuL0Dv2Ul3SbWFRq3hKjFypkOK+Iur/Ye +wW7XLAoVatOvlFZCmQ+kD59b0L9QCXqDU2odlwzgNrMpczfTyuzJKQyxm0iLJgxW +QvC329dkjyq/5RR7RvWjpjzyAopXMo5ZE4CWgHQz97Rfhv8CAwEAAaOBkDCBjTAd +BgNVHQ4EFgQUNOD0d021fHYcir4UebCMny2eQVAwUQYDVR0jBEowSIAUNOD0d021 +fHYcir4UebCMny2eQVChGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghQKYZ5Q +XA2IZ0lkvCmR69N/b3COujAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq +hkiG9w0BAQsFAAOCAQEAFwfZVGQnd1ReZeL4uyvS2ZVI3U2GYFGrdxOiC+1nt3TG +QF5W+4RN2394Mv1DaUIjtzAuKanR73qyiVjxkFetsSj4dItzbZQBCpRT32E1EHb2 +aFXbTJ76JGPHed0wmAdCxA+zlEjKZr7B73sS2GPfSLJw3CsQYMtVSCXLCox4DUrW +yOlF2kgO1OGI4kPbtw+CKWwCh0x0StckYo5tI8MF1U5UBtAXzPJ2pXyuc7t0Hejy +MMKILaiIrqCtK/9BdQWW3iqDhhcLX6VrPb33QNA7PV9UBVAfBPPIejDLSv1aS/X9 +SuegPnlhRzBl1PL0zAMlEGI9GR3HruCJoDKo9MlR7g== +-----END CERTIFICATE----- diff --git a/Dockerfile b/Dockerfile new file mode 100755 index 00000000..6dc94952 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM node:22.14.0-bullseye + +# Install ca-certificates and update them +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates && \ + update-ca-certificates && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app + +# Set the working directory +WORKDIR /home/node/app + +COPY --chown=node:node package*.json ./ + +RUN npm install -g clinic pm2 + +USER node + +RUN npm install + +# Copy the current directory contents into the container at /app +COPY --chown=node:node . . + +RUN mkdir -p /home/node/logs && chown -R node:node /home/node/logs + +# Make port 3050 available to the world outside this container +EXPOSE 3050 + +CMD [ "pm2-runtime", "ecosystem.config.js" ] \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/bin/cron-task.js b/bin/cron-task.js new file mode 100644 index 00000000..f3b5b159 --- /dev/null +++ b/bin/cron-task.js @@ -0,0 +1,25 @@ +const { convertTimeToCron } = require("../routes/lib/date.js"); +const cron = require('node-cron'); +const logger = require('../logger'); +const userClientsListManager = require('../routes/lib/userClientsListManager'); +const sseManager = require('../routes/lib/sseManager'); // Import SSE Manager +const sseClientsListManager = require('../routes/lib/sseClientsListManager'); +const usertools = require('../routes/lib/usertools.js'); +const config = require('../config.js'); + +// Schedule a task to run every x minutes +cron.schedule(convertTimeToCron(config.simva.ping_task/(1000*60)), async () => { + logger.info('SSE Ping task is running at ' + new Date()); + var clientsWithoutAction=sseClientsListManager.getTimeSuperiorToXMinClientList(5); + logger.debug(JSON.stringify(clientsWithoutAction)); + sseManager.sendMessageToClientList(clientsWithoutAction, {message:'ping',type:'ping'}); +}); + +// Schedule a task to run every x minutes +cron.schedule(convertTimeToCron(config.simva.auth_expired_task/(1000*60)), async () => { + logger.info('SSE auth expired task is running at ' + new Date()) + var sessionsToRefresh=await usertools.getRefreshSessionsList(); + var clientsToRefresh=userClientsListManager.getRefreshClientList(sessionsToRefresh); + logger.debug(JSON.stringify(clientsToRefresh)); + sseManager.sendMessageToClientList(clientsToRefresh, {message:'auth expired',type:'refresh_auth'}); +}); \ No newline at end of file diff --git a/bin/www b/bin/www old mode 100644 new mode 100755 index afa3550e..5f4e5b21 --- a/bin/www +++ b/bin/www @@ -6,8 +6,7 @@ const app = require('../routes'); const http = require('http'); const config = require('../config'); - - +const logger = require('../logger'); //XXX //require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create(); @@ -58,17 +57,17 @@ function onError (error) { const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`; - console.log(error.code); - console.log(error); + logger.info(error.code); + logger.info(error); // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.log(`${bind} requires elevated privileges`); + logger.info(`${bind} requires elevated privileges`); process.exit(1); break; case 'EADDRINUSE': - console.log(`${bind} is already in use`); + logger.info(`${bind} is already in use`); process.exit(1); break; default: @@ -82,5 +81,5 @@ function onError (error) { function onListening () { const addr = server.address(); const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`; - console.log(`Listening on ${bind}`); + logger.info(`Listening on ${bind}`); } diff --git a/config.js b/config.js old mode 100644 new mode 100755 index ae78075a..5410c841 --- a/config.js +++ b/config.js @@ -1,3 +1,4 @@ +const ms = require("ms"); let config = {} let default_protocol_ports = { @@ -11,6 +12,10 @@ config.simva.host = process.env.SIMVA_HOST || 'simva.external.test' config.simva.protocol = process.env.SIMVA_PROTOCOL || 'https' let simvaPort = ((default_protocol_ports[config.simva.protocol] !== config.simva.port) ? `:${config.simva.port}` : '') config.simva.url = process.env.SIMVA_URL || `${config.simva.protocol}://${config.simva.host}${simvaPort}`; +config.simva.cookieMaxAgeInMin=process.env.SIMVA_COOKIE_MAX_AGE_IN_MIN || 4*60 +config.simva.profiling = process.env.ENABLE_DEBUG_PROFILING == undefined ? "false" : (process.env.ENABLE_DEBUG_PROFILING == "true") +config.simva.ping_task = process.env.PING_TASK !== undefined ? ms(process.env.PING_TASK) : ms("3min") +config.simva.auth_expired_task = process.env.AUTH_EXPIRED_TASK !== undefined ? ms(process.env.AUTH_EXPIRED_TASK) : ms("30min") config.mongo = {} config.mongo.host = process.env.MONGO_HOST || 'localhost:27017' @@ -56,7 +61,43 @@ config.limesurvey.url = `${config.limesurvey.protocol}://${config.limesurvey.ho config.limesurvey.adminUser = process.env.LIMESURVEY_ADMIN_USER || 'admin' config.limesurvey.adminPassword = process.env.LIMESURVEY_ADMIN_PASSWORD || 'password' +config.hmac = {} +config.hmac.password = process.env.HMAC_PASSWORD || 'mypassword' +config.hmac.salt = process.env.HMAC_SALT || 'mysalt' +config.hmac.key = process.env.HMAC_KEY || 'mykey' +config.hmac.hmacKey = null + config.lti = {} config.lti.enabled = process.env.LTI_ENABLED || 'false' +config.i18n = {} +config.i18n.debug = process.env.I18N_DEBUG === "true" +languages = process.env.SIMVA_LOCALES || "en,es"; +config.i18n.languages = languages.split(",").map(s => s.trim());; +config.i18n.defaultLanguage = languages[0]; + +config.kafka = {} +config.kafka.clientId= process.env.SIMVA_KAFKA_CLIENTID || 'my-client-id' +config.kafka.brokers= [ process.env.SIMVA_KAFKA_BROKER ] || ['localhost:9092'] +config.kafka.groupId= process.env.SIMVA_KAFKA_GROUPID || 'my-group-id' +config.kafka.topic= process.env.SIMVA_KAFKA_SIMVA_EVENTS_TOPIC || 'minio-events' + +config.shlink = {} +config.shlink.apihost = process.env.SHLINK_SERVER_HOST || 'shlink.external.test' +config.shlink.protocol = process.env.SHLINK_PROTOCOL || 'https' +config.shlink.port = process.env.SHLINK_PORT || '443' +config.shlink.apiurl = `${config.shlink.protocol}://${config.shlink.apihost}:${config.shlink.port}` +config.shlink.apikey = process.env.SHLINK_SERVER_API_KEY || 'myapikey' + +config.tmon = {} +config.tmon.port = parseInt(process.env.TMON_PORT || 443); +config.tmon.host = process.env.TMON_HOST || 'tmon.simva.external.test' +config.tmon.protocol = process.env.TMON_PROTOCOL || 'https' +let tmonPort = ((default_protocol_ports[config.tmon.protocol] !== config.tmon.port) ? `:${config.tmon.port}` : '') +config.tmon.url = process.env.TMON_URL || `${config.tmon.protocol}://${config.tmon.host}${tmonPort}`; +config.tmon.file = process.env.TMON_MINIO_TRACES_FILE || "traces.json" + +config.activities = {}; +config.activities.enabled = process.env.TEMPLATE_ACTIVITIES_ENABLED || 'false'; + module.exports = config; \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml old mode 100644 new mode 100755 index 2be7b76b..5d0a7cb9 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,28 +10,76 @@ networks: services: mongodb: - image: mongo:4.0 + image: mongo:4.2.8 volumes: - mongo_data:/data/db hostname: mongo.simva.dev.test - simva-api: - image: node:8 - command: bash -c "cd /app && chmod +x docker-startup.sh && ./docker-startup.sh" + simva-front: + build: ./ + command: [ "npm", "run", "dev" ] stdin_open: true tty: true environment: - MONGO_HOST: mongo.simva.dev.test - MONGO_DB: /simva - LIMESURVEY_HOST: limesurvey-dev.external.test + LOG_LEVEL: debug + LOG_FOLDER: /home/node/logs + #LOG/DEBUG + DEBUG: true + #NODES + NODE_ENV: development + NODE_EXTRA_CA_CERTS: /home/node/app/DemoCA.crt + #SIMVA + SIMVA_PORT: 3050 + SIMVA_HOST: simva.external.test + SIMVA_PROTOCOL: https + SIMVA_URL: https://simva.external.test/ + #MONGO DB + MONGO_HOST: simva-mongo.dev.test + MONGO_DB: /simva-front + #SSO KEYCLOAK + SSO_HOST: sso.external.test + SSO_PROTOCOL: https + SSO_PORT: 443 + SSO_ACCOUNT_PATH: /account + SSO_USER_CAN_SELECT_ROLE: true + SSO_ADMINISTRATOR_CONTACT: contact@administrator.com + SSO_STUDENT_ALLOWED_ROLE: true + SSO_TEACHING_ASSISTANT_ALLOWED_ROLE: true + SSO_TEACHER_ALLOWED_ROLE: true + SSO_RESEARCHER_ALLOWED_ROLE: true + SSO_REALM: simva + SSO_CLIENT_ID: simva + SSO_CLIENT_SECRET: secret + SSO_SSL_REQUIRED: external + SSO_PUBLIC_CLIENT: false + #SIMVA API + SIMVA_API_HOST: simva-api.external.test + SIMVA_API_PORT: 443 + SIMVA_API_PROTOCOL: https + #LIMESURVEY + LIMESURVEY_HOST: "https://limesurvey-dev.external.test/" + LIMESURVEY_PROTOCOL: https + LIMESURVEY_PORT: 443 LIMESURVEY_ADMIN_USER: admin - LIMESURVEY_ADMIN_PASSWORD: password - NODE_EXTRA_CA_CERTS: /app/DemoCA.crt + LIMESURVEY_ADMIN_PASSWORD: secret + #LTI + LTI_ENABLED: false + #KAFKA + SIMVA_KAFKA_CLIENTID: simva_events + SIMVA_KAFKA_BROKER: "kafka1.dev.test:9092" + SIMVA_KAFKA_GROUPID: simva_events + SIMVA_KAFKA_SIMVA_EVENTS_TOPIC: simva_events_topic + #SHLINK + SHLINK_SERVER_HOST: shlink.external.test + SHLINK_PORT: 443 + SHLINK_PROTOCOL: https + SHLINK_SERVER_API_KEY: password volumes: - - ./:/app + - ./:/home/node/app + - /home/node/app/node_modules #exclude node_modules depends_on: - mongodb - hostname: simva-api.dev.test + hostname: simva.dev.test dns: - 172.31.0.53 networks: @@ -40,4 +88,4 @@ services: labels: traefik.enable: true traefik.port: 3000 - traefik.frontend.rule: "Host:simva-api.external.test" + traefik.frontend.rule: "Host:simva.external.test" diff --git a/docker-startup.sh b/docker-startup.sh deleted file mode 100755 index b1a3c5cf..00000000 --- a/docker-startup.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -[[ "${DEBUG:-false}" == "true" ]] && set -x - -if [[ ! -d "node_modules" ]]; then - npm install -fi - -if [[ "${NODE_ENV:-production}" == "development" ]]; then - npm run dev -else - npm start -fi \ No newline at end of file diff --git a/ecosystem.config.js b/ecosystem.config.js new file mode 100644 index 00000000..de852af7 --- /dev/null +++ b/ecosystem.config.js @@ -0,0 +1,32 @@ +module.exports = { + apps: [ + { + name: "main-app", + script: "bin/www", + watch: process.env.NODE_ENV === "development", + restart_delay: 5000, + node_args: process.env.NODE_ENV === "development" + ? ( process.env.PROFILING === "true" + ? "--inspect=0.0.0.0:9229 --prof --perf-basic-prof --interpreted-frames-native-stack" : + "--inspect=0.0.0.0:9229 --trace-warnings") + : "", + env : { + PROCESS_TAG: "[MAIN]" + } + }, + { + name: "process-cron-task", + script: "bin/cron-task.js", + watch: process.env.NODE_ENV === "development", + restart_delay: 5000, + node_args: process.env.NODE_ENV === "development" + ? ( process.env.PROFILING === "true" + ? "--inspect=0.0.0.0:9230 --prof --perf-basic-prof --interpreted-frames-native-stack" : + "--inspect=0.0.0.0:9230 --trace-warnings") + : "", + env : { + PROCESS_TAG: "[CRON_TASK]" + } + } + ] +}; \ No newline at end of file diff --git a/locales/en/SIMLETs.json b/locales/en/SIMLETs.json new file mode 100644 index 00000000..a1746291 --- /dev/null +++ b/locales/en/SIMLETs.json @@ -0,0 +1,78 @@ +{ + "title": "SIMLETs", + "description": "SIMLETs are the core of SIMVA, allowing you to create and manage your own simulations. A SIMLET is a container for all the elements of a simulation, including sessions, activities, users, and groups. You can create new SIMLETs, edit existing ones, archive those you no longer need, and manage their settings and content.", + "archived.title": "Archived SIMLETs", + "archived.description": "List of SIMLETs that have been archived. You can dearchive them to make them active again.", + "no_simlets.message": "You have no SIMLETs yet. Create one using the button on the bottom right (+)", + "no_archived.message": "There are no archived SIMLETS", + + "card.createdAt": "Created at", + "card.updatedAt": "Updated at", + "card.sessions": "Sessions", + "card.groups": "Groups", + "card.users": "Users", + "card.tags": "Tags", + + "add.title": "Add SIMLET", + "new.tab": "Add new", + "new.submit": "Create SIMLET", + + "import.tab": "Import from existing", + "import.input": "Select exported SIMLET file", + "import.upload.error": "Select the file to upload first", + "import.submit": "Import SIMLET", + + "settings.edit.title": "Edit", + "edit.title": "Edit SIMLET", + "edit.submit": "Edit SIMLET", + + "name.title": "Name", + "name.placeholder": "SIMLET name", + "description.title": "Description", + "description.placeholder": "SIMLET desciption", + + "settings.url.title": "URL settings", + "scheduler.shlink.generate.title": "Generate reduced URL for Scheduler", + "scheduler.shlink.generate.randomly_length.title": "Randomly generated", + "scheduler.shlink.generate.randomly_length.message": "With a length of: ", + "scheduler.shlink.generate.custom_slug.title": "Use a custom slug", + "scheduler.shlink.generate.submit": "Generate", + "scheduler.shlink.message": "Copy short URL: {{shlink}}", + "scheduler.shlink.custom_slug.placeholder": "Custom slug", + "scheduler.shlink.delete.title": "Delete Scheduler Shlink URL", + "scheduler.shlink.delete.confirm": "Are you sure you want to delete the short link '{{shlink}}' from SIMLET '{{SIMLET}}'?", + + "settings.download.title": "Download config", + "config.download.simlet": "Export SIMLET to .json", + "config.download.uadventure": "Download uAdventure config", + + "settings.archive.title": "Archive", + "archive.confirm": "Are you sure you want to archive the SIMLET '{{SIMLET}}'?\nThis action can't be reverted and the SIMLET will move to the archived tab ", + "settings.dearchive.title": "Dearchive", + + "settings.delete.title": "Delete", + "delete.confirm": "Are you sure you want to delete the SIMLET '{{SIMLET}}'?\nAll the Sessions, activities and data will be deleted too", + + "edit.no_changes.message": "No changes detected!", + + "single.title": "SIMLET", + "single.description": "General information and settings for the selected SIMLET", + "sessions.tab.description": "Manage sessions in this SIMLET: create, edit, monitor activity progress, and download session data", + "users.tab.description": "Manage users, groups, coordinators, and related assignments in this SIMLET", + "sessions.download.description": "Download all available data for this session, including activity data", + "simlets.description": "List of SIMLETs available to you and quick access to create, edit, archive, or remove them", + "sessions.tab.title": "Sessions", + "users.tab.title": "Users", + + "tester.play.title": "Play SIMLET as tester", + "tester.play.description": "Play the SIMLET as a tester to experience it as a participant would. This allows you to verify that the activities and flow are working as intended before sharing it with others.", + "play.title": "Play SIMLET", + "play.description": "Play to participate in a SIMLET", + + "scheduler.noSIMLET.title": "You have no SIMLETs yet to participate", + "scheduler.title": "Click here to start or continue your session in the SIMLET", + "scheduler.current": "Current Activity: ", + "scheduler.refresh": "Refresh Page to Continue SIMLET", + "scheduler.complete": "Complete Activity", + "scheduler.exit": "Exit SIMLET" +} \ No newline at end of file diff --git a/locales/en/about.json b/locales/en/about.json new file mode 100644 index 00000000..ffbf5103 --- /dev/null +++ b/locales/en/about.json @@ -0,0 +1,124 @@ +{ + "title": "About", + "description": "Welcome to the SIMVA front-end! This section provides an overview of the platform, its main features, and a guide to help you navigate through the interface. Whether you're a teacher, student, researcher, or developer, you'll find useful information to get started and make the most of SIMVA.", + "text": "This section collects navigation help, tutorials, and short explanations for SIMVA.\nUse the steps below to move through the main pages. Some options only appear for teachers, coordinators, or administrators.", + "header.logout.title": "Header guide for visitors", + "header.logout.description": "This is the top bar shown before login. It gives access to the public pages and the login button.", + "header.logout.note": "These are the only top buttons available before signing in.", + "header.logout.language.title": "Language selector", + "header.logout.language.description": "Change the interface language from the small selector on the left.", + "header.logout.about.title": "About", + "header.logout.about.description": "Open this page to read the SIMVA overview and the navigation help.", + "header.logout.research.title": "e-UCM Research", + "header.logout.research.description": "Go to the research site for project information and related material.", + "header.logout.contact.title": "Contact", + "header.logout.contact.description": "Use this link to reach the contact information shown in the header.", + "header.logout.login.title": "Login", + "header.logout.login.description": "Press this button to sign in and switch to the authenticated interface.", + "header.login.title": "Header guide for signed-in users", + "header.login.description": "This is the top bar shown after login. It shows your account and the logout action, plus extra controls on scheduler pages.", + "header.login.note": "On scheduler pages you may also see refresh, complete activity, and exit controls.", + "header.login.language.title": "Language selector", + "header.login.language.description": "Change the interface language from the selector on the left.", + "header.login.account.title": "Account name", + "header.login.account.description": "Open your account area or profile information from the username button.", + "header.login.logout.title": "Logout", + "header.login.logout.description": "End the current session and return to the public interface.", + "menu.title": "Menu guide for signed-in users", + "menu.description": "This is the left navigation shown after login. It links you to the main areas of SIMVA.", + "menu.note": "Some entries only appear for teachers, coordinators, or administrators.", + "menu.home.title": "Home", + "menu.home.description": "Return to the start page with the latest welcome and account information.", + "menu.play.title": "Play SIMLETs", + "menu.play.description": "Open the scheduler entry point for participants who need to play assigned SIMLETs.", + "menu.simlets.title": "SIMLETs", + "menu.simlets.description": "Manage studies, sessions, participants, and results from the SIMLET area.", + "menu.groups.title": "Groups", + "menu.groups.description": "Organize users and group-based permissions here.", + "menu.archived.title": "Archived SIMLETs", + "menu.archived.description": "Review studies that have been archived and kept for reference.", + "menu.about.title": "About", + "menu.about.description": "Open this tutorial page again whenever you need a reminder of the interface.", + + "simva.title": "SIMVA", + "simva.description": "SIMVA infrastructure is an open architecture software which is composed of several interconnected systems. Among these systems are the unified SSO login system (KeyCloak), the processing queue system (Kafka), a cloud storage system (Minio) and a Learning record Store (LRS) to store the xAPI data. Its architecture is scalable and interoperable with other third-party tools, which enables the delegation of the most critical functionalities to reliable and scalable platforms.", + "simva.frontend.title": "SIMVA Front-end", + "simva.frontend.description": "SIMVA front-end is used to integrate the games into the system, create surveys, manage sessions, manage users participation in the sessions and to track/analyze sessions' data in real-time. This data evolves from users' responses to surveys to full insights and metrics during the whole session which also includes game-play data.", + "simva.roles.title": "Roles and Permissions", + "simva.roles.description": "In SIMVA, the user can be a teacher, a student, a researcher or a developer. The roles and permissions in the front-end are categorized into a supervisor, a coordinator and a participant. Which will be explained later in this document.", + + "simlet.title": "SIMLET (SIMVA APPLET)", + "simlet.description": "A container in SIMVA front-end web application to encapsulate the data of different sessions. A SIMLET is created to achieve a particular objective, for example to compare the effectiveness of a particular SG, compare between the abilities of three groups of students or compare the programming knowledge acquired across different games. Each SIMLET has its own supervisors with full authority on the SIMLET's sessions and activities. The main supervisor (the user who created the SIMLET) is the only user allowed to delete the whole SIMLET.", + "archived_simlet.title": "Archived SIMLET", + "archived_simlet.description": "An archived SIMLET is kept for reference and can be restored later. It is hidden from active working lists but preserves its configuration and history.", + + "session.title": "Session", + "session.description": "A container in SIMVA front-end web application to encapsulate the data of several activities. A session consists of one or more activities (pre-survey, game-play or manual/traditional learning activity and post-survey) to be undertaken by a group of participants. Each session has its own coordinators with full authority on the session's activities.", + + "supervisor.title": "SIMLET Supervisor", + "supervisor.description": "A user who has full access to a particular SIMLET. The main supervisor creates the SIMLET first and then can edit/delete the SIMLET or assign other supervisors or coordinators specifying the permission mode whether \"Editor\" or \"Viewer\". A supervisor with \"Editor\" mode can edit the SIMLET's information (title and description), add/edit/delete sessions, add/edit/delete different activities that compose the sessions, and assign the participants to be involved in each session. Also, a supervisor with \"Editor\" mode can add tags to the sessions, start them, track and export the results. A supervisor with \"Viewer\" mode can only view the SIMLET's configurations alongside its sessions and the associated activities and its results with no ability to add, edit or delete. Only the main supervisor is allowed to delete the SIMLET.", + + "coordinator.title": "Session Coordinator", + "coordinator.description": "A user who has full access to a particular session. There are two permission modes: \"Editor\" and \"Viewer\". A coordinator with \"Editor\" mode can edit the session's information (title and description), add tags to the session, add/edit/delete the different activities that form a session. In addition, a coordinator with \"Editor\" mode can assign other coordinators to the session and set their permission, whether \"Editor\" or \"Viewer\". Coordinators with both modes \"Editor\" and \"Viewer\" have access to the dashboard to view results and export them but starting the session is only limited to the coordinators with \"Editor\" mode.", + + "participant.title": "Participant", + "participant.description": "A user (a student for example) whose role is to undertake the activities such as answering the surveys and playing the games. The supervisor of the SIMLET can view each participant's results.", + + "gameclient.title": "Game-client", + "gameclient.description": "A game client is all metadata of the game such as title, description, category (awareness or education), and subject area (mathematics, programming, bullying, etc). It's the game's URL for a web game or the game compressed file for a desktop game.", + + "integratedgame.title": "Integrated game into SIMVA", + "integratedgame.description": "An integrated game into SIMVA means that the game-client is described in SIMVA and presented as a game-play activity template. Each time a new game is integrated into SIMVA, a game-play activity template with an ID is automatically generated. Each time the game is used in a game-play activity within a session, a new game-play activity instance is created from this template. This means that the game-play activity instance will reference the game-play activity template using its ID. Supervisors can display the integrated games from a menu in SIMVA front-end.", + + "activity.title": "Activity", + "activity.description": "An action or set of actions to be performed by participants. This action could be answering surveys (Limesurvey activity), playing serious games (Gameplay activity) or undertaking traditional learning exercises (manual activity).", + "activity.types.title": "Activity Types", + + "limesurvey.title": "Limesurvey Activity", + "limesurvey.description": "A survey-based activity that uses LimeSurvey as service, allowing participants to answer pre and post surveys and enabling the owners to collect data effectively.", + + "gameplay.title": "Gameplay Activity", + "gameplay.description": "The action of playing the serious game where participants game interaction data are collected via the xAPI component (trackers in the code), designed to integrate educational content in an engaging manner.", + + "manual.title": "Manual Activity", + "manual.description": "A traditional learning exercise to be undertaken by participants such as reading a book, reading an article, watching a video or any other passive learning task.", + + "activitytemplate.title": "Activity Template", + "activitytemplate.description": "An activity template represents the static description of an activity. It defines the metadata of an activity such as its title and description. One template can be used within many sessions by creating instances of the template. The activity template can be a survey activity, a manual activity or a game-play activity. In case of game-play activity, it will also contain game-client data.", + + "activityinstance.title": "Activity Instance", + "activityinstance.description": "An activity instance represents a concrete execution of an activity template. It stores participant's specific data, such as surveys' responses, manual activity performance, game-play activity interactions, such as traces and results. When the user adds an activity to a particular session, an instance of that activity template is automatically created. In case of game-play activity, the activity instance is referenced to the integrated game's ID. However, the game's collected data will be stored at the session's game-play activity level.", + + "manualcompletion.title": "Manual Completion for Activities", + "manualcompletion.description": "In case a participant completes an activity but its status is not set automatically to \"completed\" for a reason, there is a button that enables the supervisor/coordinator to manually change the status to \"completed\". It's also possible to manually change the status of an activity to \"completed\" for all participants at once.", + + "dashboard.title": "SIMVA dashboard", + "dashboard.description": "Each SIMLET contains a visual dashboard with detailed information about sessions' activities. The dashboard demonstrates general information about each activity status showing the percentage of participants completion, progress and result. It also demonstrates a detailed list of the participants, this list shows each participant's name, completion status, progress status and backup result. While the activity is receiving xAPI data, whether it's in progress or completed the dashboard is updated correspondingly to the received traces.", + + "group.title": "Group", + "group.description": "A Group is a set of participants used to organize assignments and allocation rules across sessions.", + + "users.title": "Users", + "users.description": "Users, groups, and coordinators define who participates in the Simlet and how participants are assigned to sessions.", + "xapi.dashboard.title": "xAPI Data for SIMVA Dashboards", + "xapi.dashboard.intro": "For each session within a SIMLET, there are different dashboards that represent real-time tracking data for its activities. The following image shows an example of these dashboards.", + "xapi.dashboard.image.alt": "Example of SIMVA dashboards for session activities", + "xapi.dashboard.backend.title": "Backend xAPI Tracking", + "xapi.dashboard.backend.desc": "In the backend, we track the xAPI traces for the dashboards. For example:", + "xapi.dashboard.activitytypes.title": "Activity Types and xAPI Object Types", + "xapi.dashboard.activitytypes.col1": "Activity Type", + "xapi.dashboard.activitytypes.col2": "Object definition type in xAPI traces", + "xapi.dashboard.activitytypes.game": "Game-play activity", + "xapi.dashboard.activitytypes.limesurvey": "LimeSurvey activity", + "xapi.dashboard.activitytypes.manual": "Manual Activity", + "xapi.dashboard.visibledata.title": "Dashboard Data and xAPI Traces", + "xapi.dashboard.visibledata.desc": "In the following lines, we are defining the visible data on the dashboards with its corresponding tracked xAPI traces.", + "xapi.dashboard.initialized.title": "Initialized", + "xapi.dashboard.initialized.desc": "This represents whether the participant has started the activity or not. Its value could be 'true' or 'false'. The default value is 'false', and it will become 'true' when the participant initialises the activity. This means that in the backend the SIMVA server has received an xAPI trace with the verb id: 'http://adlnet.gov/expapi/verbs/initialized'.", + "xapi.dashboard.progress.title": "Progress", + "xapi.dashboard.progress.desc": "This represents the percentage of activity completion. Its value is between 0% and 100% both included. If the activity is not initialized yet, the progress default value is '-', while if it is initialized but with no progress the progress value is '0%'. If it is fully completed, the progress value is '100%'. This means that in the backend the SIMVA server has received an xAPI trace with the verb id: 'http://adlnet.gov/expapi/verbs/progressed', and also the result value scaled between 0 and 1 (both included) from the result label shown in the table:", + "xapi.dashboard.progress.col1": "Activity Type", + "xapi.dashboard.progress.col2": "Result label displayed in xAPI traces", + "xapi.dashboard.completed.title": "Completed", + "xapi.dashboard.completed.desc": "This represents whether the participant has completed the activity or not. Its value could be 'true' or 'false'. The default value is 'false', and it will become 'true' when the participant completes the activity. This means that in the backend the SIMVA server has received an xAPI trace with the verb id: 'http://adlnet.gov/expapi/verbs/completed', and also the result completion value has to be set to 'true'." +} \ No newline at end of file diff --git a/locales/en/activities.json b/locales/en/activities.json new file mode 100644 index 00000000..779abaf6 --- /dev/null +++ b/locales/en/activities.json @@ -0,0 +1,183 @@ +{ + "title": "Activities", + "single.title": "Activity", + "text": "Activities view is temporally disabled.\nThis tab is designed to create \"template activities\" for them later to be copied into tests.\nThese \"template activities\" help the creation of multiple test cases similar with small modifications.\nIt will be available in a future version.", + + "no_activities.message": "There are no activities in this session. Add one using the 3-dot menu button on the right", + + "add.title": "Add activity", + "add.new.title": "New activity", + "add.new.web.no_url_message": "You're about to create a web activity with no URL. Are you sure you want to continue? (You will be able to change the URL later)", + "add.existing.title": "Select from existing", + + "edit.title": "Edit", + + "delete.title": "Delete", + "delete.confirm": "Are you sure you want to delete the activity '{{activity}}' of session '{{session}}' from SIMLET '{{SIMLET}}'?\nAll the data of the activity will be deleted too", + + "export.title": "Export", + "import.title": "Import", + "import.message": "Select the file to import", + "import.upload.error": "Select the file to upload first", + "import.error.invalid_file": "Invalid file", + + "name.placeholder": "Activity name", + "activity.type.title": "Activity type", + "type.title": "Type", + + "activity.type.select": "Select an activity type", + "activity.type.select_required": "Activity type is required", + "activity.name": "Default Activity", + "activity.description": "A basic activity with completion state and a place to save results.", + "activity.result.title": "Result", + "activity.result.file.prefix": "activity_result", + "activity.result.zero": "No Result", + "activity.result.view.partial": null, + "activity.result.view.final": "See result", + "activity.storage.title": "Storage", + "activity.storage.file.array.suffix": "activity_traces_data_as_array", + "activity.storage.file.one_per_line.suffix": "activity_traces_data_one_per_line", + + "limesurvey.name": "Limesurvey Activity", + "limesurvey.description": "A survey-based activity that uses LimeSurvey as service, allowing participants to answer pre and post surveys and enabling the owners to collect data effectively", + "limesurvey.result.title": "Result", + "limesurvey.result.file.prefix": "survey_result", + "limesurvey.result.zero": "Unstarted", + "limesurvey.result.view.partial": "Started", + "limesurvey.result.view.final": "Completed", + "limesurvey.storage.title": "Trace Storage", + "limesurvey.storage.file.array.suffix": "survey_traces_data_as_array", + "limesurvey.storage.file.one_per_line.suffix": "survey_traces_data_one_per_line", + + "limesurvey.title": "Limesurvey", + "limesurvey.surveyid.title": "Survey ID", + "limesurvey.surveyid.placeholder": "Survey ID", + "limesurvey.existing.title": "Existing Survey", + "limesurvey.existing.zero.message": "You don't have surveys.", + "limesurvey.new.title": "New Survey", + "limesurvey.new.description": "Click to open LimeSurvey", + "limesurvey.new.after.message": "After creating new, you have to select from existing.", + "limesurvey.upload.title": "Upload LSS", + "limesurvey.upload.message": "Select LLS file", + "limesurvey.upload.description": "Upload a LSS file to create a new survey within the survey activity.", + "limesurvey.upload.error": "Select the file to upload first", + "limesurvey.language.title": "Survey Language", + "limesurvey.survey.title": "Survey", + "limesurvey.survey.only_one.message": "You don't have any other surveys.", + "limesurvey.edit.title": "Edit Survey", + "limesurvey.short_url.title": "Generate Short URL", + "limesurvey.backup.full.title": "Full", + "limesurvey.backup.code.title": "Code", + "limesurvey.no_method": "Select a method first", + + "gameplay.name": "Gameplay Activity", + "gameplay.description": "The action of playing the serious game where participants game interaction data are collected via the xAPI component (trackers in the code), designed to integrate educational content in an engaging manner.", + "gameplay.result.title": "Backup", + "gameplay.result.file.prefix": "gameplay_backup_result", + "gameplay.result.zero": "No Backup", + "gameplay.result.view.partial": null, + "gameplay.result.view.final": "See Backup", + "gameplay.result.description": "Enable the collection and download of backups during the gameplay activity.", + "gameplay.storage.title": "Trace Storage", + "gameplay.storage.description": "Enable the collection and download of the interaction data collected during the gameplay activity.", + "gameplay.storage.file.array.suffix": "gameplay_traces_data_as_array", + "gameplay.storage.file.one_per_line.suffix": "gameplay_traces_data_one_per_line", + + "gameplay.xapi_by_game.title": "Basic xAPI Data Management By Game", + "gameplay.xapi_by_game.description": "Enable the management of basic xAPI data (activity initialized, suspended/resumed, activity terminated) directly by the game.", + "gameplay.game_uri.title": "Game URI", + "gameplay.game_uri.description": "The URI of the game being played can be specified to launch the game that collects xAPI data.", + "gameplay.xasu.title": "Xasu Config", + "gameplay.xasu.description": "The xAPI statement configuration (xASU) can be specified to customize the xAPI data collection during the gameplay activity.", + "gameplay.restarted.title": "Allow restarting?", + "gameplay.restarted.description": "Allow participants to restart the gameplay activity after completion, which can be useful for collecting multiple rounds of interaction data or allowing participants to improve their performance.", + + "gameplay.web.title": "Web", + "gameplay.web.description": "The gameplay activity is based on a web game launched in an iframe, and the interaction data is collected via xAPI statements sent from the game to SIMVA.", + "gameplay.desktop.title": "Desktop Game", + "gameplay.desktop.description": "The gameplay activity is based on a desktop game launched on the user's machine, and the interaction data is collected via xAPI statements sent from the game to SIMVA.", + + "manual.name": "Manual Activity", + "manual.description": "A traditional learning exercise to be undertaken by participants such as reading a book, reading an article, watching a video or any other passive learning task. ", + "manual.result.title":null, + "manual.result.file.prefix":null, + "manual.result.zero": null, + "manual.result.view.partial": null, + "manual.result.view.final": null, + "manual.storage.title": "Trace Storage", + "manual.storage.description": "Enable the collection and download of xAPI interaction data collected during the manual activity.", + "manual.storage.file.array.suffix": "manual_traces_data_as_array", + "manual.storage.file.one_per_line.suffix": "manual_traces_data_one_per_line", + "manual.restarted.title": "Allow restarting?", + "manual.restarted.description": "Allow participants to restart the manual activity after completion, which can be useful for collecting multiple rounds of interaction data or allowing participants to improve their performance.", + "manual.web.title": "Web", + "manual.web.description": "The manual activity is based on a web resource launched in an iframe, and the interaction data is collected via xAPI statements sent from the resource to SIMVA.", + "manual.external.title": "External Resource", + "manual.external.description": "The manual activity is based on an external resource launched outside of SIMVA, and the interaction data is collected via xAPI statements sent from the resource to SIMVA.", + + "manual.student_complete.title": "Allow students to complete?", + "manual.student_complete.description": "Allow students to mark the activity as complete.", + "manual.student_complete.ok": "Students can complete.", + "manual.student_complete.nok": "Students can't complete.", + "manual.uri.title": "URI", + "manual.uri.description": "The URL of the resource to be accessed in the manual activity.", + + "ltitool.name": "LTI Tool Activity", + "ltitool.description": "An activity that allows the user to include a LTI tool as resource.", + + "imspackage.name": "IMS Package Activity", + "imspackage.description": "A gameplay activity that allows the user to upload a IMS package as game.", + "imspackage.result.title": "Backup", + "imspackage.result.file.prefix": "imspackage_backup_result", + "imspackage.result.zero": "No Backup", + "imspackage.result.view.partial": null, + "imspackage.result.view.final": "See Backup", + "imspackage.storage.title": "Trace Storage", + "imspackage.storage.file.suffix.array": "imspackage_traces_data_as_array", + "imspackage.storage.file.suffix.one_per_line": "imspackage_traces_data_one_per_line", + "imspackage.package.title": "IMS Package", + + "completed.title": "Completed", + "completed.error.message": "Error setting the completion", + "completed.all.unset": "Set Completion to any", + "completed.all.set": "Set Completion to all", + "completed.on": "Yes", + "completed.off": "No", + + "progress.title": "Progress", + "participant.title": "Participant", + "init.title": "Init", + "init.on": "Yes", + "init.off": "No", + + "result.title": "Result", + "result.disabled": "disabled", + "result.error.loading": "Error loading the result", + "result.error.downloading": "Error downloading the result", + + "storage.title": "Storage", + "storage.disabled": "disabled", + "storage.error.downloading": "Error downloading the data from storage", + "storage.file.title": "Download as", + "storage.file.array.title": "Array", + "storage.file.one_per_line.title": "One Trace Per Line", + + "participant.tooltip": "Participant identifier shown as username or token.", + "init.tooltip": "Initialization state: whether the participant has started initialization.", + "init.bar.tooltip": "Initialization summary bar: initialized participants over total participants.", + "progress.tooltip": "Current progress percentage of the participant in this activity.", + "progress.bar.tooltip": "Progress summary bar: completed and in-progress participants over total participants.", + "completed.tooltip": "Completion state: whether the participant has completed the activity.", + "completed.bar.tooltip": "Completion summary bar: completed participants over total participants.", + "result.tooltip": "Result status and access to available result or backup data.", + "result.bar.tooltip": "Result summary bar: participants with partial or final results over total participants.", + + "tmon.title": "Open TMon Dashboard", + "download.title": "Download data", + "download.activity.title": "Download activity data", + "download.test.title": "Download test data", + "download.xasu.title": "Download Xasu config", + "download.backup.title": "Download backup", + "download.test.description": "Download available test data for this activity.", + "download.description": "Download all available data for this activity." +} \ No newline at end of file diff --git a/locales/en/commons.json b/locales/en/commons.json new file mode 100644 index 00000000..5dca7247 --- /dev/null +++ b/locales/en/commons.json @@ -0,0 +1,16 @@ +{ + "title": "SIMVA - A SIMple VAlidator", + "login.title": "Login", + "logout.title": "Logout", + "home.title": "Home", + "home.description": "Welcome to SIMVA! This is the main dashboard where you can access all the features of the platform. Use the menu to navigate through different sections, such as SIMLETs, activities, and user management. Whether you're a teacher, student, or researcher, you'll find everything you need to create and manage your simulations here.", + "welcome.user.text": "Welcome {{username}}!\n", + "welcome.teacher.text": "This is the main view of Simva.\nYou can go to Activities to create survey activities, gameplay activities, and other types of custom activities required to build an study.\nUse the Studies tab to create an study where a set of activities can be set up for an evaluation to be performed.\nTo manage Users and Groups, use the Groups tab where groups of users and users themselves can be created in order to allow them to participate in the studies.\nTo get more information visit:", + "welcome.student.text": "This is the main view of Simva.\nUse the Studies tab to access to a created study where you will perform an evaluation composed by a set of activities.", + "contact.title": "Contact", + "QA.title": "Q&A", + "GDPR.title": "GDPR", + "github.title" : "GitHub", + "eUCMResearch.title": "e-UCM Research", + "moreprojects.title" : "More projects" +} \ No newline at end of file diff --git a/locales/en/groups.json b/locales/en/groups.json new file mode 100644 index 00000000..0077bef5 --- /dev/null +++ b/locales/en/groups.json @@ -0,0 +1,127 @@ +{ + "users.add.title": "Add users", + + "coordinators.title": "Coordinators", + "coordinators.table.username.title": "Username", + "coordinators.table.permissions.title": "Permissions", + + "coordinators.delete.title": "Delete", + "coordinators.delete.confirm": "Are you sure you want to delete the coordinator '{{owner}}' from SIMLET '{{SIMLET}}'?", + + "coordinators.add.title": "Add coordinator", + "coordinators.name.title": "Username", + "coordinators.name.placeholder": "Coordinator username", + "coordinators.permission.title": "Permission", + "coordinators.permission.placeholder": "Select permission", + "coordinators.permissions.full": "Full", + "coordinators.permissions.read": "Read", + "coordinators.permissions.write": "Write", + "coordinators.error.already_in": "The coordinator is already in the SIMLET", + "coordinators.error.permission": "", + "coordinators.error.not_found": "", + + "groups.title": "Groups", + "groups.no_groups.message": "You have 0 groups yet. Create one using the bottom right (+) button", + "participants.no_users.message": "There are no participants in this group. Add some using the 3-dot menu on the right", + + "participants.title": "Participants", + + "participants.table.username.title": "Username", + "participants.table.isToken.title": "Is token", + "participants.isToken.true": "Yes", + "participants.isToken.false": "No", + "participants.table.token.title": "Token", + "participants.table.email.title": "Email", + "participants.table.role.title": "Role", + "participant.delete.title": "Delete", + "participants.delete.confirm" : "Are you sure you want to delete the participant '{{participant}}' of group '{{group}}'?", + "participants.table.sessopm.title": "Session", + + "allocator.type.title": "Allocator type", + "allocator.sessions.title": "Session", + "allocator.participants.title": "Participant", + "allocator.add.error": "Error adding the allocation", + "allocator.add.message": "Allocator updated", + "allocator.add.title": "Add allocator", + + "groups.name.title": "Name", + "groups.name.placeholder": "Group name", + + "groups.add.title": "Add group", + "groups.add.new.tab": "Add new group", + "groups.add.new.submit": "Add new group", + "deprecated.title": "Use deprecated version of token generation", + "deprecated.message": "/!\\ This group use the deprecated version of token generation.", + "deprecated.tooltip": "/!\\ This group will use the deprecated version of token generation.", + + "groups.import.tab": "Import group", + "groups.import.input": "Import file of group", + "groups.import.submit": "Import group", + "groups.import.upload.error": "Select the file to upload first", + "groups.import.error.invalid_file": "", + + "groups.settings.groups.edit.title": "Edit", + "groups.edit.title": "Edit group", + "groups.edit.submit": "Edit group", + "groups.edit.no_changes.message": "No changes detected in new group name!", + + "groups.settings.add.title": "Add participants", + "participants.username.placeholder": "Participant username", + + "participants.add.existing.tab": "Add existing", + "participants.add.existing.submit": "Add existing", + "participants.errormessage.alreadyInGroup": "The participant '{{participant}}' is already in the group '{{group}}'", + + "participants.add.new.tab": "Add new", + "participants.add.new.email.placeholder": "email@example.com", + "participants.add.new.password.placeholder": "Password", + "participants.add.new.groups.add.new.submit": "Create participant", + + "participants.add.batch.tab": "Add batch of tokens", + "participants.add.batch.number.title": "How many?", + "participants.add.batch.algorithFormat": "Participants will be added with random usernames created using:", + "participants.add.batch.algorithFormat.letters": "Only letters", + "participants.add.batch.algorithFormat.alphanumeric": "Letters and numbers", + "participants.add.batch.algorithFormat.base58": "Simplified alphanumeric (Base58)", + "participants.add.batch.length.title": "And a length of:", + "participants.add.batch.submit": "Add batch", + + "groups.settings.allocator.title": "Edit allocator", + "allocator.change.title": "Select the new allocator type", + + "allocator.default.title": "Basic allocator", + "allocator.default.type": "Default", + "allocator.default.description": "This allocator allows you to manually assign the participants to the sessions one by one. (By default, the participant will be assigned to the first session)", + + "allocator.group.title": "Group allocator", + "allocator.group.type": "Group", + "allocator.group.description": "This allocator allows you assign the entire group to a session", + + "allocator.change.submit": "Change allocator", + + "allocator.no_session_assigned.title": "No session", + + "groups.settings.print.title": "Download table as PDF", + "print_table.title": "Group: ", + "print_table.number_col.title": "No", + "print_table.name_col.title": "Name", + "print_table.code_col.title": "Code", + + "groups.settings.export.title": "Export", + + "groups.settings.delete.title": "Delete", + "groups.delete.confirm": "Are you sure you want to delete the group '{{group}}' from SIMLET '{{SIMLET}}'?\nGroup will be removed to all the studies, tests and activities", + + + "lti_platform.title": "LTI Platform", + "lti_platform.add.title": "Add LTI Platform", + "lti_platform.add.name.title": "Name", + "lti_platform.add.url.title": "URL", + "lti_platform.add.client_id.title": "Client ID", + "lti_platform.add.authentication_endpoint.title": "Authentication Endpoint", + "lti_platform.add.accesstoken_endpoint.title": "Access Token Endpoint", + "lti_platform.add.jkws_url.title": "jKWS URL", + "lti_platform.delete.title": "Delete LTI Platform", + "lti_platform.delete.confirm": "Are you sure you want to delete this platform '{{platform}}' from SIMLET '{{SIMLET}}'?", + "lti_platform.zero.message": "There are no platforms yet" +} \ No newline at end of file diff --git a/locales/en/roles.json b/locales/en/roles.json new file mode 100644 index 00000000..ad23f41f --- /dev/null +++ b/locales/en/roles.json @@ -0,0 +1,12 @@ +{ + "selection.title": "Simva Role Selection", + "admin": "Administrator", + "researcher": "Researcher", + "teacher": "Teacher", + "teachingAssistant": "Teaching Assistant", + "student": "Student", + "choose.title": "Choose this Role", + "contactadmin.title": "Contact Administrator", + "contactadmin.message" : "Please contact your SIMVA administrator at {{ email }} to attribute a new role.", + "not_defined": "Not defined" +} \ No newline at end of file diff --git a/locales/en/sessions.json b/locales/en/sessions.json new file mode 100644 index 00000000..f1cc255f --- /dev/null +++ b/locales/en/sessions.json @@ -0,0 +1,77 @@ +{ + "title": "Sessions", + "single.title": "Session", + "no_sessions.message": "There are no sessions for this SIMLET. Try adding one using the button on the bottom right (+)", + + "createdAt": "Created at", + "updatedAt": "Updated at", + "activities": "Activities", + "users": "Users", + "play": "Play SIMLET", + "download.title": "Download data", + "download.session.title": "Download session data", + "download.test.title": "Download test data", + "download.test.description": "Download your own test trace data for this session.", + "download.description": "Download the data for this session.", + + "add.title": "Add session", + "add.new.tab": "Add new", + "status.title": "Initial status", + "add.submit": "Create session", + + "import.tab": "Import session", + "import.input": "Select exported session file", + "import.submit": "Import session", + + "edit.title": "Edit session", + "edit.submit": "Edit session", + + "name.title": "Name", + "name.placeholder": "Session name", + "description.title": "Description", + "description.placeholder": "Session description", + "tags.title": "Tags", + "tags.no_tags": "No tags", + "tags.input.placeholder": "Type a tag to find or create it", + "tags.dropdown.no_tags": "No tags yet. Press + to create one", + "tags.dropdown.no_matches": "No matches for your search", + "tags.dropdown.all_matches": "All matching tags are already in this session", + "tags.create.placeholder": "New tag name", + "tags.create": "Create", + "tags.create.cancel": "Cancel", + "tags.edit.placeholder": "Tag name", + "tags.edit.save": "Save", + "tags.edit.cancel": "Cancel", + + "can_be_manually_activated": "Can be manually activated", + + "settings.edit.title": "Edit", + "settings.add_activity.title": "Add activity", + + "settings.duplicate.title": "Duplicate", + "duplicate.title": "Duplicate session", + "duplicate.submit": "Duplicate", + + "settings.activate.title": "Activate", + "active.title": "Active", + + "settings.pause.title": "Pause", + "paused.title": "Paused", + + "settings.finish.title": "Finish", + "finished.title": "Finished", + "finish.confirm": "Are you sure you want to finish (terminate) this session? This action cannot be undone", + + "settings.delete.title": "Delete", + "delete.confirm": "Are you sure you want to delete the session '{{session}}' from SIMLET '{{SIMLET}}'?\nAll the activities and data will be deleted too", + + "settings.export.title": "Export", + "set_tester.title": "Set myself as tester in this session", + "reset_tester.title": "Reset tester (unset and set again)", + "unset_tester.title": "Unset myself as tester", + + "status.description": "Depending on its status, a session will behave differently:", + "active.description": "An active session will receive data, its activities can be modified, and it can be paused at any time", + "paused.description": "A paused session won't receive any data, but it's posible to modify its activities or be reactivated at any time", + "finished.description": "A finished session will no longer be able to receive data, have its activities modified, nor be reactivated" +} \ No newline at end of file diff --git a/locales/es/SIMLETs.json b/locales/es/SIMLETs.json new file mode 100644 index 00000000..5c5ad330 --- /dev/null +++ b/locales/es/SIMLETs.json @@ -0,0 +1,74 @@ +{ + "title": "SIMLETs", + "description": "Los SIMLETs son el núcleo de SIMVA, permitiéndote crear y gestionar tus propias simulaciones. Un SIMLET es un contenedor para todos los elementos de una simulación, incluyendo sesiones, actividades, usuarios y grupos. Puedes crear nuevos SIMLETs, editar los existentes, archivar aquellos que ya no necesites y gestionar su configuración y contenido.", + "archived.title": "SIMLETs archivados", + "archived.description": "Lista de SIMLETs que han sido archivados. Puedes desarchivarlos para volver a activarlos.", + "no_simlets.message": "Aún no tiene SIMLETs. Cree uno utilizando el botón inferior derecho (+)", + "no_archived.message": "No hay SIMLETs archivados", + + "card.createdAt": "Creado el", + "card.updatedAt": "Actualizado el", + "card.sessions": "Sesiones", + "card.groups": "Grupos", + "card.users": "Usuarios", + "card.tags": "Etiquetas", + + "add.title": "Añadir SIMLET", + "new.tab": "Añadir nuevo", + "new.submit": "Crear SIMLET", + + "import.tab": "Importar desde existente", + "import.input": "Seleccione un fichero de SIMLET exportado", + "import.upload.error": "Seleccione primero el archivo que desea cargar", + "import.submit": "Importar SIMLET", + + "settings.edit.title": "Editar", + "edit.title": "Editar SIMLET", + "edit.submit": "Editar SIMLET", + + "name.title": "Nombre", + "name.placeholder": "Nombre del SIMLET", + "description.title": "Descipción", + "description.placeholder": "Descipción del SIMLET", + + "settings.url.title": "Configuración de la URL", + "scheduler.shlink.generate.title": "Generar URL reducida para el Programador", + "scheduler.shlink.generate.randomly_length.title": "Generada aleatoriamente", + "scheduler.shlink.generate.randomly_length.message": "Con una longitud de: ", + "scheduler.shlink.generate.custom_slug.title": "Utilizar un nombre personalizado", + "scheduler.shlink.generate.submit": "Generar", + "scheduler.shlink.message": "Copiar URL corta: {{shlink}}", + "scheduler.shlink.custom_slug.placeholder": "Nombre personalizado", + "scheduler.shlink.delete.title": "Borrar URL Shlink del Programador", + "scheduler.shlink.delete.confirm": "¿Está seguro de que desea eliminar el enlace corto '{{shlink}}' del SIMLET '{{SIMLET}}'?", + + "settings.download.title": "Descargar configuración", + "config.download.simlet": "Exportar SIMLET a .json", + "config.download.uadventure": "Descargar configuración para uAdventure", + + "settings.archive.title": "Archivar", + "archive.confirm": "¿Está seguro de que desea archivar el SIMLET '{{SIMLET}}'?\nEsta acción no se puede revertir y el SIMLET se moverá a la pestaña de archivados", + "settings.dearchive.title": "Desarchivar", + + "settings.delete.title": "Eliminar", + "delete.confirm": "¿Está seguro de que desea eliminar el SIMLET '{{SIMLET}}'?\nTambién se borrarán todas las Sesiones, actividades y datos", + + "edit.no_changes.message": "¡No se detectan cambios!", + + "single.title": "SIMLET", + "single.description": "Informacion general y configuracion del SIMLET seleccionado", + "sessions.tab.description": "Gestiona las sesiones de este SIMLET: crear, editar, supervisar el progreso y descargar datos de sesion", + "users.tab.description": "Gestiona usuarios, grupos, coordinadores y sus asignaciones dentro de este SIMLET", + "sessions.download.description": "Descarga todos los datos disponibles de esta sesion, incluidos los datos de actividades", + "simlets.description": "Listado de SIMLETs disponibles y acceso rapido para crear, editar, archivar o eliminarlos", + "sessions.tab.title": "Sesiones", + "users.tab.title": "Usuarios", + + + "scheduler.noSIMLET.title": "Aún no tiene SIMLETs en los que participar", + "scheduler.title": "Haga clic aquí para iniciar o continuar su sesión en el SIMLET", + "scheduler.current": "Actividad actual : ", + "scheduler.refresh": "Actualizar la página para continuar el SIMLET", + "scheduler.complete": "Completa la Actividad", + "scheduler.exit": "Salir del SIMLET" +} \ No newline at end of file diff --git a/locales/es/about.json b/locales/es/about.json new file mode 100644 index 00000000..3d6047bf --- /dev/null +++ b/locales/es/about.json @@ -0,0 +1,125 @@ +{ + "title": "Acerca de", + "description": "¡Bienvenido al front-end de SIMVA! Esta sección proporciona una visión general de la plataforma, sus principales características y una guía para ayudarte a navegar por la interfaz. Ya seas un profesor, estudiante, investigador o desarrollador, encontrarás información útil para comenzar y aprovechar al máximo SIMVA.", + "text": "Esta sección reúne ayuda de navegación, tutoriales y explicaciones breves sobre SIMVA.\nSiga los pasos de abajo para moverse por las páginas principales. Algunas opciones solo aparecen para profesores, coordinadores o administradores.", + "header.logout.title": "Guía del encabezado para visitantes", + "header.logout.description": "Esta es la barra superior antes de iniciar sesión. Da acceso a las páginas públicas y al botón de inicio de sesión.", + "header.logout.note": "Estos son los únicos botones superiores disponibles antes de entrar en el sistema.", + "header.logout.language.title": "Selector de idioma", + "header.logout.language.description": "Cambie el idioma de la interfaz desde el pequeño selector de la izquierda.", + "header.logout.about.title": "Acerca de", + "header.logout.about.description": "Abra esta página para leer la información general de SIMVA y la ayuda de navegación.", + "header.logout.research.title": "e-UCM Research", + "header.logout.research.description": "Vaya al sitio de investigación para información del proyecto y material relacionado.", + "header.logout.contact.title": "Contacto", + "header.logout.contact.description": "Use este enlace para acceder a la información de contacto mostrada en el encabezado.", + "header.logout.login.title": "Inicio de sesión", + "header.logout.login.description": "Pulse este botón para entrar y cambiar a la interfaz autenticada.", + "header.login.title": "Guía del encabezado para usuarios conectados", + "header.login.description": "Esta es la barra superior después de iniciar sesión. Muestra su cuenta y la acción de cierre, además de controles extra en las páginas del programador.", + "header.login.note": "En las páginas del programador también puede ver los controles de refrescar, completar actividad y salir.", + "header.login.language.title": "Selector de idioma", + "header.login.language.description": "Cambie el idioma de la interfaz desde el selector de la izquierda.", + "header.login.account.title": "Nombre de cuenta", + "header.login.account.description": "Abra el área de su cuenta o la información de perfil desde el botón del nombre de usuario.", + "header.login.logout.title": "Cierre de sesión", + "header.login.logout.description": "Termine la sesión actual y vuelva a la interfaz pública.", + "menu.title": "Guía del menú para usuarios conectados", + "menu.description": "Este es el menú lateral que aparece tras iniciar sesión. Le lleva a las áreas principales de SIMVA.", + "menu.note": "Algunas entradas solo aparecen para profesores, coordinadores o administradores.", + "menu.home.title": "Inicio", + "menu.home.description": "Vuelva a la pantalla principal con la información más reciente de bienvenida y de su cuenta.", + "menu.play.title": "Play SIMLETs", + "menu.play.description": "Abra la entrada del programador para los participantes que tengan que realizar SIMLETs asignados.", + "menu.simlets.title": "SIMLETs", + "menu.simlets.description": "Gestione estudios, sesiones, participantes y resultados desde el área de SIMLETs.", + "menu.groups.title": "Grupos", + "menu.groups.description": "Organice aquí usuarios y permisos basados en grupos.", + "menu.archived.title": "SIMLETs archivados", + "menu.archived.description": "Revise los estudios archivados y conservados como referencia.", + "menu.about.title": "Acerca de", + "menu.about.description": "Abra esta página de tutorial cuando necesite recordar cómo funciona la interfaz.", + + "simva.title": "SIMVA", + "simva.description": "La infraestructura de SIMVA es un software de arquitectura abierta que se compone de varios sistemas interconectados. Entre estos sistemas se encuentran el sistema de login SSO unificado (KeyCloak), el sistema de cola de procesamiento (Kafka) y el sistema de almacenamiento en la nube (Minio). Su arquitectura es escalable e interoperable con otras herramientas de terceros, lo que permite delegar las funcionalidades más críticas a plataformas confiables y escalables.", + "simva.frontend.title": "Front-end de SIMVA", + "simva.frontend.description": "El front-end de SIMVA se utiliza para integrar juegos en el sistema, crear encuestas, gestionar sesiones, gestionar la participación de usuarios en sesiones y realizar seguimiento/análisis de datos de sesiones en tiempo real. Estos datos evolucionan desde las respuestas de usuarios a encuestas hasta información completa y métricas durante toda la sesión, que también incluyen datos de jugabilidad.", + "simva.roles.title": "Roles y permisos", + "simva.roles.description": "En SIMVA, el usuario puede ser un profesor, estudiante, investigador o desarrollador. Los roles y permisos en el front-end se categorizan en supervisor, coordinador y participante. Estos se explicarán más adelante en este documento.", + + "simlet.title": "SIMLET (SIMVA APPLET)", + "simlet.description": "Un contenedor en la aplicación web del front-end de SIMVA para encapsular datos de diferentes sesiones. Un SIMLET se crea para lograr un objetivo particular, por ejemplo, para comparar la efectividad de un juego serio en particular, comparar entre las habilidades de tres grupos de estudiantes o comparar el conocimiento de programación adquirido en diferentes juegos. Cada SIMLET tiene sus propios supervisores con autoridad total sobre las sesiones y actividades del SIMLET. El supervisor principal (el usuario que creó el SIMLET) es el único usuario autorizado para eliminar todo el SIMLET.", + "archived_simlet.title": "SIMLET archivado", + "archived_simlet.description": "Un SIMLET archivado se conserva como referencia y puede restaurarse más tarde. Se oculta de las listas activas pero mantiene su configuración e historial.", + + "session.title": "Sesión", + "session.description": "Un contenedor en la aplicación web del front-end de SIMVA para encapsular datos de varias actividades. Una sesión consta de una o más actividades (encuesta previa, jugabilidad o actividad de aprendizaje manual/tradicional y encuesta posterior) a ser realizadas por un grupo de participantes. Cada sesión tiene sus propios coordinadores con autoridad total sobre las actividades de la sesión.", + + "supervisor.title": "Supervisor de SIMLET", + "supervisor.description": "Un usuario que tiene acceso total a un SIMLET en particular. El supervisor principal crea el SIMLET primero y luego puede editar/eliminar el SIMLET o asignar otros supervisores o coordinadores especificando el modo de permiso, ya sea 'Editor' o 'Visor'. Un supervisor con modo 'Editor' puede editar la información del SIMLET (título y descripción), agregar/editar/eliminar sesiones, agregar/editar/eliminar diferentes actividades que componen las sesiones y asignar los participantes que estarán involucrados en cada sesión. Además, un supervisor con modo 'Editor' puede agregar etiquetas a las sesiones, iniciarlas, rastrear y exportar resultados. Un supervisor con modo 'Visor' solo puede ver las configuraciones del SIMLET junto con sus sesiones y las actividades asociadas y sus resultados sin capacidad para agregar, editar o eliminar. Solo el supervisor principal puede eliminar el SIMLET.", + + "coordinator.title": "Coordinador de sesión", + "coordinator.description": "Un usuario que tiene acceso total a una sesión en particular. Hay dos modos de permiso: 'Editor' y 'Visor'. Un coordinador con modo 'Editor' puede editar la información de la sesión (título y descripción), agregar etiquetas a la sesión, agregar/editar/eliminar las diferentes actividades que forman una sesión. Además, un coordinador con modo 'Editor' puede asignar otros coordinadores a la sesión y establecer su permiso, ya sea 'Editor' o 'Visor'. Los coordinadores con ambos modos 'Editor' y 'Visor' tienen acceso al panel para ver resultados y exportarlos, pero iniciar la sesión solo está limitado a los coordinadores con modo 'Editor'.", + + "participant.title": "Participante", + "participant.description": "Un usuario (por ejemplo, un estudiante) cuyo rol es realizar actividades como responder encuestas y jugar juegos. Cada participante también puede ver sus propios resultados.", + + "gameclient.title": "Cliente de juego", + "gameclient.description": "Un cliente de juego es todos los metadatos del juego como título, descripción, categoría (conciencia o educación) y área temática (matemáticas, programación, bullying, etc). Es la URL del juego para un juego web o el archivo comprimido del juego para un juego de escritorio.", + + "integratedgame.title": "Juego integrado en SIMVA", + "integratedgame.description": "Un juego integrado en SIMVA significa que el cliente de juego se describe en SIMVA y se presenta como una plantilla de actividad de jugabilidad. Cada vez que se integra un nuevo juego en SIMVA, se genera automáticamente una plantilla de actividad de jugabilidad con una identificación. Cada vez que se usa el juego en una actividad de jugabilidad dentro de una sesión, se crea una nueva instancia de actividad de jugabilidad a partir de esta plantilla. Esto significa que la instancia de actividad de jugabilidad hará referencia a la plantilla de actividad de jugabilidad usando su identificación. Los supervisores pueden mostrar los juegos integrados desde un menú en el front-end de SIMVA.", + + "activity.title": "Actividad", + "activity.description": "Una acción o conjunto de acciones a realizar por los participantes. Esta acción podría ser responder encuestas (actividad LimeSurvey), jugar juegos serios (actividad de jugabilidad) o realizar ejercicios de aprendizaje tradicional (actividad manual).", + "activity.types.title": "Tipos de actividad", + + "limesurvey.title": "Actividad LimeSurvey", + "limesurvey.description": "Una actividad basada en encuestas que utiliza LimeSurvey como servicio, permitiendo a los participantes responder encuestas previas y posteriores y permitiendo a los propietarios recopilar datos de manera efectiva.", + + "gameplay.title": "Actividad de jugabilidad", + "gameplay.description": "La acción de jugar el juego serio donde los datos de interacción del juego de los participantes se recopilan a través del componente xAPI (rastreadores en el código), diseñado para integrar contenido educativo de una manera atractiva.", + + "manual.title": "Actividad manual", + "manual.description": "Un ejercicio de aprendizaje tradicional a realizar por los participantes, como leer un libro, leer un artículo, ver un video o cualquier otra tarea de aprendizaje pasivo.", + + "activitytemplate.title": "Plantilla de actividad", + "activitytemplate.description": "Una plantilla de actividad representa la descripción estática de una actividad. Define los metadatos de una actividad como su título y descripción. Una plantilla se puede usar en muchas sesiones creando instancias de la plantilla. La plantilla de actividad puede ser una actividad de encuesta, una actividad manual o una actividad de jugabilidad. En caso de actividad de jugabilidad, también contendrá datos del cliente de juego.", + + "activityinstance.title": "Instancia de actividad", + "activityinstance.description": "Una instancia de actividad representa una ejecución concreta de una plantilla de actividad. Almacena datos específicos de los participantes, como respuestas de encuestas, rendimiento de actividades manuales, interacciones de actividades de jugabilidad, como rastros y resultados. Cuando el usuario agrega una actividad a una sesión particular, se crea automáticamente una instancia de esa plantilla de actividad. En caso de actividad de jugabilidad, la instancia de actividad se referencia al ID del juego integrado. Sin embargo, los datos recopilados del juego se almacenarán al nivel de actividad de jugabilidad de la sesión.", + + "manualcompletion.title": "Finalización manual para actividades", + "manualcompletion.description": "En caso de que un participante complete una actividad pero su estado no se establezca automáticamente en 'completado' por alguna razón, hay un botón que permite al supervisor/coordinador cambiar manualmente el estado a 'completado'. También es posible cambiar manualmente el estado de una actividad a 'completado' para todos los participantes a la vez.", + + "dashboard.title": "Panel de SIMVA", + "dashboard.description": "Cada SIMLET contiene un panel visual con información detallada sobre las actividades de las sesiones. El panel muestra información general sobre el estado de cada actividad, mostrando el porcentaje de finalización de participantes, progreso y resultado. También demuestra una lista detallada de los participantes, esta lista muestra el nombre de cada participante, estado de finalización, estado de progreso y resultado de copia de seguridad. Mientras la actividad recibe datos xAPI, ya sea en progreso o completada, el panel se actualiza correspondientemente a los rastros recibidos.", + + "group.title": "Grupo", + "group.description": "Un grupo es un conjunto de participantes utilizados para organizar asignaciones y reglas de distribución entre sesiones.", + + "users.title": "Usuarios", + "users.description": "Los usuarios, grupos y coordinadores definen quién participa en el SIMLET y cómo se asignan los participantes a las sesiones.", + "xapi.dashboard.title": "Datos xAPI para Paneles de SIMVA", + "xapi.dashboard.intro": "Para cada sesión dentro de un SIMLET, hay diferentes paneles que representan datos de seguimiento en tiempo real para sus actividades. La siguiente imagen muestra un ejemplo de estos paneles.", + "xapi.dashboard.image.alt": "Ejemplo de paneles de SIMVA para actividades de sesión", + "xapi.dashboard.backend.title": "Seguimiento xAPI en el Backend", + "xapi.dashboard.backend.desc": "En el backend, rastreamos los rastros xAPI para los paneles. Por ejemplo:", + "xapi.dashboard.activitytypes.title": "Tipos de Actividad y Tipos de Objeto xAPI", + "xapi.dashboard.activitytypes.col1": "Tipo de Actividad", + "xapi.dashboard.activitytypes.col2": "Tipo de definición de objeto en rastros xAPI", + "xapi.dashboard.activitytypes.game": "Actividad de juego", + "xapi.dashboard.activitytypes.limesurvey": "Actividad de LimeSurvey", + "xapi.dashboard.activitytypes.manual": "Actividad Manual", + "xapi.dashboard.visibledata.title": "Datos del Panel y Rastros xAPI Correspondientes", + "xapi.dashboard.visibledata.desc": "En las siguientes líneas, estamos definiendo los datos visibles en los paneles con sus correspondientes rastros xAPI rastreados.", + "xapi.dashboard.initialized.title": "Inicializado", + "xapi.dashboard.initialized.desc": "Esto representa si el participante ha comenzado la actividad o no. Su valor puede ser 'true' o 'false'. El valor predeterminado es 'false', y se volverá 'true' cuando el participante inicialice la actividad. Esto significa que en el backend el servidor SIMVA ha recibido un rastro xAPI con el id del verbo: 'http://adlnet.gov/expapi/verbs/initialized'.", + "xapi.dashboard.progress.title": "Progreso", + "xapi.dashboard.progress.desc": "Esto representa el porcentaje de finalización de la actividad. Su valor está entre 0% y 100% ambos incluidos. Si la actividad no está inicializada aún, el valor predeterminado del progreso es '-', mientras que si está inicializada pero sin progreso, el valor del progreso es '0%'. Si está completamente finalizada, el valor del progreso es '100%'. Esto significa que en el backend el servidor SIMVA ha recibido un rastro xAPI con el id del verbo: 'http://adlnet.gov/expapi/verbs/progressed', y también el valor del resultado escalado entre 0 y 1 (ambos incluidos) desde la etiqueta de resultado mostrada en la tabla:", + "xapi.dashboard.progress.col1": "Tipo de Actividad", + "xapi.dashboard.progress.col2": "Etiqueta de resultado mostrada en rastros xAPI para el progreso", + "xapi.dashboard.completed.title": "Completado", + "xapi.dashboard.completed.desc": "Esto representa si el participante ha completado la actividad o no. Su valor puede ser 'true' o 'false'. El valor predeterminado es 'false', y se volverá 'true' cuando el participante complete la actividad. Esto significa que en el backend el servidor SIMVA ha recibido un rastro xAPI con el id del verbo: 'http://adlnet.gov/expapi/verbs/completed', y también el valor del resultado de finalización tiene que ser establecido a 'true'." + +} \ No newline at end of file diff --git a/locales/es/activities.json b/locales/es/activities.json new file mode 100644 index 00000000..f4be3e10 --- /dev/null +++ b/locales/es/activities.json @@ -0,0 +1,186 @@ +{ + "title": "Actividades", + "single.title": "Actividad", + "text": "La vista de actividades está desactivada temporalmente.\nEsta pestaña está diseñada para crear \"actividades de plantilla\" para luego copiarlos en pruebas.\nEstos \"actividades de plantilla\" ayudar a la creación de múltiples casos de prueba similares con pequeñas modificaciones.\nEstará disponible en una futura versión.", + + "no_activities.message": "No hay actividades en esta Sesión. Añada una utilizando el botón del menú de 3 puntos a la derecha", + + "add.title": "Añadir actividad", + "add.new.title": "Nueva actividad", + "add.new.web.no_url_message": "Está a punto de crear una actividad web sin URL. ¿Está seguro de que quiere continuar? (Podrá cambiar la URL más adelante)", + "add.existing.title": "Seleccionar de las existentes", + + "edit.title": "Editar", + + "delete.title": "Eliminar", + "delete.confirm": "¿Está seguro de que desea eliminar la actividad '{{activity}}' de la sesión '{{session}}' del SIMLET '{{SIMLET}}'?\nTambién se eliminarán todos los datos de la actividad", + + "export.title": "Exportar", + "import.title": "Importar", + "import.message": "Seleccione el archivo a importar", + "import.error": "Seleccione el archivo a importar primero", + "import.upload.error": "Seleccione el archivo a subir primero", + "import.error.invalid_file": "Archivo inválido", + + "name.placeholder": "Nombre de la actividad", + "activity.type.title": "Tipo de actividad", + "type.title": "Tipo", + + "activity.type.select": "Seleccione un tipo de actividad", + "activity.type.select_required": "El tipo de actividad es obligatorio", + "activity.name": "Actividad por defecto", + "activity.description": "Una actividad básica con estado de finalización y un lugar para guardar los resultados.", + "activity.result.title": "Resultado", + "activity.result.file.prefix": "resultado_actividad", + "activity.result.zero": "Ningún resultado", + "activity.result.view.partial": null, + "activity.result.view.final": "Ver resultado", + "activity.storage.title": "Almacenamiento", + "activity.storage.file.array.suffix": "actividad_traza_matriz", + "activity.storage.file.one_per_line.suffix": "actividad_una_traza_por_linea", + + "limesurvey.name": "Actividad de Limesurvey", + "limesurvey.description": "Una actividad basada en encuestas que utiliza LimeSurvey como servicio, permitiendo a los participantes responder a encuestas previas y posteriores a otras actividades y a los coordinadores recopilar datos de forma eficaz.", + "limesurvey.result.title": "Resultado", + "limesurvey.result.file.prefix": "resultado_encuesta", + "limesurvey.result.zero": "Sin iniciar", + "limesurvey.result.view.partial": "Comenzó", + "limesurvey.result.view.final": "Completado", + "limesurvey.storage.title": "Almacenamiento de trazas", + "limesurvey.storage.file.array.suffix": "encuesta_traza_matriz", + "limesurvey.storage.file.one_per_line.suffix": "encuesta_una_traza_por_linea", + + "limesurvey.title": "Limesurvey", + "limesurvey.surveyid.title": "ID de Encuesta", + "limesurvey.surveyid.placeholder": "ID de Encuesta", + "limesurvey.existing.title": "Encuesta existente", + "limesurvey.existing.zero.message": "No tienes encuestas.", + "limesurvey.new.title": "Nueva encuesta", + "limesurvey.new.description": "Haz clic para abrir LimeSurvey", + "limesurvey.new.after.message": "Después de crear una nueva, tiene que seleccionar una de las existentes.", + "limesurvey.upload.title": "Cargar LSS", + "limesurvey.upload.message": "Seleccionar archivo LLS", + "limesurvey.upload.description": "Cargar un archivo LSS para crear una nueva encuesta dentro de la actividad de encuesta.", + "limesurvey.upload.error": "Seleccione primero el archivo que desea cargar", + "limesurvey.language.title": "Idioma de la encuesta", + "limesurvey.survey.title": "Encuesta", + "limesurvey.survey.only_one.message": "No tienes más encuestas.", + "limesurvey.edit.title": "Editar encuesta", + "limesurvey.short_url.title": "Generar URL corta", + "limesurvey.backup.full.title": "Completo", + "limesurvey.backup.code.title": "Código", + "limesurvey.no_method": "Seleccione primero un método", + + "gameplay.name": "Actividad de juego", + "gameplay.description": "La acción de jugar a un juego serio en el que se recopilan los datos de interacción de los participantes a través del componente xAPI (trackers en el código), diseñado para integrar contenido educativo de forma atractiva.", + "gameplay.result.title": "Copia de seguridad", + "gameplay.result.description": "Activar la recopilación y descarga de las copias de seguridad durante la actividad de juego.", + "gameplay.result.file.prefix": "juego_copia_seguridad", + "gameplay.result.zero": "Sin copia de seguridad", + "gameplay.result.view.partial": null, + "gameplay.result.view.final": "Ver copia de seguridad", + "gameplay.storage.title": "Almacenamiento de trazas", + "gameplay.storage.description": "Activar la recopilación y descarga de los datos de interacción xAPI recopilados durante la actividad de juego.", + "gameplay.storage.file.array.suffix": "juego_traza_matriz", + "gameplay.storage.file.one_per_line.suffix": "juego_una_traza_por_linea", + + "gameplay.restarted.title": "Permitir reiniciar?", + "gameplay.restarted.description": "Los participantes pueden reiniciar.", + + "gameplay.web.title": "Web", + "gameplay.web.description": "La actividad de juego se basa en un juego web lanzado en un iframe, y los datos de interacción se recopilan a través de declaraciones xAPI enviadas desde el juego a SIMVA.", + "gameplay.desktop.title": "Juego de escritorio", + "gameplay.desktop.description": "La actividad de juego se basa en un juego de escritorio lanzado en la máquina del usuario, y los datos de interacción se recopilan a través de declaraciones xAPI enviadas desde el juego a SIMVA.", + + "gameplay.xapi_by_game.title": "Gestión de datos xAPI básicos por juego", + "gameplay.xapi_by_game.description": "Activar la gestión de datos xAPI basicos (initializado la actividad, suspended/resumed, terminated la actividad) directamente por el juego.", + "gameplay.game_uri.title": "URI del juego", + "gameplay.game_uri.description": "La URI del juego a lanzar en la actividad de juego, que puede ser un juego web lanzado en un iframe o un juego de escritorio lanzado fuera de SIMVA, y los datos de interacción se recopilan a través de declaraciones xAPI enviadas desde el juego a SIMVA.", + "gameplay.xasu.title": "Configuración de Xasu", + "gameplay.xasu.description": "Configurar Xasu para la recopilación de datos xAPI, incluyendo parámetros como endpoint y claves de autenticación, para asegurar una integración fluida y segura de los datos de interacción de los participantes durante la actividad de juego.", + + "manual.name": "Actividad manual", + "manual.description": "Un ejercicio de aprendizaje tradicional que deben realizar los participantes, como leer un libro, leer un artículo, ver un vídeo o cualquier otra tarea de aprendizaje pasivo.", + "manual.result.title":null, + "manual.result.file.prefix":null, + "manual.result.zero": null, + "manual.result.view.partial": null, + "manual.result.view.final": null, + "manual.storage.title": "Almacenamiento de trazas", + "manual.storage.description": "Activar la recopilación y descarga de los datos de interacción xAPI recopilados durante la actividad manual.", + "manual.storage.file.array.suffix": "manual_traza_matriz", + "manual.storage.file.one_per_line.suffix": "manual_una_traza_por_linea", + + "manual.student_complete.title": "Permitir que los estudiantes completen?", + "manual.student_complete.description": "Permitir a los estudiantes marcar la actividad como completada.", + "manual.student_complete.ok": "Los estudiantes pueden completar.", + "manual.student_complete.nok": "Los estudiantes no pueden completar.", + "manual.uri.title": "URI", + "manual.uri.description": "La URL del recurso a acceder en la actividad manual. La URI puede incluir etiquetas: {username} y {activityId}.", + "manual.restarted.title": "Permitir reiniciar?", + "manual.restarted.description": "Permitir a los participantes reiniciar la actividad manual después de haberla terminado, lo que puede ser útil para recopilar varias series de datos de interacción o permitir a los participantes mejorar sus rendimientos.", + + "manual.web.title": "Web", + "manual.web.description": "La actividad manual se basa en un recurso web lanzado en un iframe, y los datos de interacción se recopilan a través de declaraciones xAPI enviadas desde el recurso a SIMVA.", + "manual.external.title": "Recurso externo", + "manual.external.description": "La actividad manual se basa en un recurso externo lanzado fuera de SIMVA, y los datos de interacción se recopilan a través de declaraciones xAPI enviadas desde el recurso a SIMVA.", + + "ltitool.name": "Actividad con Herramienta LTI", + "ltitool.description": "Una actividad que permite al usuario incluir una herramienta LTI como recurso.", + + "imspackage.name": "Actividad con Paquete IMS", + "imspackage.description": "Una actividad de juego que permite al usuario cargar un paquete IMS como juego.", + "imspackage.result.title": "Copia de seguridad", + "imspackage.result.file.prefix": "ims_package_copia_seguridad", + "imspackage.result.zero": "Sin copia de seguridad", + "imspackage.result.view.partial": null, + "imspackage.result.view.final": "Ver copia de seguridad", + "imspackage.storage.title": "Almacenamiento de trazas", + "imspackage.storage.file.suffix.array": "ims_package_traza_matriz", + "imspackage.storage.file.suffix.one_per_line": "ims_package_una_traza_por_linea", + "imspackage.package.title": "IMS Package", + + "completed.title": "Completado", + "completed.error.message": "Error al establecer la finalización", + "completed.all.unset": "Completar a ningúno", + "completed.all.set": "Completar a todos", + "completed.on": "Si", + "completed.off": "No", + + "progress.title": "Progreso", + "participant.title": "Participante", + "init.title": "Inicio", + "init.on": "Si", + "init.off": "No", + + "result.title": "Resultado", + "result.disabled": "Desactivado", + "result.error.loading": "Error al cargar el resultado", + "result.error.downloading": "Error al descargar el resultado", + + "storage.title": "Almacenamiento", + "storage.disabled": "Desactivado", + "storage.error.downloading": "Error al descargar los datos del almacenamiento", + "storage.file.title": "Descargar como", + "storage.file.array.title": "Matriz", + "storage.file.one_per_line.title": "Una Traza Por Linea", + + "participant.tooltip": "Identificador del participante mostrado como usuario o token.", + "init.tooltip": "Estado de inicializacion: indica si el participante ha iniciado la actividad.", + "init.bar.tooltip": "Barra resumen de inicializacion: participantes inicializados sobre el total de participantes.", + "progress.tooltip": "Porcentaje de progreso actual del participante en esta actividad.", + "progress.bar.tooltip": "Barra resumen de progreso: participantes completados y en progreso sobre el total de participantes.", + "completed.tooltip": "Estado de completado: indica si el participante ha completado la actividad.", + "completed.bar.tooltip": "Barra resumen de completado: participantes completados sobre el total de participantes.", + "result.tooltip": "Estado del resultado y acceso a los datos de resultado o copia de seguridad.", + "result.bar.tooltip": "Barra resumen de resultados: participantes con resultados parciales o finales sobre el total de participantes.", + + "tmon.title": "Abrir el panel TMon", + "download.title": "Descargar datos", + "download.activity.title": "Descargar datos de la actividad", + "download.test.title": "Descargar datos de prueba", + "download.xasu.title": "Descargar configuración para Xasu", + "download.backup.title": "Descargar respaldo", + "download.test.description": "Descargar datos de prueba disponibles para esta actividad.", + "download.description": "Descargar todos los datos disponibles de esta actividad." +} \ No newline at end of file diff --git a/locales/es/commons.json b/locales/es/commons.json new file mode 100644 index 00000000..343c16af --- /dev/null +++ b/locales/es/commons.json @@ -0,0 +1,16 @@ +{ + "title": "SIMVA - Un SIMple VAlidador", + "login.title": "Inicio de sesión", + "logout.title": "Cierre de sesión", + "home.title": "Inicio", + "home.description": "¡Bienvenido a SIMVA! Este es el panel principal donde puedes acceder a todas las funciones de la plataforma. Usa el menú para navegar por las diferentes secciones, como SIMLETs, actividades y gestión de usuarios. Ya seas un profesor, estudiante o investigador, encontrarás todo lo que necesitas para crear y gestionar tus simulaciones aquí.", + "welcome.user.text": "Bienvenido {{username}}!\n", + "welcome.teacher.text": "Esta es la vista principal de Simva.\nYou can go to Activities to create survey activities, gameplay activities, and other types of custom activities required to build an study.\nUse the Studies tab to create an study where a set of activities can be set up for an evaluation to be performed.\nTo manage Users and Groups, use the Groups tab where groups of users and users themselves can be created in order to allow them to participate in the studies.\nTo get more information visit:", + "welcome.student.text": "Esta es la vista principal de Simva.\nUtilice la pestaña Estudios para acceder a un estudio creado en el que realizará una evaluación compuesta por un conjunto de actividades.", + "contact.title": "Contacto", + "QA.title": "Preguntas", + "GDPR.title": "GDPR", + "github.title" : "GitHub", + "eUCMResearch.title": "Equipo de Investigación e-UCM", + "moreprojects.title" : "Más proyectos" +} \ No newline at end of file diff --git a/locales/es/groups.json b/locales/es/groups.json new file mode 100644 index 00000000..c130c53e --- /dev/null +++ b/locales/es/groups.json @@ -0,0 +1,127 @@ +{ + "users.add.title": "Añadir usuarios", + + "coordinators.title": "Coordinadores", + "coordinators.table.username.title": "Nombre de usuario", + "coordinators.table.permissions.title": "Permisos", + + "coordinators.delete.title": "Borrar", + "coordinators.delete.confirm": "¿Está seguro de que desea eliminar al coordinador '{{coordinator}}' del SIMLET '{{SIMLET}}'?", + + "coordinators.add.title": "Añadir coordinador", + "coordinators.name.title": "Nombre", + "coordinators.name.placeholder": "Nombre de usuario del coordinador", + "coordinators.permission.title": "Permisos", + "coordinators.permission.placeholder": "Seleccione los permisos", + "coordinators.permissions.full": "Completos", + "coordinators.permissions.read": "Lectura", + "coordinators.permissions.write": "Escritura", + "coordinators.error.already_in": "El coordinador ya está en el SIMLET", + "coordinators.error.permission": "", + "coordinators.error.not_found": "", + + "groups.title": "Grupos", + "groups.no_groups.message": "Aún no tiene grupos. Cree uno utilizando el botón inferior derecho (+)", + "participants.no_users.message": "No hay participantes en este grupo. Añada algunos utilizando el botón de el menú de 3 puntos a la derecha", + + "participants.title": "Participantes", + + "participants.table.username.title": "Nombre de usuario", + "participants.table.isToken.title": "Es código", + "participants.isToken.true": "Sí", + "participants.isToken.false": "No", + "participants.table.token.title": "Código", + "participants.table.email.title": "Correo electrónico", + "participants.table.role.title": "Rol", + "participant.delete.title": "Eliminar", + "participants.delete.confirm" : "¿Está seguro de que desea eliminar al participante '{{participant}}' del grupo '{{group}}'?", + "participants.table.sessopm.title": "Sesión", + + "allocator.type.title": "Tipo de asignador", + "allocator.sessions.title": "Sesión", + "allocator.participants.title": "Participante", + "allocator.add.error": "Error al añadir la asignación", + "allocator.add.message": "Asignador actualizado", + "allocator.add.title": "Añadir asignacion", + + "groups.name.title": "Nombre", + "groups.name.placeholder": "Nombre del grupo", + + "groups.add.title": "Añadir grupo", + "groups.add.new.tab": "Añadir nuevo", + "groups.add.new.submit": "Crear grupo", + "deprecated.title": "Usar versión obsoleta de generación de código", + "deprecated.message": "/!\\ Este grupo utiliza la versión obsoleta de generación de códigos.", + "deprecated.tooltip": "/!\\ Este grupo utilizará la versión obsoleta de generación de códigos.", + + "groups.import.tab": "Importar grupo", + "groups.import.input": "Fichero de importación de grupo", + "groups.import.submit": "Importar grupo", + "groups.import.upload.error": "", + "groups.import.error.invalid_file": "", + + "groups.settings.groups.edit.title": "Editar", + "groups.edit.title": "Editar grupo", + "groups.edit.submit": "Editar grupo", + "groups.edit.no_changes.message": "No se han detectado cambios en el nombre del nuevo grupo", + + "groups.settings.add.title": "Añadir participantes", + "participants.username.placeholder": "Nombre de usuario del participante", + + "participants.add.existing.tab": "Añadir existente", + "participants.add.existing.submit": "Añadir usuario", + "participants.errormessage.alreadyInGroup": "El participante '{{participant}}' ya está en el grupo '{{group}}'", + + "participants.add.new.tab": "Añadir nuevo", + "participants.add.new.email.placeholder": "email@ejemplo.com", + "participants.add.new.password.placeholder": "Contraseña", + "participants.add.new.groups.add.new.submit": "Crear usuario", + + "participants.add.batch.tab": "Añadir tanda de códigos", + "participants.add.batch.number.title": "¿Cuántos?", + "participants.add.batch.algorithFormat": "Los participantes se añadirán con nombres de usuario aleatorios creados con:", + "participants.add.batch.algorithFormat.letters": "Sólo letras", + "participants.add.batch.algorithFormat.alphanumeric": "Letras y números", + "participants.add.batch.algorithFormat.base58": "Alfanumérico simplificado (Base58)", + "participants.add.batch.length.title": "Y una longitud de:", + "participants.add.batch.submit": "Crear tanda", + + "groups.settings.allocator.title": "Editar asignador", + "allocator.change.title": "Seleccione el nuevo tipo de asignador", + + "allocator.default.title": "Asignador básico", + "allocator.default.type": "Por defecto", + "allocator.default.description": "Este asignador le permite asignar manualmente los participantes a las sesiones uno por uno. (Por defecto, el participante se asignará la primera sesión).", + + "allocator.group.title": "Asignador de grupos", + "allocator.group.type": "Grupo", + "allocator.group.description": "Este asignador permite asignar un grupo entero a una sesión", + + "allocator.change.submit": "Cambia el Asignador", + + "allocator.no_session_assigned.title": "Sin sesión", + + "groups.settings.print.title": "Descargar tabla como PDF", + "print_table.title": "Grupo: ", + "print_table.number_col.title": "Nº", + "print_table.name_col.title": "Nombre", + "print_table.code_col.title": "Código", + + "groups.settings.export.title": "Exportar", + + "groups.settings.delete.title": "Eliminar", + "groups.delete.confirm": "¿Está seguro de que desea eliminar el grupo '{{group}}' del SIMLET '{{SIMLET}}'?\nEl grupo se retirará a todos los estudios, pruebas y actividades", + + + "lti_platform.title": "Plataforma LTI", + "lti_platform.add.title": "Añadir plataforma LTI", + "lti_platform.add.name.title": "Nombre", + "lti_platform.add.url.title": "URL", + "lti_platform.add.client_id.title": "Client ID", + "lti_platform.add.authentication_endpoint.title": "Punto final de autenticación", + "lti_platform.add.accesstoken_endpoint.title": "Punto final del token de acceso", + "lti_platform.add.jkws_url.title": "jKWS URL", + "lti_platform.delete.title": "Suprimir la plataforma LTI", + "lti_platform.delete.confirm": "¿Está seguro de que desea eliminar esta plataforma '{{platform}}' del SIMLET '{{SIMLET}}'?", + "lti_platform.zero.message": "Aún no hay plataformas" +} \ No newline at end of file diff --git a/locales/es/roles.json b/locales/es/roles.json new file mode 100644 index 00000000..cff2601e --- /dev/null +++ b/locales/es/roles.json @@ -0,0 +1,12 @@ +{ + "selection.title": "Selección de papel Simva", + "admin": "Administrador", + "researcher": "Investigador", + "teacher": "Profesor", + "teachingAssistant": "Asistente de enseñanza", + "student": "Estudiante", + "choose.title": "Elija esta papel", + "contactadmin.title": "Contacto Administrador", + "contactadmin.message" : "Póngase en contacto con su administrador de SIMVA en {{ email }} atribuir un nuevo papel.", + "not_defined": "Indefinido" +} \ No newline at end of file diff --git a/locales/es/sessions.json b/locales/es/sessions.json new file mode 100644 index 00000000..60d2cd23 --- /dev/null +++ b/locales/es/sessions.json @@ -0,0 +1,77 @@ +{ + "title": "Sesiones", + "single.title": "Sesión", + "no_sessions.message": "No hay sesiones para este SIMLET. Intente añadir una utilizando el botón inferior derecho (+)", + + "createdAt": "Creado el", + "updatedAt": "Actualizado el", + "activities": "Actividades", + "users": "Usuarios", + "play": "Jugar al SIMLET", + "download.title": "Descargar datos", + "download.session.title": "Descargar datos de la sesión", + "download.test.title": "Descargar datos de prueba", + "download.test.description": "Descargar tus propios datos de traza de prueba para esta sesión.", + "download.description": "Descarga los datos de esta sesión", + + "add.title": "Añadir sesión", + "add.new.tab": "Añadir nuevo", + "status.title": "Estado inicial", + "add.submit": "Crear sesión", + + "import.tab": "Importar sesión", + "import.input": "Seleccione un fichero de sesión exportada", + "import.submit": "Importar sesión", + + "edit.title": "Editar sesión", + "edit.submit": "Editar sesión", + + "name.title": "Nombre", + "name.placeholder": "Nombre de la sesión", + "description.title": "Descipción", + "description.placeholder": "Descipción de la sesión", + "tags.title": "Etiquetas", + "tags.no_tags": "Sin etiquetas", + "tags.input.placeholder": "Escriba una etiqueta para encontrarla o créela", + "tags.dropdown.no_tags": "Aún no hay etiquetas. Presione + para crear una", + "tags.dropdown.no_matches": "No hay coincidencias para su búsqueda", + "tags.dropdown.all_matches": "Todas las etiquetas que coinciden ya están en esta sesión", + "tags.create.placeholder": "Nombre de la nueva etiqueta", + "tags.create": "Crear", + "tags.create.cancel": "Cancelar", + "tags.edit.placeholder": "Nombre de la etiqueta", + "tags.save": "Guardar", + "tags.edit.cancel": "Cancelar", + + "can_be_manually_activated": "Se puede activar manualmente", + + "settings.edit.title": "Editar", + "settings.add_activity.title": "Añadir actividad", + + "settings.duplicate.title": "Duplicar", + "duplicate.title": "Duplicar Session", + "duplicate.submit": "Duplicar", + + "settings.activate.title": "Activar", + "active.title": "Activa", + + "settings.pause.title": "Pausar", + "paused.title": "Pausada", + + "settings.finish.title": "Terminar", + "finished.title": "Terminada", + "finish.confirm": "¿Está seguro de que desea terminar (finalizar) esta sesión? Esta acción no se puede deshacer", + + "settings.delete.title": "Eliminar", + "delete.confirm": "¿Está seguro de que desea eliminar la sesión '{{session}}' del SIMLET '{{SIMLET}}'?\nTambién se eliminarán todas las actividades y datos", + + "settings.export.title": "Exportar", + "set_tester.title": "Convertirme en tester en esta sesión", + "reset_tester.title": "Reiniciar tester", + "unset_tester.title": "Quitarme como tester", + + "status.description": "Dependiendo de su estado, una sesión se comportará de manera diferente:", + "active.description": "Una sesión activa recibirá datos, sus actividades pueden ser modificadas, y puede ser pausada en cualquier momento", + "paused.description": "Una sesión pausada no recibirá datos, pero es posible modificar sus actividades o reactivarla en cualquier momento", + "finished.description": "Una sesión terminada ya no podrá recibir datos, modificar sus actividades, o ser reactivada" +} \ No newline at end of file diff --git a/locales/fr/SIMLETs.json b/locales/fr/SIMLETs.json new file mode 100644 index 00000000..b686706d --- /dev/null +++ b/locales/fr/SIMLETs.json @@ -0,0 +1,74 @@ +{ + "title": "SIMLETs", + "description": "Les SIMLETs sont le cœur de SIMVA, vous permettant de créer et de gérer vos propres simulations. Un SIMLET est un conteneur pour tous les éléments d'une simulation, y compris les sessions, les activités, les utilisateurs et les groupes. Vous pouvez créer de nouveaux SIMLETs, éditer ceux existants, archiver ceux dont vous n'avez plus besoin et gérer leurs paramètres et leur contenu.", + "archived.title": "SIMLETS Archivés", + "archived.description": "Liste des SIMLETs qui ont été archivés. Vous pouvez les désarchiver pour les réactiver.", + "no_simlets.message": "Vous n'avez pas encore de SIMLETs. Créez-en un en utilisant le bouton en bas à droite (+)", + "no_archived.message": "Pas de SIMLETs archivés. Les SIMLETs archivés apparaîtront ici.", + + "card.createdAt": "Crée le", + "card.updatedAt": "Mis à jour le", + "card.sessions": "Sessions", + "card.groups": "Groupes", + "card.users": "Utilisateurs", + "card.tags": "Tags", + + "add.title": "Ajouter SIMLET", + "new.tab": "Ajouter une nouvelle SIMLET", + "new.submit": "Ajouter SIMLET", + + "import.tab": "Importer à partir d'un fichier existant", + "import.input": "Sélectionnez fichier de SIMLET exporté", + "import.upload.error": "Sélectionnez le fichier à charger en premier", + "import.submit": "Importer SIMLET", + + "settings.edit.title": "Modifier", + "edit.title": "Modifier SIMLET", + "edit.submit": "Modifier SIMLET", + + "name.title": "Nom", + "name.placeholder": "Nom de la SIMLET", + "description.title": "Description", + "description.placeholder": "Description de la SIMLET", + + "settings.url.title": "URL settings", + "scheduler.shlink.generate.title": "Générer une URL réduite pour le planificateur", + "scheduler.shlink.generate.randomly_length.title": "Généré de manière aléatoire", + "scheduler.shlink.generate.randomly_length.message": "Avec un longueur de : ", + "scheduler.shlink.generate.custom_slug.title": "Utiliser un Slug personnalisé", + "scheduler.shlink.generate.submit": "Générer", + "scheduler.shlink.message": "Copier l'URL courte : {{shlink}}", + "scheduler.shlink.custom_slug.placeholder": "Slug personnalisé", + "scheduler.shlink.delete.title": "Supprimer l'URL du lien du planificateur", + "scheduler.shlink.delete.confirm": "Êtes-vous sûr de vouloir supprimer le lien court '{{shlink}}' du SIMLET '{{SIMLET}}'?", + + "settings.download.title": "Télécharger", + "config.download.simlet": "Télécharger la configuration du SIMLET", + "config.download.uadventure": "Télécharger la configuration du SIMLET pour uAdventure", + + "settings.archive.title": "Archiver", + "archive.confirm": "Êtes-vous sûr de vouloir archiver la SIMLET '{{SIMLET}}'?\nCette action ne peut pas être annulée et la SIMLET sera déplacée dans l'onglet archivé", + "settings.dearchive.title": "Désarchiver", + + "settings.delete.title": "Supprimer", + "delete.confirm": "Êtes-vous sûr de vouloir supprimer la SIMLET '{{SIMLET}}'?\nToutes les sessions, activités et données seront également supprimées", + + "edit.no_changes.message": "Aucun changement n'a été détecté !", + + "single.title": "SIMLET", + "single.description": "Informations generales et configuration du SIMLET selectionne.", + "sessions.tab.description": "Gerer les sessions de ce SIMLET: creer, modifier, suivre la progression et telecharger les donnees de session.", + "users.tab.description": "Gerer les utilisateurs, groupes, coordinateurs et leurs affectations dans ce SIMLET.", + "sessions.download.description": "Telecharger toutes les donnees disponibles pour cette session, y compris les donnees des activites.", + "simlets.description": "Liste des SIMLETs disponibles et acces rapide pour les creer, modifier, archiver ou supprimer.", + "sessions.tab.title": "Sessions", + "users.tab.title": "Users", + + + "scheduler.noSIMLET.title": "Vous n'avez pas encore de SIMLETs à participer.", + "scheduler.title": "Cliquez ici pour commencer ou poursuivre votre session dans le SIMLET.", + "scheduler.current": "Activité actuelle : ", + "scheduler.refresh": "Actualiser la page pour poursuivre le SIMLET", + "scheduler.complete": "Compléter Activité", + "scheduler.exit": "Sortir du SIMLET" +} \ No newline at end of file diff --git a/locales/fr/about.json b/locales/fr/about.json new file mode 100644 index 00000000..182d1d66 --- /dev/null +++ b/locales/fr/about.json @@ -0,0 +1,124 @@ +{ + "title": "À propos de", + "description": "Bienvenue sur le front-end de SIMVA ! Cette section fournit une vue d'ensemble de la plateforme, de ses principales fonctionnalités et un guide pour vous aider à naviguer dans l'interface. Que vous soyez enseignant, étudiant, chercheur ou développeur, vous trouverez des informations utiles pour commencer et tirer le meilleur parti de SIMVA.", + "text": "Cette section regroupe l'aide à la navigation, les tutoriels et de courtes explications sur SIMVA.\nUtilisez les étapes ci-dessous pour parcourir les pages principales. Certaines options n'apparaissent que pour les enseignants, les coordinateurs ou les administrateurs.", + "header.logout.title": "Guide de l'en-tête pour les visiteurs", + "header.logout.description": "Il s'agit de la barre du haut avant connexion. Elle donne accès aux pages publiques et au bouton de connexion.", + "header.logout.note": "Ce sont les seuls boutons disponibles dans la barre supérieure avant la connexion.", + "header.logout.language.title": "Sélecteur de langue", + "header.logout.language.description": "Changez la langue de l'interface depuis le petit sélecteur à gauche.", + "header.logout.about.title": "À propos", + "header.logout.about.description": "Ouvrez cette page pour lire la présentation de SIMVA et l'aide à la navigation.", + "header.logout.research.title": "e-UCM Research", + "header.logout.research.description": "Accédez au site de recherche pour les informations du projet et les documents associés.", + "header.logout.contact.title": "Contact", + "header.logout.contact.description": "Utilisez ce lien pour accéder aux informations de contact affichées dans l'en-tête.", + "header.logout.login.title": "Connexion", + "header.logout.login.description": "Appuyez sur ce bouton pour vous connecter et passer à l'interface authentifiée.", + "header.login.title": "Guide de l'en-tête pour les utilisateurs connectés", + "header.login.description": "Il s'agit de la barre du haut après connexion. Elle affiche votre compte et l'action de déconnexion, ainsi que des commandes supplémentaires sur les pages de planification.", + "header.login.note": "Sur les pages de planification, vous pouvez aussi voir les commandes actualiser, terminer l'activité et sortir.", + "header.login.language.title": "Sélecteur de langue", + "header.login.language.description": "Changez la langue de l'interface depuis le sélecteur à gauche.", + "header.login.account.title": "Nom du compte", + "header.login.account.description": "Ouvrez votre espace compte ou les informations de profil depuis le bouton du nom d'utilisateur.", + "header.login.logout.title": "Déconnexion", + "header.login.logout.description": "Terminez la session en cours et revenez à l'interface publique.", + "menu.title": "Guide du menu pour les utilisateurs connectés", + "menu.description": "Voici le menu latéral affiché après connexion. Il vous mène aux principales zones de SIMVA.", + "menu.note": "Certaines entrées n'apparaissent que pour les enseignants, les coordinateurs ou les administrateurs.", + "menu.home.title": "Accueil", + "menu.home.description": "Revenez à la page de démarrage avec les dernières informations de bienvenue et de compte.", + "menu.play.title": "Play SIMLETs", + "menu.play.description": "Ouvrez l'entrée de planification pour les participants qui doivent lancer les SIMLETs attribués.", + "menu.simlets.title": "SIMLETs", + "menu.simlets.description": "Gérez les études, les sessions, les participants et les résultats depuis la zone SIMLETs.", + "menu.groups.title": "Groupes", + "menu.groups.description": "Organisez ici les utilisateurs et les permissions basées sur les groupes.", + "menu.archived.title": "SIMLETs archivés", + "menu.archived.description": "Consultez les études archivées et conservées pour référence.", + "menu.about.title": "À propos", + "menu.about.description": "Rouvrez cette page de tutoriel chaque fois que vous devez vous rappeler comment fonctionne l'interface.", + + "simva.title": "SIMVA", + "simva.description": "L'infrastructure SIMVA est un logiciel d'architecture ouverte composé de plusieurs systèmes interconnectés. Parmi ces systèmes se trouvent le système de connexion SSO unifié (KeyCloak), le système de file d'attente de traitement (Kafka) et le système de stockage en nuage (Minio). Son architecture est scalable et interopérable avec d'autres outils tiers, ce qui permet de déléguer les fonctionnalités les plus critiques à des plateformes fiables et scalables.", + "simva.frontend.title": "Interface frontale SIMVA", + "simva.frontend.description": "L'interface frontale SIMVA est utilisée pour intégrer des jeux au système, créer des sondages, gérer les sessions, gérer la participation des utilisateurs aux sessions et suivre/analyser les données des sessions en temps réel. Ces données évoluent des réponses des utilisateurs aux sondages à des aperçus complets et des métriques pendant toute la session, y compris les données de jeu.", + "simva.roles.title": "Rôles et permissions", + "simva.roles.description": "Dans SIMVA, l'utilisateur peut être un enseignant, un étudiant, un chercheur ou un développeur. Les rôles et permissions sur l'interface frontale sont catégorisés en superviseur, coordinateur et participant. Ceux-ci seront expliqués plus loin dans ce document.", + + "simlet.title": "SIMLET (SIMVA APPLET)", + "simlet.description": "Un conteneur dans l'application web de l'interface frontale SIMVA pour encapsuler les données de différentes sessions. Un SIMLET est créé pour atteindre un objectif particulier, par exemple pour comparer l'efficacité d'un jeu sérieux particulier, comparer entre les capacités de trois groupes d'étudiants ou comparer les connaissances en programmation acquises dans différents jeux. Chaque SIMLET a ses propres superviseurs avec autorité totale sur les sessions et activités du SIMLET. Le superviseur principal (l'utilisateur qui a créé le SIMLET) est le seul utilisateur autorisé à supprimer tout le SIMLET.", + "archived_simlet.title": "SIMLET archivé", + "archived_simlet.description": "Un SIMLET archivé est conservé pour référence et peut être restauré plus tard. Il est masqué des listes actives mais conserve sa configuration et son historique.", + + "session.title": "Session", + "session.description": "Un conteneur dans l'application web de l'interface frontale SIMVA pour encapsuler les données de plusieurs activités. Une session se compose d'une ou plusieurs activités (pré-sondage, jeu ou activité d'apprentissage manuel/traditionnel et post-sondage) à entreprendre par un groupe de participants. Chaque session a ses propres coordinateurs avec autorité totale sur les activités de la session.", + + "supervisor.title": "Superviseur SIMLET", + "supervisor.description": "Un utilisateur qui a un accès total à un SIMLET particulier. Le superviseur principal crée d'abord le SIMLET, puis peut éditer/supprimer le SIMLET ou assigner d'autres superviseurs ou coordinateurs en spécifiant le mode de permission, soit 'Éditeur' soit 'Visualiseur'. Un superviseur en mode 'Éditeur' peut éditer les informations du SIMLET (titre et description), ajouter/éditer/supprimer des sessions, ajouter/éditer/supprimer différentes activités qui composent les sessions et assigner les participants impliqués dans chaque session. De plus, un superviseur en mode 'Éditeur' peut ajouter des balises aux sessions, les démarrer, suivre et exporter les résultats. Un superviseur en mode 'Visualiseur' ne peut que voir les configurations du SIMLET ainsi que ses sessions et les activités associées et ses résultats sans capacité à ajouter, éditer ou supprimer. Seul le superviseur principal peut supprimer le SIMLET.", + + "coordinator.title": "Coordinateur de session", + "coordinator.description": "Un utilisateur qui a un accès total à une session particulière. Il existe deux modes de permission : 'Éditeur' et 'Visualiseur'. Un coordinateur en mode 'Éditeur' peut éditer les informations de la session (titre et description), ajouter des balises à la session, ajouter/éditer/supprimer les différentes activités qui composent une session. De plus, un coordinateur en mode 'Éditeur' peut assigner d'autres coordinateurs à la session et définir leur permission, soit 'Éditeur' soit 'Visualiseur'. Les coordinateurs avec les deux modes 'Éditeur' et 'Visualiseur' ont accès au tableau de bord pour afficher les résultats et les exporter, mais le démarrage de la session est limité uniquement aux coordinateurs en mode 'Éditeur'.", + + "participant.title": "Participant", + "participant.description": "Un utilisateur (par exemple un étudiant) dont le rôle est d'entreprendre des activités comme répondre à des sondages et jouer à des jeux. Chaque participant peut également voir ses propres résultats.", + + "gameclient.title": "Client de jeu", + "gameclient.description": "Un client de jeu est l'ensemble des métadonnées du jeu telles que le titre, la description, la catégorie (sensibilisation ou éducation) et le domaine d'étude (mathématiques, programmation, cyberharcèlement, etc). C'est l'URL du jeu pour un jeu web ou le fichier compressé du jeu pour un jeu de bureau.", + + "integratedgame.title": "Jeu intégré dans SIMVA", + "integratedgame.description": "Un jeu intégré dans SIMVA signifie que le client de jeu est décrit dans SIMVA et présenté comme un modèle d'activité de jeu. Chaque fois qu'un nouveau jeu est intégré dans SIMVA, un modèle d'activité de jeu avec un ID est automatiquement généré. Chaque fois que le jeu est utilisé dans une activité de jeu au sein d'une session, une nouvelle instance d'activité de jeu est créée à partir de ce modèle. Cela signifie que l'instance d'activité de jeu fera référence au modèle d'activité de jeu à l'aide de son ID. Les superviseurs peuvent afficher les jeux intégrés à partir d'un menu dans l'interface frontale SIMVA.", + + "activity.title": "Activité", + "activity.description": "Une action ou un ensemble d'actions à entreprendre par les participants. Cette action pourrait être répondre à des sondages (activité LimeSurvey), jouer à des jeux sérieux (activité de jeu) ou entreprendre des exercices d'apprentissage traditionnel (activité manuelle).", + "activity.types.title": "Types d'activité", + + "limesurvey.title": "Activité LimeSurvey", + "limesurvey.description": "Une activité basée sur des sondages qui utilise LimeSurvey comme service, permettant aux participants de répondre à des pré et post-sondages et permettant aux propriétaires de collecter des données efficacement.", + + "gameplay.title": "Activité de jeu", + "gameplay.description": "L'action de jouer au jeu sérieux où les données d'interaction du jeu des participants sont collectées via le composant xAPI (trackers dans le code), conçu pour intégrer le contenu éducatif de manière attrayante.", + + "manual.title": "Activité manuelle", + "manual.description": "Un exercice d'apprentissage traditionnel à entreprendre par les participants, comme lire un livre, lire un article, regarder une vidéo ou toute autre tâche d'apprentissage passif.", + + "activitytemplate.title": "Modèle d'activité", + "activitytemplate.description": "Un modèle d'activité représente la description statique d'une activité. Il définit les métadonnées d'une activité telles que son titre et sa description. Un modèle peut être utilisé dans plusieurs sessions en créant des instances du modèle. Le modèle d'activité peut être une activité de sondage, une activité manuelle ou une activité de jeu. En cas d'activité de jeu, il contiendra également les données du client de jeu.", + + "activityinstance.title": "Instance d'activité", + "activityinstance.description": "Une instance d'activité représente une exécution concrète d'un modèle d'activité. Elle stocke les données spécifiques aux participants, telles que les réponses aux sondages, les performances des activités manuelles, les interactions des activités de jeu, telles que les traces et les résultats. Quand l'utilisateur ajoute une activité à une session particulière, une instance de ce modèle d'activité est automatiquement créée. En cas d'activité de jeu, l'instance d'activité est référencée à l'ID du jeu intégré. Cependant, les données collectées du jeu seront stockées au niveau de l'activité de jeu de la session.", + + "manualcompletion.title": "Fin manuelle pour les activités", + "manualcompletion.description": "Au cas où un participant compléterait une activité mais son statut ne serait pas automatiquement défini à 'complété' pour une raison quelconque, il y a un bouton qui permet au superviseur/coordinateur de modifier manuellement le statut à 'complété'. Il est également possible de modifier manuellement le statut d'une activité à 'complété' pour tous les participants à la fois.", + + "dashboard.title": "Tableau de bord SIMVA", + "dashboard.description": "Chaque SIMLET contient un tableau de bord visuel avec des informations détaillées sur les activités des sessions. Le tableau de bord affiche les informations générales sur le statut de chaque activité, affichant le pourcentage de fin des participants, la progression et le résultat. Il affiche également une liste détaillée des participants, cette liste affiche le nom de chaque participant, le statut de fin, le statut de progression et le résultat de sauvegarde. Tandis que l'activité reçoit des données xAPI, qu'elle soit en cours ou complétée, le tableau de bord est mis à jour en conséquence avec les traces reçues.", + + "group.title": "Groupe", + "group.description": "Un groupe est un ensemble de participants utilisés pour organiser les affectations et les règles de répartition entre les sessions.", + + "users.title": "Utilisateurs", + "users.description": "Les utilisateurs, groupes et coordinateurs définissent qui participe au SIMLET et comment les participants sont affectés aux sessions.", + "xapi.dashboard.title": "Données xAPI pour les tableaux de bord SIMVA", + "xapi.dashboard.intro": "Pour chaque session au sein d'un SIMLET, il y a différents tableaux de bord qui représentent les données de suivi en temps réel pour ses activités. L'image suivante montre un exemple de ces tableaux de bord.", + "xapi.dashboard.image.alt": "Exemple de tableaux de bord SIMVA pour les activités de session", + "xapi.dashboard.backend.title": "Suivi xAPI dans le backend", + "xapi.dashboard.backend.desc": "Dans le backend, nous suivons les traces xAPI pour les tableaux de bord. Par exemple:", + "xapi.dashboard.activitytypes.title": "Types d'activité et types d'objet xAPI", + "xapi.dashboard.activitytypes.col1": "Type d'activité", + "xapi.dashboard.activitytypes.col2": "Type de définition d'objet dans les traces xAPI", + "xapi.dashboard.activitytypes.game": "Activité de jeu", + "xapi.dashboard.activitytypes.limesurvey": "Activité LimeSurvey", + "xapi.dashboard.activitytypes.manual": "Activité manuelle", + "xapi.dashboard.visibledata.title": "Données du tableau de bord et traces xAPI correspondantes", + "xapi.dashboard.visibledata.desc": "Dans les lignes suivantes, nous définissons les données visibles sur les tableaux de bord avec leurs traces xAPI correspondantes suivies.", + "xapi.dashboard.initialized.title": "Initialisé", + "xapi.dashboard.initialized.desc": "Cela représente si le participant a commencé l'activité ou non. Sa valeur peut être 'true' ou 'false'. La valeur par défaut est 'false', et elle deviendra 'true' lorsque le participant initialisera l'activité. Cela signifie que dans le backend le serveur SIMVA a reçu une trace xAPI avec l'id du verbe: 'http://adlnet.gov/expapi/verbs/initialized'.", + "xapi.dashboard.progress.title": "Progression", + "xapi.dashboard.progress.desc": "Cela représente le pourcentage de finalisation de l'activité. Sa valeur est comprise entre 0% et 100% inclus. Si l'activité n'est pas encore initialisée, la valeur par défaut du progrès est '-', tandis que si elle est initialisée mais sans progrès, la valeur du progrès est '0%'. Si elle est complètement finalisée, la valeur du progrès est '100%'. Cela signifie que dans le backend le serveur SIMVA a reçu une trace xAPI avec l'id du verbe: 'http://adlnet.gov/expapi/verbs/progressed', et aussi la valeur du résultat mise à l'échelle entre 0 et 1 (les deux inclus) à partir de l'étiquette de résultat affichée dans le tableau:", + "xapi.dashboard.progress.col1": "Type d'activité", + "xapi.dashboard.progress.col2": "Étiquette de résultat affichée dans les traces xAPI", + "xapi.dashboard.completed.title": "Complété", + "xapi.dashboard.completed.desc": "Cela représente si le participant a complété l'activité ou non. Sa valeur peut être 'true' ou 'false'. La valeur par défaut est 'false', et elle deviendra 'true' lorsque le participant complétera l'activité. Cela signifie que dans le backend le serveur SIMVA a reçu une trace xAPI avec l'id du verbe: 'http://adlnet.gov/expapi/verbs/completed', et aussi la valeur du résultat de finalisation doit être définie à 'true'." +} \ No newline at end of file diff --git a/locales/fr/activities.json b/locales/fr/activities.json new file mode 100644 index 00000000..3ff47f13 --- /dev/null +++ b/locales/fr/activities.json @@ -0,0 +1,185 @@ +{ + "title": "Activités", + "single.title": "Activité", + "text": "L'affichage des activités est temporairement désactivé.\nCet onglet est conçu pour créer des \"modèles d'activités\" pour qu'ils soient ensuite copiés dans les tests.\nCes \"modèles d'activités\" vont aider à la création de plusieurs cas de test similaires avec de petites modifications.\nIl sera disponible dans une prochaine version.", + + "no_activities.message": "Il n'y a pas d'activités dans ce session. Ajoutez-en une en utilisant le bouton [...] à droite", + + "add.title": "Ajouter une activité", + "add.new.title": "Nouvelle activité", + "add.new.web.no_url_message": "", + "add.existing.title": "Sélectionner parmi les existantes", + + "edit.title": "Modifier", + + "delete.title": "Supprimer", + "delete.confirm": "Êtes-vous sûr de vouloir supprimer l'activité '{{activity}}' de la session '{{session}}' de la SIMLET '{{SIMLET}}'?\nToutes les données relatives à l'activité seront également supprimées", + + "export.title": "Export", + "import.title": "Import", + "import.message": "Sélectionner le fichier à importer", + "import.error": "Sélectionnez le fichier à importer en premier", + "import.upload.error": "Sélectionnez le fichier à importer en premier", + "import.error.invalid_file": "Fichier invalide", + + "name.placeholder": "Nom de l'activité", + "activity.type.title": "Type d'activité", + "type.title": "Type", + + "activity.type.select": "Sélectionner un type d'activité", + "activity.type.select_required": "Le type d'activité est requis", + "activity.name": "Activité par défaut", + "activity.description": "Une activité de base avec un état d'achèvement et un endroit où enregistrer les résultats.", + "activity.result.title": "Résultat", + "activity.result.file.prefix": "résultat_activité", + "activity.result.zero": "Pas de résultat", + "activity.result.view.partial": null, + "activity.result.view.final": "Voir le résultat", + "activity.storage.title": "Stockage", + "activity.storage.file.array.suffix": "trace_d_activité_en_table", + "activity.storage.file.one_per_line.suffix": "trace_d_activité_en_une_par_ligne", + + "limesurvey.name": "Activité de Limesurvey", + "limesurvey.description": "Une activité basée sur des sondages qui utilise LimeSurvey comme service, permettant aux participants de répondre à des sondages avant et après d'autres activités et aux coordinateurs de collecter efficacement des données.", + "limesurvey.result.title": "Résultat", + "limesurvey.result.file.prefix": "résultat_enquête", + "limesurvey.result.zero": "Non démarré", + "limesurvey.result.view.partial": "Commencé", + "limesurvey.result.view.final": "Terminé", + "limesurvey.storage.title": "Stockage de traces", + "limesurvey.storage.file.array.suffix": "trace_enquête_en_table", + "limesurvey.storage.file.one_per_line.suffix": "trace_enquête_en_une_par_ligne", + + "limesurvey.title": "Limesurvey", + "limesurvey.surveyid.title": "ID de l'enquête", + "limesurvey.surveyid.placeholder": "ID de l'enquête", + "limesurvey.existing.title": "Enquête existante", + "limesurvey.existing.zero.message": "Vous n'avez pas d'enquêtes.", + "limesurvey.new.title": "Nouvelle enquête", + "limesurvey.new.description": "Cliquer pour ouvrir LimeSurvey", + "limesurvey.new.after.message": "Après avoir créé un nouveau enquête sur LimeSurvey, vous devez le sélectionner parmi les enquêtes existantes.", + "limesurvey.upload.title": "Charger LSS", + "limesurvey.upload.message": "Sélectionner le fichier LLS", + "limesurvey.upload.description": "Sélectionner un fichier LSS pour créer une nouvelle enquête au sein de l'activité d'enquête.", + "limesurvey.upload.error": "Sélectionnez le fichier à charger en premier", + "limesurvey.language.title": "Langue de l'enquête", + "limesurvey.survey.title": "Enquête", + "limesurvey.survey.only_one.message": "Vous n'avez pas d'autres enquêtes.", + "limesurvey.edit.title": "Modifier l'enquête", + "limesurvey.short_url.title": "Générer une URL courte", + "limesurvey.backup.full.title": "Complet", + "limesurvey.backup.code.title": "Code", + "limesurvey.no_method": "Choisir d'abord une méthode", + + "gameplay.name": "Activité de jeu", + "gameplay.description": "L'action consistant à jouer à un jeu sérieux dans lequel les données d'interaction des participants sont collectées via le composant xAPI (trackers dans le code), conçu pour intégrer du contenu éducatif de manière attrayante.", + "gameplay.result.title": "Sauvegarde", + "gameplay.result.description": "Activer la collecte et le téléchargement des sauvegardes pendant l'activité de jeu.", + "gameplay.result.file.prefix": "sauvegarde_resultat_jeu", + "gameplay.result.zero": "Pas de sauvegarde", + "gameplay.result.view.partial": null, + "gameplay.result.view.final": "Voir Sauvegarde", + "gameplay.storage.title": "Stockage de traces", + "gameplay.storage.description": "Activer la collecte et le téléchargement des données d'interaction xAPI collectées pendant l'activité de jeu.", + "gameplay.storage.file.array.suffix": "trace_de_jeu_en_table", + "gameplay.storage.file.one_per_line.suffix": "trace_de_jeu_en_une_par_ligne", + + "gameplay.xapi_by_game.title": "Gestion des données xAPI basiques par jeu", + "gameplay.xapi_by_game.description": "Activer la gestion des données xAPI basiques (initialisation de l'activité, suspendue/reprise, activité terminée) directement par le jeu, ce qui permet de différencier les données d'interaction en fonction du jeu spécifique joué, facilitant ainsi l'analyse et la compréhension des performances des participants dans différents contextes de jeu.", + "gameplay.game_uri.title": "URI du jeu", + "gameplay.game_uri.description": "L'URI du jeu à lancer dans l'activité de jeu, qui peut être un jeu web lancé dans une iframe ou un jeu de bureau lancé en dehors de SIMVA, et les données d'interaction sont collectées via des déclarations xAPI envoyées du jeu à SIMVA.", + "gameplay.xasu.title": "Configuration de Xasu", + "gameplay.xasu.description": "Configurer Xasu pour la collecte de données xAPI, y compris les paramètres tels que l'endpoint et les clés d'authentification, afin d'assurer une intégration fluide et sécurisée des données d'interaction des participants pendant l'activité de jeu.", + "gameplay.restarted.title": "Permettre de redémarrer ?", + "gameplay.restarted.description": "Permettre aux participants de redémarrer l'activité de jeu après l'avoir terminée, ce qui peut être utile pour collecter plusieurs séries de données d'interaction ou permettre aux participants d'améliorer leurs performances.", + + "gameplay.web.title": "Web", + "gameplay.web.description": "L'activité de jeu est basée sur un jeu web lancé dans une iframe, et les données d'interaction sont collectées via des déclarations xAPI envoyées du jeu à SIMVA.", + "gameplay.desktop.title": "Jeu de bureau", + "gameplay.desktop.description": "L'activité de jeu est basée sur un jeu de bureau lancé sur la machine de l'utilisateur, et les données d'interaction sont collectées via des déclarations xAPI envoyées du jeu à SIMVA.", + + "manual.name": "Activité manuelle", + "manual.description": "Un exercice d'apprentissage traditionnel à réaliser par les participants, tel que la lecture d'un livre ou d'un article, le visionnage d'une vidéo ou toute autre tâche d'apprentissage passive.", + "manual.result.title":null, + "manual.result.file.prefix":null, + "manual.result.zero": null, + "manual.result.view.partial": null, + "manual.result.view.final": null, + "manual.storage.title": "Stockage de traces", + "manual.storage.description": "Activer la collecte et le téléchargement des données d'interaction xAPI collectées pendant l'activité manuelle.", + "manual.storage.file.array.suffix": "trace_manuel_en_table", + "manual.storage.file.one_per_line.suffix": "trace_manuel_en_une_par_ligne", + + "manual.student_complete.title": "Permettre aux élèves de compléter ?", + "manual.student_complete.description": "Permettre aux élèves de marquer l'activité comme terminée.", + "manual.student_complete.ok": "Les élèves peuvent compléter.", + "manual.student_complete.nok": "Les étudiants ne peuvent pas compléter.", + "manual.uri.title": "URI", + "manual.uri.explication": "L'URL de la ressource à accéder dans l'activité manuelle. L'URI peut inclure des balises : {username}, et {activityId}.", + "manual.restarted.title": "Permettre de redémarrer ?", + "manual.restarted.description": "Permettre aux participants de redémarrer l'activité manuelle après l'avoir terminée, ce qui peut être utile pour collecter plusieurs séries de données d'interaction ou permettre aux participants d'améliorer leurs performances.", + + "manual.web.title": "Web", + "manual.web.description": "L'activité manuelle est basée sur une ressource web lancée dans une iframe, et les données d'interaction sont collectées via des déclarations xAPI envoyées de la ressource à SIMVA.", + "manual.external.title": "Ressource externe", + "manual.external.description": "L'activité manuelle est basée sur une ressource externe lancée en dehors de SIMVA, et les données d'interaction sont collectées via des déclarations xAPI envoyées de la ressource à SIMVA.", + + "ltitool.name": "Activité de l'outil LTI", + "ltitool.description": "Une activité qui permet à l'utilisateur d'inclure un outil LTI en tant que ressource..", + + "imspackage.name": "Activité du paquet IMS", + "imspackage.description": "Une activité de jeu qui permet à l'utilisateur de charger un paquet IMS en tant que jeu.", + "imspackage.result.title": "Sauvegarde", + "imspackage.result.file.prefix": "résultat_sauvegarde_imspackage", + "imspackage.result.zero": "Pas de Sauvegarde", + "imspackage.result.view.partial": null, + "imspackage.result.view.final": "Voir Sauvegarde", + "imspackage.storage.title": "Stockage de traces", + "imspackage.storage.file.suffix.array": "trace_paquet_ims_en_table", + "imspackage.storage.file.suffix.one_per_line": "trace_paquet_ims_en_une_par_ligne", + "imspackage.package.title": "Paquet IMS", + + "completed.title": "Complété", + "completed.error.message": "Erreur dans la définition de l'achèvement", + "completed.all.unset": "Complété TOUS OFF", + "completed.all.set": "Complété TOUS ON", + "completed.on": "Oui", + "completed.off": "Non", + + "progress.title": "Progrès", + "participant.title": "Participant", + "init.title": "Init", + "init.on": "Oui", + "init.off": "Non", + + "result.title": "Résultat", + "result.disabled": "Desactivé", + "result.error.loading": "Erreur de chargement du résultat", + "result.error.downloading": "Erreur de téléchargement du résultat", + + "storage.title": "Stockage", + "storage.disabled": "Desactivé", + "storage.error.downloading": "Erreur de téléchargement des données à partir de la mémoire", + "storage.file.title": "Télécharger en tant que", + "storage.file.array.title": "Tableau", + "storage.file.one_per_line.title": "Une trace par ligne", + + "participant.tooltip": "Identifiant du participant affiche en tant que nom d'utilisateur ou jeton.", + "init.tooltip": "Etat d'initialisation: indique si le participant a commencé l'activité.", + "init.bar.tooltip": "Barre de resume d'initialisation: participants initialises sur le total des participants.", + "progress.tooltip": "Pourcentage de progression actuel du participant dans cette activité.", + "progress.bar.tooltip": "Barre de resume de progression: participants termines et en cours sur le total des participants.", + "completed.tooltip": "Etat d'achevement: indique si le participant a termine l'activité.", + "completed.bar.tooltip": "Barre de resumé d'achevement: participants ayant termine sur le total des participants.", + "result.tooltip": "Etat du resultat et acces aux donnees de resultat ou de sauvegarde.", + "result.bar.tooltip": "Barre de resumé des resultats: participants avec des resultats partiels ou finaux sur le total des participants.", + + "tmon.title": "Tableau de bord TMon", + "download.title": "Telecharger les donnees", + "download.activity.title": "", + "download.test.title": "Telecharger les données de test", + "download.xasu.title": "", + "download.backup.title": "", + "download.test.description": "Telecharger les donneés de test disponibles pour cette activité.", + "download.description": "Telecharger toutes les donnees disponibles pour cette activité." +} \ No newline at end of file diff --git a/locales/fr/commons.json b/locales/fr/commons.json new file mode 100644 index 00000000..d46259b0 --- /dev/null +++ b/locales/fr/commons.json @@ -0,0 +1,16 @@ +{ + "title": "SIMVA - Un SIMple VAlidateur", + "login.title": "Connexion", + "logout.title": "Déconnexion", + "home.title": "Accueil", + "home.description": "Bienvenue à SIMVA ! C'est le tableau de bord principal où vous pouvez accéder à toutes les fonctionnalités de la plateforme. Utilisez le menu pour naviguer à travers les différentes sections, telles que les SIMLETs, les activités et la gestion des utilisateurs. Que vous soyez enseignant, étudiant ou chercheur, vous trouverez tout ce dont vous avez besoin pour créer et gérer vos simulations ici.", + "welcome.user.text": "Bienvenue {{username}}!\n", + "welcome.teacher.text": "Voici la vue principale de Simva.\nVous pouvez aller dans Activités pour créer des activités d'enquête, des activités de jeu et d'autres types d'activités personnalisées nécessaires à l'élaboration d'une étude.\nL'onglet Études permet de créer une étude dans laquelle un ensemble d'activités peut être mis en place pour réaliser une évaluation.\nPour gérer les utilisateurs et les groupes, utilisez l'onglet Groupes où des groupes d'utilisateurs et les utilisateurs eux-mêmes peuvent être créés afin de leur permettre de participer aux études.\nPour plus d'informations, consultez le site:", + "welcome.student.text": "Voici la vue principale de Simva.\nL'onglet Études permet d'accéder à toutes vos études dans lesquelles vous réaliserez une évaluation composé d'un ensemble d'activités qui ont été mise en place.", + "contact.title": "Contact", + "QA.title": "Questions & Réponses", + "GDPR.title": "RGDP", + "github.title" : "GitHub", + "eUCMResearch.title": "Equipe de Recherche e-UCM", + "moreprojects.title" : "Plus de projets" +} \ No newline at end of file diff --git a/locales/fr/groups.json b/locales/fr/groups.json new file mode 100644 index 00000000..5afe1606 --- /dev/null +++ b/locales/fr/groups.json @@ -0,0 +1,127 @@ +{ + "users.add.title": "", + + "coordinators.title": "Coordinateurs", + "coordinators.table.username.title": "Nom d'utilisateur", + "coordinators.table.permissions.title": "", + + "coordinators.delete.title": "Supprimer", + "coordinators.delete.confirm": "Êtes-vous sûr de vouloir supprimer le coordinateur '{{owner}}' du SIMLET '{{SIMLET}}'?", + + "coordinators.add.title": "Ajouter un coordinateur", + "coordinators.name.title": "Nom", + "coordinators.name.placeholder": "Nom d'utilisateur du coordinateur", + "coordinators.permission.placeholder": "", + "coordinators.permission.title": "", + "coordinators.permissions.full": "", + "coordinators.permissions.read": "", + "coordinators.permissions.write": "", + "coordinators.error.already_in": "Le coordinateur est déjà dans le SIMLET.", + "coordinators.error.permission": "", + "coordinators.error.not_found": "", + + "groups.title": "Groups", + "groups.no_groups.message": "You have 0 groups yet. Create one using the bottom right (+) button", + + "participants.no_users.message": "Il n'y a pas de participants dans ce groupe. Essayez d'en ajouter en utilisant le bouton [...] à droite.", + + "participants.title": "Participants", + + "participants.table.username.title": "Nom d'utilisateur", + "participants.table.isToken.title": "Est un jeton", + "participants.isToken.true": "Oui", + "participants.isToken.false": "Nom", + "participants.table.token.title": "Jeton", + "participants.table.email.title": "Mail", + "participants.table.role.title": "Rôle", + "participant.delete.title": "Supprimer", + "participants.delete.confirm" : "Êtes-vous sûr de vouloir supprimer le participant '{{participant}}' du groupe '{{group}}' ?", + "participants.table.sessopm.title": "Session", + + "allocator.type.title": "Allocateur type", + "allocator.sessions.title": "Session", + "allocator.participants.title": "Participant", + "allocator.add.error": "Erreur dans l'ajout de l'allocation", + "allocator.add.message": "Mise à jour de l'Allocateur", + "allocator.add.title": "Ajouter un allocation", + + "groups.name.title": "Nom", + "groups.name.placeholder": "Nom du groupe", + + "groups.add.title": "Ajouter un groupe", + "groups.add.new.tab": "Ajouter un groupe", + "groups.add.new.submit": "Ajouter le groupe", + "deprecated.title": "Utiliser la version obsolète de génération de code", + "deprecated.message": "/!\\ Ce groupe utilise la version obsolète de génération de code.", + "deprecated.tooltip": "/!\\ Ce groupe utilisera la version obsolète de génération de code.", + + "groups.import.tab": "Importer un groupe", + "groups.import.input": "Fichier d'import du groupe", + "groups.import.submit": "Importer le groupe", + "groups.import.upload.error": "Sélectionnez le fichier à charger en premier", + "groups.import.error.invalid_file": "", + + "groups.settings.groups.edit.title": "Modifier", + "groups.edit.title": "Modifier groupe", + "groups.edit.submit": "Modifier groupe", + "groups.edit.no_changes.message": "Aucun changement n'a été détecté avec groupe nom !", + "groups.settings.add.title": "Ajouter des participants", + "participants.username.placeholder": "Nom d'utilisateur du participant", + + "participants.add.existing.tab": "Ajouter existant", + "participants.add.existing.submit": "Ajouter existant", + "participants.errormessage.alreadyInGroup": "Le participant '{{participant}}' est déjà dans le groupe '{{group}}'.", + + "participants.add.new.tab": "Ajouter un nouveau", + "participants.add.new.email.placeholder": "email@example.com", + "participants.add.new.password.placeholder": "Mot de passe", + "participants.add.new.groups.add.new.submit": "Cree participant", + + "participants.add.batch.tab": "Ajouter un lot de jeton", + "participants.add.batch.number.title": "Combien ?", + "participants.add.batch.algorithFormat": "Les participants seront ajoutés avec des noms d'utilisateur aléatoires créés à l'aide de :", + "participants.add.batch.algorithFormat.letters": "Uniquement des lettres", + "participants.add.batch.algorithFormat.alphanumeric": "Lettres et chiffres", + "participants.add.batch.algorithFormat.base58": "Alphanumérique simplifié (Base58)", + "participants.add.batch.length.title": "Et une longueur de :", + "participants.add.batch.submit": "Ajouter lot", + + "groups.settings.allocator.title": "Modifier allocateur", + "allocator.change.title": "Sélectionner le nouveau type d'allocateur", + + "allocator.default.title": "Allocateur de base", + "allocator.default.type": "Défaut", + "allocator.default.description": "Cet allocateur vous permet d'affecter manuellement les participants aux sessions un par un. (S'il n'est pas assigné, il prendra le premier).", + + "allocator.group.title": "Allocateur de Groupe", + "allocator.group.type": "Groupe", + "allocator.group.description": "Cet allocateur vous permet de sélectionner la branche de session à laquelle chaque groupe est affecté.", + + "allocator.change.submit": "Changer d'Allocateur", + + "allocator.no_session_assigned.title": "Pas de session", + + "groups.settings.print.title": "Telecharger le tableau en PDF", + "print_table.title": "Groupe : ", + "print_table.number_col.title": "No.", + "print_table.name_col.title": "Nom", + "print_table.code_col.title": "Code", + + "groups.settings.export.title": "Exporter", + + "groups.settings.delete.title": "Supprimer", + "groups.delete.confirm": "Êtes-vous sûr de vouloir supprimer le groupe '{{group}}' du SIMLET '{{SIMLET}}'?", + + + "lti_platform.title": "Plate-forme LTI", + "lti_platform.add.title": "Ajouter un plateforme LTI", + "lti_platform.add.name.title": "Nom", + "lti_platform.add.url.title": "URL", + "lti_platform.add.client_id.title": "ID du Client", + "lti_platform.add.authentication_endpoint.title": "Point final d'authentification", + "lti_platform.add.accesstoken_endpoint.title": "Point final du jeton d'accès", + "lti_platform.add.jkws_url.title": "URL de jKWS", + "lti_platform.delete.title": "Supprimer la plate-forme LTI", + "lti_platform.delete.confirm": "Êtes-vous sûr de vouloir supprimer cette plate-forme '{{platform}}' du SIMLET '{{SIMLET}}' ?", + "lti_platform.zero.message": "Il n'y a pas encore de plateformes." +} \ No newline at end of file diff --git a/locales/fr/roles.json b/locales/fr/roles.json new file mode 100644 index 00000000..377fdb7e --- /dev/null +++ b/locales/fr/roles.json @@ -0,0 +1,12 @@ +{ + "selection.title": "Sélection du rôle de Simva", + "admin": "Administrateur", + "researcher": "Chercheur", + "teacher": "Enseignant", + "teachingAssistant": "Assistant d'enseignement", + "student": "Étudiant", + "choose.title": "Choisir ce rôle", + "contactadmin.title": "Contact Administrateur", + "contactadmin.message" : "Veuillez contacter votre administrateur SIMVA à l'adresse suivante {{ email }} pour lui attribuer un nouveau rôle.", + "not_defined": "Non défini" +} \ No newline at end of file diff --git a/locales/fr/sessions.json b/locales/fr/sessions.json new file mode 100644 index 00000000..e300b7e1 --- /dev/null +++ b/locales/fr/sessions.json @@ -0,0 +1,77 @@ +{ + "title": "Sessions", + "single.title": "Session", + "no_sessions.message": "Il n'y a pas de sessions pour cette SIMLET. Essayez d'en ajouter une en utilisant le bouton en bas à droite (+)", + + "createdAt": "Créé le", + "updatedAt": "Mis à jour le", + "activities": "Activités", + "users": "Utilisateurs", + "play": "Jouer le SIMLET", + "download.title": "Télécharger données", + "download.session.title": "Télécharger les données de la session", + "download.test.title": "Télécharger les données de test", + "download.test.description": "Télécharger vos propres données de trace de test pour cette session.", + "download.description": "", + + "add.title": "Ajouter une session", + "add.new.tab": "Ajouter nouveau", + "status.title": "", + "add.submit": "Ajouter une session", + + "import.tab": "Importer une session", + "import.input": "Sélectionnez fichier de session exporté", + "import.submit": "Importer une session", + + "edit.title": "Modifier le session", + "edit.submit": "Modifier le session", + + "name.title": "Nom", + "name.placeholder": "Nom du session", + "description.title": "Description", + "description.placeholder": "Description du session", + "tags.title": "Tags", + "tags.no_tags": "Aucun tag", + "tags.input.placeholder": "Ajouter un tag", + "tags.dropdown.no_tags": "Aucun tag disponible", + "tags.dropdown.no_matches": "Aucun tag correspondant", + "tags.dropdown.all_matches": "Tous les tags correspondants sont déjà dans cette session", + "tags.create.placeholder": "Nom du nouveau tag", + "tags.create": "Créer", + "tags.create.cancel": "Annuler", + "tags.edit.placeholder": "Nom du tag", + "tags.save": "Enregistrer", + "tags.edit.cancel": "Annuler", + + "can_be_manually_activated": "La session peut être activée manuellement", + + "settings.edit.title": "Modifier", + "settings.add_activity.title": "Ajouter une activité", + + "settings.duplicate.title": "Dupliquer", + "duplicate.title": "Dupliquer la session", + "duplicate.submit": "Dupliquer", + + "settings.activate.title": "Activer", + "active.title": "Active", + + "settings.pause.title": "Mettre en pause", + "paused.title": "En pause", + + "settings.finish.title": "Terminer", + "finished.title": "Terminée", + "finish.confirm": "Êtes-vous sûr de vouloir terminer cette session ? Cette action est irréversible.", + + "settings.delete.title": "Supprimer", + "delete.confirm": "Êtes-vous sûr de vouloir supprimer la session '{{session}}' de l'SIMLET '{{SIMLET}}'?\nToutes les activités et les données seront également supprimées", + + "settings.export.title": "Exporter", + "set_tester.title": "Me définir comme testeur dans cette session", + "reset_tester.title": "Réinitialiser testeur (retirer et remettre)", + "unset_tester.title": "Me retirer comme testeur", + + "status.description": "", + "active.description": "", + "paused.description": "", + "finished.description": "" +} \ No newline at end of file diff --git a/logger.js b/logger.js new file mode 100755 index 00000000..78ef6c77 --- /dev/null +++ b/logger.js @@ -0,0 +1,88 @@ +const pino = require('pino'); +const fs = require('fs'); +const path = require('path'); + +const logsFolder = process.env.LOG_FOLDER || path.join(__dirname, '../../logs'); + +// Ensure logs folder exists +if (!fs.existsSync(logsFolder)) { + fs.mkdirSync(logsFolder, { recursive: true }); +} + +// Safe timestamp for filename (no colons) +const timestamp = new Date().toISOString().replace(/:/g, '-'); +const processTag = process.env.PROCESS_TAG || '[MAIN]'; +const logFile = path.join(logsFolder, `${processTag}_${timestamp}.log`); + +// Base logger options +const options = { + base: { + tag: processTag + }, + level: (process.env.LOG_LEVEL || 'info').toLowerCase(), + redact: { + paths: [ + 'config.clientSecret', + 'config.password', + 'config.api.adminPassword', + 'config.JWT.secret', + 'config.limesurvey.adminPassword', + 'config.sso.clientSecret', + 'config.sso.adminPassword', + 'config.a2.adminPassword', + 'config.LTI.platform.mongo.password', + 'config.LTI.platform.key' + ], + censor: '**REDACTED**' + }, + customLevels: { log: 30 }, + serializers: { + err: pino.stdSerializers.err, + req: pino.stdSerializers.req, + res: pino.stdSerializers.res + }, + transport:{ + targets: [ + { + target: 'pino/file', + level: (process.env.LOG_LEVEL || 'info').toLowerCase(), + options: { + destination: logFile, + singleLine: true, + mkdir: true + } + } + ] + } +}; + +if(process.env.NODE_ENV !== 'production') { + options.transport.targets.push( + { + target: 'pino-pretty', + options: { colorize: true, translateTime: 'yyyy-mm-dd HH:MM:ss', ignore: 'pid,hostname' } + } + ); +} +// Create logger +const logger = pino(options); + +// Global exception handlers (safe fallback) +process.on('uncaughtException', err => { + try { + logger.fatal(err, 'uncaughtException'); + } catch { + console.error('uncaughtException', err); + } + process.exitCode = 1; +}); + +process.on('unhandledRejection', reason => { + try { + logger.fatal(reason, 'unhandledRejection'); + } catch { + console.error('unhandledRejection', reason); + } +}); + +module.exports = logger; \ No newline at end of file diff --git a/logs/.gitignore b/logs/.gitignore new file mode 100755 index 00000000..21910320 --- /dev/null +++ b/logs/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files in this dir... +* +# ... except for this one. +!.gitignore \ No newline at end of file diff --git a/middleware/setLanguageMiddleware.js b/middleware/setLanguageMiddleware.js new file mode 100644 index 00000000..e3fcabd5 --- /dev/null +++ b/middleware/setLanguageMiddleware.js @@ -0,0 +1,4 @@ +export const setLanguage = (req, res, next) => { + res.locals.lng = req.language; + next(); +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 919873ed..bfabbf08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,67 +1,309 @@ { "name": "simva-front", - "version": "1.0.0", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "simva-front", - "version": "1.0.0", + "version": "0.0.1", "dependencies": { "axios": "^1.7.4", + "base58-universal": "^2.0.0", "body-parser": "1.20.3", "connect-mongo": "3", - "cookie-parser": "1.3.5", + "cookie-parser": "^1.4.7", "ejs": "^3.1.10", - "express": "4.21.0", + "express": "^4.21.2", "express-ejs-extend": "^0.0.1", "express-fileupload": "1.4.0", - "express-session": "1.15.6", + "express-session": "^1.18.1", "html": "^1.0.0", + "i18next": "^25.3.2", + "i18next-fs-backend": "^2.6.0", + "i18next-http-middleware": "^3.7.4", "jsonwebtoken": "^9.0.0", - "mongoose": "^5.7.8", + "kafkajs": "^2.2.4", + "ms": "^2.1.3", + "multer": "^2.1.1", + "node-cron": "3.0.3", "passport": "^0.6.0", - "passport-keycloak-oauth2-oidc": "^1.0.3" + "passport-keycloak-oauth2-oidc": "^1.0.3", + "pino": "^9.6.0", + "pm2": "^6.0.14" }, "devDependencies": { - "nodemon": "^3.1.4" + "nodemon": "^3.1.9", + "pino-pretty": "^13.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@types/bson": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", - "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", + "node_modules/@pm2/agent": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.1.1.tgz", + "integrity": "sha512-0V9ckHWd/HSC8BgAbZSoq8KXUG81X97nSkAxmhKDhmF8vanyaoc1YXwc2KVkbWz82Rg4gjd2n9qiT3i7bdvGrQ==", + "license": "AGPL-3.0", + "dependencies": { + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.3.1", + "eventemitter2": "~5.0.1", + "fast-json-patch": "^3.1.0", + "fclone": "~1.0.11", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.0", + "proxy-agent": "~6.4.0", + "semver": "~7.5.0", + "ws": "~7.5.10" + } + }, + "node_modules/@pm2/agent/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", "dependencies": { - "@types/node": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "node_modules/@pm2/agent/node_modules/dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==", + "license": "MIT" + }, + "node_modules/@pm2/agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { - "@types/bson": "*", - "@types/node": "*" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@types/node": { - "version": "20.11.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.23.tgz", - "integrity": "sha512-ZUarKKfQuRILSNYt32FuPL20HS7XwNT7/uRwSV8tiHWfyyVwDLYZNF6DZKc2bove++pgfsXn9sUwII/OsQ82cQ==", + "node_modules/@pm2/agent/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==", + "license": "ISC", "dependencies": { - "undici-types": "~5.26.4" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "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/@pm2/agent/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==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-ZcNHqQjMuNRcQ7Z1zJbFIQZO/BDKV3KbiTckWdfbUaYhj7uNmUwb+FbdDWSCkvxNr9dBJQwvV17o6QBkAvgO0g==", + "license": "MIT", + "bin": { + "blessed": "bin/tput.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@pm2/io": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz", + "integrity": "sha512-IxHuYURa3+FQ6BKePlgChZkqABUKFYH6Bwbw7V/pWU1pP6iR1sCI26l7P9ThUEB385ruZn/tZS3CXDUF5IA1NQ==", + "license": "Apache-2", + "dependencies": { + "async": "~2.6.1", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "~7.5.4", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@pm2/io/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/io/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/@pm2/io/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==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/io/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==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/js-api": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz", + "integrity": "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==", + "license": "Apache-2", + "dependencies": { + "async": "^2.6.3", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "extrareqp2": "^1.0.0", + "ws": "^7.0.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@pm2/js-api/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/js-api/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/js-api/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1" + } + }, + "node_modules/@pm2/pm2-version-check/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" }, "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==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -70,10 +312,44 @@ "node": ">= 0.6" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==", + "license": "MIT" + }, + "node_modules/amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", + "license": "MIT", + "dependencies": { + "amp": "0.3.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "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==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -84,11 +360,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "4.0.0-node10", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.0.0-node10.tgz", + "integrity": "sha512-BRrU0Bo1X9dFGw6KgGz6hWrqQuOlVEDOzkb0QSLZY9sXHqA7pNj7yHPVJRz7y/rj4EOJ3d/D5uxH+ee9leYgsg==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "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, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -97,25 +382,67 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "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==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -123,54 +450,66 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/axios/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/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base58-universal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base58-universal/-/base58-universal-2.0.0.tgz", + "integrity": "sha512-BgkgF8zVLOAygszG4W8NkLm7iXrw80VYAOcedrzANrIhS14+4W6zVqjyGTFUBM/FpqkHUt8aAYd4DbBBfn3zKg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14" + } }, "node_modules/base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, + "node_modules/basic-ftp": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "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, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "license": "MIT", "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, - "node_modules/bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "node_modules/bodec": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", + "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==", + "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.3", @@ -197,18 +536,20 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -220,6 +561,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "license": "Apache-2.0", "engines": { "node": ">=0.6.19" } @@ -227,12 +569,14 @@ "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==" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" }, "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==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/busboy": { "version": "1.6.0", @@ -249,21 +593,32 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "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==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "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" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -276,6 +631,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -287,11 +643,17 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/charm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==", + "license": "MIT/X11" + }, "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, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -311,10 +673,35 @@ "fsevents": "~2.3.2" } }, + "node_modules/cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "dependencies": { + "chalk": "3.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/cli-tableau/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, "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==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -325,12 +712,21 @@ "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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -338,10 +734,17 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, "node_modules/concat-stream": { "version": "1.6.2", @@ -350,6 +753,7 @@ "engines": [ "node >= 0.8" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -361,6 +765,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-3.2.0.tgz", "integrity": "sha512-0Mx88079Z20CG909wCFlR3UxhMYGg6Ibn1hkIje1hwsqOLWtL9HJV+XD0DAjUvQScK6WqY/FA8tSVQM9rR64Rw==", + "license": "MIT", "dependencies": { "mongodb": "^3.1.0" } @@ -369,6 +774,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -380,24 +786,27 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz", - "integrity": "sha512-mWkFhcL+HVG1KjeCjEBVJJ7s4sAGMLiBDFSDs4bzzvgLZt7rW8BhP6XV/8b1+pNvx/skd3yYxPuaF3Z6LlQzyw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { - "node": "*" + "node": ">= 0.6" } }, "node_modules/cookie-parser": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz", - "integrity": "sha512-YN/8nzPcK5o6Op4MIzAd4H4qUal5+3UaMhVIeaafFYL0pKvBQA/9Yhzo7ZwvBpjdGshsiTAb1+FC37M6RdPDFg==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", + "license": "MIT", "dependencies": { - "cookie": "0.1.3", + "cookie": "0.7.2", "cookie-signature": "1.0.6" }, "engines": { @@ -407,47 +816,86 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==", + "license": "MIT" + }, + "node_modules/culvert": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", + "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } }, - "node_modules/crc": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", - "integrity": "sha512-wcAOOnkzlwFAlFCCF20ZAiGn25JgSBy+oQrdOeszuk0bxI2nc29YFFmlCbDEfZJJljuw4XVqHrGV34J89910yA==" + "node_modules/dayjs": { + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.15.tgz", + "integrity": "sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ==", + "license": "MIT" }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "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==", + "node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 14" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -456,6 +904,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } @@ -464,6 +913,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -472,15 +922,31 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "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==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -488,12 +954,14 @@ "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==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -513,14 +981,33 @@ "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==", + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4" + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -534,12 +1021,103 @@ "node": ">= 0.4" } }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "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==", "license": "MIT" }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "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==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -549,10 +1127,16 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==", + "license": "MIT" + }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -560,7 +1144,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -574,7 +1158,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -589,12 +1173,17 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express-ejs-extend": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/express-ejs-extend/-/express-ejs-extend-0.0.1.tgz", "integrity": "sha512-XsqcWrDm5rvNqJisFe93mFTXX8mP12eIzBcTzuzqtGu/zQetkxkvgbCaP4RLHJTpdmkc89dIvTlurLB8VHmP/A==", + "license": "MIT", "dependencies": { "ejs": ">=2.4.1" } @@ -603,6 +1192,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.0.tgz", "integrity": "sha512-RjzLCHxkv3umDeZKeFeMg8w7qe0V09w3B7oGZprr/oO2H/ISCgNzuqzn7gV3HRWb37GjRk429CCpSLS2KNTqMQ==", + "license": "MIT", "dependencies": { "busboy": "^1.6.0" }, @@ -611,60 +1201,106 @@ } }, "node_modules/express-session": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", - "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz", + "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==", + "license": "MIT", "dependencies": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "crc": "3.4.4", + "cookie": "0.7.2", + "cookie-signature": "1.0.7", "debug": "2.6.9", - "depd": "~1.1.1", - "on-headers": "~1.0.1", - "parseurl": "~1.3.2", - "uid-safe": "~2.1.5", - "utils-merge": "1.0.1" + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "node_modules/express-session/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/express-session/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" + "node_modules/extrareqp2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz", + "integrity": "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.0" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=6" } }, + "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, + "license": "MIT" + }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", + "license": "MIT" + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -676,7 +1312,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -703,15 +1339,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -721,10 +1358,27 @@ } } }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "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", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -742,8 +1396,8 @@ "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, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -762,16 +1416,21 @@ } }, "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==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -780,11 +1439,67 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/git-node-fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", + "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==", + "license": "MIT" + }, + "node_modules/git-sha1": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", + "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==", + "license": "MIT" + }, "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, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -793,12 +1508,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -808,26 +1523,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } }, - "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==", - "license": "MIT", - "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==", + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -836,11 +1540,14 @@ "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==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -860,10 +1567,18 @@ "node": ">= 0.4" } }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "dev": true, + "license": "MIT" + }, "node_modules/html": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz", "integrity": "sha512-lw/7YsdKiP3kk5PnR1INY17iJuzdAtJewxr14ozKJWbbR97znovZ0mh+WEMZ8rjc3lgTK+ID/htTjuyGKB52Kw==", + "license": "BSD", "dependencies": { "concat-stream": "^1.4.7" }, @@ -875,6 +1590,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -886,41 +1602,163 @@ "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==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, - "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==", + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">= 0.10" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/i18next": { + "version": "25.3.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.2.tgz", + "integrity": "sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-fs-backend": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.0.tgz", + "integrity": "sha512-3ZlhNoF9yxnM8pa8bWp5120/Ob6t4lVl1l/tbLmkml/ei3ud8IWySCHt2lrY5xWRlSU5D9IV2sm5bEbGuTqwTw==", + "license": "MIT" + }, + "node_modules/i18next-http-middleware": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/i18next-http-middleware/-/i18next-http-middleware-3.7.4.tgz", + "integrity": "sha512-RANEF3XNpR5ExJryg3wKIycrPEYg7IdZiEvWFwb2lyDTwG5nB3AvhD5SfqRFT02Jbn8MHS5+xq7p4W+dX2ZJ8g==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "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, + "license": "ISC" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "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==", + "license": "MIT", + "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, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -928,11 +1766,26 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -941,7 +1794,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -953,7 +1806,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -961,12 +1814,14 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -980,32 +1835,76 @@ "node": ">=10" } }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-git": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", + "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", + "license": "MIT", + "dependencies": { + "bodec": "^0.1.0", + "culvert": "^0.1.2", + "git-sha1": "^0.1.2", + "pako": "^0.2.5" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC", + "optional": true + }, "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", "dependencies": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "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.3.8" + "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==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } @@ -1014,25 +1913,92 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, - "node_modules/kareem": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", - "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + "node_modules/kafkajs": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", + "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1041,6 +2007,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT", "optional": true }, "node_modules/merge-descriptors": { @@ -1056,6 +2023,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1076,6 +2044,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1084,6 +2053,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -1095,6 +2065,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1102,19 +2073,39 @@ "node": "*" } }, - "node_modules/minimatch/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/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, "node_modules/mongodb": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz", "integrity": "sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==", + "license": "Apache-2.0", "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", @@ -1149,109 +2140,128 @@ } } }, - "node_modules/mongoose": { - "version": "5.13.22", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.22.tgz", - "integrity": "sha512-p51k/c4X/MfqeQ3I1ranlDiggLzNumZrTDD9CeezHwZxt2/btf+YZD7MCe07RAY2NgFYVMayq6jMamw02Jmf9w==", + "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==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz", + "integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==", + "license": "MIT", "dependencies": { - "@types/bson": "1.x || 4.0.x", - "@types/mongodb": "^3.5.27", - "bson": "^1.1.4", - "kareem": "2.3.2", - "mongodb": "3.7.4", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.8.4", - "mquery": "3.2.5", - "ms": "2.1.2", - "optional-require": "1.0.x", - "regexp-clone": "1.0.0", - "safe-buffer": "5.2.1", - "sift": "13.5.2", - "sliced": "1.0.1" + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "type-is": "^1.6.18" }, "engines": { - "node": ">=4.0.0" + "node": ">= 10.16.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mongoose" + "url": "https://opencollective.com/express" } }, - "node_modules/mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", - "peerDependencies": { - "mongoose": "*" + "node_modules/multer/node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" } }, - "node_modules/mongoose/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/mongoose/node_modules/optional-require": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", - "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", + "node_modules/multer/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==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/mpath": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz", - "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==", - "engines": { - "node": ">=4.0.0" - } + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" }, - "node_modules/mquery": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", - "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", + "node_modules/needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "license": "MIT", "dependencies": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" }, "engines": { - "node": ">=4.0.0" + "node": ">= 4.4.x" } }, - "node_modules/mquery/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "node_modules/mquery/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-cron": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", + "license": "ISC", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/nodemon": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", - "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", "debug": "^4", @@ -1276,12 +2286,13 @@ } }, "node_modules/nodemon/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1297,21 +2308,17 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, - "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/nodemon/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, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -1319,39 +2326,25 @@ "node": ">=4" } }, - "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, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/oauth": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz", - "integrity": "sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q==" + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.2.tgz", + "integrity": "sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q==", + "license": "MIT" }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1360,10 +2353,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "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==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -1375,14 +2378,26 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.10.tgz", + "integrity": "sha512-0r3OB9EIQsP+a5HVATHq2ExIy2q/Vaffoo4IAikW1spCYswhLxqWQS0i3GwS3AdY/OIP4SWZHLGz8CMU558PGw==", + "license": "Apache-2.0", "dependencies": { "require-at": "^1.0.6" }, @@ -1390,10 +2405,66 @@ "node": ">=4" } }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1402,6 +2473,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "license": "MIT", "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", @@ -1419,6 +2491,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/passport-keycloak-oauth2-oidc/-/passport-keycloak-oauth2-oidc-1.0.5.tgz", "integrity": "sha512-uvZGTFu7MozqOIocDdSlEImEQTaPd8g5Lwbt83SbFqOVvCS3PelKjMQOYoJ7ERL7ELOY6puV0BY+Pw8ExM4EYw==", + "license": "MIT", "dependencies": { "lodash": "^4.17.20", "passport-oauth2": "^1.5.0" @@ -1428,6 +2501,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.8.0.tgz", "integrity": "sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA==", + "license": "MIT", "dependencies": { "base64url": "3.x.x", "oauth": "0.10.x", @@ -1451,10 +2525,16 @@ "node": ">= 0.4.0" } }, + "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==", + "license": "MIT" + }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/pause": { @@ -1466,7 +2546,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1474,15 +2554,310 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidusage": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", + "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pino": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.7.0.tgz", + "integrity": "sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.0.0.tgz", + "integrity": "sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pump": "^3.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "license": "MIT" + }, + "node_modules/pm2": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.14.tgz", + "integrity": "sha512-wX1FiFkzuT2H/UUEA8QNXDAA9MMHDsK/3UHj6Dkd5U7kxyigKDA5gyDw78ycTQZAuGCLWyUX5FiXEuVQWafukA==", + "license": "AGPL-3.0", + "dependencies": { + "@pm2/agent": "~2.1.1", + "@pm2/blessed": "0.1.81", + "@pm2/io": "~6.1.0", + "@pm2/js-api": "~0.8.0", + "@pm2/pm2-version-check": "^1.0.4", + "ansis": "4.0.0-node10", + "async": "3.2.6", + "chokidar": "3.6.0", + "cli-tableau": "2.0.1", + "commander": "2.15.1", + "croner": "4.1.97", + "dayjs": "1.11.15", + "debug": "4.4.3", + "enquirer": "2.3.6", + "eventemitter2": "5.0.1", + "fclone": "1.0.11", + "js-yaml": "4.1.1", + "mkdirp": "1.0.4", + "needle": "2.4.0", + "pidusage": "3.0.2", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.1", + "pm2-deploy": "~1.0.2", + "pm2-multimeter": "^0.1.2", + "promptly": "2.2.0", + "semver": "7.7.2", + "source-map-support": "0.5.21", + "sprintf-js": "1.1.2", + "vizion": "~2.2.1" + }, + "bin": { + "pm2": "bin/pm2", + "pm2-dev": "bin/pm2-dev", + "pm2-docker": "bin/pm2-docker", + "pm2-runtime": "bin/pm2-runtime" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "pm2-sysmonit": "^1.2.8" + } + }, + "node_modules/pm2-axon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", + "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", + "license": "MIT", + "dependencies": { + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^4.3.1", + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=5" + } + }, + "node_modules/pm2-axon-rpc": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", + "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1" + }, + "engines": { + "node": ">=5" + } + }, + "node_modules/pm2-axon-rpc/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-axon/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-deploy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", + "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", + "license": "MIT", + "dependencies": { + "run-series": "^1.1.8", + "tv4": "^1.3.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pm2-multimeter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", + "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", + "license": "MIT/X11", + "dependencies": { + "charm": "~0.1.1" + } + }, + "node_modules/pm2-sysmonit": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", + "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==", + "license": "Apache", + "optional": true, + "dependencies": { + "async": "^3.2.0", + "debug": "^4.3.1", + "pidusage": "^2.0.21", + "systeminformation": "^5.7", + "tx2": "~1.0.4" + } + }, + "node_modules/pm2-sysmonit/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-sysmonit/node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pm2/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/promptly": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", + "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", + "license": "MIT", + "dependencies": { + "read": "^1.0.4" + } }, "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==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -1491,16 +2866,65 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "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==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } }, "node_modules/qs": { "version": "6.13.0", @@ -1517,10 +2941,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, "node_modules/random-bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1538,6 +2969,7 @@ "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==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -1548,10 +2980,23 @@ "node": ">= 0.8" } }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1565,13 +3010,14 @@ "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -1579,19 +3025,95 @@ "node": ">=8.10.0" } }, - "node_modules/regexp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } }, "node_modules/require-at": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", + "license": "Apache-2.0", "engines": { "node": ">=4" } }, + "node_modules/require-in-the-middle": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", + "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1609,17 +3131,29 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/saslprep": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "license": "MIT", "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" @@ -1628,10 +3162,27 @@ "node": ">=6" } }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1672,12 +3223,6 @@ "node": ">= 0.8" } }, - "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==", - "license": "MIT" - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -1693,38 +3238,82 @@ "node": ">= 0.8.0" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "license": "BSD-2-Clause" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "define-data-property": "^1.1.4", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -1733,16 +3322,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sift": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + "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==", + "license": "ISC" }, "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, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -1750,24 +3341,119 @@ "node": ">=10" } }, - "node_modules/sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" + "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==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "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==", + "license": "MIT", "optional": true, "dependencies": { "memory-pager": "^1.0.2" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "license": "BSD-3-Clause" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1784,6 +3470,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -1791,12 +3478,27 @@ "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "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==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1804,11 +3506,59 @@ "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/systeminformation": { + "version": "5.31.5", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.5.tgz", + "integrity": "sha512-5SyLdip4/3alxD4Kh+63bUQTJmu7YMfYQTC+koZy7X73HgNqZSD2P4wOZQWtUncvPvcEmnfIjCoygN4MRoEejQ==", + "license": "MIT", + "optional": true, + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, "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, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1820,26 +3570,60 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "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==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, + "license": "ISC", "bin": { "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "license": "Apache-2.0" + }, + "node_modules/tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", + "license": [ + { + "type": "Public Domain", + "url": "http://geraintluff.github.io/tv4/LICENSE.txt" + }, + { + "type": "MIT", + "url": "http://jsonary.com/LICENSE.txt" + } + ], + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tx2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz", + "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==", + "license": "MIT", + "optional": true, + "dependencies": { + "json-stringify-safe": "^5.0.1" + } + }, "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==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -1851,12 +3635,14 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" }, "node_modules/uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "license": "MIT", "dependencies": { "random-bytes": "~1.0.0" }, @@ -1867,23 +3653,21 @@ "node_modules/uid2": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", - "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" + "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==", + "license": "MIT" }, "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/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==" + "dev": true, + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1891,23 +3675,93 @@ "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==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "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==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "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==", + "license": "MIT", "engines": { "node": ">= 0.8" } + }, + "node_modules/vizion": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", + "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==", + "license": "Apache-2.0", + "dependencies": { + "async": "^2.6.3", + "git-node-fs": "^1.0.0", + "ini": "^1.3.5", + "js-git": "^0.7.8" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vizion/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" } } } diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 405191a0..93294ede --- a/package.json +++ b/package.json @@ -1,28 +1,43 @@ { "name": "simva-front", "description": "Simva, AKA Simple Validator, AKA SurveyManager is the evolution of a tool created to integrate and ease the task of validating serious games using pre-post surveys as a control point. This version allows to create more complex studies with more variety of activities and different allocations.", - "version": "1.0.0", + "version": "0.0.1", "scripts": { - "start": "node bin/www", - "dev": "nodemon --inspect=0.0.0.0:9229 bin/www" + "start": "pm2-runtime ecosystem.config.js", + "dev": "pm2-runtime ecosystem.config.js", + "dev:profiling": "pm2-runtime ecosystem.config.js", + "dev:clinic:doctor": "clinic doctor $CLINIC_ARGS -- pm2-runtime ecosystem.config.js", + "dev:clinic:bubbleprof": "clinic bubbleprof $CLINIC_ARGS -- pm2-runtime ecosystem.config.js", + "dev:clinic:flame": "clinic flame $CLINIC_ARGS -- pm2-runtime ecosystem.config.js", + "dev:clinic:heapprofiler": "clinic heapprofiler $CLINIC_ARGS -- pm2-runtime ecosystem.config.js" }, "dependencies": { + "axios": "^1.7.4", + "base58-universal": "^2.0.0", "body-parser": "1.20.3", - "cookie-parser": "1.3.5", + "connect-mongo": "3", + "cookie-parser": "^1.4.7", "ejs": "^3.1.10", - "express": "4.21.0", + "express": "^4.21.2", "express-ejs-extend": "^0.0.1", "express-fileupload": "1.4.0", - "express-session": "1.15.6", + "express-session": "^1.18.1", "html": "^1.0.0", + "i18next": "^25.3.2", + "i18next-fs-backend": "^2.6.0", + "i18next-http-middleware": "^3.7.4", "jsonwebtoken": "^9.0.0", - "mongoose": "^5.7.8", - "connect-mongo": "3", + "kafkajs": "^2.2.4", + "ms": "^2.1.3", + "multer": "^2.1.1", + "node-cron": "3.0.3", "passport": "^0.6.0", "passport-keycloak-oauth2-oidc": "^1.0.3", - "axios": "^1.7.4" + "pino": "^9.6.0", + "pm2": "^6.0.14" }, "devDependencies": { - "nodemon": "^3.1.4" + "nodemon": "^3.1.9", + "pino-pretty": "^13.0.0" } } diff --git a/profiling.js b/profiling.js new file mode 100755 index 00000000..f6f77eb8 --- /dev/null +++ b/profiling.js @@ -0,0 +1,8 @@ +const config = require('./config.js'); +const path = require('path'); +const logger = require("./logger.js"); +const ms = require('ms'); + +if(process.env.NODE_ENV == "development" && config.simva.profiling) { + logger.info("Profiling in progress..."); +} \ No newline at end of file diff --git a/public/activities/activitypainter.js b/public/activities/activitypainter.js index 0432ffdb..744e603e 100644 --- a/public/activities/activitypainter.js +++ b/public/activities/activitypainter.js @@ -9,75 +9,291 @@ if(!PainterFactory){ var ActivityPainter = { supportedType: 'activity', - simpleName: 'Default activity', - description: '', - + simple_name: 'activity.activity_type', + description: 'activity.description', + commun : {}, + communSpecific : {}, + specific : {}, utils: {}, setUtils: function(utils){ this.utils = utils; }, - getExtraForm: function () { + getUsernameOrToken : function (user) { + if(user.isToken) { + return user.token; + } else { + return user.username; + } + }, + + getParticipantKey: function(participant){ + if(participant && participant.user_id !== undefined && participant.user_id !== null){ + return String(participant.user_id); + } + + if(participant && participant.participant_id !== undefined && participant.participant_id !== null){ + return String(participant.participant_id); + } + + if(participant && participant.id !== undefined && participant.id !== null){ + return String(participant.id); + } + + if(participant && participant.isToken && participant.token !== undefined && participant.token !== null){ + return String(participant.token); + } + + return String(participant.username); + }, + + getParticipantKeys: function(participant){ + let keys = []; + + if(participant && participant.user_id !== undefined && participant.user_id !== null){ + keys.push(String(participant.user_id)); + } + + if(participant && participant.participant_id !== undefined && participant.participant_id !== null){ + keys.push(String(participant.participant_id)); + } + + if(participant && participant.id !== undefined && participant.id !== null){ + keys.push(String(participant.id)); + } + + if(participant && participant.username !== undefined && participant.username !== null){ + keys.push(String(participant.username)); + } + + if(participant && participant.token !== undefined && participant.token !== null){ + keys.push(String(participant.token)); + } + + if(participant && participant.isToken && participant.token !== undefined && participant.token !== null){ + keys.unshift(String(participant.token)); + } + + return Array.from(new Set(keys)); + }, + + getParticipantMappedValue: function(map, participant){ + if(!map){ + return undefined; + } + + const keys = this.getParticipantKeys(participant); + for (let i = 0; i < keys.length; i++) { + if(Object.prototype.hasOwnProperty.call(map, keys[i])) { + return map[keys[i]]; + } + } + + return undefined; + }, + + isDownloadUrl: function(value){ + return Utils.isDownloadUrl(value); + }, + + downloadContent: function(source, filename, errorHeading){ + Utils.downloadContent(source, filename, errorHeading); + }, + + getExtraForm: function (callback) { + callback(null, ''); + }, + + getEditExtraForm: function () { return ''; }, + updateInputEditExtraForm(activity) { + }, + + extractFileFromEditForm(form, inputName, activity, fileField, typeField, typeValue) { + console.log('[activitypainter] extractFileFromEditForm called'); + let fileInput = null; + + // Normalize form (always jQuery) + let $form = (form instanceof $) ? form : $(form); + + // Much simpler + reliable selector + fileInput = $form.find(`input[name="${inputName}"], input[id="${inputName}"], input[id="edit_${inputName}"]`).get(0); + + console.log('[activitypainter] fileInput selected:', fileInput); + + if (fileInput && fileInput.files && fileInput.files.length > 0) { + let file = fileInput.files[0]; + console.log('[activitypainter] File selected:', file); + + // 🚨 KEY CHANGE: use FormData instead of base64 + let formData = new FormData(); + formData.append('formData', true); + // Append file + formData.append(fileField, file); + + // Append metadata + formData.append(typeField, typeValue); + + // Add other activity fields + Object.keys(activity).forEach(key => { + formData.append(key, activity[key]); + }); + + console.log('[activitypainter] FormData ready'); + console.log('FormData entries:'); + for (let pair of formData.entries()) { + console.log(pair[0]+ ':', pair[1]); + } + return formData; // 👈 send FormData instead of activity + } + + console.log('[activitypainter] No file selected'); + return undefined; + }, + + extractEditInformation: function(form, actualActivity, callback){ + let jform = $(form); + let formdata = Utils.getFormData(jform); + let activity = {}; + console.log('[activitypainter] extractEditInformation called'); + console.log('Form:', form); + console.log('FormData:', formdata); + console.log('actualActivity:', actualActivity); + if(actualActivity.activity_name !== formdata.name) { + activity.activity_name = formdata.name; + } + callback(null, activity); + }, + + extractInformation: function(form, callback){ let activity = {}; let jform = $(form); let formdata = Utils.getFormData(jform); - activity.name = formdata.name; - activity.type = this.supportedType; + console.log('[activitypainter] extractInformation called'); + console.log('Form:', form); + console.log('FormData:', formdata); + + activity.activity_name = formdata.name; + activity.activity_type = this.supportedType; callback(null, activity); }, - fullyPaintActivity: function(activity){ + fullyPaintActivity: function(activity, participants){ this.paintActivity(activity, participants); - let tmp = this; + this.updateParticipants(activity, participants); + }, - this.updateParticipants(activity); - setInterval(function(){ - tmp.updateParticipants(activity); - }, 5000); + updateParticipants: function(activity, participants){ + this.paintActivityInit(activity, activity.data.init, participants); + this.paintActivityProgress(activity, activity.data.progress, participants); + this.paintActivityCompletion(activity, activity.data.completion, true, participants); + this.paintActivityResult(activity, activity.data.hasresult, true, participants); + if(activity.data.openable){ + PainterFactory.Painters["activity"].paintActivityTargets(activity, activity.data.target, participants); + } }, - updateParticipants: function(activity){ - let tmp = this; - activity.tmp = {}; + paintActivityTargets: function(activity, results, participants=[]){ + if(!results) { + return; + } - Simva.getActivityCompletion(activity._id, function(error, result){ - tmp.paintActivityCompletion(activity, result); - }); + for (var i = 0; i < participants.length; i++) { + const participantKey = this.getParticipantKey(participants[i]); + const target = this.getParticipantMappedValue(results, participants[i]); + if(target) { + $(`#${activity.activity_id}_${participantKey}_target`).attr('href', target); + } + } + }, + + getExtraKebabItems: function(activity) { + return ''; + }, - Simva.hasActivityResult(activity._id, function(error, result){ - tmp.paintActivityResult(activity, result); - }); + paintActivityTopBar: function(activity, extraItems) { + return `
${this.simpleName}
-Default Activity
-${this.simple_name}
+ ${this.paintActivityParticipantsTable(activity, participants, true)} +| User | Completed | Result | |||||
|---|---|---|---|---|---|---|---|
| ${this.commun.user_title} | `; + if(init) { + toret += `${this.commun.init_title} | `; + } + if(progress) { + toret += `${this.commun.progress_title} | `; + } + toret += `${this.commun.completed_title} | `; + if(result) { + toret += `${this.commun.result_title} | `; + } + toret += '
|---|---|---|---|---|
| ${this.paintUsernameOrToken(activity, participants[i])} | `; + if(init) { + toret += `${this.paintInitRow(activity.activity_id,participantKey)}`; + } + if(progress) { + toret += `${this.paintProgressRow(activity.activity_id,participantKey)}` + } + toret += `${this.paintCompletionRow(activity.activity_id,participantKey, checkbox)}`; + if(result){ + toret += `${this.paintResultRow(activity.activity_id,participantKey)}`; + }else{ + toret += `${this.commun.result_disabled} | `; } - - toret += `|||
| ${participants[i].username} | ---- | ---- | `; } toret += '
- Game URI can include tags: {authToken}, {username}, and {activityId}
${this.specific.web_description}
++ ${this.specific.game_uri_description}
+${this.specific.web_description}
++ ${this.specific.game_uri_description}
+${this.simpleName}
`; - - - /* - activitybox += 'Realtime: '; - if(activity.extra_data.config.realtime){ - activitybox += `Dashboard`; - }else{ - activitybox += 'Disabled'; - } - activitybox += 'Trace Storage: '
- if(activity.extra_data.config.trace_storage) {
- activitybox += `Download Data
-
- XASU Config:
-
-
- `;
- } else {
- activitybox += 'Disabled';
- }
- activitybox +='
'
- activitybox += 'Backup: '
- if(activity.extra_data.config.backup){
- activitybox += ` ⬇️`
- } else {
- activitybox += 'Disabled';
- }
- activitybox += '
| User | Completed | '; - if(activity.extra_data.config.realtime){ - toret += 'Progress | Traces | '; - } - toret += 'Backup | |
|---|---|---|---|---|---|
| - ${participants[i].username} | `; - }else{ - toret += `${participants[i].username} | `; - } - - toret += `--- | `; - - if(activity.extra_data.config.realtime){ - toret += `--- | `; - }else{ - toret += '' - } - - if(activity.extra_data.config.backup){ - toret += `--- | Disabled | '; - } - } - - toret += '
URL : ${activity.game_url ? activity.game_url : '-'}
`; + } else { + urlOrType = `Type : Desktop
`; + } + let activitybox = `${this.simple_name} - ${activity.game_type == 'DESKTOP' ? this.specific.desktop_title : this.specific.web_title}
+ + ${PainterFactory.Painters["activity"].paintActivityParticipantsTable(activity, participants, true)} +${keys[i]}
`; - block += printAnalysisRecursive(analysis[keys[i]]); - }else{ - block += `${keys[i]}: ${analysis[keys[i]]}
`; + Simva.getMinioDataUrl(activity, (error, result) => { + if(error) { + Simva.getActivityResult(activity, (error, result) => { + if(error) { + toastParams.text = error.message; + $.toast(toastParams); + } else { + let hasResults = false; + for(const participant in result) { + if(result.hasOwnProperty(participant) && result[participant] != null) { + Utils.downloadContent(result[participant], `${this.communSpecific.result_file_prefix}_${activity}_${participant}.json`); + hasResults = true; + }; + } + if(!hasResults) { + Utils.download(`${this.communSpecific.result_file_prefix}_${activity}.json`, JSON.stringify(result,null,2)); + } } - } - - block += '`; - //
` + getExtraForm: function (callback) { + callback(null, ``); + }, + + getEditExtraForm: function () { + return `
${this.simpleName}
`; - - /* - activitybox += 'Realtime: '; - if(activity.extra_data.config.realtime){ - activitybox += `Dashboard`; - }else{ - activitybox += 'Disabled'; - } - activitybox += ' - ' - */ + const topBar = PainterFactory.Painters['activity'].paintActivityTopBar.call(this, activity, this.getExtraKebabItems(activity)); + let activitybox = `
${this.simple_name}
`; - activitybox += 'Trace Storage: ' - if(activity.extra_data.config.trace_storage){ - activitybox += `Folder`; + activitybox += `${this.communSpecific.storage_title}: ` + if(activity.trace_storage){ + activitybox += `Folder`; }else{ - activitybox += 'Disabled'; - } - - activitybox += `| User | Completed | Progress | Traces | Backup | |||
|---|---|---|---|---|---|---|---|
| ${participants[i].username} | `; - }else{ - toret += `${participants[i].username} | `; - } - - toret += `--- | `; - - if(activity.extra_data.config.realtime){ - toret += `--- | `; - }else{ - toret += 'Disabled | ' - } - - if(activity.extra_data.config.backup){ - toret += `--- | Disabled | '; - } + activitybox += `${this.commun.storage_disabled}`; } - - toret += '|
Survey ID:
- -You don\'t have surveys.
' - } - - form += `Click to open LimeSurvey
- -Select LLS file
- -${this.specific.new_description}
` + } else { + form += `${this.specific.surveyid_title}:
+ +${this.specific.new_description}
` + }; + callback(null, form); + }); + }, + getEditExtraForm: function () { + let form=`${this.specific.survey_title}`; + form += ''; + form+=`${this.simpleName}
-Survey ID: ${activity.extra_data.surveyId}
- - -| User | Completed | Result |
|---|---|---|
| ${participants[i].username} | ---- | ---- | `; + updateParticipants: async function(activity, participants){ + if(activity.data.openable){ + PainterFactory.Painters["activity"].paintActivityTargets(activity, activity.data.target, participants); } + PainterFactory.Painters["activity"].paintActivityCompletion(activity, activity.data.completion, false, participants); + PainterFactory.Painters["activity"].paintActivityProgress(activity, activity.data.progress, participants); + PainterFactory.Painters["activity"].paintActivityInit(activity, activity.data.init, participants); + console.log("Result"); + console.log(activity.data.result); + if(!activity.data.result){ + // Still update totals even without results + PainterFactory.Painters["activity"].paintActivityResult(activity, null, "No Results", participants, this.communSpecific.result_zero, "Started", this.communSpecific.result_view_partial_value, "Completed",this.communSpecific.result_view_final_value); + return; + } + const userids = Object.keys(activity.data.result); + const map = {}; + for (const userid of userids) { + let state = this.communSpecific.result_zero; + try { + const value = activity.data.result[userid]; + const completed = activity.data.completion[userid]; + map[userid] = state; + if (PainterFactory.Painters["activity"].isDownloadUrl(value)) { + console.log(`Fetching result for user ${userid} from URL: ${value}`); + map[userid] = this.communSpecific.result_view_partial_value; + //const response = await fetch(value); + //if (!response.ok) { + // throw new Error(`HTTP ${response.status}`); + //} + //const blob = await response.blob(); + //const text = await blob.text(); // ⚠️ must await + //console.log(text); + //let parsed; + //try { + // parsed = JSON.parse(text); // assuming JSON + //} catch { + // parsed = {}; + //} + if (completed) { + map[userid] = this.communSpecific.result_view_final_value; + } + } + } catch (error) { + $.toast({ + heading: 'Error loading the result', + text: error.message, + position: 'top-right', + icon: 'error', + stack: false + }); + } + }; + console.log("Map:"); + console.log(map); - toret += '
${this.simple_name}
+ + ${PainterFactory.Painters["activity"].paintActivityParticipantsTable(activity, participants, false)}${stringifyres}`;
-
- let context = $('#iframe_floating iframe')[0].contentWindow.document;
- let body = $('body', context);
-
- // Set the content and ensure proper styling
- body.html(content);
- body.css({
- 'margin': '0',
- 'padding': '0',
- 'overflow': 'auto',
- 'height': '100vh'
+ downloadResults: function(activity, user, type){
+ Simva.getActivityResultWithTypeForUser(activity, type, user, function(error, result){
+ if(error){
+ $.toast({
+ heading: this.commun.result_error_downloading,
+ text: error.message,
+ position: 'top-right',
+ icon: 'error',
+ stack: false
});
- toggleAddForm('iframe_floating');
+ }else{
+ let stringifyres=JSON.stringify(result[user], null, 2);
+ var filename = `${this.communSpecific.result_file_prefix}_${activity}_${user}_${type}.json`;
+ Utils.download(filename, stringifyres);
}
})
}
}
-PainterFactory.addPainter(LimeSurveyPainter);
\ No newline at end of file
+PainterFactory.addPainter(LimeSurveyPainter);
+// Patch: Update survey list when switching to 'limesurvey_byexisting' tab
+LimesurveyChangeTab = function(tab, form, subform){
+ console.log(`Changing to tab: ${subform}`);
+ Utils.changeTab(tab, form, subform);
+ // Add survey list update logic for limesurvey_byexisting
+ if(subform === 'limesurvey_byexisting'){
+ Simva.getSurveyList((error, result) => {
+ if(error){
+ console.error('Error fetching survey list:', error);
+ return;
+ }
+ var select = document.getElementById('existingid_select');
+ if(select){
+ while(select.firstChild){
+ select.removeChild(select.firstChild);
+ }
+ for(var i=0;i